1

I am trying to get my telegram bot to send messages at a certain time but it doesn't work. The bot launches fine, everything works as intended except for the scheduled messages. I suspect the line await asyncio.create_task(scheduler()) never runs but I don't know why or how to fix it/get it to work. Any help is appreciated.

import asyncio
import logging
import aioschedule as schedule

from aiogram import Bot, Dispatcher
from aiogram.types import BotCommand
from aiogram.contrib.fsm_storage.memory import MemoryStorage

from app.config_reader import load_config
from app.handlers.feedback import register_handlers_feedback
from app.handlers.food import register_handlers_food
from app.handlers.common import register_handlers_common
from app.handlers.database import register_handlers_db
from app.handlers.mailing import mail_one, mail_two, mail_three

logger = logging.getLogger(__name__)


async def set_commands(bot: Bot):
    commands = [
        BotCommand(command="/feedback", description="Take a poll"),
        BotCommand(command="/db", description="Add your info to our database"),
        BotCommand(command="/cancel", description="Cancel")
    ]
    await bot.set_my_commands(commands)


async def main():
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
    )
    logger.error("Starting bot")

    # Parsing the config file
    config = load_config("config/bot.ini")

    # Instantiating Bot and Dispatcher objects
    bot = Bot(token=config.tg_bot.token)
    dp = Dispatcher(bot, storage=MemoryStorage())

    async def scheduler():
        # this line is here temporarily for debugging/checking if it works
        schedule.every(5).seconds.do(lambda: mail_one(bot))
        schedule.every().day.at('10:00').do(lambda: mail_one(bot))
        schedule.every().day.at('10:00').do(lambda: mail_two(bot))
        schedule.every().day.at('10:00').do(lambda: mail_three(bot))
        while True:
            await schedule.run_pending()
            await asyncio.sleep(1)

    await set_commands(bot)

    # Registering handlers
    register_handlers_common(dp, config.tg_bot.admin_id)
    register_handlers_feedback(dp)
    register_handlers_db(dp)

    # optional: await dp.skip_updates()
    await dp.start_polling()
    await asyncio.create_task(scheduler())


if __name__ == '__main__':
    asyncio.run(main())```
Naerwen
  • 23
  • 4
  • `await create_task(x)` can be replaced with `await x` - the whole point of creating a task is that you _don't_ immediately await it. Try moving the line that creates the scheduler above `await dp.start_polling()` and drop the `await` before it, so you're left with `asyncio.create_task(scheduler()); await dp.start_polling()` – user4815162342 Jun 25 '21 at 05:38

1 Answers1

0

If the line await asyncio.create_task(scheduler()) never runs, it is because the line before it, await dp.start_pooling(), is blocking it. If you look inside aiogram.Dispacher's start_pooling(), there is a while loop. If execution order doesn't matter, you can try putting await dp.start_polling() inside asyncio.create_task().

Kirk KD
  • 97
  • 9
  • I tried it, and nothing changes, the messages don't get sent while everything else works fine. – Naerwen Jun 23 '21 at 14:05
  • Can you try switching those two lines, `await dp.start_polling()` and `await asyncio.create_task(scheduler())`, if it doesn't break anything? I'm not that familiar with aiogram. – Kirk KD Jun 23 '21 at 14:15
  • If I do that, then everything but the scheduled messages part stops working, as in the bot launches and sends the messages but none of the commands work – Naerwen Jun 23 '21 at 14:27