Appearance
Aiogram 3: Командное меню
https://habr.com/ru/articles/820733/
Работа с командным меню
Так выглядит командное меню в BotFather
Похожее меню мы можем создать двумя способами:
- Через
BotFather
- Напрямую через код
Оба способа мы рассмотрим далее.
Настройка командного меню через BotFather
Вводим /mybots
(или выбираем через командное меню)
Выбираем нашего бота
Выбираем Edit bot
Выбираем Edit command
Отправляем боту сообщение такого вида как на скрине
python
start - Главная страница
start_3 - Вызов спец. клавиатуры
1
2
2
После этих действий в боте появится кнопка «Меню» с этими командами. Для того чтоб все работало необходимо в боте привязать к каждой команде нужное действие.
Настройка командного меню через код:
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())
1
2
3
4
5
6
7
2
3
4
5
6
7
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())
1
Вызываем метод 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)
1
2
3
4
5
2
3
4
5
Проверяем:
Использование 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
1
Изменение функции 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))
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Тут нас может заинтересовать только извлечение аргументов из команды:
python
command_args: str = cmd.args
1
Далее уже работаем с переменной command_args
, как с обычным значением. Если метки не будет, то command_args
будет равно None (этот случай я так же обработал в своем коде).
Тестируем:
Тут я сделал клик по ссылке и после нажал на "Запустить". Видим что мы захватили метку.
Тот же результат мы получим если передадим свою метку в конструкцию такого вида:
/start метка
Мы видим, что бот успешно обработал метку. Ничто не мешает добавить такой же обработчик к любой другой команде. Это будет работать аналогично команде /start
, за исключением того, что другие команды нельзя использовать в стартовой ссылке.