diff --git a/changelog/1438.feature.rst b/changelog/1438.feature.rst new file mode 100644 index 0000000000..26db9cc72e --- /dev/null +++ b/changelog/1438.feature.rst @@ -0,0 +1 @@ +Add :meth:`Guild.fetch_role_member_counts` to retrieve member counts for each :class:`Role` without requiring members to be cached. diff --git a/disnake/guild.py b/disnake/guild.py index cabf40fe75..40ece9481f 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -3821,6 +3821,42 @@ async def fetch_roles(self) -> List[Role]: data = await self._state.http.get_roles(self.id) return [Role(guild=self, state=self._state, data=d) for d in data] + async def fetch_role_member_counts(self) -> Dict[Union[Role, Object], int]: + """|coro| + + Retrieves the member counts of all :class:`Role`\\s that the guild has. + + .. note:: + + This method is an API call. For general usage, consider :attr:`roles` instead. + + .. versionadded:: |vnext| + + Raises + ------ + HTTPException + Retrieving the role member counts failed. + + Returns + ------- + :class:`dict`\\[:class:`Role` | :class:`Object`, :class:`int`] + The member counts of the roles. + Roles that could not be found in the bot's cache are + :class:`Object` with the corresponding ID instead. + """ + data = await self._state.http.get_role_member_counts(self.id) + counts: Dict[Union[Role, Object], int] = {} + for id_str, count in data.items(): + id = int(id_str) + if id == self.id: + # skip @everyone role, since it's a synthetic role and always has a member count of 0 + continue + + obj = self.get_role(id) or Object(id) + counts[obj] = count + + return counts + @overload async def get_or_fetch_member( self, member_id: int, *, strict: Literal[False] = ... diff --git a/disnake/http.py b/disnake/http.py index c32cbc8842..4513bc6b36 100644 --- a/disnake/http.py +++ b/disnake/http.py @@ -2017,6 +2017,11 @@ def get_role(self, guild_id: Snowflake, role_id: Snowflake) -> Response[role.Rol def get_roles(self, guild_id: Snowflake) -> Response[List[role.Role]]: return self.request(Route("GET", "/guilds/{guild_id}/roles", guild_id=guild_id)) + def get_role_member_counts(self, guild_id: Snowflake) -> Response[Dict[Snowflake, int]]: + return self.request( + Route("GET", "/guilds/{guild_id}/roles/member-counts", guild_id=guild_id) + ) + def edit_role( self, guild_id: Snowflake,