diff --git a/telethon/events/chataction.py b/telethon/events/chataction.py index b9db44cd..3844eb4c 100644 --- a/telethon/events/chataction.py +++ b/telethon/events/chataction.py @@ -344,20 +344,10 @@ class ChatAction(EventBuilder): return [] if self._users is None or len(self._users) != len(self._user_peers): - have, missing = [], [] - for peer in self._user_peers: - user = self._entities.get(utils.get_peer_id(peer)) - if user: - have.append(user) - else: - missing.append(peer) - - try: - missing = await self._client.get_entity(missing) - except (TypeError, ValueError): - missing = [] - - self._users = have + missing + await self.action_message._reload_message() + self._users = [ + u for u in self.action_message.action_entities + if isinstance(u, (types.User, types.UserEmpty))] return self._users @@ -381,8 +371,15 @@ class ChatAction(EventBuilder): """ Returns `input_users` but will make an API call if necessary. """ - # TODO Maybe we could re-fetch the message - return self.input_users + self._input_users = None + if self._input_users is None: + await self.action_message._reload_message() + self._input_users = [ + utils.get_input_peer(u) + for u in self.action_message.action_entities + if isinstance(u, (types.User, types.UserEmpty))] + + return self._input_users or [] @property def user_ids(self): diff --git a/telethon/tl/custom/message.py b/telethon/tl/custom/message.py index 687e8b46..9d4ee1ff 100644 --- a/telethon/tl/custom/message.py +++ b/telethon/tl/custom/message.py @@ -177,6 +177,7 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC): self._sender_id = from_id self._sender = None self._input_sender = None + self._action_entities = None if not out and isinstance(to_id, types.PeerUser): self._chat_peer = types.PeerUser(from_id) @@ -220,6 +221,23 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC): if self.fwd_from: self._forward = Forward(self._client, self.fwd_from, entities) + if self.action: + if isinstance(self.action, (types.MessageActionChatAddUser, + types.MessageActionChatCreate)): + self._action_entities = [entities.get(i) + for i in self.action.users] + elif isinstance(self.action, types.MessageActionChatDeleteUser): + self._action_entities = [entities.get(self.action.user_id)] + elif isinstance(self.action, types.MessageActionChatJoinedByLink): + self._action_entities = [entities.get(self.action.inviter_id)] + elif isinstance(self.action, types.MessageActionChatMigrateTo): + self._action_entities = [entities.get(utils.get_peer_id( + types.PeerChannel(self.action.channel_id)))] + elif isinstance( + self.action, types.MessageActionChannelMigrateFrom): + self._action_entities = [entities.get(utils.get_peer_id( + types.PeerChat(self.action.chat_id)))] + # endregion Initialization # region Public Properties @@ -432,6 +450,22 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC): """ return self._document_by_attribute(types.DocumentAttributeSticker) + @property + def action_entities(self): + """ + Returns a list of entities that can took part in this action. + + Possible cases for this are :tl:`MessageActionChatAddUser`, + :tl:`types.MessageActionChatCreate`, :tl:`MessageActionChatDeleteUser`, + :tl:`MessageActionChatJoinedByLink` :tl:`MessageActionChatMigrateTo` + and :tl:`MessageActionChannelMigrateFrom). + + If the action is neither of those, the result will be ``None``. + If some entities could not be retrieved, the list may contain + some ``None`` items in it. + """ + return self._action_entities + # endregion Public Properties # region Public Methods @@ -670,6 +704,7 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC): self._input_sender = msg._input_sender self._chat = msg._chat self._input_chat = msg._input_chat + self._action_entities = msg._action_entities async def _refetch_sender(self): await self._reload_message()