2525log = logging .getLogger (__name__ )
2626
2727
28+ async def get_chunk (
29+ client : "pyrogram.Client" ,
30+ chat_id : Union [int , str ],
31+ offset : int ,
32+ filter : "enums.ChatMembersFilter" ,
33+ limit : int ,
34+ query : str ,
35+ ):
36+ is_queryable = filter in [enums .ChatMembersFilter .SEARCH ,
37+ enums .ChatMembersFilter .BANNED ,
38+ enums .ChatMembersFilter .RESTRICTED ]
39+
40+ filter = filter .value (q = query ) if is_queryable else filter .value ()
41+
42+ r = await client .invoke (
43+ raw .functions .channels .GetParticipants (
44+ channel = await client .resolve_peer (chat_id ),
45+ filter = filter ,
46+ offset = offset ,
47+ limit = limit ,
48+ hash = 0
49+ ),
50+ sleep_threshold = 60
51+ )
52+
53+ members = r .participants
54+ users = {u .id : u for u in r .users }
55+ chats = {c .id : c for c in r .chats }
56+
57+ return [types .ChatMember ._parse (client , member , users , chats ) for member in members ]
58+
59+
2860class GetChatMembers :
2961 async def get_chat_members (
3062 self : "pyrogram.Client" ,
3163 chat_id : Union [int , str ],
32- offset : int = 0 ,
33- limit : int = 200 ,
3464 query : str = "" ,
35- filter : "enums.ChatMembersFilter" = enums .ChatMembersFilter .ANY
65+ limit : int = 0 ,
66+ filter : "enums.ChatMembersFilter" = enums .ChatMembersFilter .SEARCH
3667 ) -> List ["types.ChatMember" ]:
37- """Get a chunk of the members list of a chat.
68+ """Get the members list of a chat.
3869
39- You can get up to 200 chat members at once.
4070 A chat can be either a basic group, a supergroup or a channel.
41- You must be admin to retrieve the members list of a channel (also known as "subscribers").
42- For a more convenient way of getting chat members see :meth:`~pyrogram.Client.iter_chat_members`.
71+ Requires administrator rights in channels.
4372
4473 Parameters:
4574 chat_id (``int`` | ``str``):
4675 Unique identifier (int) or username (str) of the target chat.
4776
48- offset (``int``, *optional*):
49- Sequential number of the first member to be returned.
50- Only applicable to supergroups and channels. Defaults to 0.
51-
52- limit (``int``, *optional*):
53- Limits the number of members to be retrieved.
54- Only applicable to supergroups and channels.
55- Defaults to 200.
56-
5777 query (``str``, *optional*):
5878 Query string to filter members based on their display names and usernames.
5979 Only applicable to supergroups and channels. Defaults to "" (empty string).
60- A query string is applicable only for *"all"*, *"banned"* and *"restricted"* filters only
80+ A query string is applicable only for :obj:`~pyrogram.enums.ChatMembersFilter.SEARCH`,
81+ :obj:`~pyrogram.enums.ChatMembersFilter.BANNED` and :obj:`~pyrogram.enums.ChatMembersFilter.RESTRICTED`
82+ filters only.
83+
84+ limit (``int``, *optional*):
85+ Limits the number of members to be retrieved.
6186
62- filter (``str` `, *optional*):
87+ filter (:obj:`~pyrogram.enums.ChatMembersFilter `, *optional*):
6388 Filter used to select the kind of members you want to retrieve. Only applicable for supergroups
64- and channels. It can be any of the followings:
65- *"all"* - all kind of members,
66- *"banned"* - banned members only,
67- *"restricted"* - restricted members only,
68- *"bots"* - bots only,
69- *"recent"* - recent members only,
70- *"administrators"* - chat administrators only.
71- Only applicable to supergroups and channels.
72- Defaults to *"recent"*.
89+ and channels.
7390
7491 Returns:
75- List of :obj:`~pyrogram.types.ChatMember`: On success, a list of chat members is returned.
76-
77- Raises:
78- ValueError: In case you used an invalid filter or a chat id that belongs to a user.
92+ ``Generator``: On success, a generator yielding :obj:`~pyrogram.types.ChatMember` objects is returned.
7993
8094 Example:
8195 .. code-block:: python
8296
83- # Get first 200 recent members
84- app.get_chat_members(chat_id)
97+ from pyrogram import enums
98+
99+ # Get members
100+ for member in app.get_chat_members(chat_id):
101+ print(member)
85102
86- # Get all administrators
87- app.get_chat_members(chat_id, filter="administrators")
103+ # Get administrators
104+ administrators = list(app.get_chat_members(
105+ chat_id,
106+ filter=enums.ChatMembersFilter.ADMINISTRATORS))
88107
89- # Get all bots
90- app.get_chat_members(chat_id, filter="bots")
108+ # Get bots
109+ bots = list(app.get_chat_members(
110+ chat_id,
111+ filter=enums.ChatMembersFilter.BOTS))
91112 """
92113 peer = await self .resolve_peer (chat_id )
93114
@@ -101,40 +122,35 @@ async def get_chat_members(
101122 members = getattr (r .full_chat .participants , "participants" , [])
102123 users = {i .id : i for i in r .users }
103124
104- return types .List (types .ChatMember ._parse (self , member , users , {}) for member in members )
105- elif isinstance (peer , raw .types .InputPeerChannel ):
106- filter = filter .lower ()
107-
108- if filter == enums .ChatMembersFilter .ANY :
109- filter = raw .types .ChannelParticipantsSearch (q = query )
110- elif filter == enums .ChatMembersFilter .BANNED :
111- filter = raw .types .ChannelParticipantsKicked (q = query )
112- elif filter == enums .ChatMembersFilter .RESTRICTED :
113- filter = raw .types .ChannelParticipantsBanned (q = query )
114- elif filter == enums .ChatMembersFilter .BOTS :
115- filter = raw .types .ChannelParticipantsBots ()
116- elif filter == enums .ChatMembersFilter .RECENT :
117- filter = raw .types .ChannelParticipantsRecent ()
118- elif filter == enums .ChatMembersFilter .ADMINISTRATORS :
119- filter = raw .types .ChannelParticipantsAdmins ()
120- else :
121- raise ValueError (f'Invalid filter "{ filter } "' )
125+ for member in members :
126+ yield types .ChatMember ._parse (self , member , users , {})
122127
123- r = await self .invoke (
124- raw .functions .channels .GetParticipants (
125- channel = peer ,
126- filter = filter ,
127- offset = offset ,
128- limit = limit ,
129- hash = 0
130- ),
131- sleep_threshold = 60
128+ return
129+
130+ current = 0
131+ offset = 0
132+ total = abs (limit ) or (1 << 31 ) - 1
133+ limit = min (200 , total )
134+
135+ while True :
136+ members = await get_chunk (
137+ client = self ,
138+ chat_id = chat_id ,
139+ offset = offset ,
140+ filter = filter ,
141+ limit = limit ,
142+ query = query
132143 )
133144
134- members = r .participants
135- users = {i .id : i for i in r .users }
136- chats = {i .id : i for i in r .chats }
145+ if not members :
146+ return
147+
148+ offset += len (members )
149+
150+ for member in members :
151+ yield member
152+
153+ current += 1
137154
138- return types .List (types .ChatMember ._parse (self , member , users , chats ) for member in members )
139- else :
140- raise ValueError (f'The chat_id "{ chat_id } " belongs to a user' )
155+ if current >= total :
156+ return
0 commit comments