From d81eb0b2e8121f68bf91ae66477b2d7c52b607fc Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Sat, 14 Jan 2023 12:31:01 +0100 Subject: [PATCH] Apply pts returned by some additional requests When a bot account sends a message, deletes it, and sends a new one, very reliably it would detect a gap, and as a result recover the second message it sent, processing it itself (because the hack with `_self_outgoing` cannot possibly work when catching up). Now certain `rpc_result` are also processed as-if they were updates (including the ones from deleting messages), which solves this gap issue. Not entirely sure if it's a hack or the intended way to do it (since Telegram *does* return proper `updates` for other RPCs), but it seems to solve this particular problem. Other requests such as reading history, mentions or reactions also return an instance of this type, but the `pts_count` should be 0, and at worst it should simply trigger a gap, which shouldn't be a big deal. --- telethon/network/mtprotosender.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/telethon/network/mtprotosender.py b/telethon/network/mtprotosender.py index 1c666185..90ae665d 100644 --- a/telethon/network/mtprotosender.py +++ b/telethon/network/mtprotosender.py @@ -674,11 +674,28 @@ class MTProtoSender: _tl.UpdatesCombined.CONSTRUCTOR_ID, _tl.Updates.CONSTRUCTOR_ID, _tl.UpdateShortSentMessage.CONSTRUCTOR_ID, + )), _update_like_ids=frozenset(( + _tl.messages.AffectedHistory.CONSTRUCTOR_ID, + _tl.messages.AffectedMessages.CONSTRUCTOR_ID, + _tl.messages.AffectedFoundMessages.CONSTRUCTOR_ID, ))): try: if obj.CONSTRUCTOR_ID in _update_ids: obj._self_outgoing = True # flag to only process, but not dispatch these self._updates_queue.put_nowait(obj) + elif obj.CONSTRUCTOR_ID in _update_like_ids: + # Ugly "hack" (?) - otherwise bots reliably detect gaps when deleting messages. + # + # Note: the `date` being `None` is used to check for `updatesTooLong`, so `0` is + # used instead. It is still not read, because `updateShort` has no `seq`. + # + # Some requests, such as `readHistory`, also return these types. But the `pts_count` + # seems to be zero, so while this will produce some bogus `updateDeleteMessages`, + # it's still one of the "cleaner" approaches to handling the new `pts`. + # `updateDeleteMessages` is probably the "least-invasive" update that can be used. + upd = _tl.UpdateShort(_tl.UpdateDeleteMessages([], obj.pts, obj.pts_count), 0) + upd._self_outgoing = True + self._updates_queue.put_nowait(upd) except AttributeError: pass