Skip to content

Commit a52f857

Browse files
authored
fix: issue on parse_messages.
Enhancements: - Refactor the `parse_messages` function to improve message parsing logic, including handling scheduled messages and business messages more effectively. - Introduce a new parameter `fetch_replies` in the `Client` class to control the number of replies fetched when parsing messages.
1 parent 1e3bc2e commit a52f857

File tree

3 files changed

+66
-111
lines changed

3 files changed

+66
-111
lines changed

pyrogram/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
__version__ = "v2.186.1"
3+
__version__ = "v2.186.2"
44
__license__ = "MIT License"
55

66
from concurrent.futures.thread import ThreadPoolExecutor

pyrogram/client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ class Client(Methods):
193193
client_platform (:obj:`~pyrogram.enums.ClientPlatform`, *optional*):
194194
The platform where this client is running.
195195
Defaults to 'other'
196+
197+
fetch_replies (``int``, *optional*):
198+
Set the number of replies to be fetched when parsing the :obj:`~pyrogram.types.Message` object. Defaults to 1.
199+
:doc:`More on Errors <../../api/errors/index>`
196200
"""
197201

198202
APP_VERSION = f"Pyrogram {__version__}"
@@ -246,6 +250,7 @@ def __init__(
246250
client_platform: enums.ClientPlatform = enums.ClientPlatform.OTHER,
247251
max_message_cache_size: int = MAX_CACHE_SIZE,
248252
max_business_user_connection_cache_size: int = MAX_CACHE_SIZE,
253+
fetch_replies: int = 1,
249254
) -> None:
250255
super().__init__()
251256
self.name = name
@@ -321,6 +326,7 @@ def __init__(
321326
self.business_user_connection_cache = Cache(
322327
self.max_business_user_connection_cache_size
323328
)
329+
self.fetch_replies = fetch_replies
324330
self.updates_watchdog_task = None
325331
self.updates_watchdog_event = asyncio.Event()
326332
self.last_update_time = datetime.now()

pyrogram/utils.py

Lines changed: 59 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -80,124 +80,73 @@ def get_input_media_from_file_id(
8080
async def parse_messages(
8181
client,
8282
messages: raw.types.messages.Messages,
83+
is_scheduled: bool = False,
8384
replies: int = 1,
84-
business_connection_id: str | None = None,
85+
business_connection_id: str = "",
86+
r: raw.base.Updates = None,
8587
) -> list[types.Message]:
88+
parsed_messages = []
89+
90+
if not messages and r:
91+
users = {i.id: i for i in getattr(r, "users", [])}
92+
chats = {i.id: i for i in getattr(r, "chats", [])}
93+
94+
for u in getattr(r, "updates", []):
95+
if isinstance(
96+
u,
97+
raw.types.UpdateNewMessage
98+
| raw.types.UpdateNewChannelMessage
99+
| raw.types.UpdateNewScheduledMessage,
100+
):
101+
parsed_messages.append(
102+
await types.Message._parse(
103+
client,
104+
u.message,
105+
users,
106+
chats,
107+
is_scheduled=isinstance(
108+
u, raw.types.UpdateNewScheduledMessage
109+
),
110+
replies=client.fetch_replies,
111+
)
112+
)
113+
114+
elif isinstance(u, raw.types.UpdateBotNewBusinessMessage):
115+
parsed_messages.append(
116+
await types.Message._parse(
117+
client,
118+
u.message,
119+
users,
120+
chats,
121+
business_connection_id=getattr(
122+
u, "connection_id", business_connection_id
123+
),
124+
raw_reply_to_message=u.reply_to_message,
125+
replies=0,
126+
)
127+
)
128+
129+
return types.List(parsed_messages)
130+
86131
users = {i.id: i for i in messages.users}
87132
chats = {i.id: i for i in messages.chats}
88-
if hasattr(messages, "topics"):
89-
topics = {i.id: i for i in messages.topics}
90-
else:
91-
topics = None
133+
92134
if not messages.messages:
93135
return types.List()
94136

95-
parsed_messages = [
96-
await types.Message._parse(
97-
client,
98-
message,
99-
users,
100-
chats,
101-
topics,
102-
replies=0,
103-
business_connection_id=business_connection_id,
104-
)
105-
for message in messages.messages
106-
]
107-
108-
if replies:
109-
messages_with_replies = {
110-
i.id: i.reply_to
111-
for i in messages.messages
112-
if not isinstance(i, raw.types.MessageEmpty)
113-
and i.reply_to
114-
and isinstance(i.reply_to, raw.types.MessageReplyHeader)
115-
}
116-
117-
message_reply_to_story = {
118-
i.id: {
119-
"user_id": i.reply_to.user_id,
120-
"story_id": i.reply_to.story_id,
121-
}
122-
for i in messages.messages
123-
if not isinstance(i, raw.types.MessageEmpty)
124-
and i.reply_to
125-
and isinstance(i.reply_to, raw.types.MessageReplyStoryHeader)
126-
}
127-
128-
if messages_with_replies:
129-
for m in parsed_messages:
130-
if not isinstance(m, types.Message):
131-
continue
132-
133-
if m.chat:
134-
chat_id = m.chat.id
135-
break
136-
else:
137-
chat_id = 0
138-
139-
is_all_within_chat = not any(
140-
value.reply_to_peer_id for value in messages_with_replies.values()
137+
parsed_messages.extend(
138+
[
139+
await types.Message._parse(
140+
client,
141+
message,
142+
users,
143+
chats,
144+
is_scheduled=is_scheduled,
145+
replies=client.fetch_replies,
141146
)
142-
reply_messages: list[pyrogram.types.Message] = []
143-
if is_all_within_chat:
144-
# fast path: fetch all messages within the same chat
145-
reply_messages = await client.get_messages(
146-
chat_id,
147-
reply_to_message_ids=messages_with_replies.keys(),
148-
replies=replies - 1,
149-
)
150-
else:
151-
for target_reply_to in messages_with_replies.values():
152-
to_be_added_msg = None
153-
the_chat_id = chat_id
154-
if target_reply_to.reply_to_peer_id:
155-
the_chat_id = get_channel_id(
156-
target_reply_to.reply_to_peer_id.channel_id
157-
)
158-
to_be_added_msg = await client.get_messages(
159-
chat_id=the_chat_id,
160-
message_ids=target_reply_to.reply_to_msg_id,
161-
replies=replies - 1,
162-
)
163-
if isinstance(to_be_added_msg, list):
164-
for current_to_be_added in to_be_added_msg:
165-
reply_messages.append(current_to_be_added)
166-
elif to_be_added_msg:
167-
reply_messages.append(to_be_added_msg)
168-
169-
for message in parsed_messages:
170-
reply_to = messages_with_replies.get(message.id, None)
171-
if not reply_to:
172-
continue
173-
174-
reply_id = reply_to.reply_to_msg_id
175-
176-
for reply in reply_messages:
177-
if reply.id == reply_id and not reply.forum_topic_created:
178-
message.reply_to_message = reply
179-
180-
if message_reply_to_story:
181-
for m in parsed_messages:
182-
if not isinstance(m, types.Message):
183-
continue
184-
185-
if m.chat:
186-
chat_id = m.chat.id
187-
break
188-
else:
189-
chat_id = 0
190-
191-
reply_messages = {}
192-
for msg_id in message_reply_to_story:
193-
reply_messages[msg_id] = await client.get_stories(
194-
message_reply_to_story[msg_id]["user_id"],
195-
message_reply_to_story[msg_id]["story_id"],
196-
)
197-
198-
for message in parsed_messages:
199-
if message.id in reply_messages:
200-
message.reply_to_story = reply_messages[message.id]
147+
for message in messages.messages
148+
]
149+
)
201150

202151
return types.List(parsed_messages)
203152

0 commit comments

Comments
 (0)