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, CommandObject1
Изменение функции 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.args1
Далее уже работаем с переменной command_args, как с обычным значением. Если метки не будет, то command_args будет равно None (этот случай я так же обработал в своем коде).
Тестируем:
Тут я сделал клик по ссылке и после нажал на "Запустить". Видим что мы захватили метку.

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

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