Ожидание ответа от пользователя Телеграмм бот на python
Пишу банальную программу для записи дел в ToDo, и при вводе задачи без конкретной даты хочу спросить у пользователя «На какую дату поставить задачу?» После этого вопроса бот не дожидается ответа, и проскакивает date = message.text , принимая за ответ предыдущее сообщение, и получается в итоге что-то такое «Задача Work добавлен на дату /add Work». Как сделать так, чтобы бот дождался ответа и не проскакивал? Вот код:
@bot.message_handler(commands = ["add", "random"]) def add_random(message): content = message.text.split(maxsplit = 1) if content[0] == "/add": #mesage.text -> /add || /add command = message.text.split(maxsplit = 2) if len(command) == 3: date = command[1].lower() task = command[2] add_todo(date, task) text = "Задача " + task + " добавлен на дату " + date bot.send_message(message.chat.id, text) elif len(command) == 2: bot.send_message(message.chat.id, "На какую дату поставить задачу??") date = message.text task = command[1] add_todo(date, task) text = "Задача " + task + " добавлен на дату " + date bot.send_message(message.chat.id, text) elif content[0] == "/random": date = "сегодня" task = random.choice(random_task)`` add_todo(date, task) text = "Задача " + task + " добавлен на дату " + date bot.send_message(message.chat.id, text)
Отслеживать
67.9k 216 216 золотых знаков 77 77 серебряных знаков 219 219 бронзовых знаков
Типы обработчиков модуля python-telegram-bot
Внимание! Пакеты python-telegram-bot версии 13.x будут придерживаться многопоточной парадигмы программирования (*на данный момент актуальна версия 13.15). Пакеты версий 20.x и новее предоставляют чистый асинхронный Python интерфейс для Telegram Bot API. Дополнительно смотрите основные изменения в пакете python-telegram-bot версии 20.x.
Обработчик сообщений — это экземпляр, производный от базового класса telegram.ext.Handler , который отвечает за передачу различных видов сообщений (текст, звук, встроенный запрос, нажатия кнопок и т. д.) в соответствующую функцию обратного вызова.
Например, если надо, чтобы бот отвечал на команду /start , нужно использовать обработчик telegram.ext.CommandHandler , который сопоставляет ввод команды пользователя /start с обратным вызовом с именем start_callback :
Например, обработка команды /start для python-telegram-bot версии 13.x:
. def start_callback(update, context): update.message.reply_text("Welcome to my awesome bot!") . updater = Updater('TOKEN') dispatcher = updater.dispatcher dispatcher.add_handler(CommandHandler("start", start_callback))
Пример обработки команды /start для асинхронного python-telegram-bot версии 20.x:
. async def start_callback(update, context): await update.message.reply_text("Welcome to my awesome bot!") . application = ApplicationBuilder().token('TOKEN').build() application.add_handler(CommandHandler("start", start_callback))
Обработчики сообщений пакета python-telegram-bot :
Для разных типов пользовательского ввода в полученных от telegram.Update сообщениях будут установлены разные атрибуты. Например, входящее сообщение приведет к update.message , содержащему отправленное сообщение. Нажатие встроенной кнопки приведет к установке update.callback_query . Чтобы различать все эти сообщения, модуль telegram.ext содержит следующие обработчики:
- Класс MessageHandler(filters, callback) предназначен для обработки всех сообщений Telegram. Они могут содержать текст, мультимедиа или обновления статуса и т.д. Будете использовать в 70% случаев совместно с фильтрами сообщений.
- Класс CommandHandler(command, callback, filters=None) предназначен для обработки команд. Команды представляют собой сообщения, которые начинаются с / . Будете использовать в 20% случаев.
- Класс CallbackQueryHandler(callback) предназначен для обработки запросов обратного вызова Telegram (нажатие кнопок встроенной клавиатуры).
- Класс ConversationHandler(entry_points, states, fallbacks) предназначен для ведения разговора с одним или несколькими пользователями через сообщения Telegram путем управления четырьмя коллекциями других обработчиков. Пример использования данного обработчика можно посмотреть в разделе создания меню из кнопок (Пример встроенной клавиатуры с 2-мя состояниями).
- entry_points — список обработчиков сообщений, которые используются для инициирования разговора, например, с CommandHandler или MessageHandler .
- state — представляет собой словарь dict , который в качестве ключей хранит состояния/этапы разговора, а в качестве значений этих ключей один или несколько (список) связанных обработчиков сообщений, которые должны быть использованы, если пользователь отправляет сообщение, когда разговор с ними в настоящее время находится в этом состоянии/этапе. Здесь также можно определить состояние TIMEOUT для определения поведения при превышении conversation_timeout .
- fallbacks — это список обработчиков сообщений, которые используются, если пользователь в данный момент находится в разговоре, но состояние либо не имеет связанного обработчика, либо обработчик, связанный с состоянием, не подходит для обновления, например, если обновление содержит команду, но ожидается обычное текстовое сообщение. Это поведение можно использовать для отмены разговора или сообщения пользователю, что его сообщение не было распознано.
Чтобы изменить состояние разговора, функция обратного вызова обработчика должна вернуть новое состояние после ответа пользователю. Если она ничего не возвращает (по умолчанию), то состояние не изменится. Если функция обратного вызова точки входа возвращает None, разговор заканчивается сразу же после выполнения этой функции обратного вызова. Чтобы завершить разговор, функция обратного вызова должна вернуть END или -1. Для обработки тайм-аута разговора используйте TIMEOUT или -2.
Пример фрагмента кода определения обработчика разговора ConversationHandler :
conv_handler = ConversationHandler( # точка входа в разговор entry_points=[CommandHandler('start', start)], # словарь состояний разговора, возвращаемых callback функциями states= # Этап `FIRST` - т.е. функция обработчик сообщения в этом разговоре явно # вернула константу FIRST (return `FIRST`), а так же послала/ответила # на сообщение. Ответ пользователя на это сообщение будет # обрабатываться обработчиками определенными в этом списке FIRST: [ CallbackQueryHandler(one, pattern='^' + str(ONE) + '$'), CallbackQueryHandler(two, pattern='^' + str(TWO) + '$'), CallbackQueryHandler(three, pattern='^' + str(THREE) + '$'), CallbackQueryHandler(four, pattern='^' + str(FOUR) + '$'), ], # Этап `SECOND` - происходит то же самое, что и в описании этапа `FIRST` SECOND: [ CallbackQueryHandler(start_over, pattern='^' + str(ONE) + '$'), CallbackQueryHandler(end, pattern='^' + str(TWO) + '$'), ], >, # точка выхода из разговора fallbacks=[CommandHandler('start', start)], )
from telegram.ext import ChosenInlineResultHandler def result_chosen(update, _): print(update.to_dict()) # результат inline запроса result = update.chosen_inline_result # параметры результата result_id = result.result_id query = result.query user = result.from_user.id print(result_id) print(user) print(query) print(result.inline_message_id) result_chosen_handler = ChosenInlineResultHandler(result_chosen) dispatcher.add_handler(result_chosen_handler)
# сработает на команду '!test'. PrefixHandler('!', 'test', callback) # сработает на команды '!test' и '#test'. PrefixHandler(['!', '#'], 'test', callback) # сработает на команды '!test', '#test', '!help' и '#help'. PrefixHandler(['!', '#'], ['test', 'help`], callback)
В некоторых случаях полезно обрабатывать сообщения, поступающие не из Telegram. Например. можно обрабатывать уведомления от сторонней службы и пересылать их своим пользователям. Для таких случаев python-telegram-bot предоставляет следующие обработчики:
- Класс TypeHandler() предназначен для обработки обновлений пользовательских типов. Тип type — тип сообщения, которые должен обрабатывать этот обработчик, как определено isinstance() .
- Класс StringRegexHandler(pattern, callback) предназначен для обработки обновлений строк на основе регулярного выражения, которое проверяет содержимое сообщения.
- Класс StringCommandHandler(command, callback) предназначен для обработки пользовательских строковых команд. Команды представляют собой сообщения, которые начинаются с / .
Эти обработчики не используется для обработки Telegram.Update , но строки вручную помещаются в очередь. Например, чтобы отправлять сообщения с ботом, используя командную строку или API.
Обработка сообщений обработчиком MessageHandler .
Особенностью MessageHandler является то, что существует такое огромное разнообразие типов сообщений (текст, gif, изображение, документ, стикер и т. д.), что невозможно предоставить отдельный обработчик для каждого типа. Вместо этого MessageHandler сочетается с так называемыми фильтрами, которые позволяют проводить мелкие различия: MessageHandler(Filters.all, callback) будет обрабатывать все сообщения, которые содержат:
- update.message ;
- update.edited_message ;
- update.channel_post ;
- update.edited_channel_post .
Вы можно использовать различные фильтры, чтобы сузить круг сообщений, которые будет обрабатывать конкретный MessageHandler . Смотрите также раздел по использованию фильтров.
Обработка команд обработчиком CommandHandler .
Команды — это сообщения Telegram, которые начинаются с символа / , за которым могут следовать @ и имя бота и / или некоторый дополнительный текст. Обработчик добавит список в context с именем CallbackContext.args . Он будет содержать список строк, который представляет собой текст, следующий за командой, разделенной на одиночные или последовательные символы пробела.
По умолчанию обработчик прослушивает все сообщения, а также отредактированные сообщения. Чтобы изменить это поведение, используйте ~Filters.update.edited_message в аргументе фильтра.
Класс telegram.ext.CommandHandler не обрабатывает отредактированные сообщения на канале.
Для примера использования обработчика CommandHandler , расширим функцию start_callback() некоторыми аргументами, чтобы пользователь мог предоставить дополнительную информацию:
Для многопоточной версии 13.x библиотеки:
. def start_callback(update, context): # обработка аргументов, переданных с командой user_says = " ".join(context.args) update.message.reply_text("User said: " + user_says) . updater = Updater('TOKEN') dispatcher = updater.dispatcher dispatcher.add_handler(CommandHandler("start", start_callback))
Для асинхронной версии 20.x библиотеки:
. async def start_callback(update, context): # обработка аргументов, переданных с командой user_says = " ".join(context.args) await update.message.reply_text("User said:" + user_says) . application = ApplicationBuilder().token('TOKEN').build() application.add_handler(CommandHandler("start", start_callback))
Отправка команды ‘/start Hello World!’ приведет к тому, что бот разделит все, что находится после /start , на список слов по пробелам и передаст его параметру args контекста: [‘Hello’, ‘World!’] . Мы объединяем эти фрагменты вместе, вызывая ».join(context.args) , и выводим полученную строку обратно пользователю.
Старт Telegram бота с параметрами.
Описанная выше передача аргументов работает точно так же, когда пользователь нажимает на глубоко связанный начальный URL, например этот:
Щелчок по этой ссылке откроет Telegram-клиент и покажет большую кнопку СТАРТ. При ее нажатии параметры URL-адреса Hello_World! будут переданы в аргументы объекта контекста.
Обратите внимание, поскольку Telegram не поддерживает пробелы в параметрах URL для запуска ботов таким образом, то придется вручную разделить единственный аргумент Hello_World на [‘Hello’, ‘World!’] , например используя вызов context.args[0].split(‘_’) .
Также обратите внимание на максимальную длину, принимаемую самим Telegram. Как указано в документации, максимальная длина параметра start в URL составляет не более 64 символа.
Кроме того, так как это параметр URL-адреса, то необходимо правильно передавать значения, чтобы избежать зарезервированных символов URL-адреса. Рассмотрим использование base64.urlsafe_b64encode .
Соответствие шаблону: Filters.regex(pattern)
Для более сложных входных данных можно использовать telegram.ext.MessageHandler с фильтром telegram.ext.Filters.regex , который внутренне использует модуль re для сопоставления текстового ввода пользователя с предоставленным шаблоном.
Имейте в виду, что для извлечения URL-адресов, #Hashtags , @Mentions и других объектов Telegram нет необходимости, потому что Bot AP уже присылает их нам с каждым сообщением.
Сущности сообщения MessageEntity .
Для использования MessageEntity , сначала необходимо извлечь сущности и соответствующий им текст из объекта Message с помощью метода parse_entities .
Примечание. Этот метод всегда следует использовать вместо атрибута сущностей, поскольку он вычисляет правильную подстроку из текста сообщения на основе кодовых точек UTF-16, то есть извлекает правильную строку даже при работе со странными символами, такими как Emojis .
entity = message.parse_entities()
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Переход на асинхронный python-telegram-bot версии 20.x
- Чистый интерфейс Python для Telegram Bot API
- Команды и оповещения @BotFather в Telegram
- Обработка сообщений модулем python-telegram-bot
- Фильтры сообщений модуля python-telegram-bot
- Хранение временных данных модулем python-telegram-bot
- Настройки по умолчанию модуля python-telegram-bot
- Планировщик сообщений модуля python-telegram-bot
- Форматирование и отправка сообщений в python-telegram-bot
- Работа с файлами/media, модуль python-telegram-bot
- Меню из кнопок, модуль python-telegram-bot
- Объект CallbackContext модуля python-telegram-bot
- Подключения Telegram-бота через webhook
- Обработка исключений модуля python-telegram-bot
- Создание Inline-бота, модуль python-telegram-bot
- Работа с опросами в модуле python-telegram-bot
- Создание разговоров ConversationHandler в python-telegram-bot
- Перезапуск телеграмм-бота в случае ошибки
- Декоратор-обработчик сообщений в python-telegram-bot
- Авторизация на сайте через Telegram Passport
- Ведение публикаций в Telegram-канале с python-telegram-bot
- UTF коды emoji/эмодзи для отправки в Telegram из Python
Как ждать ответ от пользователя в Telegram боте на Aiogram?
У меня есть вопрос: Я сделал бота на библиотеке aiogram. Но надо сделать так чтобы когда пользователь нажал на кнопку «Google» то при выборе он должен принимать сообщения и поискать принятые сообщения на Google. А если пользователь нажал на кнопку «Google» то тоже самое только надо искать не в Google а на Wikipedia. Я хотел попробовать сделать с помощью if но бот ищет в Wikpedia кнопку которую я нажал. А сообщения которое пишу, бот осознает его как кнопку и запрос отклоняется. Я видел ответ на этом форуме «Как ждать ответ от пользователя Aiogram Telegram Bot» Но на ответе было использовано класса и внутри класса хранились класса. Но я понял суть, но не мог применить. Помогите пожалуйста как это сделать Вот код:
import logging from aiogram import Bot, Dispatcher, executor, types import wikipedia from aiogram.types import ReplyKeyboardMarkup, ReplyKeyboardRemove, KeyboardButton API_TOKEN = 'BOT TOKEN HERE' wikipedia.set_lang('en') logging.basicConfig(level=logging.INFO) bot = Bot(token=API_TOKEN) dp = Dispatcher(bot) wikipedia = KeyboardButton(" Wikipedia") google = KeyboardButton(" Google") reply_keyboard = (resize_keyboard = True, one_time_keyboard = True).add(wikipedia, google) @dp.message_handler(commands=['start']) async def echo(message: types.Message): await message.answer("Welcome to Telegradroid!\nThis bot can do anything. Type /help for more", reply_markup = reply_keyboard) @dp.message_handler() async def wiki(message: types.Message): if message.text == " Wikipedia": await message.answer("Current search system: Wikipedia") try: await message.answer(wikipedia.summary(message.text)) except: await message.answer("Resource not found") elif message.text == " Google": await message.answer("Current search system: Google") else: await message.answer("Invalid request") if __name__ == '__main__': executor.start_polling(dp, skip_updates=True)Отслеживать
KsenjiaRegard
задан 3 июл в 10:29
KsenjiaRegard KsenjiaRegard
1 3 3 бронзовых знака
Как не получается применить FSM? Ошибка какая-то?
3 июл в 10:46
Нет без ошибок. Просто логика не правильная
3 июл в 12:50
А код, который использовали у себя можете показать? (без токена)
3 июл в 12:52
Проблема как я понял не в ошибке, а в отсутствии минимально понимания того что нужно делать. В таком случае вопрос бесполезен, так как он не содержит ничего конкретного да и вы сами указали решение своей проблемы, разжевать и положить в рот у людей нет ни желания ни времени. Ознакомьтесь с обучающим материалом по данной теме и попробуйте правильно осознать ответ на ваш вопрос. mastergroosha.github.io/aiogram-3-guide/fsm
3 июл в 17:55
Попробуйте воспользоваться кнопкой «Wikipedia». Не получиться
Как реализовать в телеграм боте ожидание ответа?
Как сделать чтобы после команды “info” бот у меня попросил написать текст и далее он его присвоил model?
Общая суть такая , после ввода команды (/info) бот должен спрашивать у меня «введите вопрос» и далее он должен обрабатывать функцию и задействовать введеный текст- Вопрос задан 28 янв.
- 849 просмотров
2 комментария
Простой 2 комментария
Вам поможет
bot.register_next_step_handler
погуглите пример
Модератор @TosterModerator
Фрагменты кода надо размещать в виде текста и оборачивать тэгом code для корректного отображения. Удобно делать кнопкой >
Это обязательно, см.п.3.8 Регламента.
Сюда же относится traceback, ввод и вывод в консоли и другая структурированная текстовая инфа.Решения вопроса 0
Ответы на вопрос 1@bot.message_handler(commands=['info']) def handle_message(message): bot.send_message(chat_id=message.chat.id, text='Enter text:') bot.register_next_step_handler(message, process_text) def process_text(message): model = message.text # выполнить дальнейшую обработку введенного текстаОтвет написан 29 янв.
Комментировать
Нравится Комментировать
Ваш ответ на вопросВойдите, чтобы написать ответ

- Python
- +1 ещё
Как сделать форму с добавлением нескольких элементов на django?
- 1 подписчик
- 3 часа назад
- 23 просмотра
