события телемарафона не будут получать события определенного пользователя

#python-3.x #events #telegram #telethon

#python-3.x #Мероприятия #telegram #телемарафон

Вопрос:

Итак, я работаю над этим сценарием уже несколько дней, и сценарий, похоже, работает правильно, не получая никаких ошибок, но проблема в том, что моя точка скрипта получает изменения статуса конкретного пользователя, и вместо этого скрипт печатает меня каждый раз, когда КТО-ЛИБО из моих участников меняет свой статус, включая меня. Пожалуйста, кто-нибудь думает, что он может мне помочь? Я застрял на этом слишком долго, и я действительно отчаиваюсь заставить этот скрипт работать..

Кстати, я добавлял print(client.user_id) просто чтобы посмотреть, работает ли это, и я получил идентификатор пользователя любого из моих контактов, который совершил какое-то действие.

 from telethon.tl.types import UserStatusOffline
from telethon.sync import TelegramClient
from telethon import events
from datetime import datetime
import time

### Client Side ###

target = ""
phone = " "
api_id = 
api_hash = ""
client = TelegramClient(phone, api_id, api_hash)
client.start()
if client.is_user_authorized():
    print(f"Session started at : {datetime.now()}")
    time.sleep(2)
    print("Logging in to Telegram complete.")
    time.sleep(2)
else:
    client.send_code_request(phone)
    client.sign_in(phone, input('Enter the code: '))
print(f"Started listening to {target}'s status...")
time.sleep(2)
target_id = client.get_peer_id(target)
print(f"{target}'s User ID is : {target_id}")
time.sleep(2)

############################################
# First status check to see rather         #
# the user is correctly online or not      #
# once it prints hes correct statement     #
# global value will be changed so it wont  #
# be printed again and again.              #
############################################

first_msg = False
async def first_con():
    if first_msg == False:
        account = await client.get_entity(target)
        if isinstance(account.status, UserStatusOffline):
            print(f"{target} is correctly Offline.")
            first_msg = True
        else:
            print(f"{target} is correctly Online.")
            first_msg = True
    else:
        print("Something went wrong checking correct status.")
        
            
##################EVENTS####################
# Only events thats occurred after script  #
# first run will pop up with prints !      #
# Every event that doesn't come from the   #
# target gets as "event from username"     #
############################################

@client.on(events.UserUpdate())
async def handler(event):
    await first_con()
    time.sleep(2)
    if event.user_id == target_id:
        if event.online:
            print(f"{target} went Online at : {datetime.now()}")
        elif event.recently:
            print(f"{target} was recently online at : {datetime.now()}")
        elif event.typing:
            print(f"{target} typed a message at : {datetime.now()}")
        else:
            print("Sorry there was an error.")
    else:
        #print("Event from non-intersting user.") debugging propuses only
client.run_until_disconnected()
  

Ответ №1:

Давайте увеличим масштаб кода:

 @client.on(events.UserUpdate())
async def handler(event):
    x = await client.get_entity(target)
    target_id = x.id
    event.input_user = target_id
    if event.input_user == target_id:
  

Давайте разорвем его на части:

     event.input_user = target_id
    if event.input_user == target_id:
  

Давайте дадим ему разные имена. event.input_user будет foo и target_id будет bar :

     foo = bar
    if foo == bar:
  

Вы только что присвоили значение первой переменной, а затем сравниваете первую переменную с тем же значением. Конечно, это всегда True , для любых foo bar значений и .

Изменение, как event правило, плохая идея, и я не уверен, каковы были ваши намерения, но мне кажется, что вы должны кэшировать целочисленный идентификатор, а затем сравнивать его вместо того, чтобы вызывать get_entity каждый раз (потому input_user что это a InputPeerUser и не будет сравниваться с User , вот почему, я думаю, вы пробовалистранное назначение):

 target_id = client.get_peer_id(target)


@client.on(events.UserUpdate)
async def handler(event):
    if event.user_id == target_id:
        ...
  

Таким образом, выполняется не более одного вызова, и вы сравниваете целые числа, что происходит быстро. Обязательно ознакомьтесь с документацией UserUpdate для получения дополнительной информации.

Комментарии:

1. Итак, я делал это, и вы правы, код намного чище, чем раньше, и он заменяет функцию blabla. Но все же по некоторым причинам он ничего не печатает. Я имею в виду, например, если я запускаю скрипт и все работает правильно, я должен получить первую печать с момента проверки статуса пользователя при первом запуске, и у пользователя должно быть одно из этих 3 условий if.. так что, в принципе, если все работает хорошо, я должен получить, как если бы цель перешла в автономный режим / зависела от оператора hes, который я не получаю

2. Вы также должны включить logging и, прежде всего, убедиться, что событие вообще вызывается (без каких-либо странностей if ). Telegram может не отправлять обновления в первую очередь. Хотя я не знаю правил, вам, вероятно, нужно проявить «интерес» к пользователю, чтобы получать обновления о них.

3. Извините, я все еще на нем, и я все равно не смог найти, чтобы заставить его работать должным образом… Всегда есть что-то еще, что не работает.