diff --git a/telethon/client/messages.py b/telethon/client/messages.py index 6ec6ad24..7574142f 100644 --- a/telethon/client/messages.py +++ b/telethon/client/messages.py @@ -19,7 +19,7 @@ class _MessagesIter(RequestIter): """ async def _init( self, entity, offset_id, min_id, max_id, - from_user, offset_date, add_offset, filter, search + from_user, offset_date, add_offset, filter, search, reply_to ): # Note that entity being `None` will perform a global search. if entity: @@ -87,6 +87,18 @@ class _MessagesIter(RequestIter): offset_id=offset_id, limit=1 ) + elif reply_to is not None: + self.request = functions.messages.GetRepliesRequest( + peer=self.entity, + msg_id=reply_to, + offset_id=offset_id, + offset_date=offset_date, + add_offset=add_offset, + limit=1, + max_id=0, + min_id=0, + hash=0 + ) elif search is not None or filter or from_user: # Telegram completely ignores `from_id` in private chats ty = helpers._entity_type(self.entity) @@ -236,7 +248,7 @@ class _MessagesIter(RequestIter): # (only for the first request), it's safe to just clear it off. self.request.max_date = None else: - # getHistory and searchGlobal call it offset_date + # getHistory, searchGlobal and getReplies call it offset_date self.request.offset_date = last_message.date if isinstance(self.request, functions.messages.SearchGlobalRequest): @@ -325,7 +337,8 @@ class MessageMethods: from_user: 'hints.EntityLike' = None, wait_time: float = None, ids: 'typing.Union[int, typing.Sequence[int]]' = None, - reverse: bool = False + reverse: bool = False, + reply_to: int = None ) -> 'typing.Union[_MessagesIter, _IDsIter]': """ Iterator over the messages for the given chat. @@ -433,6 +446,26 @@ class MessageMethods: You cannot use this if both `entity` and `ids` are `None`. + reply_to (`int`, optional): + If set to a message ID, the messages that reply to this ID + will be returned. This feature is also known as comments in + posts of broadcast channels, or viewing threads in groups. + + This feature can only be used in broadcast channels and their + linked megagroups. Using it in a chat or private conversation + will result in ``telethon.errors.PeerIdInvalidError`` to occur. + + When using this parameter, the ``filter`` and ``search`` + parameters have no effect, since Telegram's API doesn't + support searching messages in replies. + + .. note:: + + This feature is used to get replies to a message in the + *discussion* group. If the same broadcast channel sends + a message and replies to it itself, that reply will not + be included in the results. + Yields Instances of `Message `. @@ -459,6 +492,10 @@ class MessageMethods: from telethon.tl.types import InputMessagesFilterPhotos async for message in client.iter_messages(chat, filter=InputMessagesFilterPhotos): print(message.photo) + + # Getting comments from a post in a channel: + async for message in client.iter_messages(channel, reply_to=123): + print(message.chat.title, message.text) """ if ids is not None: if not utils.is_list_like(ids): @@ -486,7 +523,8 @@ class MessageMethods: offset_date=offset_date, add_offset=add_offset, filter=filter, - search=search + search=search, + reply_to=reply_to ) async def get_messages(self: 'TelegramClient', *args, **kwargs) -> 'hints.TotalList':