Как сделать клавиатуру в телеграмм боте python

от admin

Меню из кнопок, модуль python-telegram-bot в Python.

Создание на Telegram меню из кнопок (встроенные клавиатуры).

Всякий раз, когда бот отправляет сообщение, он может передать специальную клавиатуру с предопределенными параметрами ответа. Приложения Telegram, которые получают сообщение, будут отображать эту клавиатуру для пользователя. Нажатие любой из кнопок немедленно отправит соответствующую команду. Таким образом можно значительно упростить взаимодействие пользователя с ботом.

Содержание.

Встроенные клавиатуры Telegramm в сообщения бота.

Бывают случаи, когда нужно что-либо сделать, не отправляя никаких сообщений в чат. Например, когда пользователь меняет настройки или просматривает результаты поиска. В таких случаях можно использовать встроенные InlineKeyboardButton клавиатуры, которые интегрированы непосредственно в сообщения, которым они принадлежат.

В отличие от настраиваемых клавиатур KeyboardButtons , которые посылают текст кнопки в качестве ответа, нажатие кнопок на встроенных клавиатурах InlineKeyboardButton не приводит к отправке сообщений в чат. Вместо этого встроенные клавиатуры поддерживают кнопки, которые работают за кулисами: кнопки обратного вызова, кнопки с URL и переключение на встроенные кнопки.

Когда используются кнопки обратного вызова (с аргументом callback_data ), бот может обновлять свои существующие сообщения или клавиатуры. При нажатии на такую кнопку, бот просто получает соответствующий запрос. Получив запрос, бот может отображать результат в уведомлении в верхней части экрана чата или в предупреждении.

Классы KeyboardButton и InlineKeyboardButton .

Данные классы определяют атрибуты и методы, одноименные с названиями аргументов.

KeyboardButton(text, request_contact=None, request_location=None, request_poll=None, **_kwargs) :

Объект KeyboardButton представляет собой одну кнопку клавиатуры для ответа текстом text , который отображается на кнопке. Необязательные аргументы исключают друг друга. Импортируется из основного модуля telegram.KeyboardButton .

Значение и поведение аргументов KeyboardButton :

  • text (str) — текст кнопки. Если ни одно из дополнительных полей не используется, оно будет отправлено боту в виде сообщения при нажатии кнопки.
  • request_contact (bool, необязательно) — если True , то при нажатии будет отправлен телефонный номер пользователя, как контакт. Доступно только в приватных чатах.
  • request_location (bool, необязательный) — если True , то при нажатии будет отправлено текущее местоположение пользователя. Доступно только в приватных чатах.
  • request_poll (KeyboardButtonPollType, необязательно) — если указано, то при нажатии кнопки пользователю будет предложено создать опрос и отправить его боту. Доступно только в приватных чатах.
  • **_kwargs (dict) — произвольные ключевые аргументы.
InlineKeyboardButton(text, url=None, callback_data=None, switch_inline_query=None, switch_inline_query_current_chat=None, callback_game=None, pay=None, login_url=None, **_kwargs)

Объект InlineKeyboardButton представляет одну кнопку встроенной клавиатуры. Допускается использовать ровно одно из необязательных полей. Импортируется из основного модуля telegram.InlineKeyboardButton .

Значение и поведение аргументов InlineKeyboardButton :

  • text (str) — текст кнопки. Если ни одно из дополнительных полей не используется, оно будет отправлено боту в виде сообщения при нажатии кнопки.
  • url (str) — HTTP или tg://url, который открывается при нажатии кнопки.
  • login_url (telegram.LoginUrl, необязательно) — URL-адрес HTTP, используемый для автоматической авторизации пользователя. Может использоваться как замена виджета входа в Telegram.
  • callback_data (str, необязательно) — данные, которые будут отправлены в запросе обратного вызова боту при нажатии кнопки, UTF-8 1-64 байта.
  • switch_inline_query (str, необязательно) — если установлено, то нажатие кнопки предложит пользователю выбрать один из своих чатов, открыть этот чат и вставить логин бота и указанный встроенный запрос в поле ввода. Может быть пустым, и в этом случае будет вставлено только логин бота. Это дает пользователям простой способ начать использовать вашего бота во встроенном режиме, в то время как они находятся с ним в приватном чате. Особенно полезно в сочетании с действиями switch_pm* — в этом случае пользователь автоматически вернется в чат, из которого он переключился, пропуская экран выбора чата.
  • switch_inline_query_current_chat (str, необязательно) — если установлено, то нажатие кнопки вставит логин бота и указанный встроенный запрос в поле ввода текущего чата. Может быть пустым, и в этом случае будет вставлено только логин бота. Это предлагает пользователю быстрый способ открыть вашего бота во встроенном режиме в том же чате — удобно для выбора чего-либо из нескольких вариантов.
  • callback_game (telegram.CallbackGame, необязательно) — описание игры, которая будет запускаться при нажатии кнопки пользователем. Кнопка этого типа всегда должна быть первой кнопкой в ​​первом ряду.
  • pay (bool, необязательно) — укажите True , чтобы отправить кнопку Pay. Кнопка этого типа всегда должна быть первой кнопкой в ​​первом ряду.
  • **_kwargs (dict) — произвольные ключевые аргументы.

Алгоритм построения и отправки кнопок в Telegram чат.

Для создания макета кнопок со столбцами n_cols из списка кнопок необходимо создать функцию build_menu() , которая будет шаблоном для построения кнопок:

В коде выше определены списки header_buttons и footer_buttons , их можно использовать чтобы поместить кнопки в первую или последнюю строку соответственно.

В приведенном ниже фрагменте кода нужно заменить . соответствующим значением аргумента callback_data — это строка (UTF-8 1-64 байта) с данными, отправляемые боту в ответном запросе при нажатии кнопки. Если будете использовать кнопки KeyboardButtons для создания списка кнопок button_list , то для построения передаваемой в чат клавиатуры из кнопок используйте ReplyKeyboardMarkup вместо InlineKeyboardMarkup .

Или, если нужна динамическая версия, используйте генератор списка для динамического создания button_list из списка строк:

Это особенно полезно, если поместить внутрь вспомогательного метода, такого как get_data_buttons , для работы с динамическими данными и обновления меню в соответствии с вводом пользователя.

Чтобы обработать callback_data , необходимо подключить обработчик CallbackQueryHandler .

Обработчик сообщений CallbackQueryHandler .

Обработчик сообщений CallbackQueryHandler определяет атрибуты и методы, одноименные с названиями аргументов. Обработчик CallbackQueryHandler импортируется из модуля расширения telegram.ext .

CallbackQueryHandler(callback, pattern=None, run_async=False) :

Объект CallbackQueryHandler представляет собой обработчик запросов обратного вызова Telegram. Может использовать дополнительную фильтрацию на основе регулярных выражений модуля re .

Значение и поведение аргументов InlineKeyboardButton :

  • callback — Функция обратного вызова для этого обработчика. Будет вызываться, когда сообщение должно быть обработано этим обработчиком.
  • pattern=None ( str , необязательно) — шаблон регулярного выражения. Если не None , то для поиска совпадений в telegram.CallbackQuery.data (должно ли сообщение обрабатываться этим обработчиком) будет использоваться функция re.match() .
  • run_async=False ( bool ) — определяет, будет ли обратный вызов выполняться асинхронно.

Остальные аргументы устарели. Такие параметры, как update_queue , job_queue , groups , groupdict , user_data , chat_data функциях обратного вызова можно получить объект контекста context

Базовый пример, использующий встроенную клавиатуру.

Пример встроенной клавиатуры с 2-мя состояниями.

Данный пример снабжен комментариями, так что понять как и что работает не составит труда. Он так же демонстрирует использование обработчиков CallbackQueryHandler и ConversationHandler .

Как работает обработчик разговора ConversationHandler() .

Основная магия происходит в обработчике разговора ConversationHandler() . Обработчик ConversationHandler() имеет три основные точки, которые необходимо определить для ведения беседы:

  • entry_points — точка входа в разговор, представляет собой список обработчиков, которые запускают разговор. Разговор можно запустить по команде, отправленной пользователем (в данном случае /start ) и/или по каким то фразам, которые можно поймать при помощи обработчика MessageHandler() и фильтра Filters.regex (например: Filters.regex('(поговорим|скучно)'), callback_func)],
  • states — состояния разговора. Представляет собой словарь, в котором ключ, это этап разговора, который явно возвращает функция обратного вызова, при этом высылает или отвечает на сообщение или передает кнопки для выбора и т.д. Так вот, реакция/ответ пользователя на это сообщение/нажатие кнопки будет обрабатываться обработчиками, находящихся в списке значений этого ключа — этапа/состояния разговора.
  • fallbacks — точка выхода из разговора. Разговор заканчивается, если функция обработчик сообщения явно возвращает return ConversationHandler.END

Переключение между этапами разговора происходит при помощи функций обратного вызова, которые при обработке/анализе ответа пользователя будут возвращать нужный этап/состояние разговора.

Создаем бота в Telegram

В этом статье я покажу как создать Telegram бота с помощью Python, поскольку не нашел хорошей русскоязычной статьи по этой теме.

Создание бота

Бот создается с помощью BotFather через Telegram. После команды /newbot надо просто следовать инструкции.

В конце мы получаем токен для управления ботом и работы с Telegram API.

pyTelegramBotApi

Ссылки на документации всех библиотек будут в конце.

Создадим простого бота, отвечающего на команду /start , с помощью этой библиотеки:

pyTelegramBotApi является просто обёрткой для всего Telegram Bot API, но здесь разберутся только основные составляющие.
Взаимодействие с ботом происходит через переменную bot (токен надо вставить свой).
Декоратор @message_handler реагирует на входящие сообщение.
Message – это объект из Bot API, содержащий в себе информацию о сообщении. Полезные поля:
message.chat.id – идентификатор чата
message.from.id – идентификатор пользователя
message.text – текст сообщения
Функция send_message принимает идентификатор чата (берем его из сообщения) и текст для отправки.

Примеры функций

Отправка изображений

Можно отправлять фото из локального хранилища, но удобнее это делать по ссылке. Код аналогичен предыдущему:

Замена клавиатуры

У ботов есть функция замены стандартной клавиатуры на кнопочную. Для этого у всех функций есть опциональный аргумент reply_markup:

ReplyKeyboardMarkup – и есть та самая клавиатура. Метод row() создает ряд (максимум 12) из кнопок, передаваемых в качестве аргумента.
Также есть особенная клавиатура types.ReplyMarkupRemove(), которая меняет клавиатуру на стандартную.

Клавиатура для сообщений

Можно создавать клавиатуру для отдельного сообщения. Передавать его нужно так же в аргумент reply_markup:

У кнопок есть несколько режимов, в зависимости от второго аргумента. Подробнее можно прочитать в официальной документации, но я остановлюсь только на callback_data.
При нажатии на такую кнопку боту придет отдельный CallbackQuery, который нужно обрабатывать подобно сообщению:

Для обработки обязательно указать аргумент func для «отсеивания» Callback запросов.
После обработки каждого запроса нужно выполнить команду answer_callback_query, чтобы Telegram понял, что запрос обработан. В поле callback.data хранится информация из callback_data нажатой кнопки.

Изменение сообщений

У ботов есть функция изменения своих сообщений (можно использовать, чтобы сделать перелистывание страниц, например). Для этого нужно воспользоваться методом edit_message_text (edit_message_caption для картинок):

Смысл аргументов понятен из их названия.

Flask

Если запустить бота, то через какое-то время он упадет с ошибкой Connection to api.telegram.org timed out. Чтобы это исправить нужно использовать вебхук:

Этот код при запуске сначала удалит вебхук, если такой был, и установит его на желаемый. Все запросы, которые приходят в функцию getMessage будут направляться в bot с помощью метода process_new_updates. Этот код уже можно использовать для запуска, например, на Heroku.

Кнопки¶

В этой главе мы познакомимся с такой замечательной фичей Telegram-ботов, как кнопки. Прежде всего, чтобы избежать путаницы, определимся с названиями. То, что цепляется к низу экрана вашего устройства, будем называть обычными кнопками, а то, что цепляется непосредственно к сообщениям, назовём инлайн-кнопками. Ещё раз картинкой:

Обычные кнопки¶

Кнопки как шаблоны¶

Этот вид кнопок появился вместе с Bot API в далёком 2015 году и представляет собой не что иное, как шаблоны сообщений (за исключением нескольких особых случаев, но о них позже). Принцип простой: что написано на кнопке, то и будет отправлено в текущий чат. Соответственно, чтобы обработать нажатие такой кнопки, бот должен распознавать входящие текстовые сообщения.

Напишем хэндлер, который будет при нажатии на команду /start отправлять сообщение с двумя кнопками:

Обратите внимание, что т.к. обычные кнопки суть шаблоны сообщений, то их можно создавать не только как объекты KeyboardButton , но и как обычные строки.
Что ж, запустим бота и обалдеем от громадных кнопок:

Как-то некрасиво. Во-первых, хочется сделать кнопки поменьше, а во-вторых, расположить их горизонтально.
Почему вообще они такие большие? Дело в том, что по умолчанию «кнопочная» клавиатура должна занимать на смартфонах столько же места, сколько и обычная буквенная. Для уменьшения кнопок к объекту клавиатуры надо указать дополнительный параметр resize_keyboard=True .
Но как заменить вертикальные кнопки на горизонтальные? С точки зрения Bot API, клавиатура — это массив массивов кнопок, а если говорить проще, массив строк. Метод add() при каждом вызове создаёт новую строку (ряд) и принимает произвольное число аргументов по количеству желаемых кнопок в строке. Перепишем наш код, чтобы было красиво:

Обратите внимание на конструкцию *buttons . Здесь вам не C++ и звёздочка используется для распаковки списка. Подробнее об операторах * и ** можно прочитать здесь.

Смотрим — действительно красиво:

Осталось научить бота реагировать на нажатие таких кнопок. Как уже было сказано выше, необходимо делать проверку на полное совпадение текста. Сделаем это двумя способами: через специальный фильтр Text и обычной лямбдой:

Чтобы удалить кнопки, необходимо отправить новое сообщение со специальной «удаляющей» клавиатурой типа ReplyKeyboardRemove . Например: await message.reply(«Отличный выбор!», reply_markup=types.ReplyKeyboardRemove())

У объекта обычной клавиатуры есть ещё две полезных опции: one_time_keyboard для скрытия кнопок после нажатия и selective для показа клавиатуры лишь некоторым участникам группы. Их использование остаётся для самостоятельного изучения.

Помимо стандартных опций, описанных выше, aiogram немного расширяет функциональность клавиатур параметром row_width . При его использовании, фреймворк автоматически разобьёт массив кнопок на строки по N элементов в каждой, где N — значение row_width , например, row_width=2 . Попробуйте!

Читать:
Как убрать номер телефона из телеграмма

Специальные обычные кнопки¶

По состоянию на конец ужасного 2020 года в Telegram существует три специальных вида обычных кнопок, не являющихся шаблонами: для отправки текущей геолокации, для отправки своего номера телефона и ярлык для создания опроса/викторины. Для первых двух типов достаточно установить булевый флаг, а для опросов и викторин нужно передать специальный тип KeyboardButtonPollType и, по желанию, указать тип создаваемого объекта.

Впрочем, проще один раз увидеть код:

Инлайн-кнопки¶

URL-кнопки и колбэки¶

В отличие от обычных кнопок, инлайновые цепляются не к низу экрана, а к сообщению, с которым были отправлены. В этой главе мы рассмотрим два типа таких кнопок: URL и Callback. Ещё один — Switch — будет рассмотрен в главе про инлайн-режим.

Login- и Pay-кнопки в книге рассматриваться не будут вообще. Если у кого-то есть желание помочь хотя бы с рабочим кодом для авторизации или оплаты, пожалуйста, создайте Pull Request на GitHub. Спасибо!

Самые простые инлайн-кнопки относятся к типу URL, т.е. «ссылка». Поддерживаются только протоколы HTTP(S) и tg://

А если хотите обе кнопки в ряд, то уберите row_width=1 (тогда будет использоваться значение по умолчанию 3).

С URL-кнопками больше обсуждать, по сути, нечего, поэтому перейдём к гвоздю сегодняшней программы — Callback-кнопкам. Это очень мощная штука, которую вы можете встретить практически везде. Кнопки-реакции у постов (лайки), меню у @BotFather и т.д. Суть в чём: у колбэк-кнопок есть специальное значение (data), по которому ваше приложение опознаёт, что нажато и что надо сделать. И выбор правильного data очень важен! Стоит также отметить, что, в отличие от обычных кнопок, нажатие на колбэк-кнопку позволяет сделать практически что угодно, от заказа пиццы до перезагрузки сервера.

Напишем хэндлер, который по команде /random будет отправлять сообщение с колбэк-кнопкой:

Но как же обработать нажатие? Если раньше мы использовали message_handler для обработки входящих сообщений, то теперь будем использовать callback_query_handler для обработки колбэков. Ориентироваться будем на «значение» кнопки, т.е. на её data:

Несмотря на то, что параметр кнопки callback_data , а значение data лежит в одноимённом поле data объекта CallbackQuery, собственный фильтр aiogram называется text .

Ой, а что это за часики? Оказывается, сервер Telegram ждёт от нас подтверждения о доставке колбэка, иначе в течение 30 секунд будет показывать специальную иконку. Чтобы скрыть часики, нужно вызвать метод answer() у колбэка (или использовать метод API answer_callback_query() ). В общем случае, в метод answer() можно ничего не передавать, но можно вызвать специальное окошко (всплывающее сверху или поверх экрана):

В функции send_random_value мы вызывали метод answer() не у message , а у call.message . Это связано с тем, что колбэк-хэндлеры работают не с сообщениями (тип Message), а с колбэками (тип CallbackQuery), у которого другие поля, и само сообщение — всего лишь его часть. Учтите также, что message — это сообщение, к которому была прицеплена кнопка (т.е. отправитель такого сообщения — сам бот). Если хотите узнать, кто нажал на кнопку, смотрите поле from (в вашем коде это будет call.from_user , т.к. слово from зарезервировано в Python)

Когда вызывать answer() ?

В общем случае, главное — просто не забыть сообщить Telegram о получении колбэк-запроса, но я рекомендую ставить вызов answer() в самом конце, и вот почему: если вдруг в процессе обработки колбэка случится какая-то ошибка и бот нарвётся на необработанное исключение, пользователь увидит неубирающиеся полминуты часики и поймёт, что что-то не так. В противном случае, часики исчезнут, а пользователь останется в неведении, выполнился его запрос успешно или нет.

Перейдём к примеру посложнее. Пусть пользователю предлагается сообщение с числом 0, а внизу три кнопки: +1, -1 и Подтвердить. Первыми двумя он может редактировать число, а последняя удаляет всю клавиатуру, фиксируя изменения. Хранить значения будем в памяти в словаре (про конечные автоматы поговорим как-нибудь в другой раз).

И, казалось бы, всё работает:

Но теперь представим, что ушлый пользователь сделал следующее: вызвал команду /numbers (значение 0), увеличил значение до 1, снова вызвал /numbers (значение сбросилось до 0) и отредактировал нажал кнопку «+1» на первом сообщении. Что произойдёт? Бот по-честному отправит запрос на редактирование текста со значением 1, но т.к. на том сообщении уже стоит цифра 1, то Bot API вернёт ошибку, что старый и новый тексты совпадают, а бот словит исключение: aiogram.utils.exceptions.MessageNotModified: Message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message

С этой ошибкой вы, скорее всего, будете поначалу часто сталкиваться, пытаясь редактировать сообщения. Но, в действительности, решается проблема очень просто: мы проигнорируем исключение MessageNotModified . Из первой главы вы уже знаете о такой прекрасной штуке, как errors_handler , но в этот раз мы поступим чуть иначе и перепишем функцию update_num_text() следующим образом:

Если теперь вы попробуете повторить пример выше, то указанное исключение в этом блоке кода бот просто-напросто проигнорирует.

Фабрика колбэков¶

В aiogram существует т.н. фабрика колбэков. Вы создаёте объект CallbackData , указываете ему префикс и произвольное количество доп. аргументов, которые в дальнейшем указываете при создании колбэка для кнопки.
Например, рассмотрим следующий объект:

В примере выше в кнопку запишется callback_data , равный post:5:like , а хэндлер на префикс post будет выглядеть так:

В предыдущем примере с числами мы грамотно выбрали callback_data , поэтому смогли легко запихнуть все обработчики в один хэндлер. Но можно логически разнести обработку инкремента и декремента от обработки нажатия на кнопку «Подтвердить». Для этого в фильтре фабрики можно указать желаемые значения какого-либо параметра. Давайте перепишем наш пример с использоваанием фабрики:

На этом глава про кнопки окончена, но про некоторые других их виды мы поговорим в следующих главах.

Боты для Telegram

В настоящее время существует достаточно много разных популярных мессенджеров. Достоинством мессенджера Telegram является наличие богатого API, позволяющего взаимодействовать с мессенжером не людям, а программам, то есть писать боты.

Краткое введение в Telegram Bot API

Можете изучить полную документацию на Telegram Bot API, но непосредственно этим API мы пользоваться не будем. Но нужно понять, как это устроено внутри.

На самом простом уровне это API, использующее HTTP с JSON-ответом. Вы можете промоделировать работу бота, просто используя GET-запросы в браузере, то есть загружая страницы с определённым адресом используя браузер.

Самый простой пример тестовой страницы, которую можно загрузить при помощи API:

  1. Название бота (произвольное текстовое имя),
  2. Имя пользователя для бота (уникальное, из латинских букв, цифр, символа подчёркивания, должно заканчиваться на bot ).

В ответ вы получите от @BotFather токен.

Дальнейшее описание Telegram Bot API не нужно для выполнения заданий (т.к. мы будем использовать упрощающую разработку ботов библиотеку), но полезно для понимания.

Пример простого запроса getMe для проверки токена, который можно просто ввести в адресную строку браузера, заменив <token> на токен вашего бота:

В ответ вы должны получить небольшой JSON с информацией о вашем боте.

Если написать боту сообщение (например, с телефона или используя web.telegram.org), то это сообщение будет храниться на серверах Telegram. Чтобы получить сообщения, адресованные боту, необходимо выполнить запрос getUpdates:

Вы получите JSON, содержащий все сообщения, написанные боту, за последние 24 часа. Повторно вызвав этот запрос, мы снова получим все сообщения с сервера. Чтобы не получать сообщения повторно, можно передать запросу параметр offset , например

где <update_id> — минимальное значение параметра update_id , начиная с которого вы хотите получить сообщения. Оно должно быть на 1 больше значения параметра update_id последнего сообщения, которое вы получили. Все сообщения с меньшим значением update_id вам больше не будут отдаваться.

Для того, чтобы отправить сообщение, вам необходимо сделать запрос sendMessage с двумя обязательными параметрами в адресной строке: chat_id —идентификатор чата для отправки сообщения и text — сообщение, отправляемое пользователю. Например:

Таким образом, простейшая схема реализации бота следующая. Бот — это постоянно запущенное приложение, которое регулярно опрашивает сервер, посылая запросы getUpdates и “засыпая” на некоторое время после этого. Если ответ сервера содержит какие-то новые сообщения, то их нужно обработать и отправить запросы sendMessage для отправки ответных сообщений.

Библиотека pytelegrambotapi (telebot)

Установка библиотеки

Как мы видим, реализация бота содержит много стандартной работы, типа запуск цикла обработки сообщений с учётом значения offset , разбор полученного JSON, ответ на все сообщения, отправка запросов, для ответа на сообщения. Для этого есть ряд библиотек, содержащих реализацию этой рутины, одна из наиболее популярных из таких библиотек — telebot.

Её необходимо установить при помощи pip, в pip она называется pytelegrambotapi. Соответствующая консольная команда может выглядеть, например, так:

Сразу же установите библиотеку requests, она пригодится для выполнения ряда заданий.

Под Windows команда называется просто pip . Параметр —user необходим, если вы запускаете pip под обычным пользователем и хотите установить библиотеку в пользовательский каталог.

Простой обработчик сообщений

Пример простого бота, который на любое сообщение всегда отвечает одним словом “Привет!”:

В этом примере создаётся объект с именем bot класса telebot.TeleBot , которому в конструктор передаётся значение токена в качестве параметра. Затем объявляется функция get_text_message , принимающая в качестве параметра объект message , в котором будет хранится информация о полученном сообщении.

Эта функция регистрируется в качестве обработчика для сообщений типа “text”, что делается при помощи так называемых “декораторов” — это строчка, начинающаяся со значка “@” перед нашей функцией.

Декоратор: это специальная функция (или метод), которая получает другую функцию в качестве параметра, и создаёт новую функцию, используя переданную ей функцию. Строка, начинающаяся с “@” — это на самом деле вызов метода bot.message_handler , который зарегистрирует функцию get_text_messages , как обработчик для сообщений указанного типа. Подробней про декораторы можно прочитать, например, здесь.

Теперь при поступлении сообщений объект bot будет вызывать функцию get_text_messages для каждого сообщения отдельно, тем самым принимая на себя работу по получению и парсингу полученных сообщений. Вам нужно всего лишь определить, что делает бот для ответа на полученное сообщение. Вы можете отправлять сообщения, вызывая метод send_message с параметрами: идентификатор чата и текст отправляемого сообщения.

Наконец, запускается метод polling , который представляет собой бесконечный ( none_stop=True ) цикл запроса обновлений с сервера, который и будет вызывать функцию get_text_messages при получении новых сообщений.

Немного более подробно ознакомиться с написанием простейших ботов можно, например, в следующих статьях:

Реализация клавиатуры

Команды, набираемые пользователем, сложно декодировать, да и пользователь может ошибиться в их написании. Поэтому в Телеграме у ботов есть возможность использования клавиатуры для выбора стандартных действий пользователя. Есть два типа клавиатуры: ReplyKeyboardMarkup (более древняя) и InlineKeyboardMarkup (более современная и богатая возможностями), на второй и остановимся.

В клавиатуру можно добавлять кнопки, у кнопки есть два параметра: text — это надпись, отображаемая на кнопке, и callback_data — это информация, которая будет передана в обработчик нажатия на кнопку. Сначала создадим все кнопки, потом добавим их в объект-клавиатуру. Метод row у клавиатуры добавляет к клавиатуре ряд из нескольких кнопок, если вызвать метод row ещё раз, то будет добавлен следущий ряд кнопок, и т.д. После этого при отправке сообщения укажем параметр reply_markup , указав созданную клавиатуру.

Теперь нам необходимо сделать обработчики кнопок. Это отдельные функции, которые необходимо зарегистрировать при помощи декоратора callback_query_handler . Эта функция будет получать объект callback_obj , которых хранит информацию о нажатии кнопки. В частности, помимо обычных данных о пользователе, чате и т.д. у этого объекта есть поле data , в котором хранится та самая информация, которая была привязана к кнопке. Пример такого обработчика:

Обратите внимание на вызов метода answer_callback_query . Он сообщает серверу телеграма, что обработка данного callback-запроса завершена. Если этот метод не вызвать, то на кнопке будут изображены часики, а сама кнопка будет недоступна для повторного нажатия.

Есть и другой способ определить, какая кнопка была нажата. Обратите внимание на параметр декоратора: func=lambda call: True . Это лямбда-функция, которая в данном случае всегда возвращает True . Это означает, что данный обработчик будет применяться ко всем callback-запросам. Но если эта функция будет возвращать не всегда True , то так можно установить обработчик для отдельных callback-запросов, а именно, будет вызван тот обработчик, для которого эта функция вернёт True .

Используем это для того, чтобы сделать разные обработчики для разных кнопок.

Похожие статьи