Skip to content

Commit

Permalink
Add support for cross-chat replies.
Browse files Browse the repository at this point in the history
Signed-off-by: Aliwoto <[email protected]>
  • Loading branch information
Aliwoto committed Nov 1, 2023
1 parent 16cf07c commit 0093ab0
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 13 deletions.
32 changes: 26 additions & 6 deletions pyrogram/types/messages_and_media/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
45 changes: 38 additions & 7 deletions pyrogram/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
Expand Down

0 comments on commit 0093ab0

Please sign in to comment.