Skip to content

Commit 8543428

Browse files
feat: Paginate guilds when syncing (#1185)
* fix: small fix * feat: create Guild.get_all_guilds() + account for 200 limit when getting bot's guilds when syncing * ci: correct from checks. * pass bot instead of http + param docstring * oops missed import * ci: correct from checks. * fix: wrong value * feat: make the method private to Client * fix: one underscore only Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a787500 commit 8543428

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

interactions/api/http/guild.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,27 @@ class GuildRequest:
2020
def __init__(self) -> None:
2121
pass
2222

23-
async def get_self_guilds(self) -> List[dict]:
23+
async def get_self_guilds(
24+
self, limit: Optional[int] = 200, before: Optional[int] = None, after: Optional[int] = None
25+
) -> List[dict]:
2426
"""
2527
Gets all guild objects associated with the current bot user.
2628
27-
:return a list of partial guild objects the current bot user is a part of.
29+
:param limit: Number of guilds to return. Defaults to 200.
30+
:param before: Consider only users before the given Guild ID snowflake.
31+
:param after: Consider only users after the given Guild ID snowflake.
32+
:return: A list of partial guild objects the current bot user is a part of.
2833
"""
29-
request = await self._req.request(Route("GET", "/users/@me/guilds"))
34+
35+
params = {}
36+
if limit is not None:
37+
params["limit"] = limit
38+
if before:
39+
params["before"] = before
40+
if after:
41+
params["after"] = after
42+
43+
request = await self._req.request(Route("GET", "/users/@me/guilds"), params=params)
3044

3145
for guild in request:
3246
if guild.get("id"):

interactions/api/models/guild.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,9 +2067,9 @@ async def get_all_bans(self) -> List[Dict[str, User]]:
20672067

20682068
for ban in res:
20692069
ban["user"] = User(**ban["user"])
2070-
_all.append(res)
2070+
_all.extend(res)
20712071

2072-
return res
2072+
return _all
20732073

20742074
async def prune(
20752075
self,

interactions/client/bot.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,39 @@ async def wait_until_ready(self) -> None:
507507
"""
508508
await self._websocket.wait_until_ready()
509509

510+
async def _get_all_guilds(self) -> List[dict]:
511+
"""
512+
Gets all guilds that the bot is present in.
513+
514+
:return: List of guilds
515+
:rtype: List[dict]
516+
"""
517+
518+
_after = None
519+
_all: list = []
520+
521+
res = await self._http.get_self_guilds(limit=200)
522+
523+
while len(res) >= 200:
524+
525+
_all.extend(res)
526+
_after = int(res[-1]["id"])
527+
528+
res = await self._http.get_self_guilds(
529+
after=_after,
530+
)
531+
532+
_all.extend(res)
533+
534+
return _all
535+
510536
async def __get_all_commands(self) -> None:
511537
# this method is just copied from the sync method
512538
# I expect this to be changed in the sync rework
513539
# until then this will deliver a cache if sync is off to make autocomplete work bug-free
514540
# but even with sync off, we should cache all commands here always
515541

516-
_guilds = await self._http.get_self_guilds()
542+
_guilds = await self._get_all_guilds()
517543
_guild_ids = [int(_["id"]) for _ in _guilds]
518544
self._scopes.update(_guild_ids)
519545
_cmds = await self._http.get_application_commands(
@@ -618,7 +644,7 @@ async def __sync(self) -> None: # sourcery no-metrics
618644
# sourcery skip: low-code-quality
619645

620646
log.debug("starting command sync")
621-
_guilds = await self._http.get_self_guilds()
647+
_guilds = await self._get_all_guilds()
622648
_guild_ids = [int(_["id"]) for _ in _guilds]
623649
self._scopes.update(_guild_ids)
624650
_cmds = await self._http.get_application_commands(

0 commit comments

Comments
 (0)