Цикл while зибирает весь поток

Я пишу telegram userbot на pyrogram. У меня есть основная задача, которая обрабатывает все личные сообщения, а также есть вторая фоновая, которая раз в час пишет сообщения в определённый чат. В фоновой задаче я использовал цикл while, но из-за этого хендлер обработки сообщений не работает. Помогите пожалуйста

import asyncio
from pyrogram import Client, filters, idle

api_id = 123
api_hash = ""
CHATS = []

app = Client(
    "my_bot_session", 
    api_id=api_id, 
    api_hash=api_hash
)

@app.on_message(filters.private)
async def autor_reply(client, message):
    await message.reply("скоро отвечу")

async def send_periodic():
    while True:
        for chat_id in CHATS:
            await app.send_message(chat_id, "Привет, это автоматическое сообщение")
        await asyncio.sleep(3600)

async def main():
    await app.start()
    print("Бот запущен!")
    asyncio.create_task(send_periodic())
    await idle()
    await app.stop()

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

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

Автор решения: SVBazuev

Декоратор Вам поможет:

def every(delay):
    """Декорирующая функция для интервальных вызовов."""
    def decorator(func):
        async def wrapper():
            while True:
                await asyncio.sleep(delay)
                await func()
        return wrapper
    return decorator

немного подправить тело функции send_periodic

@every(3600)  # Вызов каждые 3600 секунд
async def send_periodic():
    for chat_id in CHATS:
        try:
            await app.send_message(chat_id, "Привет, это автоматическое сообщение")
        except Exception as e:
            print(f"Ошибка при отправке сообщения в чат {chat_id}: {e}")

и в функции main вызывать уже просто await send_periodic()


Либо, Вам надо паралельно запускать две задачи.
Пример можно посмотреть здесь.

Успехов!

→ Ссылка
Автор решения: Егор

Изменил финальный запуск юзербота. Насколько я понял, в конце я так и не запустил app, соответсвенно и хендлеры не запускались.

Запуск который помог мне:

if __name__ == "__main__":
    app.run(main())
→ Ссылка
Автор решения: Тим Муранов

А зачем вообще while? Можно в основном потоке создать переменную hours и добавить if, проверяющий, совпадает ли переменная с текущим временем. Если не совпадает - присвоить ей текущее время. Эта конструкция будет раз в час срабатывать

→ Ссылка