Перейти к содержимому

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

  • автор:

Кнопки в телеграм-ботах

Это статья из серии о телеграм-ботах. Я по частям расскажу о важных моментах в pytelegrambotapi. Сразу полезная информация: я начал учиться делать ботов по этой статье и всем ее рекомендую.

Кнопки в телеграм бывают двух видов — inline и обычные (reply).

Обычные вы видите вместо клавиатуры, все, что они делают, как правило, — отправляют текстовое сообщение боту.

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

Но, перед тем, как сделать кнопку, нужно создать клавиатуру. Для обычных кнопок она одна, для inline другая, вот обычная:

keyboard = types.ReplyKeyboardMarkup(row_width=1, resize_keyboard=False, one_time_keyboard=True)

resize_keyboard: bool — необязательный | будет ли клавиатура растягиваться (по умолчанию: без значения)

one_time_keyboard: bool — необязательный \ разовая ли клавиатура (по умолчанию: без значения)

selective: bool — необязательный | кому показывать (по умолчанию: без значения)

row_width: int — обязательный | количество столбцов кнопок (по умолчанию: 3)

input_field_placeholder: str — необязательный | заменяет текст-заглушку в поле ввода (по умолчанию: без значения)

Создав клавиатуру, создадим к ней кнопку:

stop = types.KeyboardButton(text=’отмена ❌’)

text: str — обязательный | текст кнопки. Если указан только он, то кнопка будет просто отправлять текст при нажатии.

request_contact: bool — необязательный | если указан как true то пользователь при нажатии отправит свой контакт. Доступен только в приватных чатах.

request_location: bool — необязательный | если указан как true, то пользователь при нажатии отправит свою локацию. Доступен только в приватных чатах.

request_poll: bool — необязательный | если указан как true, то пользователь при нажатии отправит свою локацию. Доступен только в приватных чатах.

web_app: WebAppInfo — необязательный | если указан как true, то при нажатии откроется страница указанного веб-приложения — про это есть отдельная статья. Доступен только в приватных чатах.

После создания кнопки ее нужно добавить в клавиатуру вот так:

keyboard.add(stop)

И далее дать эту клавиатуру пользователю с сообщением:

bot.send_message(message.chat.id, ‘Клавиатура с одной кнопкой, reply_markup=keyboard)

  • Отправить можно только одну клавиатуру за раз
  • Это актуально для всех типов клавиатур.

Inline-кнопки вы видите под сообщением.

Keyboa: клавиатуры на максималках для ботов в Telegram

Боты — одна из особенностей Telegram, сделавших мессенджер столь популярным. А его встроенные клавиатуры дают разработчикам большую свободу взаимодействия с пользователями.

Keyboa помогает создавать встроенные клавиатуры любой сложности для ботов, разработанных на базе pyTelegramBotAPI.

В этой статье рассмотрим базовые возможности модуля — создание клавиатур из разных наборов данных, автоматическое и ручное распределение кнопок по рядам, объединение нескольких клавиатур в одну. Научимся создавать сложные, динамические callback, сохраняя в них информацию о выборе пользователя.

Статья рассчитана на тех, кто знает основы Telegram Bot API и хотя бы немного знаком с фреймворком pyTelegramBotAPI.

Модуль требует > Python 3.5 и ставится через pip:

pip install keyboa

В официальной документации Telegram объект inline_keyboard определен как массив, состоящий из массивов кнопок (Array of Array of InlineKeyboardButton). То есть основной массив (список) — это клавиатура в целом, а его элементы (вложенные списки) — это ряды кнопок. Не переживайте, если определение кажется сложным — позже мы разберём его на простом примере.

Предположим, что сам бот у нас уже настроен:

import os from telebot import TeleBot from keyboa import keyboa_maker token = os.environ["TELEGRAM_BOT_TOKEN"] uid = os.environ["TELEGRAM_USER_ID"] bot = TeleBot(token=token)

Создаём клавиатуру

Предположим, нам нужно отправить пользователю на выбор список фруктов.

fruits = [ "banana", "coconut", "orange", "peach", "apricot", "apple", "pineapple", "avocado", "melon" ]

Создадим самую простую клавиатуру, в которой каждый элемент встанет на отдельный ряд:

kb_fruits = keyboa_maker(items=fruits, copy_text_to_callback=True)

Всё, что потребовалось — передать список в items . Оставить пустой сallback_data (ответную часть кнопки) мы не можем, ведь иначе не узнаем, что нажал пользователь. Поэтому добавляем текст каждой кнопки в её callback_data , устанавливая параметр copy_text_to_callback .

Отправим сообщение пользователю:

bot.send_message( chat_id=uid, reply_markup=kb_fruits, text="Please select one of the fruit:")

Распределяем кнопки по рядам

Разместить несколько кнопок в ряд можно любым из трёх способов.

Указать количество кнопок в ряду

Определите параметр items_in_row , чтобы задать количество кнопок в ряду. Их число должно быть от одного до восьми. Больше кнопок нам не позволит добавить сам Telegram.

Создадим клавиатуру и отправим обновлённое сообщение:

kb_fruits = keyboa_maker(items=fruits, copy_text_to_callback=True, items_in_row=3) bot.send_message( chat_id=uid, reply_markup=kb_fruits, text="Please select one of the fruit:")

Использовать автоподбор

Если клавиатура создается динамически, мы не всегда знаем, сколько в ней окажется кнопок. Чтобы автоматически равномерно распределить их по рядам, установите параметр auto_alignment . Если выставить True , Keyboa попробует подобрать делитель в диапазоне от трёх до пяти, а можно задать свой диапазон в виде списка чисел от одного до восьми, например, [2, 3, 7] .

Параметр reverse_alignment_range определяет, будет ли Keyboa искать делитель с начала или с конца диапазона, указанного в auto_alignment .

Распределить кнопки вручную

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

fruitscomplex = [ "banana", ["coconut", "orange"], ["peach", "apricot", "apple"], "pineapple", ["avocado", "melon"], ] kb_fruits_complex = keyboa_maker(items=fruits_complex, copy_text_to_callback=True) bot.send_message( chat_id=uid, reply_markup=kb_fruits_complex, text="Please select one of the fruit:")

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

Управляем содержимым callback

Мы упоминали, что callback_data — это строка, которую Telegram отправляет вам после нажатия кнопки пользователем. По её содержимому вы можете понять, какая именно кнопка была нажата.

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

fruits_with_ids = [ , , , , , , , , , ] # or [ # ("banana", "101"), ("coconut", "102"), ("orange", "103"), # ("peach", "104"), ("apricot", "105"), ("apple", "106"), # ("pineapple", "107"), ("avocado", "108"), ("melon", "109"), ]

В этом случае ключ каждого словаря станет текстом кнопки, а его значение пойдет в callback_data. Для кортежей это будут нулевой и первый элементы соответственно. И поскольку мы явно указываем, что добавить в callback_data, параметр copy_text_to_callback больше не нужен.

kb_fruits = keyboa_maker(items=fruits_with_ids, items_in_row=3) bot.send_message( chat_id=uid, reply_markup=kb_fruits, text="Please select one of the fruit:")

Теперь, после нажатия пользователем одной из кнопок, мы получим в ответ не название фрукта, а его id номер, записанный в callback_data.

Этого достаточно, если мы используем числа только для обозначения фруктовых id. А если нужно принимать разные числовые параметры, например вес или цену? Как определить, к чему относится полученное число?

С Keyboa мы можем явно указать это при создании клавиатуры. Параметр front_marker добавляет одинаковый текст в начало callback_data каждой кнопки, а back_marker , соответственно, в конец. Рассмотрим на примере:

kb_fruits = keyboa_maker(items=fruits_with_ids, front_marker="&fruit_id python"># коллбек, полученный после нажатия на кнопку, например "&fruit_id=102" selected_fruit_id = call.data available_weight = [1, 2, 5, 10, 100, ] kb_available_weight = keyboa_maker( items=available_weight, copy_text_to_callback=True, front_marker="&weight python">from keyboa import keyboa_maker, keyboa_combiner controls = [["⏹️", "⏪️", "⏏️", "⏩️", "▶️"], ] tracks = list(range(1, 13)) keyboard_controls = keyboa_maker(items=controls, copy_text_to_callback=True) keyboard_tracks = keyboa_maker(items=tracks, items_in_row=4, copy_text_to_callback=True) keyboard = keyboa_combiner(keyboards=(keyboard_tracks, keyboard_controls)) bot.send_message( chat_id=uid, reply_markup=keyboard, text="Please select the track number:")

Можно объединить сразу много клавиатур — главное, чтобы общее количество кнопок было не больше ста. Это ограничение Telegram.

Итог

В этой статье мы кратко рассмотрели создание клавиатур для ботов в Telegram с помощью Keyboa. Больше информации и описание остальных параметров можно найти на странице проекта в Github.

Буду рад вашим отзывам, идеям и конструктивной критике по развитию проекта.

Урок 5. Клавиатуры и кнопки

В сегодняшнем уроке мы разберём шаблоны сообщений и инлайн-клавиатуры и научимся применять встроенные в aiogram методы для составления сложных клавиатур.

Не забывайте своевременно обновлять библиотеку командой python3.6 -m pip install aiogram -U ! Урок проводится с использованием версии 1.2.3

Весь код, использованный в уроке, как обычно доступен на GitHub

Для начала стоит понять, в чем основное различие ReplyKeyboardMarkup и InlineKeyboardMarkup :

ReplyKeyboardMarkup — это шаблоны сообщений. К примеру, ваш бот задаёт пользователю вопрос и предлагает варианты ответа. Пользователь может самостоятельно напечатать ответ, либо нажать на готовую кнопку. Такая клавиатура показывается вместо основной и не привязана ни к какому сообщению. В кнопки такой клавиатуры нельзя заложить никакой информации, нельзя запрограммировать для неё подобный если пользователь нажимает кнопку с текстом «abc» отправить текст «qwerty» алгоритм, отправлено будет только то, что написано на кнопке (есть два исключения, о которых ниже).

InlineKeyboardMarkup — это уже настоящая кастомная клавиатура. С её помощью мы можем выполнять более сложные действия. Она привязывается к сообщению, с которым была отправлена. В кнопки можно заложить любой текст размером от 1 до 64 байт (будьте осторожны, недобросовестные клиенты позволяют изменять эти данные). Инлайн кнопки позволяют скрыть в себе внутреннюю телеграм ссылку, ссылку на внешний ресурс, а также шорткат для инлайн запроса (об инлайн режиме в одном из следующих уроков).

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

Переходим к коду

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

В первую очередь импортируем необходимые нам модули и создаём первую клавиатуру:

from aiogram.types import ReplyKeyboardRemove, \ ReplyKeyboardMarkup, KeyboardButton, \ InlineKeyboardMarkup, InlineKeyboardButton button_hi = KeyboardButton('Привет! ��') greet_kb = ReplyKeyboardMarkup() greet_kb.add(button_hi) 

При инициализации класса KeyboardButton необходимо передать один обязательный параметр — текст, который пользователь будет отправлять по нажатию на эту кнопку. У объекта класса ReplyKeyboardMarkup есть несколько методов, позволяющих добавить кнопку, в данном случае мы используем add . Таким образом мы получили первую готовую клавиатуру.

Создаём обработчик, который будет отправлять нам сообщение и наш шаблон (напомню, что отправить отдельно клавиатуру никак нельзя, она является параметром к сообщению).

@dp.message_handler(commands=['start']) async def process_start_command(message: types.Message): await message.reply("Привет!", reply_markup=kb.greet_kb) 

Запускаем и проверяем:

Отлично, клавиатура появилась! Но эта одна кнопка с маленьким текстом занимает очень много места. Телеграм позволяет автоматически уменьшить размер, для этого необходимо передать в инициализатор класса ReplyKeyboardMarkup параметру resize_keyboard значение True . Создадим новую клавиатуру:

greet_kb1 = ReplyKeyboardMarkup(resize_keyboard=True).add(button_hi) 

Мы передали параметр в инициализатор и следом сразу добавили уже существующую кнопку. Отправляем новую версию клавиатуры:

@dp.message_handler(commands=['hi1']) async def process_hi1_command(message: types.Message): await message.reply("Первое - изменяем размер клавиатуры", reply_markup=kb.greet_kb1) 

Очевидно, так как у нас нет обработчика обычных сообщений, текст, отправляемый нажатием на эту кнопку, остаётся без ответа. При желании можно добавить функцию эхо из первого урока. А что ещё можно было заметить при использовании этой кнопки? Что она остаётся всё там же, даже если мы после нажатия хотели бы вернуться к привычной клавиатуре. Да, нажать одну кнопку, чтобы переключиться, не сложно. Но если клавиатура в принципе не подразумевает повторного нажатия прямо сейчас? И для этого тоже есть решение:

# keyboards.py greet_kb2 = ReplyKeyboardMarkup( resize_keyboard=True, one_time_keyboard=True ).add(button_hi) # bot.py @dp.message_handler(commands=['hi2']) async def process_hi2_command(message: types.Message): await message.reply("Второе - прячем клавиатуру после одного нажатия", reply_markup=kb.greet_kb2) 

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

Добавляем больше кнопок

Рассмотрим подробно работу встроенных методов для создания более сложных клавиатур, а именно row , insert и add . Создаём кнопки, которые мы сможем использовать повторно и генерируем несколько разных клавиатур:

button1 = KeyboardButton('1️⃣') button2 = KeyboardButton('2️⃣') button3 = KeyboardButton('3️⃣') markup3 = ReplyKeyboardMarkup().add( button1).add(button2).add(button3) markup4 = ReplyKeyboardMarkup().row( button1, button2, button3 ) markup5 = ReplyKeyboardMarkup().row( button1, button2, button3 ).add(KeyboardButton('Средний ряд')) button4 = KeyboardButton('4️⃣') button5 = KeyboardButton('5️⃣') button6 = KeyboardButton('6️⃣') markup5.row(button4, button5) markup5.insert(button6) 

Важно: сейчас мы отталкиваемся от того, что клавиатура по умолчанию имеет 3 кнопки в ряд. О том, как изменить это значение, будет в примере с инлайн клавиатурами — этот параметр идентичен для обоих видов.

  • Метод add принимает в себя любое количество кнопок, всегда начинает добавление с новой строки и переносит ряд при достижении значения установленной ширины.
  • Метод row тоже принимает любое количество, но при этом не переносит кнопки на новый ряд, а добавляет всё полученное в одну строчку.
  • Метод insert работает по схеме схожей с add , но только начинает добавлять к последнему ряду. И только если там уже достигнута максимальная ширина, начинает новую строку. Взглянем на него ещё раз при создании следующей клавиатуры.

Отправляем все готовые кнопки и смотрим на результат:

@dp.message_handler(commands=['hi3']) async def process_hi3_command(message: types.Message): await message.reply("Третье - добавляем больше кнопок", reply_markup=kb.markup3) 

@dp.message_handler(commands=['hi4']) async def process_hi4_command(message: types.Message): await message.reply("Четвертое - расставляем кнопки в ряд", reply_markup=kb.markup4) 

@dp.message_handler(commands=['hi5']) async def process_hi5_command(message: types.Message): await message.reply("Пятое - добавляем ряды кнопок", reply_markup=kb.markup5) 

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

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

# keyboards.py markup_request = ReplyKeyboardMarkup(resize_keyboard=True).add( KeyboardButton('Отправить свой контакт ☎️', request_contact=True) ).add( KeyboardButton('Отправить свою локацию ��️', request_location=True) ) #bot.py @dp.message_handler(commands=['hi6']) async def process_hi6_command(message: types.Message): await message.reply("Шестое - запрашиваем контакт и геолокацию\nЭти две кнопки не зависят друг от друга", reply_markup=kb.markup_request) 

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

Запрос контакта

Запрос текущей геолокации

Данные пользователя

Рассмотрим подробнее последний метод для составления клавиатур — insert . Он похож на метод add , но начинает добавлять кнопки не с нового ряда, а сначала проверяет, заполнен ли до конца последний ряд. И если нет, то сначала добавляет кнопки туда, а переносит строку только при достижении указанного лимита.

# keyboards.py markup_big = ReplyKeyboardMarkup() markup_big.add( button1, button2, button3, button4, button5, button6 ) markup_big.row( button1, button2, button3, button4, button5, button6 ) markup_big.row(button4, button2) markup_big.add(button3, button2) markup_big.insert(button1) markup_big.insert(button6) markup_big.insert(KeyboardButton('9️⃣')) # bot.py @dp.message_handler(commands=['hi7']) async def process_hi7_command(message: types.Message): await message.reply("Седьмое - все методы вместе", reply_markup=kb.markup_big) 

После каждой отправки ботом пользователю клавиатуры, последняя заменяет предыдущую. Поэтому пользователь всегда может открыть её, даже когда по контексту она не нужна. Для того, чтобы у пользователя в клиенте клавиатура убралась совсем, нужно отправить ему ReplyKeboardRemove :

@dp.message_handler(commands=['rm']) async def process_rm_command(message: types.Message): await message.reply("Убираем шаблоны сообщений", reply_markup=kb.ReplyKeyboardRemove()) 

Получив сообщение с такой клавиатурой, клиент уберёт шаблоны полностью.

Инлайн клавиатуры

Теперь перейдем к инлайн клавиатурам. Они имеют больше параметров, поэтому позволяют нам делать больше разных вещей. Самое популярное использование — как кнопка, являющаяся шорткатом для какого-то действия. То есть «если пользователь нажал кнопку X, сделать Y». И под Y можно понимать вообще что угодно, так как это уже не ограничивается даже API. Рассмотрим наглядно, для этого передадим в инициализатор значение callback_data :

# keyboards.py inline_btn_1 = InlineKeyboardButton('Первая кнопка!', callback_data='button1') inline_kb1 = InlineKeyboardMarkup().add(inline_btn_1) #bot.py @dp.message_handler(commands=['1']) async def process_command_1(message: types.Message): await message.reply("Первая инлайн кнопка", reply_markup=kb.inline_kb1) 

Нажимаем кнопку и.. ничего не происходит! Почему? Если у бота было включено логгирование, то вы могли заметить, что приходит обновление типа CallbackQuery . Так вот именно его нам и нужно отлавливать. Добавляем нужный хэндлер (я предпочитаю ставить их выше, но относительно хэндлеров обычных сообщений значения это не имеет):

@dp.callback_query_handler(func=lambda c: c.data == 'button1') async def process_callback_button1(callback_query: types.CallbackQuery): await bot.answer_callback_query(callback_query.id) await bot.send_message(callback_query.from_user.id, 'Нажата первая кнопка!') 

Здесь мы делаем проверку прямо в хэндлере. Аргумент func ожидает функцию, которая принимает один параметр (туда передаётся апдейт), и хэндлер срабатывает, если возвращается истина. Этот аргумент можно использовать и в других хэндлерах, мы уже использовали его в уроке по FSM.

Внутри мы можем делать вообще что угодно, так как работаем с обычным питоном. Подача корма для кошки? Управление светом? Пределом является только ваша фантазия.

Хорошим тоном будет отвечать на все колбеки — для этого есть метод answerCallbackQuery . В документации сказано, что ответ ожидается клиентом, и дать его нужно обязательно, даже если вы не собираетесь передавать что-либо. Этого времени предостаточно, чтобы собрать необходимые данные и прислать их. При этом во время ожидания на кнопке будут крутиться часики, показывающие, то клиент ждёт ответа, поэтому если мы не хотим, чтобы пользователь наблюдал их, то нужно не забывать отвечать. Обязательный аргумент — айди запроса, на который мы отвечаем. Остальные параметры рассмотрим ниже. А в данном случае мы для наглядности отправим сообщение с информацией о том, что нажата первая кнопка. Запускаем снова, жмём кнопку и таки получаем ответ:

В этот раз установим ширину клавиатуры 2 и посмотрим, что будет.
Ну и так как методы добавления новых элементов мы уже разобрали, добавим сразу все доступные кнопки и отправим получившуюся клавиатуру, не забыв добавить хэндлер кнопок:

# keyboards.py inline_kb_full = InlineKeyboardMarkup(row_width=2).add(inline_btn_1) inline_kb_full.add(InlineKeyboardButton('Вторая кнопка', callback_data='btn2')) inline_btn_3 = InlineKeyboardButton('кнопка 3', callback_data='btn3') inline_btn_4 = InlineKeyboardButton('кнопка 4', callback_data='btn4') inline_btn_5 = InlineKeyboardButton('кнопка 5', callback_data='btn5') inline_kb_full.add(inline_btn_3, inline_btn_4, inline_btn_5) inline_kb_full.row(inline_btn_3, inline_btn_4, inline_btn_5) inline_kb_full.insert(InlineKeyboardButton("query=''", switch_inline_query='')) inline_kb_full.insert(InlineKeyboardButton("query='qwerty'", switch_inline_query='qwerty')) inline_kb_full.insert(InlineKeyboardButton("Inline в этом же чате", switch_inline_query_current_chat='wasd')) inline_kb_full.add(InlineKeyboardButton('Уроки aiogram', url='https://surik00.gitbooks.io/aiogram-lessons/content/')) # bot.py @dp.callback_query_handler(func=lambda c: c.data and c.data.startswith('btn')) async def process_callback_kb1btn1(callback_query: types.CallbackQuery): code = callback_query.data[-1] if code.isdigit(): code = int(code) if code == 2: await bot.answer_callback_query(callback_query.id, text='Нажата вторая кнопка') elif code == 5: await bot.answer_callback_query( callback_query.id, text='Нажата кнопка с номером 5.\nА этот текст может быть длиной до 200 символов ��', show_alert=True) else: await bot.answer_callback_query(callback_query.id) await bot.send_message(callback_query.from_user.id, f'Нажата инлайн кнопка! code=') @dp.message_handler(commands=['2']) async def process_command_2(message: types.Message): await message.reply("Отправляю все возможные кнопки", reply_markup=kb.inline_kb_full) 

Пройдёмся по строчкам по порядку, чтобы не осталось вопросов:

  • мы создаём клавиатуру типа InlineKeyboardMarkup , указываем, что ширина строки должна быть не больше двух (напомню, что это не распространяется на метод row ) и сразу добавляем туда уже готовую кнопку
  • далее добавляем кнопку, у которой указываем другие данные в параметре callback_data
  • следом генерируем три новые кнопки и добавляем их дважды. Сначала методом add , затем через row . И так как ширина клавиатуры равна двум, то в первом случае происходит перенос третьей кнопки, во втором случае нет
  • затем добавляем кнопки, у которых указываем уже не callback_data , а другие параметры. То, что мы добавим в switch_inline_query , будет автоматически использовано при нажатии кнопки: пользователю предложат выбрать чат, а там вызовется инлайн режим этого бота (в поле ввода сообщения добавится юзернейм бота), следом через пробел будет прописано то, что мы указали. Параметр может принимать пустую строку, тогда инлайн режим запустится без какого-либо запроса, но если будет указан текст, то он и добавится
  • при использовании switch_inline_query_current_chat произойдёт ровно то же, что и в предыдущем пункте, но без выбора чата, а запустится в текущем (было сложно догадаться по названию, я знаю)
  • ну и последний параметр url - добавляем ссылку на внешний ресурс, либо диплинк в самом Телеграме

Так как параметр клавиатуры row_width равен двум, то кнопки автоматически расставились соответствующе. Рассмотрим реакцию на кнопки по порядку: При нажатии первой срабатывает наш первый колбек, так как не важно, в какую клавиатуру добавлена кнопка, важно, какая у неё callback_data ☝️. Поэтому добавлять инлайн кнопку можно сколько угодно раз в любые инлайн клавиатуры.

Кнопки со второй по пятую имеют схожую структуру в callback_data , поэтому внутри хэндлера проверяем, какой код у нажатой кнопки и:

  • если 2, то отвечаем на запрос и передаем информационное сообщение. Аргумент text это текст ответа на запрос. По умолчанию он будет показан вверху чата и сам скроется через пару секунд.
  • если 5, то отвечаем так же, но указываем show_alert=True , таким образом мы сообщаем клиенту, что нужно показать окошко с текстом
  • в ином случае просто отвечаем на колбек

И во всех случаях шлем сообщение пользователю:

Ещё можно отправить кнопку с игрой или платежом, но первое мы разберем в одном из следующих уроков, а о втором я уже упоминал в одном из предыдущих. При ответе на колбек можно ещё передать в ответ ссылку формата t.me/your_bot?start=XXXX , чтобы пользователь запустил вашего бота с определенным параметром, но диплинкинг мы тоже оставим для другого урока, так как здесь только о кнопках.

На последок не забываем добавить обработку команы /help и запускаем:

help_message = text( "Это урок по клавиатурам.", "Доступные команды:\n", "/start - приветствие", "\nШаблоны клавиатур:", "/hi1 - авто размер", "/hi2 - скрыть после нажатия", "/hi3 - больше кнопок", "/hi4 - кнопки в ряд", "/hi5 - больше рядов", "/hi6 - запрос локации и номера телефона", "/hi7 - все методы" "/rm - убрать шаблоны", "\nИнлайн клавиатуры:", "/1 - первая кнопка", "/2 - сразу много кнопок", sep="\n" ) @dp.message_handler(commands=['help']) async def process_help_command(message: types.Message): await message.reply(help_message) if __name__ == '__main__': executor.start_polling(dp) 

Вот и всё!

В этом уроке мы разобрали как работать с клавиатурами в Телеграм

Чат-боты в Telegram на Python. Часть 2. Создаём и настраиваем меню

Продолжаем писать чат-бота для Telegram — добавляем кнопки и интерактив.

Иллюстрация: Катя Павловская для Skillbox Media

Антон Яценко

Антон Яценко
Изучает Python, его библиотеки и занимается анализом данных. Любит путешествовать в горах.

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

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

Виды клавиатур

Библиотека aiogram позволяет создать на Python клавиатуры двух видов, отличающиеся друг от друга расположением кнопок:

  • Reply-кнопки для шаблонных ответов, которые закрепляются вместо основной клавиатуры на экране. Часто используются в чат-ботах как меню. Создаются с помощью метода ReplyKeyboardMarkup.
  • Инлайн-кнопки, связанные с сообщениями в чате. При этом пользователь видит и основную клавиатуру. Создаются с помощью метода InlineKeyboardMarkup.

Создание меню

Наш эхо-бот для Telegram сейчас позволяет только отправлять текстовые сообщения и получать их обратно. Давайте проапгрейдим его и добавим кнопки с готовыми сообщениями, которые не надо вводить самому. Это будут reply-кнопки.

Нам понадобится класс ReplyKeyboardMarkup — для начала импортируем его и дополнительные необходимые классы:

Если нажать на любую кнопку, текст кнопки отправится в чат, а Telegram-бот пришлёт в ответ эту же фразу:

Можно создавать сколько угодно шаблонов, а также связывать кнопку с новыми действиями. Попробуем это на примере инлайн-клавиатур.

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

Инлайн-кнопки отличаются от обычных тем, что связаны не с областью клавиатуры в мессенджере, а с каким-то сообщением в Telegram-чате. Самый простой пример инлайн-кнопки — это меню в канале @BotFather, с помощью которого мы создавали токен для доступа к API Telegram. Например, вот так в нём выглядит инлайн-меню с уже созданными ботами:

Создадим на Python для нашего бота инлайн-кнопки со ссылками на Skillbox Media и курсы по программированию. Для этого вернёмся к разделу с импортами в коде и добавим ещё одну строку, чтобы можно было использовать необходимые классы:

Всё получилось. Теперь инлайн-клавиатура появляется при отправке команды /ссылки в бот.

Заключение

В нашем эхо-боте для Telegram появилось два вида меню, написанных на Python: reply-кнопки для быстрых сообщений и инлайн-кнопки для перехода на блог и сайт Skillbox. Для создания сложных ботов — например, ботов онлайн-магазинов — можно самостоятельно изучить документацию к библиотеке aiogram: попробовать новые классы, методы и объекты.

Читайте также:

  • С# для новичков: развеиваем мифы и пишем простого чат-бота
  • Тест. Какой язык создадите вы — Java или Python?
  • Что можно сделать на JavaScript и что нельзя

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *