Кнопки и колбэки
Набирать команды неудобно. Гораздо приятнее нажимать кнопки — в aiogram для этого есть инлайн-клавиатуры под сообщениями.
Клавиатура
from aiogram.utils.keyboard import InlineKeyboardBuilder
builder = InlineKeyboardBuilder()
for m in [5, 10, 15, 30]:
builder.button(text=f"{m} мин", callback_data=f"in:{m}")
builder.button(text="Отмена", callback_data="cancel")
builder.adjust(2, 2, 1) # ряды: 2, 2 и 1 кнопка
await message.answer("Через сколько?", reply_markup=builder.as_markup())
text— надпись на кнопке,callback_data— строка (до 64 байт), которую бот получит при нажатии;adjust(…)раскладывает кнопки по рядам; последнее число повторяется для оставшихся кнопок;- кнопка-ссылка —
builder.button(text="Сайт", url="https://…").
Бывают ещё «обычные» клавиатуры вместо поля ввода (ReplyKeyboardBuilder) — их нажатия приходят как текстовые сообщения.
Нажатие
from aiogram.types import CallbackQuery
@router.callback_query(F.data.startswith("in:"))
async def picked(callback: CallbackQuery):
minutes = int(callback.data.split(":")[1])
await callback.message.edit_text(f"Напомню через {minutes} мин")
await callback.answer("Принято!")
- нажатие приходит как CallbackQuery:
callback.data— данные кнопки,callback.from_user— кто нажал,callback.message— сообщение с кнопками; callback.message.edit_text(…, reply_markup=…)меняет само сообщение — так делают листалки и меню;await callback.answer()обязателен: иначе на кнопке у пользователя долго крутятся часики. С текстом — всплывающее уведомление.
Фабрика данных
Склеивать и разбирать строки вручную легко с ошибкой. Для этого есть CallbackData:
from aiogram.filters.callback_data import CallbackData
class ReminderCb(CallbackData, prefix="rem"):
action: str
rid: int
kb.button(text="Готово", callback_data=ReminderCb(action="done", rid=3)) # "rem:done:3"
@router.callback_query(ReminderCb.filter(F.action == "done"))
async def done(callback: CallbackQuery, callback_data: ReminderCb):
callback_data.rid # 3 — уже число
Фабрика сама собирает строку и разбирает её обратно, с проверкой типов. Фильтр .filter(...) пропускает только данные с этим префиксом и нужными значениями.
Итог
InlineKeyboardBuilder,button(text, callback_data),adjust,as_markup();@router.callback_query(...),callback.data,edit_text;await callback.answer()— всегда;- фабрика
CallbackDataсprefixи полями,.filter(...).