Skip to content

Commit 460aa7b

Browse files
Prevent uneeded put requests
Make a GET request for each scope and compare it against the commands registered If there is a difference update them Added fields to CommandData to represent fields returned by discord
1 parent 249d84f commit 460aa7b

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

discord_slash/client.py

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -296,24 +296,62 @@ async def sync_all_commands(self, delete_from_unused_guilds=False):
296296
Matches commands registered on Discord to commands registered here.
297297
Deletes any commands on Discord but not here, and registers any not on Discord.
298298
This is done with a `put` request.
299+
A PUT request will only be made if there are changes detected.
299300
If ``sync_commands`` is ``True``, then this will be automatically called.
300301
301302
:param delete_from_unused_guilds: If the bot should make a request to set no commands for guilds that haven't got any commands registered in :class:``SlashCommand``
302303
"""
303304
cmds = await self.to_dict()
304305
self.logger.info("Syncing commands...")
305-
other_guilds = [x.id for x in self._discord.guilds if x.id not in cmds["guild"]]
306-
# This is an extremly bad way to do this, because slash cmds can be in guilds the bot isn't in
307-
# But it's the only way until discord makes an endpoint to request all the guild with cmds registered.
306+
cmds_formatted = {None: cmds['global']}
307+
for guild in cmds['guild']:
308+
cmds_formatted[guild] = cmds['guild'][guild]
309+
310+
for scope in cmds_formatted:
311+
new_cmds = cmds_formatted[scope]
312+
existing_cmds = await self.req.get_all_commands(guild_id = scope)
313+
existing_by_name = {}
314+
to_send=[]
315+
changed = False
316+
for cmd in existing_cmds:
317+
existing_by_name[cmd["name"]] = model.CommandData(**cmd)
318+
319+
if len(new_cmds) != len(existing_cmds):
320+
changed = True
321+
322+
for command in new_cmds:
323+
cmd_name = command["name"]
324+
if cmd_name in existing_by_name:
325+
cmd_data = model.CommandData(**command)
326+
existing_cmd = existing_by_name[cmd_name]
327+
if cmd_data != existing_cmd:
328+
changed=True
329+
to_send.append(command)
330+
else:
331+
command_with_id = command
332+
command_with_id["id"] = existing_cmd.id
333+
to_send.append(command_with_id)
334+
else:
335+
changed=True
336+
to_send.append(command)
308337

309-
await self.req.put_slash_commands(slash_commands=cmds["global"], guild_id=None)
338+
339+
if changed:
340+
self.logger.debug(f"Detected changes on {scope if scope is not None else 'global'}, updating them")
341+
await self.req.put_slash_commands(slash_commands=to_send, guild_id=scope)
342+
else:
343+
self.logger.debug(f"Detected no changes on {scope if scope is not None else 'global'}, skipping")
310344

311-
for x in cmds["guild"]:
312-
await self.req.put_slash_commands(slash_commands=cmds["guild"][x], guild_id=x)
313345
if delete_from_unused_guilds:
314-
for x in other_guilds:
346+
other_guilds = [guild.id for guild in self._discord.guilds if guild.id not in cmds["guild"]]
347+
# This is an extremly bad way to do this, because slash cmds can be in guilds the bot isn't in
348+
# But it's the only way until discord makes an endpoint to request all the guild with cmds registered.
349+
350+
for guild in other_guilds:
315351
with suppress(discord.Forbidden):
316-
await self.req.put_slash_commands(slash_commands=[], guild_id=x)
352+
existing = self.req.get_all_commands(guild_id = guild)
353+
if len(existing) != 0:
354+
await self.req.put_slash_commands(slash_commands=[], guild_id=guild)
317355

318356
self.logger.info("Completed syncing all commands!")
319357

discord_slash/model.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ class CommandData:
7272
"""
7373

7474
def __init__(
75-
self, name, description, options, id=None, **kwargs
75+
self, name, description, options = [], id=None, application_id = None, version = None, **kwargs
7676
):
7777
self.name = name
7878
self.description = description
7979
self.id = id
80+
self.application_id = application_id
81+
self.version = version
8082
if options is not None:
8183
self.options = []
8284
for option in options:

0 commit comments

Comments
 (0)