Цикл 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 шт):
Декоратор Вам поможет:
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, проверяющий, совпадает ли переменная с текущим временем. Если не совпадает - присвоить ей текущее время. Эта конструкция будет раз в час срабатывать