Skip to content

Commit 459a3ad

Browse files
committed
Use sync_all_commands to avoid request limit
1 parent f13b387 commit 459a3ad

File tree

1 file changed

+13
-72
lines changed

1 file changed

+13
-72
lines changed

discord_slash/client.py

Lines changed: 13 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import typing
33
import discord
44
from inspect import iscoroutinefunction, getdoc
5+
from contextlib import suppress
56
from discord.ext import commands
67
from . import http
78
from . import model
@@ -26,29 +27,22 @@ class SlashCommand:
2627
:ivar req: :class:`.http.SlashCommandRequest` of this client.
2728
:ivar logger: Logger of this client.
2829
:ivar auto_register: Whether to register commands automatically.
29-
:ivar auto_delete: Whether to delete commands not found in the project automatically.
3030
:ivar has_listener: Whether discord client has listener add function.
3131
"""
3232

3333
def __init__(self,
3434
client: typing.Union[discord.Client, commands.Bot],
3535
auto_register: bool = False,
36-
auto_delete: bool = False,
3736
override_type: bool = False):
3837
self._discord = client
3938
self.commands = {}
4039
self.subcommands = {}
4140
self.logger = logging.getLogger("discord_slash")
4241
self.req = http.SlashCommandRequest(self.logger, self._discord)
4342
self.auto_register = auto_register
44-
self.auto_delete = auto_delete
4543

46-
if self.auto_register and self.auto_delete:
44+
if self.auto_register:
4745
self._discord.loop.create_task(self.sync_all_commands())
48-
elif self.auto_register:
49-
self._discord.loop.create_task(self.register_all_commands())
50-
elif self.auto_delete:
51-
self._discord.loop.create_task(self.delete_unused_commands())
5246

5347
if not isinstance(client, commands.Bot) and not isinstance(client, commands.AutoShardedBot) and not override_type:
5448
self.logger.info("Detected discord.Client! It is highly recommended to use `commands.Bot`.")
@@ -256,85 +250,32 @@ async def to_dict(self):
256250

257251
return commands
258252

259-
async def sync_all_commands(self, delete_from_unused_guilds=True):
253+
async def sync_all_commands(self, delete_from_unused_guilds=False):
260254
"""
261255
Matches commands registered on Discord to commands registered here.
262256
Deletes any commands on Discord but not here, and registers any not on Discord.
263257
This is done with a `put` request.
264-
If ``auto_register`` and ``auto_delete`` are ``True`` then this will be automatically called.
258+
If ``auto_register`` is ``True``, then this will be automatically called.
265259
266260
: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``
267261
"""
268-
commands = await self.to_dict()
269-
self.logger.info("Syncing commands...")
270-
all_bot_guilds = [guild.id for guild in self._discord.guilds]
262+
cmds = await self.to_dict()
263+
self.logger.info("Registering commands...")
264+
other_guilds = [x.id for x in self._discord.guilds if x.id not in cmds["guild"]]
271265
# This is an extremly bad way to do this, because slash cmds can be in guilds the bot isn't in
272266
# But it's the only way until discord makes an endpoint to request all the guild with cmds registered.
273267

274-
await self.req.put_slash_commands(slash_commands=commands["global"], guild_id=None)
268+
await self.req.put_slash_commands(slash_commands=cmds["global"], guild_id=None)
275269

276-
for guild in commands["guild"]:
277-
await self.req.put_slash_commands(slash_commands=commands["guild"][guild], guild_id=guild)
278-
all_bot_guilds.remove(guild)
270+
for x in cmds["guild"]:
271+
await self.req.put_slash_commands(slash_commands=cmds["guild"][x], guild_id=x)
279272
if delete_from_unused_guilds:
280-
for guild in all_bot_guilds:
281-
await self.req.put_slash_commands(slash_commands=[], guild_id=guild)
282-
283-
self.logger.info("Completed syncing all commands!")
273+
for x in other_guilds:
274+
with suppress(discord.Forbidden):
275+
await self.req.put_slash_commands(slash_commands=[], guild_id=x)
284276

285-
async def register_all_commands(self):
286-
"""
287-
Registers all slash commands to Discord API.\n
288-
If ``auto_register`` is ``True`` and ``auto_delete`` is ``False``, then this will be automatically called.
289-
"""
290-
self.logger.info("Registering commands...")
291-
commands = await self.to_dict()
292-
for command in commands["global"]:
293-
name = command.pop('name')
294-
self.logger.debug(f"Registering global command {name}")
295-
await self.req.add_slash_command(guild_id=None, cmd_name=name, **command)
296-
297-
for guild in commands["guild"]:
298-
guild_cmds = commands["guild"][guild]
299-
for command in guild_cmds:
300-
name = command.pop('name')
301-
self.logger.debug(f"Registering guild command {name} in guild: {guild}")
302-
await self.req.add_slash_command(guild_id=guild, cmd_name=name, **command)
303277
self.logger.info("Completed registering all commands!")
304278

305-
async def delete_unused_commands(self):
306-
"""
307-
Unregisters all slash commands which are not used by the project to Discord API.\n
308-
This might take some time because for every guild the bot is on an API call is made.\n
309-
If ``auto_delete`` is ``True`` and ``auto_register`` is ``False``, then this will be automatically called.
310-
"""
311-
await self._discord.wait_until_ready()
312-
self.logger.info("Deleting unused commands...")
313-
registered_commands = {}
314-
global_commands = await self.req.get_all_commands(None)
315-
316-
for cmd in global_commands:
317-
registered_commands[cmd["name"]] = {"id": cmd["id"], "guild_id": None}
318-
319-
for guild in self._discord.guilds:
320-
# Since we can only get commands per guild we need to loop through every one
321-
try:
322-
guild_commands = await self.req.get_all_commands(guild.id)
323-
except discord.Forbidden:
324-
# In case a guild has not granted permissions to access commands
325-
continue
326-
327-
for cmd in guild_commands:
328-
registered_commands[cmd["name"]] = {"id": cmd["id"], "guild_id": guild.id}
329-
330-
for x in registered_commands:
331-
if x not in self.commands:
332-
# Delete command if not found locally
333-
selected = registered_commands[x]
334-
await self.req.remove_slash_command(selected["guild_id"], selected["id"])
335-
336-
self.logger.info("Completed deleting unused commands!")
337-
338279
def add_slash_command(self,
339280
cmd,
340281
name: str = None,

0 commit comments

Comments
 (0)