Как ждать ответа пользователя telegram python
Создаем анкету (опрос), пользователь должен пройти последовательность шагов, где Handler сообщает системе, каким должен быть следующий шаг. В зависимости от ответа, последовательность может меняться.
Для этого используется обработчик ConversationHandler — позволяет строить (описывать) диалоги со сложной логикой. У каждого ConversationHandler есть:
entry_points — запускает данный диалог, точка входа.
states — шаги диалога, у каждого шага есть название и обработчик на который этот шаг реагирует.
fallbacks — выход из диалога или можно использовать при некорректном вводе информации пользователем.
1. В файле utility.py создадим дополнительную кнопку «Заполнить анкету».
2. В файл bot.py импортируем ConversationHandler, и создаем базовую структуру обработчика.
3. Сделаем так чтобы диалог начинался с фразы «Заполнить анкету» или при нажатии кнопки «Заполнить анкету».
4. В файле handlers.py создаем функцию anketa_start(). Функция будет убирать основную клавиатуру с помощью ReplyKeyboardRemove и определять следующий шаг диалога по ключу user_name.
5. Добавим ключ user_name в словарь states файла bot.py, указав следующий шаг функция anketa_get_name().
6. В файле handlers.py создаем (описываем) функцию anketa_get_name() и в ней укажем ключ user_age.
7. Следующий шаг ссылается на функцию anketa_get_age(). В файле handlers.py создаем (описываем) функцию anketa_get_age() и в ней укажем ключ evalution. Для реализации клавиатуры понадобится импортировать ReplyKeyboardMarkup.
8. Следующий шаг ссылается на функцию anketa_get_evalution(). В файле handlers.py создаем (описываем) функцию anketa_get_evalution() и в ней укажем ключ comment.
9. Завершаем нашу анкету (диалог) создав две функции anketa_exit_comment() и anketa_comment().
10. Что бы избежать получения от пользователя текста вместо цифр или цифр не указанных на шаге, где пользователь оценивает статью нажимая на кнопки от 1 до 5. Используем Failback для проверки введенных данных и создадим функцию реагирующую на неправильный ответ.
11. Для того чтобы в телефонном клиенте клавиатура не растягивалась на пол экрана, добавим resize_keyboard=True.
Запускаем Telegram бота и проверяем работоспособность.
Фиксируем изменения программы в Git репозиторий и по необходимости выкладываем на сайт GitHub. Написанный код в этой статье можно скачать (скопировать) на GitHub .
Если ты совсем не ориентируешься в Python, то отличным началом будет прочтение трех вводных статей, которые я публиковал в «Хакере» этим летом, либо посещение курса «Python для новичков», который я начну вести для читателей «Хакера» уже совсем скоро — 30 ноября.
Чтобы создать бота, нам нужно дать ему название, адрес и получить токен — строку, которая будет однозначно идентифицировать нашего бота для серверов Telegram. Зайдем в Telegram под своим аккаунтом и откроем «отца всех ботов», BotFather.
Жмем кнопку «Запустить» (или отправим / start ), в ответ BotFather пришлет нам список доступных команд:
- / newbot — создать нового бота;
- / mybots — редактировать ваших ботов;
- / setname — сменить имя бота;
- / setdescription — изменить описание бота;
- / setabouttext — изменить информацию о боте;
- / setuserpic — изменить фото аватарки бота;
- / setcommands — изменить список команд бота;
- / deletebot — удалить бота.
Отправим бате‑боту команду / newbot , чтобы создать нового бота. В ответ он попросит ввести имя будущего бота, его можно писать на русском. После ввода имени нужно будет отправить адрес бота, причем он должен заканчиваться на слово bot. Например, xakepbot или xakep_bot . Если адрес будет уже кем‑то занят, BotFather начнет извиняться и просить придумать что‑нибудь другое.
Для взаимодействия с Telegram API есть несколько готовых модулей. Самый простой из них — Telebot. Чтобы установить его, набери
В Linux, возможно, понадобится написать pip3 вместо pip , чтобы указать, что мы хотим работать с третьей версией Python.
Эхо-бот
Для начала реализуем так называемого эхо‑бота. Он будет получать от пользователя текстовое сообщение и возвращать его.
Создание бота
Для регистрации нового бота необходимо обратиться к боту BotFather. Для этого в строке поиска наберите BotFather и в показанных результатах найдите интересующего нас бота:
Обратите внимание на его имя, изображение и знак в виде галочки, говорящий о том, что это действительно отец всех ботов.
Первым шагом нам предлагают дать имя новому боту, оно может быть произвольным. Мы назовем его PocketAdmin:
Теперь требуется указать идентификатор бота (username), он должен заканчиваться на _bot и быть уникальным в системе. Мы укажем PocketAdminTech_bot:
Обязательно сохраните токен и храните его в тайне!
Установка Python и библиотеки pyTelegramBotAPI
Чтобы установить пакет pyTelegramBotAPI воспользуемся pip:
На этом подготовительная работа завершена, приступаем непосредственно к написанию нашего бота.
Пишем Telegram Bot на Python
Так как наш бот создается в ознакомительных целях и не будет содержать много кода, то писать я его буду сразу на сервере с установленной Centos 8 используя обычный редактор nano. Создадим файл bot.py, открыв его nano:
Для начала импортируем библиотеку pyTelegramBotAPI:
Затем зададим переменную token равную нашему токену, который мы получили от BotFather для взаимодействия с Telegram Bot Api:
Далее задается декоратор. Пока наш бот будет обрабатывать только команду start:
и в ответ писать нам “Привет!”:
Чтобы бот постоянно ожидал запрос от пользователя в конце пропишем:
В итоге мы получим код:
Затем откроем нашего бота (можно найти по имени) и напишем ему команду /start:
Поздравлю с первыми словами нашего бота PocketAdmin!
Использование прокси в telebot
При запуске скрипта может появиться ошибка следующего вида:
где login:password@ip:port – соответствующие данные для подключения к прокси.
Если при использовании прокси возникают ошибки, подобные: Not supported proxy scheme socks5 или Missing dependencies for SOCKS support, то необходимо установить модули:
Думаю тут все понятно. На слово “Привет” бот будет отвечать “Ещё раз привет!”, а на “Пока” – “Пока!”. Весь код нашего telegram bot на python теперь будет выглядеть следующим образом:
Перезапустим скрипт и пообщаемся с ботом:
Таким образом мы можем описывать различные диалоги с ботом.
Клавиатура в Telegram Bot на Python
Апи телеграма позволяет использовать свою клавиатуру, а точнее быстрые кнопки, позволяющие пользователю отправлять текст по их нажатию.
Добавим в обработчик команды /start клавиатуру с кнопками “Привет “и “Пока”:
И запустим измененный скрипт. Как только мы отправим боту команду /start у нас внизу появится наша клавиатура:
InLine клавиатура
Давайте добавим простой вопрос от бота на команду /test:
Переменная markup объявляет новую переменную с inline keyboard, а markup.add – создает отдельную кнопку. Основные параметры при создании кнопки – text и callback_data: первый отвечает за текст на кнопке, второй – данные, которые будут переданы боту при выборе пользователем определенного варианта ответа.
Запустим скрипт и напишем /test:
Отлично, все работает. Но будет лучше, если после ответа, клавиатура будет исчезать из чата. Это можно сделать добавив в конец функции query_handler следующую строку:
Это функция редактирования клавиатуры, вызванная без указания объекта клавиатуры. Теперь после ответа пользователя клавиатура будет убрана ботом:
Конечный листинг телеграм бот на питоне
Мы рассмотрели лишь малую часть возможностей telegram bot api, однако, это очень полезные инструменты по работе с ним. В конце приведем полный листинг получившегося у нас telegram bot на python:
Что необходимо учитывать при использовании планировщика JobQueue :
- Класс JobQueue обеспечивает простой и готовый к использованию способ планирования задач в соответствии с архитектурой библиотеки python-telegram-bot .
- Логика управления расписанием не является основной задачей python-telegram-bot , поэтому с версии 13 используется сторонняя библиотека.
- Если необходимы настраиваемые штуки для планирования, то можно использовать расширенные функции стороннего модуля | APScheduler |.
- Разработчики python-telegram-bot не гарантируют, что серверная часть останется неизменной. Например, если поддержка стороннего модуля APScheduler будет прекращена, то придется искать альтернативы.
Содержание:
Использование планировщика JobQueue .
Класс JobQueue тесно интегрирован с другими классами расширений telegram.ext . Подобно Updater и Dispatcher , он работает асинхронно в отдельном потоке.
Чтобы использовать JobQueue , не нужно много делать. Когда создается экземпляр средства обновления Updater , он автоматически создаст планировщик JobQueue , подобно диспетчеру Dispatcher :
Созданная очередь заданий jq также связана с диспетчером. Имейте ввиду, что если нет веской причины, то не следует создавать экземпляр класса JobQueue самостоятельно.
Добавление в очередь и планирование задания.
Добавим первое задание в очередь, для этого определим функцию обратного вызова и добавим ее в очередь заданий. Внимание! В примере необходимо заменить строку @examplechannel каналом, в котором ваш бот является администратором, или своим идентификатором пользователя. Для того, чтобы узнать свой идентификатор пользователя, можно использовать @userinfobot .
Функция callback_minute будет выполняться каждые 60,0 секунд, первый раз через 10 секунд (аргумент first=10 ). Аргументы interval и first указываются в секундах (могут иметь тип int , float или datetime.timedelta() ). А аргумент first кроме того может принимать значения datetime.date() и datetime.time() .
Возвращаемое значение функций обратного вызова - это создаваемые объекты Job . Не нужно сохранять результат run_repeating (который является новым экземпляром задания), воспользуемся им позже.
Также можно добавить задание, которое будет выполняться только один раз, с задержкой:
Для того, что бы временно отключить задание или даже полностью удалить его из очереди, сделайте следующее:
Примечание: метод .schedule_removal() не удаляет задание сразу из очереди. Задание помечается для удаления и будет удалено, как только истечет его текущий интервал (задание не будет снова запускаться после того, как будет помечено для удаления).
Иногда необходимо сделать "напоминалку", т.е. добавить задания в ответ на определенный пользовательский ввод, и есть удобный способ сделать это. Аргумент контекста обратных вызовов Handler имеет JobQueue , прикрепленный как context.job_queue , готовый к использованию. Еще одна возможность, которую можно использовать - это ключевой аргумент context для задания Job . То есть можно передать любой объект в качестве параметра контекста при запуске задания и получить его на более позднем этапе, пока задание существует.
Смотрим, как это выглядит в коде:
Если остановить Updater методом upd.stop() , то соответствующая очередь заданий также будет остановлена. Очередь заданий можете быть остановлена сама по себе методом jq.stop() . (переменные upd и jq были определены в начале материала)
Краткая справка по классу telegram.ext.JobQueue .
Класс JobQueue позволяет периодически выполнять задачи с ботом. Это удобная обертка модуля APScheduler .
Атрибуты и методы объекта JobQueue :
JobQueue.scheduler
Возвращает планировщик APScheduler ,
JobQueue.get_jobs_by_name(name) :
Возвращает кортеж всех ожидающих/запланированных заданий с заданным именем name , которые в настоящее время находятся в JobQueue .
JobQueue.jobs() :
Возвращает кортеж всех ожидающих / запланированных заданий, которые в настоящее время находятся в JobQueue .
Создает новое настраиваемое задание.
- callback - функция обратного вызова.
- job_kwargs=None - словарь: произвольные ключевого аргументы для передачи в scheduler.add_job() .
- context=None - дополнительные данные, необходимые для функции обратного вызова. Доступ к нему можно получить через job.context в обратном вызове.
- name=None - имя задания. По умолчанию callback.__name__ .
Создает новое задание, которое запускается ежедневно, и добавляет его в очередь.
- time - datetime.time : время дня, в которое должно выполняться задание. Если часовой пояс time.tzinfo=None , то будет использоваться часовой пояс бота по умолчанию.
- days=(0, 1, 2, 3, 4, 5, 6) - кортеж: определяет, в какие дни недели должно выполняться задание (где 0-6 соответствуют понедельник - воскресенье). По умолчанию каждый день.
Создает новое задание, которое запускается ежемесячно, и добавляет его в очередь.
- when - время дня, в которое должно выполняться задание. Если часовой пояс time.tzinfo=None , то будет использоваться часовой пояс бота по умолчанию.
- day - int : определяет день месяца, в который будет запускаться задание. Оно должно быть в пределах от 1 до 31 включительно.
- day_is_strict=True - bool : если False и day > month.days , то будет выбран последний день месяца.
Создает новое задание, которое запускается один раз, и добавляет его в очередь.
-
when - int или float или datetime.timedelta или datetime.datetime или datetime.time . Определяет время в которое должно выполняться задание. Этот параметр будет интерпретироваться в зависимости от его типа:
-
или float будут интерпретироваться как "секунды с этого момента", в которые должно выполняться задание. будет интерпретироваться как "время с этого момента", в течение которого должно выполняться задание. будет интерпретироваться как конкретная дата и время, в которое должно выполняться задание. Если часовой пояс datetime.tzinfo=None , то будет использоваться часовой пояс бота по умолчанию. будет интерпретироваться как определенное время суток, в которое должно выполняться задание. Это может быть либо сегодня, либо, если время уже прошло - завтра. Если часовой пояс time.tzinfo=None , то будет использоваться часовой пояс бота по умолчанию.
Создает новое задание, которое запускается с заданными интервалами, и добавляет его в очередь.
Если last - это тип datetime.datetime или datetime.time , а last.tzinfo=None , то будет принят часовой пояс бота по умолчанию.
JobQueue.set_dispatcher(dispatcher) :
Устанавливает диспетчер dispatcher , который будет использоваться JobQueue .
JobQueue.start() :
Запускает поток job_queue .
JobQueue.stop() :
Пример бота Telegram c использованием планировщика:
Читайте также: