Skip to content

Aiogram 3: Командное меню

https://habr.com/ru/articles/820733/

Работа с командным меню

Так выглядит командное меню в BotFather

img.png

Похожее меню мы можем создать двумя способами:

  • Через BotFather
  • Напрямую через код

Оба способа мы рассмотрим далее.

Настройка командного меню через BotFather

Вводим /mybots (или выбираем через командное меню)

img_1.png

Выбираем нашего бота

img_2.png

Выбираем Edit bot

img_3.png

Выбираем Edit command

img_4.png

Отправляем боту сообщение такого вида как на скрине

img_5.png

python
start - Главная страница
start_3 - Вызов спец. клавиатуры

После этих действий в боте появится кнопка «Меню» с этими командами. Для того чтоб все работало необходимо в боте привязать к каждой команде нужное действие.

img_6.png

Настройка командного меню через код:

python
from aiogram.types import BotCommand, BotCommandScopeDefault

async def set_commands():
    commands = [BotCommand(command='start', description='Старт'),
                BotCommand(command='start_2', description='Старт 2'),
                BotCommand(command='start_3', description='Старт 3')]
    await bot.set_my_commands(commands, BotCommandScopeDefault())
  • BotCommand: объект, используемый для создания команд бота. Каждая команда имеет два атрибута: command (имя команды) и description (описание команды).
  • BotCommandScopeDefault: объект, определяющий область действия команд. В данном случае используется область по умолчанию, что означает, что команды будут действовать для всех пользователей.

Объявляем асинхронную функцию set_commands, которая будет использоваться для установки команд бота. Асинхронная функция используется, потому что взаимодействие с API Telegram требует выполнения асинхронных запросов.

Создаем список commands, содержащий три команды:

  • BotCommand(command='start', description='Старт'): команда /start с описанием "Старт".
  • BotCommand(command='start_2', description='Старт 2'): команда /start_2 с описанием "Старт 2".
  • BotCommand(command='start_3', description='Старт 3'): команда /start_3 с описанием "Старт 3".

Установка команд бота

python
await bot.set_my_commands(commands, BotCommandScopeDefault())

Вызываем метод set_my_commands объекта bot для установки команд бота. Передаем в метод два аргумента:

  • commands: список команд, который мы создали ранее.
  • BotCommandScopeDefault(): область действия команд по умолчанию, которая устанавливает команды для всех пользователей.

Вызовем функцию в конце главной функции (то есть наш бот сначала будет запускаться, а после отправлять командное меню):

python
async def main():
    dp.include_router(start_router)
    await bot.delete_webhook(drop_pending_updates=True)
    await set_commands()
    await dp.start_polling(bot)

Проверяем:

img_7.png

Использование Command Object для обработки аргументов команды

Ссылка вида https://t.me/your_bot?start=12345 имеют особое значение для Telegram ботов. Бот может захватывать и обрабатывать информацию, следующую за start=. Это особенно полезно для реализации реферальных программ или отслеживания источника, откуда пришел пользователь.

Рассмотрим пример использования этой возможности на практическом примере. Писал бота клиники, который периодически рекламируется в различных Telegram-каналах и группах. Вместо простой ссылки на бота, такой как https://t.me/your_bot, менеджеры используют ссылки с метками, например, https://t.me/your_bot?start=habr, где habr - это метка источника.

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

То же самое можно сделать для реферальной программы. Например, реферальная ссылка может содержать Telegram ID пользователя. Бот проверяет, является ли пользователь новым, и если это так, то пользователю, который поделился своей реферальной ссылкой, начисляются бонусы.

Для начала нам нужно выполнить новый импорт (CommandObject):

python
from aiogram.filters import CommandStart, Command, CommandObject

Изменение функции cmd_start:

python
@start_router.message(CommandStart())
async def cmd_start(message: Message, command: CommandObject):
command_args: str = command.args
    if command_args:
        await message.answer(
            f'Запуск сообщения по команде /start используя фильтр CommandStart() с меткой <b>{command_args}</b>',
            reply_markup=main_kb(message.from_user.id))
    else:
        await message.answer(
            f'Запуск сообщения по команде /start используя фильтр CommandStart() без метки',
            reply_markup=main_kb(message.from_user.id))

Тут нас может заинтересовать только извлечение аргументов из команды:

python
command_args: str = cmd.args

Далее уже работаем с переменной command_args, как с обычным значением. Если метки не будет, то command_args будет равно None (этот случай я так же обработал в своем коде).

Тестируем:

Тут я сделал клик по ссылке и после нажал на "Запустить". Видим что мы захватили метку.

img_8.png

Тот же результат мы получим если передадим свою метку в конструкцию такого вида:

/start метка

img_9.png

Мы видим, что бот успешно обработал метку. Ничто не мешает добавить такой же обработчик к любой другой команде. Это будет работать аналогично команде /start, за исключением того, что другие команды нельзя использовать в стартовой ссылке.

Contacts: teffal@mail.ru