22import typing
33import discord
44from inspect import iscoroutinefunction , getdoc
5+ from contextlib import suppress
56from discord .ext import commands
67from . import http
78from . 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