Fix issues with to/from ID in private chats with multiple clients

This should address #1218.
This commit is contained in:
Lonami Exo 2019-08-07 00:46:19 +02:00
parent b1eed82b7f
commit 45d82f2a85
11 changed files with 26 additions and 19 deletions

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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):
"""

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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):

View File

@ -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)