Найти тему
Дойти до IT

Callback в aiogram - как сделать бота ещё умнее

Как упоминалось на прошлом уроке, в aiogram Inline клавиатура может отправлять callback — это строка, которая с помощью фильтра вызывает нужную функцию (хэндлер). Пользователь не видит этот callback, но мы можем использовать его для передачи какой-либо полезной информации, например ID.

Рассмотрим пример использования Inline клавиатуры с callback:

-2
inline_main = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='Корзина', callback_data='basket')],
[InlineKeyboardButton(text='Каталог', callback_data='catalog')],
[InlineKeyboardButton(text='Контакты', callback_data='contacts')]
])

Коллбэки basket/catalog/contacts будут обрабатываться хэндлерами по примеру:

-3
from aiogram import Router, F
from aiogram.types import Message, CallbackQuery
from aiogram.filters import CommandStart
import app.keyboards as kb
router = Router()
@router.message(CommandStart())
async def cmd_start(message: Message):
await message.answer(f'Привет!', reply_markup=kb.inline_main)
@router.callback_query(F.data == 'basket')
async def basket(callback: CallbackQuery):
await callback.message.answer('Ваша корзина пуста.')

Следует отметить, что мы импортируем класс CallbackQuery. Затем у роутера вызывается метод callback_query, в который передаётся ранее импортированный класс в качестве параметра функции. С помощью метода callback.message.answer мы отправляем сообщение пользователю. Посмотрим на результат:

-4

Когда пользователь нажимает кнопку «Корзина», отправляется сообщение, но нажатая кнопка остаётся подсвеченной. Это связано с тем, что на callback-запрос необходимо ответить с помощью метода callback.answer:

-5
@router.callback_query(F.data == 'basket')
async def basket(callback: CallbackQuery):
await callback.answer('Вы выбрали корзину.')
await callback.message.answer('Ваша корзина пуста.')
-6

Кнопка перестаёт быть подсвеченной, и в центре экрана появляется уведомление (на MacOS, мобильных устройствах и других клиентах оно может отображаться сверху или в другом формате).

Отправляя подобное уведомление, мы можем не просто показать исчезающее сообщение, а вывести полноценное окно, если добавим аргумент show_alert=True:

-7
@router.callback_query(F.data == 'basket')
async def basket(callback: CallbackQuery):
await callback.answer('Вы выбрали корзину.', show_alert=True)
await callback.message.answer('Ваша корзина пуста.')
-8

Вы успешно освоили создание и использование Reply- и Inline-клавиатур. Для этого вы научились применять классы ReplyKeyboardMarkup и InlineKeyboardMarkup, а также передавать списки вида [ [], [] ].

Reply-клавиатура появляется снизу и отправляет содержимое нажатой кнопки в чат. Это сообщение можно перехватить с помощью фильтра F.text и обработать нужным образом.

Inline-клавиатура отображается под сообщением и может открывать ссылку, WebApp или отправлять callback. Callback обрабатывается методом роутера .callback_query с помощью фильтра F.data.

Все клавиатуры необходимо прикреплять к сообщению с помощью метода reply_markup.

P.S. Даже, если эта статья будет неактуальна, она всё равно станет отличным блокнотом для меня, чтобы не потерять некоторые команды и не гуглить их повторно. Может через пару лет я вернусь сюда, чтобы вспомнить некоторые моменты. А дочитавшим до конца желаю, чтобы ваши работы, проекты и поделки были актуальными всегда!=)

Не забудьте почитать: