- Регистрация
- 21.07.20
- Сообщения
- 40.408
- Реакции
- 1
- Репутация
- 0
Боты - одна из особенностей Telegram, сделавших мессенджер столь популярным. А его встроенные клавиатуры дают разработчикам большую свободу взаимодействия с пользователями.
You must be registered for see links
помогает создавать встроенные клавиатуры любой сложности для ботов, разработанных на базе
You must be registered for see links
.В этой статье рассмотрим базовые возможности модуля - создание клавиатур из разных наборов данных, автоматическое и ручное распределение кнопок по рядам, объединение нескольких клавиатур в одну. Научимся создавать сложные, динамические callback, сохраняя в них информацию о выборе пользователя.
Статья рассчитана на тех, кто знает основы
You must be registered for see links
и хотя бы немного знаком с фреймворком 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 = [
{"banana": "101"}, {"coconut": "102"}, {"orange": "103"},
{"peach": "104"}, {"apricot": "105"}, {"apple": "106"},
{"pineapple": "107"}, {"avocado": "108"}, {"melon": "109"}, ]
# 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.
{"text": "banana", "callback_data": "101"}, ...
Этого достаточно, если мы используем числа только для обозначения фруктовых id. А если нужно принимать разные числовые параметры, например вес или цену? Как определить, к чему относится полученное число?
С Keyboa мы можем явно указать это при создании клавиатуры. Параметр front_marker добавляет одинаковый текст в начало callback_data каждой кнопки, а back_marker, соответственно, в конец. Рассмотрим на примере:
kb_fruits = keyboa_maker(items=fruits_with_ids, front_marker="&fruit_id=")
Теперь callback_data кнопок будет состоять из текста формата front_marker + value, например: '&fruit_id=101', '&fruit_id=102' и т. д. Такой подход позволит нам легко расшифровать строку и понять, какие получены данные и с какими значениями.
Представим, что на следующем шаге пользователю предлагают выбрать желаемый вес выбранного фрукта:
# коллбек, полученный после нажатия на кнопку, например "&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=", back_marker=selected_fruit_id)
Теперь callback_data каждой кнопки будет выглядеть так:
'&weight=1&fruit_id=102', '&weight=2&fruit_id=102', '&weight=5&fruit_id=102'…
Здесь мы используем front_marker и back_marker, чтобы обернуть передаваемое значение, указав тип текущего значения и добавив в callback_data уже полученную информацию. Имейте в виду, что у Telegram есть ограничение на длину callback_data в 64 байта, поэтому, если передаваемых параметров будет много - придётся сокращать названия или использовать аббревиатуры.
Объединение нескольких клавиатур в одну
Иногда в одну клавиатуру могут входить статические и динамические элементы, например, навигационное меню и меняющийся набор элементов. Тогда возникает потребность собрать клавиатуру из нескольких частей. Специально для этого у нас есть функция keyboa_combiner().
У нее есть только один параметр - keyboards, представляющий собой набор уже созданных клавиатур. Вот, как это работает:
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. Больше информации и описание остальных параметров можно найти на
You must be registered for see links
.Буду рад вашим отзывам, идеям и конструктивной критике по развитию проекта.