• Как написать телеграм-бот на python с использованием облачных сервисов яндекс?

    @partyinvitation Автор вопроса
    Антон, Константин Нагибович, Спасибо большое! Всё получилось и заработало. Правда пришлось асинхронность кода убрать, но первый шаг сделан, и уже на рабочем варианте несомненно проще будет тестить и применять новый функционал и оптимизацию. Ещё раз благодарю!
  • Как написать телеграм-бот на python с использованием облачных сервисов яндекс?

    @partyinvitation Автор вопроса
    Константин Нагибович, сейчас работаю с яндекс.функциями и API-шлюзами. Возможно, требуется что-то ещё, но я пока копаюсь с тем, что есть. (Кстати, пошаманив, заставил бота говорить (приветствовать без остановки - что-то вызывает функцию постоянно, без команд, и вроде бы не в ответ на сообщения; в прошлых версиях кода этого не было, разбираюсь что сделал не так), но на команды всё же не реагирует)
  • Как написать телеграм-бот на python с использованием облачных сервисов яндекс?

    @partyinvitation Автор вопроса
    datka, благодарю, отредактировал. Забыл, что хранить токены нужно в переменных окружения :)
    Но интернет всё помнит, интернет не простит...
  • Как написать телеграм-бот на python с использованием облачных сервисов яндекс?

    @partyinvitation Автор вопроса
    import telebot
    import yadisk
    import requests
    import pandas as pd
    #from datetime import datetime
    
    # создаем объект бота и авторизуемся в Яндекс.Диске
    bot = telebot.TeleBot('токен')
    y = yadisk.YaDisk(token='токен')
    
    
    # задаем путь к файлу на Яндекс Диске
    path = '/Бот/Расписание для бота.xlsx'
    
    # получаем ссылку на скачивание файла
    url = y.get_download_link(path)
    
    # скачиваем файл и читаем его в датафрейм
    response = requests.get(url)
    with open('file.xlsx', 'wb') as f:
        f.write(response.content)
    df = pd.read_excel('file.xlsx', engine='openpyxl')
    
    
    # Обработчик команды /start, отправляет приветственное сообщение и кнопку с вызовом /menu
    @bot.message_handler(commands=['start'])
    def send_welcome(message):
        markup = telebot.types.ReplyKeyboardMarkup(row_width=1, resize_keyboard=True)
        itembtn1 = telebot.types.KeyboardButton('/menu')
        markup.add(itembtn1)
        bot.reply_to(message, "Привет, я бот для студентов.", reply_markup=markup)
    
    # Обработчик команды /menu, отправляет кнопки с выбором действия
    @bot.message_handler(commands=['menu'])
    def send_menu(message):
        chat_id = message.chat.id
        markup = telebot.types.InlineKeyboardMarkup()
        itembtn1 = telebot.types.InlineKeyboardButton('Контакты преподавателей', callback_data='contacts')
        itembtn2 = telebot.types.InlineKeyboardButton('Расписание занятий', callback_data='schedule_button')
        markup.add(itembtn1, itembtn2)
        bot.send_message(chat_id, 'Выберите команду:', reply_markup=markup)
    
    # Обработчик нажатия на кнопку в Inline-режиме
    @bot.callback_query_handler(func=lambda call: True)
    def callback_query(call):
        if call.data == 'contacts':
            bot.send_message(call.message.chat.id, 'Вот контакты преподавателей...')
        elif call.data == 'schedule_button':
            # Запоминаем chat_id пользователя, который нажал на кнопку
            chat_id = call.message.chat.id
            # Отправляем сообщение с просьбой ввести номер группы и день недели
            bot.send_message(chat_id, 'Введите номер группы и день недели (например, 301 понедельник)')
            # Запоминаем chat_id пользователя для последующей обработки ввода
            bot.register_next_step_handler(call.message, process_schedule_input)
    
    
    # Обработчик ввода данных для команды /schedule
    def process_schedule_input(message):
        try:
            # Загружаем данные из файла в объект Pandas DataFrame
            direct_link = y.get_download_link('/Бот/Расписание для бота.xlsx')
            response = requests.get(direct_link)
            response.raise_for_status()  # проверяем успешность загрузки файла
            df = pd.read_excel(response.content, engine='openpyxl', dtype=str, header=0)
    
            # Выводим все данные таблицы для отладки
            print(df)
            print(df.columns)  # выводим на экран названия столбцов
            print(df.index)  # выводим на экран названия строк
    
            # Получаем от пользователя номер группы и день недели
            group, weekday = message.text.split()
            group = int(group)  # Преобразуем значение group в строковое значение
    
            # Выводим номер группы и день недели для отладки
            print(f"Group: {group}, Weekday: {weekday}")
    
            # Проверяем, есть ли строка с названием дня недели
            weekday_row_index = df.index[df['День недели'] == weekday].tolist()
            if not weekday_row_index:
                raise ValueError(f"Название дня недели {weekday} не найдено в таблице")
    
            # Получаем данные для номера группы и дня недели
            group_col_name = int(group)
            filtered = df.loc[weekday_row_index, group_col_name]
    
            pd.set_option('display.max_colwidth', None)
            # Если данные найдены, отправляем их пользователю
            if not filtered.empty:
                # Формируем строку вывода
                output = "\n\n".join(["\n".join(cell.split("\n")) for cell in filtered])
                bot.send_message(message.chat.id, output)
            else:
                bot.send_message(message.chat.id, "Данные для этой группы и дня недели не найдены.")
        except requests.exceptions.HTTPError as e:
            bot.send_message(message.chat.id, f"Ошибка загрузки файла: {e}")
        except ValueError as e:
            bot.send_message(message.chat.id, f"Ошибка ввода: {e}")
        except Exception as e:
            bot.send_message(message.chat.id, f"Неизвестная ошибка: {e}")
    
    # Запускаем бота
    bot.polling()


    import base64
    import json
    import logging
    import aiohttp
    import pandas as pd
    from aiogram import Bot, Dispatcher, types
    from aiogram.contrib.middlewares.logging import LoggingMiddleware
    from aiohttp import web
    import yadisk
    
    API_TOKEN = 'токен'
    YANDEX_DISK_TOKEN = 'токен'
    
    logging.basicConfig(level=logging.INFO)
    
    bot = Bot(token=API_TOKEN)
    dp = Dispatcher(bot)
    dp.middleware.setup(LoggingMiddleware())
    
    y = yadisk.YaDisk(token=YANDEX_DISK_TOKEN)
    path = '/Бот/Расписание для бота.xlsx'
    
    async def on_startup(dp):
        webhook_url = "https://d5d803gi8o8tuc18idq7.apigw.yandexcloud.net/webhook"
        await bot.set_webhook(url=webhook_url)
    
    async def on_shutdown(dp):
        await bot.close()
    
    @dp.message_handler(commands=['start'])
    async def send_welcome(message: types.Message):
        markup = types.ReplyKeyboardMarkup(row_width=1, resize_keyboard=True)
        markup.add(types.KeyboardButton('/menu'))
        await bot.send_message(message.chat.id, "Привет, я бот для студентов.", reply_markup=markup)
    
    @dp.message_handler(commands=['menu'])
    async def send_menu(message: types.Message):
        chat_id = message.chat.id
        markup = types.InlineKeyboardMarkup()
        markup.add(
            types.InlineKeyboardButton('Контакты преподавателей', callback_data='contacts'),
            types.InlineKeyboardButton('Расписание занятий', callback_data='schedule_button')
        )
        await bot.send_message(chat_id, 'Выберите команду:', reply_markup=markup)
    
    @dp.callback_query_handler(lambda c: True)
    async def callback_query(call: types.CallbackQuery):
        if call.data == 'contacts':
            await bot.send_message(call.message.chat.id, 'Вот контакты преподавателей...')
        elif call.data == 'schedule_button':
            chat_id = call.message.chat.id
            await bot.send_message(chat_id, 'Введите номер группы и день недели (например, 301 понедельник)')
            await dp.register_next_step_handler(call.message, process_schedule_input)
    
    async def process_schedule_input(message: types.Message):
        pd.set_option('display.max_colwidth', None)
        try:
            direct_link = y.get_download_link(path)
            async with aiohttp.ClientSession() as session:
                async with session.get(direct_link) as response:
                    df = pd.read_excel(await response.read(), engine='openpyxl', dtype=str, header=0)
    
            group, weekday = message.text.split()
            group = int(group)
    
            weekday_row_index = df.index[df['День недели'] == weekday].tolist()
            if not weekday_row_index:
                raise ValueError(f"Название дня недели {weekday} не найдено в таблице")
    
            group_col_name = int(group)
            filtered = df.loc[weekday_row_index, group_col_name]
    
        except ValueError as e:
            await bot.send_message(message.chat.id, f"Ошибка ввода: {e}")
        except Exception as e:
            await bot.send_message(message.chat.id, f"Неизвестная ошибка: {e}")
        else:
            if not filtered.empty:
                output = "\n\n".join(["\n".join(cell.split("\n")) for cell in filtered])
                await bot.send_message(message.chat.id, output)
            else:
                await bot.send_message(message.chat.id, "Данные для этой группы и дня недели не найдены.")
    
    async def handle_webhook(request):
        logging.info(f"Received data: {request.content_type}")
    
        if request.content_type == 'application/json':
            data = await request.json()
        else:
            logging.warning(f"Unexpected content type: {request.content_type}")
            return web.Response(text=json.dumps({"status": "error"}))
    
        logging.info(f"Received data: {data}")
    
        if data is None:
            logging.warning("Received empty data")
            return web.Response(text=json.dumps({"status": "ok"}))
    
        try:
            update = types.Update(**data)
            await dp.process_updates([update])
        except Exception as e:
            logging.error(f"Error processing update: {e}")
    
        return web.Response(text=json.dumps({"status": "ok"}))
    
    async def handler(event, context):
        if event is not None and 'headers' in event and 'content-type' in event['headers']:
            content_type = event['headers']['content-type']
        else:
            content_type = 'application/json'
    
        if content_type == 'application/json':
            if 'body' in event and event['body'] is not None:
                data = json.loads(event['body'])
            else:
                logging.warning("Received empty body")
                return {"statusCode": 200, "body": json.dumps({"status": "error"})}
        elif content_type == 'application/x-www-form-urlencoded':
            raw_data = event['body']
            decoded_data = base64.b64decode(raw_data).decode('utf-8')
            data = json.loads(decoded_data)
        else:
            logging.warning(f"Unexpected content type: {content_type}")
            return {"statusCode": 200, "body": json.dumps({"status": "error"})}
    
        request = web.Request(web.RequestHandler(web.Application(), {}), {}, method='POST', path='/webhook', headers=event['headers'], content_type=content_type)
        request._read_bytes = data
        response = await handle_webhook(request)
        return {"statusCode": response.status, "body": await response.text()}