Как выполнить цикл в асинхронном режиме, чтобы проверить сообщение, если оно изменилось, не блокируя скрипт?

#python #telegram #message #telethon

Вопрос:

Я сделал скрипт, который сохраняет сообщения с каналов или ботов в telegram.

Но сейчас я столкнулся с проблемой: некоторые сообщения меняются через несколько минут по сравнению с моментом события, когда я их сохраняю.

Таким образом, вопрос в том, как будет выглядеть правильный цикл после «если событие.сообщение.идентификатор отправителя в bots_channels:», чтобы подождать с сохранением в файл в течение некоторого времени. Проверять сообщение каждые 10 секунд, если оно изменено, и тайм-аут примерно через 15 минут. Но чтобы не блокировать весь скрипт и функцию для других сообщений, которые могут исходить от того же бота.

Например, всего может быть 20-30 сообщений в день, но часто несколько за 5 минут. Я хочу, чтобы все они обрабатывались одинаково. Я очень новичок в Python асинхронных функций, я пришел из autoit, там нет никакой асинхронности, я прочитал какую-то большую статью, но пока не могу понять (или поверить). Итак, как выглядел бы правильный цикл, и возможно ли это на самом деле?

 # the script uses telethon and python for geting messages from bot. from datetime import datetime import time import requests import configparser import json import re from telethon.errors import SessionPasswordNeededError from telethon import TelegramClient, events, sync from telethon.tl.functions.messages import (GetHistoryRequest) from telethon.tl.types import ( PeerChannel )  api_id = Yourapiid api_hash = 'yourhash' client = TelegramClient('name',api_id,api_hash)   bot_1 = "some_bot" # an exact bot channel name bots_channels = [123456789101] # an user(s) id number(s) in telegram   def printRAW1(*Text):  RAWOut = open('file.txt', 'a', encoding='utf8', closefd=True)  print(*Text, file=RAWOut)  RAWOut.flush()  RAWOut.close()   @client.on(events.NewMessage(outgoing=False)) # every incoming message   async def my_event_handler(event):   if event.message.sender_id in bots_channels:  current_message_id = event.message.id # its for example: 79304  #loop here  sleep(10) # sleeps 10s  message_check = client.get_messages(bot_1, ids=current_message_id) # gets message content of id=79304 (its current event.message)  event_message_string = str(message_check)  check_for_some_text = event_message_string.find("sometext") # finds some text  # lets say after 5 minutes the orginal message, has changed  if check_for_some_text != -1:  # now we can stop loop, and save it to file  time = datetime.now().strftime("%d-%m-%Y %H:%M:%S")  printRAW1("====================================== "   time)  printRAW1(message_check)  break  elif check_for_some_text == -1 and timediference15minutes: # dont know how to do timeout for 15min yet  time = datetime.now().strftime("%d-%m-%Y %H:%M:%S")  printRAW1("=== after 15minuets no change: ==== "   time)  printRAW1(message_check)  #EndLoop   # now, when event occures, the message content is not complete.   # After some secounds, or minutes the bot channel changes the message (not every messages, many stays the same)  # i need to act upon that changes,  # how to make a loop, that gives a message a chance to change, and catches that change?  # and also to not block the execution of script?  # because the script is listening for messages,   # if the function waits for example: 3 minutes and check every 10 sec, if a message changed, untill given timeout example 5 minutes  # i want that function to be avaiable for other messages from the same bot_1,  # there can be tottal 20-30 messages a day, but like 10 messages in 5 minutes  # up on each message script does something.  # the need is, to process every message for checkking for additional changes, before final verdict what to do.    #never meet async functions before, i just read its prooobably capable of concurent function execution.   # its days of reading documentation for me to understand this, or weeks,  #so i would like to kindly ask for example, how the loop could looks like for this situation?   with client:  client.run_until_disconnected()  

Редактировать:

Вау, я только что попробовал эту простую петлю, и, похоже, она просто работает, это потрясающе:

Im testing. But with 9 messages in «memory», during 10 minutes time, i see the more the messages it tracks, the slower the response for message being edited for key word. The loop i set for 5s sleep, and the script noticed the difference after 30 secounds from editing. Or mayby its time for functions get_message hmm or too less threads? surprised i didnt got any flooderror. How i can improove that loop any help greatly appreciated!

 from time import time  from time import sleep  start_time = time()  d = 600  while True:  message_check = await client.get_messages(bot_1, ids=current_message_id) # gets message content of id=79304 (its current event.message)  event_message_string = str(message_check)  check_for_some_text = event_message_string.find("sometext") # finds some text  end_time = time()  secounds_elapsed = end_time - start_time  if check_for_some_text != -1:  # now we can stop loop, and save it to file  time = datetime.now().strftime("%d-%m-%Y %H:%M:%S")  printRAW2("====================================== "   time)  printRAW2(message_check)  break  elif check_for_some_text == -1 and secounds_elapsed gt;= d: #   time = datetime.now().strftime("%d-%m-%Y %H:%M:%S")  printRAW2("=== after 10minuets no change: ==== "   time)  printRAW2(message_check)  break  sleep(5) # sleeps 5s