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 keyboardresize_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 keyboardrequest_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())Смотрим что получилось:
