Настройка что Бот печатет AIOGRAM 3 @flags.chat_action("typing") ChatActionMiddleware

Продолжаю изучение aiogram 3 (делаем TG бота), интересное нашел тут https://habr.com/ru/articles/733732/ Очень хочу научиться делать что бот печатает, когда пользователь чтото нажал и пока готовится ответ ... в целом по посту выше получилось и это работает для обработок пунктов меню (start, help и прочее), если там чтото делается долго (можно sleep поставить), то появляется что бот печатает ... очень круто. Но никак не могу сделать так, чтобы это же работало с при нажатии на inline кнопки. В итоге при нажатии на пункт меню (например отчеты) работает отображение что бот печатает ...:

обработка нажатия кнопки меню - report
@router.message(Command("report"))
@flags.chat_action("typing")
async def report_handler(msg: Message):
    asyncio.sleep(3)
    mainLogger.info('User press command <report>')
        await msg.answer('Строим отчеты ...')
        ...

А вот при добавлении такого же флага для хэндлера нажатия кнопки, статут печатает не работает никак:

@router.callback_query(F.data == "btnOrdersToday")
@flags.chat_action("typing")
async def btnOrdersToday_handler(clbck: CallbackQuery, state: FSMContext):
    asyncio.sleep(3)
    mainLogger.info('User press <btnOrdersToday> ')
    ...

В чем может быть проблема?


Ответы (3 шт):

Автор решения: Alex Mar

Вероятно, вы не подключили ChatActionMiddleware, подключение описано перед использованием @flags.chat_action в этом абзаце описание подключения ChatActionMiddleware

UPD:

  1. asyncio.sleep(3) асинхронный - следует указать как await
  2. В место строк экшенов, например "typing", лучше будет использовать константы из ChatAction, например @flags.chat_action(ChatAction.TYPING)
→ Ссылка
Автор решения: Руслан Исмагилов

Изучил документацию, и выяснил, что ChatActionMiddleware работает только с объектами message, и не работает с callback_query. В итоге решил по другому, через конструкцию:

async with ChatActionSender.typing(bot=bot, chat_id=message.chat.id):
    # Do something...
    # Perform some long calculations
    await message.answer(result)
→ Ссылка
Автор решения: andrey

Возможно кому-то пригодится. В Aiogram есть уже реализованная мидлваря для этого, которую достаточно просто зарегистрировать в боте:

from aiogram.utils.chat_action import ChatActionMiddleware

def register_middlewares(dp: Dispatcher) -> None:
    dp.message.outer_middleware(ChatActionMiddleware())

и хендлер пометить флогом:

@router.message(CommandStart())
@flags.chat_action("typing")
async def start_handler(message: Message) -> None:
    await message.answer(
        text="⏳ Думаю...",
    )

    await some_long_operation()

    await message.answer(
        f"Мой ответ:",
        reply_markup=IntakeCalculatorKeyboard.calculate_daily_intake_keyboard()
    )
→ Ссылка