Тема 3 из 6

Команды с аргументами

Команды становятся полезнее, когда принимают аргументы: /remind 15 купить хлеб, /add 2 3.

CommandObject

from aiogram.filters import Command, CommandObject


@router.message(Command("remind"))
async def remind(message: Message, command: CommandObject):
    args = command.args              # "15 купить хлеб" или None

Достаточно добавить в обработчик параметр с типом CommandObject — aiogram сам его заполнит. command.args — всё после команды одной строкой, или None, если после команды ничего нет. Поэтому частый приём — (command.args or "").

Разбор и проверка

minutes, _, text = (command.args or "").partition(" ")
text = text.strip()
if not minutes.isdigit() or not 1 <= int(minutes) <= 1440 or not text:
    await message.answer("Пример: /remind 15 купить хлеб")
    return

Пользователь может прислать что угодно: пусто, слова вместо чисел, лишние пробелы, огромные числа. Если обработчик упадёт с исключением, aiogram запишет ошибку в лог, а пользователь просто не получит ответа — и не поймёт, что сделал не так. Поэтому неверный ввод ловят и отвечают подсказкой с примером.

Для чисел со знаком удобно try: int(x) except ValueError: — isdigit() не понимает минус.

Несколько фильтров

@router.message(Command("stats"), F.from_user.id.in_(ADMINS))
async def stats(message: Message): ...


@router.message(Command("stats"))
async def no_access(message: Message):
    await message.answer("Нет доступа")

Фильтры через запятую должны выполниться все. Более узкий обработчик (для админов) ставят раньше общего. Номер пользователя message.from_user.id постоянный и уникальный, а имя можно поменять в любой момент, и тёзок бывает много — поэтому людей различают по номеру.

Итог

  • command: CommandObject, command.args (или None);
  • разбор partition/split, проверка, ответ-подсказка вместо исключения;
  • несколько фильтров через запятую, узкий обработчик раньше общего;
  • людей различают по from_user.id.