@@ -29,6 +29,8 @@ class SlashCommand:
2929 :type client: Union[discord.Client, discord.ext.commands.Bot]
3030 :param sync_commands: Whether to sync commands automatically. Default `False`.
3131 :type sync_commands: bool
32+ :param debug_guild: Guild ID of guild to use for testing commands. Prevents setting global commands in favor of guild commands, which update instantly
33+ :type debug_guild: int
3234 :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``. Default `False`.
3335 :type delete_from_unused_guilds: bool
3436 :param sync_on_cog_reload: Whether to sync commands on cog reload. Default `False`.
@@ -56,6 +58,7 @@ def __init__(
5658 self ,
5759 client : typing .Union [discord .Client , commands .Bot ],
5860 sync_commands : bool = False ,
61+ debug_guild : typing .Optional [int ] = None ,
5962 delete_from_unused_guilds : bool = False ,
6063 sync_on_cog_reload : bool = False ,
6164 override_type : bool = False ,
@@ -68,6 +71,7 @@ def __init__(
6871 self .logger = logging .getLogger ("discord_slash" )
6972 self .req = http .SlashCommandRequest (self .logger , self ._discord , application_id )
7073 self .sync_commands = sync_commands
74+ self .debug_guild = debug_guild
7175 self .sync_on_cog_reload = sync_on_cog_reload
7276
7377 if self .sync_commands :
@@ -424,7 +428,8 @@ async def sync_all_commands(
424428 permissions_map = {}
425429 cmds = await self .to_dict ()
426430 self .logger .info ("Syncing commands..." )
427- cmds_formatted = {None : cmds ["global" ]}
431+ # if debug_guild is set, global commands get re-routed to the guild to update quickly
432+ cmds_formatted = {self .debug_guild : cmds ["global" ]}
428433 for guild in cmds ["guild" ]:
429434 cmds_formatted [guild ] = cmds ["guild" ][guild ]
430435
@@ -1389,15 +1394,24 @@ async def on_socket_response(self, msg):
13891394
13901395 to_use = msg ["d" ]
13911396 interaction_type = to_use ["type" ]
1392- if interaction_type in (1 , 2 , 3 ) or msg ["s" ] == 5 :
1397+
1398+ # dis_snek variance seq
1399+
1400+ if interaction_type in (1 , 2 ):
13931401 await self ._on_slash (to_use )
13941402 await self ._on_context_menu (to_use )
1403+ elif interaction_type == 3 :
13951404 try :
13961405 await self ._on_component (to_use ) # noqa
13971406 except KeyError :
13981407 pass # for some reason it complains about custom_id being an optional arg when it's fine?
1408+ finally :
1409+ await self ._on_context_menu (to_use )
1410+ else :
1411+ raise NotImplementedError (
1412+ f"Unknown Interaction Received: { interaction_type } "
1413+ ) # check if discord does a sneaky event change on us
13991414 return
1400- # raise NotImplementedError
14011415
14021416 async def _on_component (self , to_use ):
14031417 ctx = context .ComponentContext (self .req , to_use , self ._discord , self .logger )
@@ -1410,7 +1424,7 @@ async def _on_component(self, to_use):
14101424 self ._discord .dispatch ("component_callback" , ctx , callback )
14111425 await self .invoke_component_callback (callback , ctx )
14121426
1413- async def _on_slash (self , to_use ):
1427+ async def _on_slash (self , to_use ): # slash commands only.
14141428 if to_use ["data" ]["name" ] in self .commands :
14151429
14161430 ctx = context .SlashContext (self .req , to_use , self ._discord , self .logger )
@@ -1421,6 +1435,9 @@ async def _on_slash(self, to_use):
14211435
14221436 selected_cmd = self .commands [to_use ["data" ]["name" ]]
14231437
1438+ if selected_cmd ._type != 1 :
1439+ return # If its a menu, ignore.
1440+
14241441 if (
14251442 selected_cmd .allowed_guild_ids
14261443 and ctx .guild_id not in selected_cmd .allowed_guild_ids
@@ -1457,6 +1474,12 @@ async def _on_slash(self, to_use):
14571474 await self .invoke_command (selected_cmd , ctx , args )
14581475
14591476 async def _on_context_menu (self , to_use ):
1477+ # Slash Command Logic
1478+
1479+ # to prevent any potential keyerrors:
1480+ if "name" not in to_use ["data" ].keys ():
1481+ return
1482+
14601483 if to_use ["data" ]["name" ] in self .commands ["context" ]:
14611484 ctx = context .MenuContext (self .req , to_use , self ._discord , self .logger )
14621485 cmd_name = to_use ["data" ]["name" ]
@@ -1484,6 +1507,39 @@ async def _on_context_menu(self, to_use):
14841507
14851508 await self .invoke_command (selected_cmd , ctx , args = {})
14861509
1510+ # Cog Logic
1511+
1512+ elif to_use ["data" ]["name" ] in self .commands :
1513+ ctx = context .MenuContext (self .req , to_use , self ._discord , self .logger )
1514+ cmd_name = to_use ["data" ]["name" ]
1515+
1516+ if cmd_name not in self .commands and cmd_name in self .subcommands :
1517+ return # menus don't have subcommands you smooth brain
1518+
1519+ selected_cmd = self .commands [cmd_name ]
1520+ if type (selected_cmd ) == dict :
1521+ return # Get rid of any selection thats a dict somehow
1522+ if selected_cmd ._type == 1 : # noqa
1523+ return # Slash command obj.
1524+
1525+ if (
1526+ selected_cmd .allowed_guild_ids
1527+ and ctx .guild_id not in selected_cmd .allowed_guild_ids
1528+ ):
1529+ return
1530+
1531+ if selected_cmd .has_subcommands and not selected_cmd .func :
1532+ return await self .handle_subcommand (ctx , to_use )
1533+
1534+ if "options" in to_use ["data" ]:
1535+ for x in to_use ["data" ]["options" ]:
1536+ if "value" not in x :
1537+ return await self .handle_subcommand (ctx , to_use )
1538+
1539+ self ._discord .dispatch ("context_menu" , ctx )
1540+
1541+ await self .invoke_command (selected_cmd , ctx , args = {})
1542+
14871543 async def handle_subcommand (self , ctx : context .SlashContext , data : dict ):
14881544 """
14891545 Coroutine for handling subcommand.
0 commit comments