@Technoid91

Как вызывать сторонние функции бота на aiogram?

Пишу развлекательного бота. Фоном он должен раз в сутки отправлять отчет txt-файлом и каждые 3 часа обновлять свой контент посредством парсинга нескольких сайтов. Проблема в том, что executor.start_polling(dp, skip_updates=True) блокирует выполнение любых других функций, кроме обработки сообщений. Если я вызываю их до executor, то они выполняются один раз, если после - не выполняются вообще. Каждая функция получает объект datetime, сравнивает его с datetime, когда она должна выполняться и если час настал, то выполняет задачу и возвращает время следующего вызова. Как можно поместить всё в один цикл? Чтобы сначала мои функции проверяли не пора ли им выполниться и если нет, то бот проверял входящие сообщения
  • Вопрос задан
  • 176 просмотров
Решения вопроса 1
@Technoid91 Автор вопроса
Нашёл решение. Я отказался от использования executor совсем и сделал следующее:
async def coro_func1():
    # здесь вызов обычной функции для обновления контента

async def coro_func2():
    # тут расписана асинхронная функция

async def сoro_func3():
    # тут ещё одна асинхронная функция

async def poller_coro():
    await dp.start_polling()

async def main():
  asyncio.create_task(poller_coro())
  while True:
    asyncio.create_task(coro_func1())
    asyncio.create_task(coro_func2())
    asyncio.create_task(coro_func3())
    await asyncio.sleep(1)

if __name__ == '__main__':
    asyncio.run(main())

В таком виде всё работает именно так как мне нужно. Бот проверяет и моментально отвечает на входящие сообщения, при этом выполняются другие функции. asyncio.run(main()) вызывает асинхронную функцию main, в которой создается задача poller_coro() (проверка входящих сообщений), а затем в цикле крутятся остальные задачи. При этом await dp.start_polling() из poller_coro() не прекращает выполняться.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Читай документацию.
У start_polling() есть параметр on_startup, который принимает корутину (async-функцию). Эта корутина будет выполнена при старте бота.
Внутри корутины просто через asyncio.create_task() запускаешь другую корутину, которая уже и будет выполнять периодические обновления.
И да, вместо велосипеда с datetime посмотри в сторону пакета aioschedule.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы