From 45d82f2a85835590f4a15497bf2a33ff58402b2c Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Wed, 7 Aug 2019 00:46:19 +0200 Subject: [PATCH] Fix issues with to/from ID in private chats with multiple clients This should address #1218. --- telethon/client/updates.py | 10 +++++++++- telethon/events/callbackquery.py | 2 +- telethon/events/chataction.py | 2 +- telethon/events/common.py | 10 +++++----- telethon/events/inlinequery.py | 2 +- telethon/events/messagedeleted.py | 2 +- telethon/events/messageedited.py | 2 +- telethon/events/messageread.py | 2 +- telethon/events/newmessage.py | 9 ++++----- telethon/events/raw.py | 2 +- telethon/events/userupdate.py | 2 +- 11 files changed, 26 insertions(+), 19 deletions(-) diff --git a/telethon/client/updates.py b/telethon/client/updates.py index 47e18175..1d8d0637 100644 --- a/telethon/client/updates.py +++ b/telethon/client/updates.py @@ -383,6 +383,12 @@ class UpdateMethods: except OSError: pass # We were disconnected, that's okay + if not self._self_input_peer: + # Some updates require our own ID, so we must make sure + # that the event builder has offline access to it. Calling + # `get_me()` will cache it under `self._self_input_peer`. + await self.get_me(input_peer=True) + built = EventBuilderDict(self, update, others) for conv_set in self._conversations.values(): for conv in conv_set: @@ -539,7 +545,9 @@ class EventBuilderDict: try: return self.__dict__[builder] except KeyError: - event = self.__dict__[builder] = builder.build(self.update, self.others) + event = self.__dict__[builder] = builder.build( + self.update, self.others, self.client._self_input_peer.user_id) + if isinstance(event, EventCommon): event.original_update = self.update event._entities = self.update._entities diff --git a/telethon/events/callbackquery.py b/telethon/events/callbackquery.py index 03da1596..cb879682 100644 --- a/telethon/events/callbackquery.py +++ b/telethon/events/callbackquery.py @@ -64,7 +64,7 @@ class CallbackQuery(EventBuilder): )) @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, types.UpdateBotCallbackQuery): return cls.Event(update, update.peer, update.msg_id) elif isinstance(update, types.UpdateInlineBotCallbackQuery): diff --git a/telethon/events/chataction.py b/telethon/events/chataction.py index 320c0350..781539f7 100644 --- a/telethon/events/chataction.py +++ b/telethon/events/chataction.py @@ -9,7 +9,7 @@ class ChatAction(EventBuilder): Occurs whenever a user joins or leaves a chat, or a message is pinned. """ @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, types.UpdateChannelPinnedMessage) and update.id == 0: # Telegram does not always send # UpdateChannelPinnedMessage for new pins diff --git a/telethon/events/common.py b/telethon/events/common.py index ea91ecd2..42586608 100644 --- a/telethon/events/common.py +++ b/telethon/events/common.py @@ -66,8 +66,6 @@ class EventBuilder(abc.ABC): async def handler(event): pass # code here """ - self_id = None - def __init__(self, chats=None, *, blacklist_chats=False, func=None): self.chats = chats self.blacklist_chats = bool(blacklist_chats) @@ -77,13 +75,17 @@ class EventBuilder(abc.ABC): @classmethod @abc.abstractmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): """ Builds an event for the given update if possible, or returns None. `others` are the rest of updates that came in the same container as the current `update`. + + `self_id` should be the current user's ID, since it is required + for some events which lack this information but still need it. """ + # TODO So many parameters specific to only some update types seems dirty async def resolve(self, client): """Helper method to allow event builders to be resolved before usage""" @@ -100,8 +102,6 @@ class EventBuilder(abc.ABC): async def _resolve(self, client): self.chats = await _into_id_set(client, self.chats) - if not EventBuilder.self_id: - EventBuilder.self_id = await client.get_peer_id('me') def filter(self, event): """ diff --git a/telethon/events/inlinequery.py b/telethon/events/inlinequery.py index 81c007f9..73044700 100644 --- a/telethon/events/inlinequery.py +++ b/telethon/events/inlinequery.py @@ -46,7 +46,7 @@ class InlineQuery(EventBuilder): raise TypeError('Invalid pattern type given') @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, types.UpdateBotInlineQuery): return cls.Event(update) diff --git a/telethon/events/messagedeleted.py b/telethon/events/messagedeleted.py index aa6ba177..bd2a84a4 100644 --- a/telethon/events/messagedeleted.py +++ b/telethon/events/messagedeleted.py @@ -25,7 +25,7 @@ class MessageDeleted(EventBuilder): unless you intend on working with channels and super-groups only. """ @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, types.UpdateDeleteMessages): return cls.Event( deleted_ids=update.messages, diff --git a/telethon/events/messageedited.py b/telethon/events/messageedited.py index 91575f38..a0578f41 100644 --- a/telethon/events/messageedited.py +++ b/telethon/events/messageedited.py @@ -33,7 +33,7 @@ class MessageEdited(NewMessage): not you). """ @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, (types.UpdateEditMessage, types.UpdateEditChannelMessage)): return cls.Event(update.message) diff --git a/telethon/events/messageread.py b/telethon/events/messageread.py index 99182003..5dfec30f 100644 --- a/telethon/events/messageread.py +++ b/telethon/events/messageread.py @@ -20,7 +20,7 @@ class MessageRead(EventBuilder): self.inbox = inbox @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, types.UpdateReadHistoryInbox): return cls.Event(update.peer, update.max_id, False) elif isinstance(update, types.UpdateReadHistoryOutbox): diff --git a/telethon/events/newmessage.py b/telethon/events/newmessage.py index 5ace95ed..3034879c 100644 --- a/telethon/events/newmessage.py +++ b/telethon/events/newmessage.py @@ -76,7 +76,7 @@ class NewMessage(EventBuilder): self.from_users = await _into_id_set(client, self.from_users) @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if not isinstance(update.message, types.Message): @@ -91,10 +91,8 @@ class NewMessage(EventBuilder): id=update.id, # Note that to_id/from_id complement each other in private # messages, depending on whether the message was outgoing. - to_id=types.PeerUser( - update.user_id if update.out else cls.self_id - ), - from_id=cls.self_id if update.out else update.user_id, + to_id=types.PeerUser(update.user_id if update.out else self_id), + from_id=self_id if update.out else update.user_id, message=update.message, date=update.date, fwd_from=update.fwd_from, @@ -127,6 +125,7 @@ class NewMessage(EventBuilder): if isinstance(ori.to_id, types.PeerUser): if ori.from_id == ori.to_id.user_id and not ori.fwd_from: event.message.out = True + print('ooOoOo', ori) return event diff --git a/telethon/events/raw.py b/telethon/events/raw.py index 82b64b96..f0a4cd9d 100644 --- a/telethon/events/raw.py +++ b/telethon/events/raw.py @@ -32,7 +32,7 @@ class Raw(EventBuilder): self.resolved = True @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): return update def filter(self, event): diff --git a/telethon/events/userupdate.py b/telethon/events/userupdate.py index 900e11ad..dee6e470 100644 --- a/telethon/events/userupdate.py +++ b/telethon/events/userupdate.py @@ -38,7 +38,7 @@ class UserUpdate(EventBuilder): Occurs whenever a user goes online, starts typing, etc. """ @classmethod - def build(cls, update, others=None): + def build(cls, update, others=None, self_id=None): if isinstance(update, types.UpdateUserStatus): return cls.Event(update.user_id, status=update.status)