InlineKeyboardButton¶
class telegram. 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 , web_app = None , switch_inline_query_chosen_chat = None , * , api_kwargs = None ) [source] ¶ Bases: telegram.TelegramObject This object represents one button of an inline keyboard. Objects of this class are comparable in terms of equality. Two objects of this class are considered equal, if their text , url , login_url , callback_data , switch_inline_query , switch_inline_query_current_chat , callback_game , web_app and pay are equal.
- You must use exactly one of the optional fields. Mind that callback_game is not working as expected. Putting a game short name in it might, but is not guaranteed to work.
- If your bot allows for arbitrary callback data, in keyboards returned in a response from telegram, callback_data maybe be an instance of telegram.ext.InvalidCallbackData . This will be the case, if the data associated with the button was already deleted.
- If your bot allows your arbitrary callback data, buttons whose callback data is a non-hashable object will become unhashable. Trying to evaluate hash(button) will result in a TypeError .
Changed in version 20.0: web_app is considered as well when comparing objects of this type in terms of equality.
- text ( str ) – Label text on the button.
- url ( str , optional) – HTTP or tg:// url to be opened when the button is pressed. Links tg://user?id= can be used to mention a user by their ID without using a username, if this is allowed by their privacy settings.
Tip This is similar to the new parameter switch_inline_query_chosen_chat , but gives no control over which chats can be selected.
Caution The PTB team has discovered that this field works correctly only if your Telegram client is released after April 20th 2023.
Optional. HTTP or tg:// url to be opened when the button is pressed. Links tg://user?id= can be used to mention a user by their ID without using a username, if this is allowed by their privacy settings.
Changed in version 13.9: You can now mention a user using tg://user?id= .
Optional. An HTTPS URL used to automatically authorize the user. Can be used as a replacement for the Telegram Login Widget.
Only HTTPS links are allowed after Bot API 6.1.
Optional. Data to be sent in a callback query to the bot when button is pressed, UTF-8 1 — 64 bytes.
Optional. Description of the Web App that will be launched when the user presses the button. The Web App will be able to send an arbitrary message on behalf of the user using the method answer_web_app_query() . Available only in private chats between a user and the bot.
Optional. If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the bot’s username and the specified inline query in the input field. Can be empty, in which case just the bot’s username will be inserted. This offers an easy way for users to start using your bot in inline mode when they are currently in a private chat with it. Especially useful when combined with switch_pm* actions — in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen.
This is similar to the new parameter switch_inline_query_chosen_chat , but gives no control over which chats can be selected.
Optional. If set, pressing the button will insert the bot’s username and the specified inline query in the current chat’s input field. Can be empty, in which case only the bot’s username will be inserted. This offers a quick way for the user to open your bot in inline mode in the same chat — good for selecting something from multiple options.
Optional. Description of the game that will be launched when the user presses the button. This type of button must always be the first button in the first row.
Optional. Specify True , to send a Pay button. This type of button must always be the first button in the first row and can only be used in invoice messages.
Optional. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot’s username and the specified inline query in the input field.
This is similar to switch_inline_query , but gives more control on which chats can be selected.
The PTB team has discovered that this field works correctly only if your Telegram client is released after April 20th 2023.
Sets callback_data to the passed object. Intended to be used by telegram.ext.CallbackDataCache .
Bot API v2: Кнопки и редактирование сообщений
В начале апреля 2016 года вышло первое по-настоящему крупное обновление API для ботов. Изменений довольно много, поэтому материал я разобью на несколько частей. Сегодня поговорим об inline-кнопках и редактировании сообщений, а затем обсудим новые инлайн-режимы вместе со специальными кнопками для отправки геолокации и номера телефона.
Новые возможности
- Каждая кнопка, будь то обычная или инлайн, это теперь самостоятельный объект KeyboardButton или InlineKeyboardButton , не забудьте обновить своих ботов!
- В Inline-режиме все текстовые поля теперь представлены отдельными объектами InputMessageContent , которые, в свою очередь могут быть аж 4-х типов (подробности тут).
URL-кнопки
Итак, инлайн-кнопки. Что это такое? Это специальные объекты, которые “цепляются” к конкретным сообщениям и распространяют своё действие, в общем случае, только на них. Делятся такие кнопки на три типа: URL-кнопки, Callback-кнопки и Switch-кнопки. Самыми простыми являются кнопки-ссылки (URL). Как видно из названия, их цель — просто перекидывать пользователей по определенным веб-адресам. Давайте сразу напишем обработчик, который будет на любое сообщение отвечать каким-либо текстом и предложением перейти, например, на Яндекс.
@bot.message_handler(content_types=["text"]) def default_test(message): keyboard = types.InlineKeyboardMarkup() url_button = types.InlineKeyboardButton(text="Перейти на Яндекс", url="https://ya.ru") keyboard.add(url_button) bot.send_message(message.chat.id, "Привет! Нажми на кнопку и перейди в поисковик.", reply_markup=keyboard)
Инлайн-клавиатура представляет собой объект InlineKeyboardMarkup , а каждая инлайн-кнопка – это объект InlineKeyboardButton . Чтобы получилась URL-кнопка, нужно указать значения параметров text (текст на кнопке) и url (валидный веб-адрес). В результате бот пришлет нам такое сообщение (см. рис.). В целях обеспечения безопасности, перед переходом по URL-кнопкам появляется всплывающее окно, в котором видна ссылка целиком.
Callback-кнопки и редактирование сообщений
Прежде, чем мы перейдем к другим кнопкам, давайте познакомимся с функциями редактирования сообщений, коих тоже три: editMessageText (редактирование текста), editMessageCaption (редактирование подписи к медиа) и editMessageReplyMarkup (редактирование инлайн-клавиатуры). В рамках этого урока рассмотрим только первую функцию, остальные работают аналогично и предлагаются для самостоятельного изучения.
Чтобы отредактировать сообщение, нам надо знать, про какое именно идёт речь. В случае, если оно было отправлено самим ботом, идентификаторами служит связка chat_id + message_id . Но если сообщение было отправлено в инлайн-режиме, то ориентироваться надо по параметру inline_message_id .
И вот теперь вернемся к нашим баранам кнопкам. На очереди – Callback. Это, на мой взгляд, самая крутая фича нового обновления. Колбэк-кнопки позволяют выполнять произвольные действия по их нажатию. Всё зависит от того, какие параметры каждая кнопка в себе несёт. Соответственно, все нажатия будут приводить к отправке боту объекта CallbackQuery , содержащему поле data , в котором написана некоторая строка, заложенная в кнопку, а также либо объект Message , если сообщение отправлено ботом в обычном режиме, либо поле inline_message_id , если сообщение отправлено в инлайн-режиме.
Приведу пример, после которого все вопросы должны отпасть: пусть, например, если сообщение отправлено ботом в обычном режиме, то нажатие на кнопку заменит текст сообщения на “Пыщь”, если в инлайн – то “Бдыщь”. При этом в обоих случаях значение callback_data будет равно test . Что для этого нужно сделать: во-первых, написать простейший хэндлер для всех входящих сообщений, во-вторых, написать простейший хэндлер для инлайн-сообщений, в-третьих, написать простейший хэндлер для колбэка, который определит, из какого режима пришло сообщение.
# Обычный режим @bot.message_handler(content_types=["text"]) def any_msg(message): keyboard = types.InlineKeyboardMarkup() callback_button = types.InlineKeyboardButton(text="Нажми меня", callback_data="test") keyboard.add(callback_button) bot.send_message(message.chat.id, "Я – сообщение из обычного режима", reply_markup=keyboard) # Инлайн-режим с непустым запросом @bot.inline_handler(lambda query: len(query.query) > 0) def query_text(query): kb = types.InlineKeyboardMarkup() # Добавляем колбэк-кнопку с содержимым "test" kb.add(types.InlineKeyboardButton(text="Нажми меня", callback_data="test")) results = [] single_msg = types.InlineQueryResultArticle( style=color:#a31515>"1", title="Press me", input_message_content=types.InputTextMessageContent(message_text="Я – сообщение из инлайн-режима"), reply_markup=kb ) results.append(single_msg) bot.answer_inline_query(query.id, results) # В большинстве случаев целесообразно разбить этот хэндлер на несколько маленьких @bot.callback_query_handler(func=lambda call: True) def callback_inline(call): # Если сообщение из чата с ботом if call.message: if call.data == "test": bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text="Пыщь") # Если сообщение из инлайн-режима elif call.inline_message_id: if call.data == "test": bot.edit_message_text(inline_message_id=call.inline_message_id, text="Бдыщь") if __name__ == '__main__': bot.infinity_polling()
Запускаем бота, отправляем инлайн-сообщение, которое, в свою очередь, вызовет обычное:
Нажмем на обе кнопки, результат правильный:
Таким образом, callback-кнопки – это очень мощный инструмент для взаимодействия пользователей с ботом, а редактирование сообщений дополнительно помогает в этом. Более того, нажатие на колбэк-кнопку может дополнительно тригернуть либо уведомление в верхней части экрана, либо всплывающее окно. Покажу первый вариант. Пускай помимо изменения сообщения на “Пыщь”, аналогичное слово показывается уведомлением. Для этого перепишем первое if-условие в хендлере колбэков:
if call.message: if call.data == "test": bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text="Пыщь") bot.answer_callback_query(callback_query_id=call.id, show_alert=False, text="Пыщь!")
Результат – на скриншоте. Попробуйте, кстати, изменить аргумент show_alert на True и посмотрите, что получится.
Всплывающее уведомление
Switch-кнопки
Наконец, остался последний тип кнопок — Switch (переключатель). Они нужны, чаще всего, для обучения пользователей работе с ботом в инлайн-режиме. Чтобы активировать сделать кнопку такого типа, нужно указать аргумент switch_inline_query либо пустой, либо с каким-либо текстом. В последнем случае этот текст будет сразу подставлен в поле ввода, например, для показа демонстрации инлайна. Как вообще работает такая кнопка? При нажатии на неё Telegram предложит выбрать чат, после чего подставит в поле ввода ник вашего бота и (если есть), текст, указанный вами в аргументе switch_inline_query . Давайте попробуем так сделать. Добавим кнопку, которая будет перенаправлять пользователя в какой-либо чат и предлагать в инлайн-режиме запрос “Telegram”. Код всего хендлера выглядит вот так:
@bot.message_handler(content_types=["text"]) def any_msg(message): keyboard = types.InlineKeyboardMarkup() switch_button = types.InlineKeyboardButton(text="Нажми меня", switch_inline_query="Telegram") keyboard.add(switch_button) bot.send_message(message.chat.id, "Я – сообщение из обычного режима", reply_markup=keyboard)
Теперь, если мы нажмем на кнопку и выберем чат, вот что получится:
Итак, в этом уроке мы познакомились с новыми кнопками в Telegram Bot API, научились переписывать историю редактировать сообщения и отправлять небольшие уведомления по нажатию. В следующий раз продолжим изучать новые возможности для ботов. А исходники к этому уроку можно найти в этом репозитории.