pythonpython-3.xtelegramaiogramtelebot

How to register multiple message handlers in aiogram


I'm trying to make multiple different message handlers, is this an acceptable way to register multiple ones?:

import asyncio

from aiogram import Bot, Dispatcher, types
from settings import BOT_TOKEN


async def start_handler(event: types.Message):
    await event.answer(
        f"Hello, {event.from_user.get_mention(as_html=True)} 👋!",
        parse_mode=types.ParseMode.HTML,
    )

async def echo_answer(event: types.Message):
    await event.answer(event.text, parse_mode=types.ParseMode.HTML
    )


async def main():
    bot = Bot(token=BOT_TOKEN)
    try:
        disp = Dispatcher(bot=bot)
        disp.register_message_handler(start_handler, commands={"start", "restart"})
        disp.register_message_handler(echo_answer, lambda msg: msg.text)
        await disp.start_polling()
    finally:
        await bot.close()

asyncio.run(main())

my settings.py file contains

import os

BOT_TOKEN = os.getenv('BOT_TOKEN')
if not BOT_TOKEN:
    print('You have forgot to set BOT_TOKEN')
    BOT_TOKEN = 'missing'
    quit()

This code runs, and sends echo responses to any message and replies with Hello, @username 👋! for start and restart commands. to reproduce one must have a bot and have a BOT_TOKEN in the environmental variables before running the code.

I tried this code, described above, looked ad https://docs.aiogram.dev/en/latest/dispatcher/index.html documentation and modified example on the source code page https://github.com/aiogram/aiogram#poll-botapi-for-updates-and-process-updates


Solution

  • I faced the same problem, so I made little dive into source code of aiogram.

    Handlers in Dispatcher instance held in multiple properties.

    Every handler is instance of Handler class, so they have once property, that shows, can mulltiple handlers be called on one message

    So in your case, you should set message_handlers.once to False

    async def main():
        bot = Bot(token=BOT_TOKEN)
        try:
            disp = Dispatcher(bot=bot)
            disp.message_handlers.once = False 
            disp.register_message_handler(start_handler, commands={"start", "restart"})
            disp.register_message_handler(echo_answer, lambda msg: msg.text)
            await disp.start_polling()
        finally:
            await bot.close()