diff --git a/pyrogram/methods/chats/get_dialogs.py b/pyrogram/methods/chats/get_dialogs.py
index 2ebf090a..f4f7e016 100644
--- a/pyrogram/methods/chats/get_dialogs.py
+++ b/pyrogram/methods/chats/get_dialogs.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see .
-from typing import AsyncGenerator, Optional
+from typing import AsyncGenerator
import pyrogram
from pyrogram import types, raw, utils
diff --git a/pyrogram/methods/chats/get_forum_topics.py b/pyrogram/methods/chats/get_forum_topics.py
index 3bd38c03..8e24e48e 100644
--- a/pyrogram/methods/chats/get_forum_topics.py
+++ b/pyrogram/methods/chats/get_forum_topics.py
@@ -16,11 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see .
-from typing import Union, Optional, AsyncGenerator
+from typing import Union, AsyncGenerator
import pyrogram
-from pyrogram import raw
-from pyrogram import types
+from pyrogram import types, raw, utils
class GetForumTopics:
@@ -39,26 +38,66 @@ class GetForumTopics:
limit (``int``, *optional*):
Limits the number of topics to be retrieved.
+ By default, no limit is applied and all topics are returned.
Returns:
- ``Generator``: On success, a generator yielding :obj:`~pyrogram.types.ForumTopic` objects is returned.
+ ``Generator``: A generator yielding :obj:`~pyrogram.types.ForumTopic` objects.
Example:
.. code-block:: python
- # get all forum topics
+ # Iterate through all topics
async for topic in app.get_forum_topics(chat_id):
print(topic)
"""
- r = await self.invoke(
- raw.functions.channels.GetForumTopics(
- channel=await self.resolve_peer(chat_id),
- offset_date=0,
- offset_id=0,
- offset_topic=0,
- limit=limit
- )
- )
+ current = 0
+ total = limit or (1 << 31) - 1
+ limit = min(100, total)
- for topic in r.topics:
- yield types.ForumTopic._parse(topic)
+ offset_date = 0
+ offset_id = 0
+ offset_topic = 0
+
+ while True:
+ r = await self.invoke(
+ raw.functions.channels.GetForumTopics(
+ channel=await self.resolve_peer(chat_id),
+ offset_date=offset_date,
+ offset_id=offset_id,
+ offset_topic=offset_topic,
+ limit=limit
+ )
+ )
+
+ users = {i.id: i for i in r.users}
+ chats = {i.id: i for i in r.chats}
+
+ messages = {}
+
+ for message in r.messages:
+ if isinstance(message, raw.types.MessageEmpty):
+ continue
+
+ messages[message.id] = await types.Message._parse(self, message, users, chats)
+
+ topics = []
+
+ for topic in r.topics:
+ topics.append(types.ForumTopic._parse(self, topic, messages, users, chats))
+
+ if not topics:
+ return
+
+ last = topics[-1]
+
+ offset_id = last.top_message.id
+ offset_date = utils.datetime_to_timestamp(last.top_message.date)
+ offset_topic = last.id
+
+ for topic in topics:
+ yield topic
+
+ current += 1
+
+ if current >= total:
+ return
diff --git a/pyrogram/methods/chats/get_forum_topics_by_id.py b/pyrogram/methods/chats/get_forum_topics_by_id.py
index 4e685e98..ee79aad3 100644
--- a/pyrogram/methods/chats/get_forum_topics_by_id.py
+++ b/pyrogram/methods/chats/get_forum_topics_by_id.py
@@ -71,9 +71,20 @@ class GetForumTopicsByID:
)
)
+ users = {i.id: i for i in r.users}
+ chats = {i.id: i for i in r.chats}
+
+ messages = {}
+
+ for message in r.messages:
+ if isinstance(message, raw.types.MessageEmpty):
+ continue
+
+ messages[message.id] = await types.Message._parse(self, message, users, chats)
+
topics = types.List()
- for i in r:
- topics.append(types.ForumTopic._parse(i))
+ for i in r.topics:
+ topics.append(types.ForumTopic._parse(self, i, messages, users, chats))
- return topics if is_iterable else topics[0]
+ return topics if is_iterable else topics[0] if topics else None
diff --git a/pyrogram/types/messages_and_media/forum_topic.py b/pyrogram/types/messages_and_media/forum_topic.py
index a7e425b4..a2525c69 100644
--- a/pyrogram/types/messages_and_media/forum_topic.py
+++ b/pyrogram/types/messages_and_media/forum_topic.py
@@ -16,7 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see .
-from pyrogram import raw, utils
+import pyrogram
+from pyrogram import types, raw, utils
from ..object import Object
@@ -27,28 +28,31 @@ class ForumTopic(Object):
id (``int``):
Unique topic identifier inside this chat.
- date (``int``):
- Date when the topic was created.
-
title (``str``):
The topic title.
- icon_color (``int``):
- Color of the topic icon in RGB format
+ date (``int``, *optional*):
+ Date when the topic was created.
+
+ icon_color (``str``, *optional*):
+ Color of the topic icon in HEX format
icon_emoji_id (``int``, *optional*):
Unique identifier of the custom emoji shown as the topic icon
- top_message (``int``):
+ creator (:obj:`~pyrogram.types.Chat`, *optional*):
+ Topic creator.
+
+ top_message (:obj:`~pyrogram.types.Message`, *optional*):
The last message sent in the topic at this time.
- unread_count (``int``):
+ unread_count (``int``, *optional*):
Amount of unread messages in this topic.
- unread_mentions_count (``int``):
+ unread_mentions_count (``int``, *optional*):
Amount of unread messages containing a mention in this topic.
- unread_reactions_count (``int``):
+ unread_reactions_count (``int``, *optional*):
Amount of unread messages containing a reaction in this topic.
is_my (``bool``, *optional*):
@@ -59,31 +63,41 @@ class ForumTopic(Object):
is_pinned (``bool``, *optional*):
True, if the topic is pinned.
+
+ is_short (``bool``, *optional*):
+ True, if the topic is short.
+
+ is_hidden (``bool``, *optional*):
+ True, if the topic is hidden.
"""
def __init__(
self,
*,
id: int,
- date: int,
- title: str,
- icon_color: int,
+ title: str = None,
+ date: int = None,
+ icon_color: str = None,
icon_emoji_id: int = None,
- top_message: int,
- unread_count: int,
- unread_mentions_count: int,
- unread_reactions_count: int,
+ creator: "types.Chat" = None,
+ top_message: "types.Message" = None,
+ unread_count: int = None,
+ unread_mentions_count: int = None,
+ unread_reactions_count: int = None,
is_my: bool = None,
is_closed: bool = None,
is_pinned: bool = None,
+ is_short: bool = None,
+ is_hidden: bool = None
):
super().__init__()
self.id = id
- self.date = date
self.title = title
+ self.date = date
self.icon_color = icon_color
self.icon_emoji_id = icon_emoji_id
+ self.creator = creator
self.top_message = top_message
self.unread_count = unread_count
self.unread_mentions_count = unread_mentions_count
@@ -91,20 +105,37 @@ class ForumTopic(Object):
self.is_my = is_my
self.is_closed = is_closed
self.is_pinned = is_pinned
+ self.is_short = is_short
+ self.is_hidden = is_hidden
@staticmethod
- def _parse(forum_topic: "raw.types.ForumTopic") -> "ForumTopic":
+ def _parse(client: "pyrogram.Client", forum_topic: "raw.types.ForumTopic", messages: dict = {}, users: dict = {}, chats: dict = {}) -> "ForumTopic":
+ creator = None
+
+ peer = getattr(forum_topic, "from_id", None)
+
+ if peer:
+ peer_id = utils.get_raw_peer_id(peer)
+
+ if isinstance(peer, raw.types.PeerUser):
+ creator = types.Chat._parse_user_chat(client, users[peer_id])
+ else:
+ creator = types.Chat._parse_channel_chat(client, chats[peer_id])
+
return ForumTopic(
id=forum_topic.id,
- date=utils.timestamp_to_datetime(forum_topic.date),
title=forum_topic.title,
- icon_color=getattr(forum_topic, "icon_color", None),
+ date=utils.timestamp_to_datetime(forum_topic.date),
+ icon_color=format(forum_topic.icon_color, "x") if getattr(forum_topic, "icon_color", None) else None,
icon_emoji_id=getattr(forum_topic, "icon_emoji_id", None),
- top_message=getattr(forum_topic, "top_message", None),
+ creator=creator,
+ top_message=messages.get(getattr(forum_topic, "top_message", None)),
unread_count=getattr(forum_topic, "unread_count", None),
unread_mentions_count=getattr(forum_topic, "unread_mentions_count", None),
unread_reactions_count=getattr(forum_topic, "unread_reactions_count", None),
is_my=getattr(forum_topic, "my", None),
is_closed=getattr(forum_topic, "closed", None),
is_pinned=getattr(forum_topic, "pinned", None),
+ is_short=getattr(forum_topic, "short", None),
+ is_hidden=getattr(forum_topic, "hidden", None),
)
diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py
index e0d59213..fb54f557 100644
--- a/pyrogram/types/messages_and_media/message.py
+++ b/pyrogram/types/messages_and_media/message.py
@@ -1025,12 +1025,14 @@ class Message(Object, Update):
parsed_message.reply_to_message_id = message.reply_to.reply_to_msg_id
else:
thread_id = message.reply_to.reply_to_msg_id
+
parsed_message.message_thread_id = thread_id
+
if topics:
- parsed_message.topic = types.ForumTopic._parse(topics[thread_id])
+ parsed_message.topic = types.ForumTopic._parse(client, topics[thread_id], users=users, chats=chats)
else:
try:
- msg = await client.get_messages(parsed_message.chat.id,message.id)
+ msg = await client.get_messages(parsed_message.chat.id, message.id, replies=0)
if msg.topic:
parsed_message.topic = msg.topic
except Exception:
@@ -1051,6 +1053,7 @@ class Message(Object, Update):
if media is None or web_page is not None
else None
)
+
parsed_message.reply_to_message_id = message.reply_to.reply_to_msg_id
parsed_message.reply_to_top_message_id = message.reply_to.reply_to_top_id
else:
diff --git a/pyrogram/types/user_and_chats/chat_event.py b/pyrogram/types/user_and_chats/chat_event.py
index 2c4ddb41..9faea6a0 100644
--- a/pyrogram/types/user_and_chats/chat_event.py
+++ b/pyrogram/types/user_and_chats/chat_event.py
@@ -454,16 +454,16 @@ class ChatEvent(Object):
action = enums.ChatEventAction.INVITE_LINK_DELETED
elif isinstance(action, raw.types.ChannelAdminLogEventActionCreateTopic):
- created_forum_topic = types.ForumTopic._parse(action.topic)
+ created_forum_topic = types.ForumTopic._parse(client, action.topic, users=users, chats=chats)
action = enums.ChatEventAction.CREATED_FORUM_TOPIC
elif isinstance(action, raw.types.ChannelAdminLogEventActionEditTopic):
- old_forum_topic = types.ForumTopic._parse(action.prev_topic)
- new_forum_topic = types.ForumTopic._parse(action.new_topic)
+ old_forum_topic = types.ForumTopic._parse(client, action.prev_topic, users=users, chats=chats)
+ new_forum_topic = types.ForumTopic._parse(client, action.new_topic, users=users, chats=chats)
action = enums.ChatEventAction.EDITED_FORUM_TOPIC
elif isinstance(action, raw.types.ChannelAdminLogEventActionDeleteTopic):
- created_forum_topic = types.ForumTopic._parse(action.topic)
+ created_forum_topic = types.ForumTopic._parse(client, action.topic, users=users, chats=chats)
action = enums.ChatEventAction.DELETED_FORUM_TOPIC
else:
@@ -526,7 +526,7 @@ class ChatEvent(Object):
new_invite_link=new_invite_link,
revoked_invite_link=revoked_invite_link,
deleted_invite_link=deleted_invite_link,
-
+
created_forum_topic=created_forum_topic,
old_forum_topic=old_forum_topic,
new_forum_topic=new_forum_topic,