From 0093ab0404148dcea031c117aa4f082a27540149 Mon Sep 17 00:00:00 2001 From: Aliwoto Date: Wed, 1 Nov 2023 23:44:40 +0330 Subject: [PATCH] Add support for cross-chat replies. Signed-off-by: Aliwoto --- pyrogram/types/messages_and_media/message.py | 32 +++++++++++--- pyrogram/utils.py | 45 +++++++++++++++++--- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index 7e7bf2c3da6..64f73929549 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -852,17 +852,37 @@ async def _parse( if isinstance(message.reply_to, raw.types.MessageReplyStoryHeader): parsed_message.reply_to_message_id = message.reply_to.story_id + setattr(parsed_message, "is_cross_chat", False) if replies: try: - key = (parsed_message.chat.id, parsed_message.reply_to_message_id) + is_cross_chat = \ + message.reply_to and \ + hasattr(message.reply_to, "reply_to_peer_id") and \ + message.reply_to.reply_to_peer_id and \ + hasattr(message.reply_to.reply_to_peer_id, "channel_id") and \ + message.reply_to.reply_to_peer_id.channel_id + if is_cross_chat: + key = (f"-100{message.reply_to.reply_to_peer_id.channel_id}", + message.reply_to.reply_to_msg_id) + setattr(parsed_message, "is_cross_chat", True) + else: + key = (parsed_message.chat.id, parsed_message.reply_to_message_id) + reply_to_message = client.message_cache[key] if not reply_to_message: - reply_to_message = await client.get_messages( - parsed_message.chat.id, - reply_to_message_ids=message.id, - replies=replies - 1 - ) + if is_cross_chat: + reply_to_message = await client.get_messages( + chat_id=key[0], + message_ids=key[1], + replies=replies - 1 + ) + else: + reply_to_message = await client.get_messages( + chat_id=key[0], + reply_to_message_ids=key[1], + replies=replies - 1 + ) parsed_message.reply_to_message = reply_to_message except MessageIdsEmpty: diff --git a/pyrogram/utils.py b/pyrogram/utils.py index 9806dd5b57e..52e0464458c 100644 --- a/pyrogram/utils.py +++ b/pyrogram/utils.py @@ -112,7 +112,7 @@ async def parse_messages( if replies: messages_with_replies = { - i.id: i.reply_to.reply_to_msg_id + i.id: i.reply_to for i in messages.messages if not isinstance(i, raw.types.MessageEmpty) and i.reply_to } @@ -127,15 +127,46 @@ async def parse_messages( else: chat_id = 0 - reply_messages = await client.get_messages( - chat_id, - reply_to_message_ids=messages_with_replies.keys(), - replies=replies - 1 - ) + # whether all messages are inside of our current chat + is_all_within_chat = True + for current_message_id in messages_with_replies: + if messages_with_replies[current_message_id].reply_to_peer_id: + is_all_within_chat = False + break + + reply_messages: List[pyrogram.types.Message] = [] + if is_all_within_chat: + # fast path: fetch all messages within the same chat + reply_messages = await client.get_messages( + chat_id, + reply_to_message_ids=messages_with_replies.keys(), + replies=replies - 1 + ) + else: + # slow path: fetch all messages individually + for current_message_id in messages_with_replies: + target_reply_to = messages_with_replies[current_message_id] + to_be_added_msg = None + the_chat_id = chat_id + if target_reply_to.reply_to_peer_id: + the_chat_id = f"-100{target_reply_to.reply_to_peer_id.channel_id}" + to_be_added_msg = await client.get_messages( + chat_id=the_chat_id, + message_ids=target_reply_to.reply_to_msg_id, + replies=replies - 1 + ) + if isinstance(to_be_added_msg, list): + for current_to_be_added in to_be_added_msg: + reply_messages.append(current_to_be_added) + elif to_be_added_msg: + reply_messages.append(to_be_added_msg) for message in parsed_messages: - reply_id = messages_with_replies.get(message.id, None) + reply_to = messages_with_replies.get(message.id, None) + if not reply_to: + continue + reply_id = reply_to.reply_to_msg_id for reply in reply_messages: if reply.id == reply_id: message.reply_to_message = reply