Appearance
Aiogram 3: Текстовая клавиатура
https://habr.com/ru/articles/820733/
Текстовая клавиатура
Текстовая клавиатура отображается под полем набора сообщения. Основная её особенность в том, что она не содержит никакой информации, кроме текста на кнопках.
Другими словами, текст на кнопке отправляется боту, который реагирует на это сообщение, например, через F.text ==
.
Начнем с кода. Реализуем его в файле all_kb.py
, который находится в пакете keyboards
.
Создадим простую клавиатуру главного меню. Для разнообразия сделаем так, чтоб у администраторов была дополнительная кнопка "Админ Панель" после выполнения простого фильтра.
Импорты в all_kb.py:
python
from aiogram.types import KeyboardButton, ReplyKeyboardMarkup
from create_bot import admins
Создание клавиатуры "Главное меню":
python
def main_kb(user_telegram_id: int):
kb_list = [
[KeyboardButton(text="📖 О нас"), KeyboardButton(text="👤 Профиль")],
[KeyboardButton(text="📝 Заполнить анкету"), KeyboardButton(text="📚 Каталог")]
]
if user_telegram_id in admins:
kb_list.append([KeyboardButton(text="⚙️ Админ панель")])
keyboard = ReplyKeyboardMarkup(keyboard=kb_list, resize_keyboard=True, one_time_keyboard=True)
return keyboard
Функция main_kb
принимает один аргумент user_telegram_id
типа int
, который представляет собой ID
пользователя в Telegram.
Создание списка кнопок:
python
kb_list = [
[KeyboardButton(text="📖 О нас"), KeyboardButton(text="👤 Профиль")],
[KeyboardButton(text="📝 Заполнить анкету"), KeyboardButton(text="📚 Каталог")]
]
kb_list
: список списков с объектами KeyboardButton.- Первая строка кнопок:
📖 О нас
и👤 Профиль
. - Вторая строка кнопок:
📝 Заполнить анкету
и📚 Каталог
.
Добавление кнопки для админов:
python
if user_telegram_id in admins:
kb_list.append([KeyboardButton(text="⚙️ Админ панель")])
Если user_telegram_id
присутствует в списке admins
, добавляется строка с кнопкой ⚙️ Админ панель
.
Создание и возврат объекта клавиатуры:
python
keyboard = ReplyKeyboardMarkup(keyboard=kb_list, resize_keyboard=True, one_time_keyboard=True)
return keyboard
Функция возвращает созданную клавиатуру, которую мы затем привязываем к сообщению.
Привязка клавиатуры к сообщению (handlers/start.py):
python
from aiogram import Router, F
from aiogram.filters import CommandStart
from aiogram.types import Message
from keyboards.all_kb import main_kb
start_router = Router()
@start_router.message(CommandStart())
async def cmd_start(message: Message):
await message.answer('Запуск сообщения по команде /start используя фильтр CommandStart()',
reply_markup=main_kb(message.from_user.id))
Для нашего фильтра мы вытянули телеграм айди пользователя из объекта message
(message.from_user.id)
.
Импортируем клавиатуру из пакета keyboards
и при помощи reply_markup
привязываем её к сообщению. Давайте посмотрим что у нас получилось:
Так как у нас кнопок было достаточно много — они у нас получились более-менее обычного размера, но, если бы это была всего 1 кнопка, то тут бы вышло такое:
На любителя. Давайте исправим.
Улучшение клавиатуры
python
def main_kb(user_telegram_id: int):
kb_list = [
[KeyboardButton(text="📖 О нас"), KeyboardButton(text="👤 Профиль")],
[KeyboardButton(text="📝 Заполнить анкету"), KeyboardButton(text="📚 Каталог")]
]
if user_telegram_id in admins:
kb_list.append([KeyboardButton(text="⚙️ Админ панель")])
keyboard = ReplyKeyboardMarkup(
keyboard=kb_list,
resize_keyboard=True,
one_time_keyboard=True,
input_field_placeholder="Воспользуйтесь меню:"
)
return keyboard
resize_keyboard=True
: клавиатура будет автоматически изменять размер.one_time_keyboard=True
: клавиатура скрывается после одного использования.input_field_placeholder
: заменяет стандартную подпись «Написать сообщение...» на пользовательскую.
Смотрим что получилось:
Красиво, правда?
Особые текстовые кнопки
Теперь создадим клавиатуру с "особыми кнопками". На примере будут кнопки:
- Поделиться контактами
- Поделиться локацией
- Создать викторину/опрос
Создание специальной клавиатуры:
python
def create_spec_kb():
kb_list = [
[KeyboardButton(text="Отправить гео", request_location=True)],
[KeyboardButton(text="Поделиться номером", request_contact=True)],
[KeyboardButton(text="Отправить викторину/опрос", request_poll=KeyboardButtonPollType())]
]
keyboard = ReplyKeyboardMarkup(keyboard=kb_list,
resize_keyboard=True,
one_time_keyboard=True,
input_field_placeholder="Воспользуйтесь специальной клавиатурой:")
return keyboard
request_location=True
: позволяет пользователю отправить геолокацию.request_contact=True
: позволяет отправить контактный номер.request_poll=KeyboardButtonPollType()
: позволяет создать викторину или опрос. Может принимать один из параметров type = «quiz» (викторина) или «regular» (опрос). В нашем случае и то и то будет обработано.
Привязка специальной клавиатуры под обработчик /start_2:
python
@start_router.message(Command('start_2'))
async def cmd_start(message: Message):
await message.answer('Запуск сообщения по команде /start_2 используя фильтр Command()',
reply_markup=create_spec_kb())
Смотрим что получилось:
Визуально ничем не отличается от обычной текстовой клавиатуры.
Геолокацию можно отправить только со смартфона. При вызове этой опции через пк - получим такое сообщение:
Со смартфона данные передаются корректно, и теперь остается только обработать гео-данные. Как это сделать мы подробно обговорим в теме про FSM.
При клике на "Поделиться номером" (текст может быть любой). Пользователь увидит всплывающее окно:
Так выглядит всплывающее окно на этом этапе.
После клика на "Поделиться" произойдет отправка номера телефона, который привязан к профилю телеграмм. Далее останется захватить ответ. Как это сделать мы тоже подробно обговорим в теме про FSM.
Так выглядит универсально окно. Давайте создадим опрос.
Пример
Штуку с викториной и опросником удобно использовать в группах и телеграмм каналах, которые будет администрировать ваш бот.
Использование ReplyKeyboardBuilder
Теперь давайте воспользуемся нововведением в aiogram 3, а именно строителем текстовых клавиатур. Для начала сделаем импорт:
python
from aiogram.utils.keyboard import ReplyKeyboardBuilder
Давайте сгенирируем некую шкалу голосования в котором результаты у нас записаны в виде баллов от 1 до 10. Пример кода:
python
def create_rat():
builder = ReplyKeyboardBuilder()
for item in [str(i) for i in range(1, 11)]:
builder.button(text=item)
builder.button(text='Назад')
builder.adjust(4, 4, 2, 1)
return builder.as_markup(resize_keyboard=True)
Описание функции create_rat
Создаем объект ReplyKeyboardBuilder()
, который будет использоваться для построения клавиатуры.
Добавление кнопок с оценками
python
for item in [str(i) for i in range(1, 11)]:
builder.button(text=item)
Создаем список строк от '1' до '10' с помощью генератора списка.
Для каждого элемента в этом списке добавляем кнопку с текстом, равным этому элементу.
Настройка расположения кнопок
adjust(4, 4, 2, 1)
указывает, что кнопки должны быть размещены в строках по 4, 4, 2 и 1 кнопке соответственно.
- Первая строка будет содержать 4 кнопки.
- Вторая строка будет содержать 4 кнопки.
- Третья строка будет содержать 2 кнопки.
- Четвертая строка будет содержать 1 кнопку ("Назад").
Возврат разметки клавиатуры
python
return builder.as_markup(resize_keyboard=True)
Преобразуем построенную клавиатуру в объект ReplyKeyboardMarkup
с помощью метода as_markup
.
Указываем параметр resize_keyboard=True
, чтобы клавиатура автоматически изменяла размер в зависимости от количества и размера кнопок.
Привяжем клавиатуру к команде /start_3
python
@start_router.message(F.text == '/start_3')
async def cmd_start(message: Message):
await message.answer('Запуск сообщения по команде /start_3 используя магический фильтр F.text!',
reply_markup=create_rat())
Смотрим что получилось: