44from discord .ext import commands
55from . import http
66from . import model
7+ from .utils import manage_commands
78
89
910class SlashCommand :
@@ -12,25 +13,29 @@ class SlashCommand:
1213
1314 :param client: discord.py Bot class. Although it accepts :class:`discord.Client` at init, using it is not allowed since :class:`discord.Client` doesn't support :func:`add_listener`.
1415 :type client: Union[discord.Client, discord.ext.commands.Bot]
16+ :param auto_register: Whether to register commands automatically. Default `False`.
17+ :type auto_register: bool
1518
1619 :ivar _discord: Discord client of this client.
1720 :ivar commands: Dictionary of the registered commands via :func:`.slash` decorator.
1821 :ivar req: :class:`.http.SlashCommandRequest` of this client.
1922 :ivar logger: Logger of this client.
23+ :ivar auto_register: Whether to register commands automatically.
2024 """
2125 def __init__ (self ,
22- client : typing .Union [discord .Client ,
23- commands . Bot ]
26+ client : typing .Union [discord .Client , commands . Bot ],
27+ auto_register : bool = False
2428 ):
2529 if isinstance (client , discord .Client ) and not isinstance (client , commands .Bot ):
2630 raise Exception ("Currently only commands.Bot is supported." )
2731 self ._discord = client
2832 self .commands = {}
2933 self .req = http .SlashCommandRequest ()
3034 self .logger = logging .getLogger ("discord_slash" )
35+ self .auto_register = auto_register
3136 self ._discord .add_listener (self .on_socket_response )
3237
33- def slash (self , name = None , auto_convert : dict = None ):
38+ def slash (self , name : str = None , description : str = None , auto_convert : dict = None , guild_id : int = None ):
3439 """
3540 Decorator that registers coroutine as a slash command.\n
3641 1 arg is required for ctx(:class:`.model.SlashContext`), and if your slash command has some args, then those args are also required.\n
@@ -63,13 +68,22 @@ async def _pick(ctx, choice1, choice2): # Command with 1 or more args.
6368 "option_user": 6, # Also can use number for type
6469 "option_channel": "CHANNEL"} # and all upper case.
6570
66- :param name: Name of the slash command.
67- :param auto_convert: Dictionary of how to convert option values.
68- :type auto_convert: dict
71+ :param name: Name of the slash command. Default name of the coroutine.
72+ :param description: Description of the slash command. Default `None`.
73+ :param auto_convert: Dictionary of how to convert option values. Default `None`.
74+ :param guild_id: Guild ID of where the command will be used. Default `None`, which will be global command.
6975 """
7076 def wrapper (cmd ):
7177 self .commands [cmd .__name__ if not name else name ] = [cmd , auto_convert ]
7278 self .logger .debug (f"Added command `{ cmd .__name__ if not name else name } `" )
79+ """
80+ if self.auto_register:
81+ manage_commands.add_slash_command(self._discord.user.id,
82+ self._discord.http.token,
83+ guild_id,
84+ cmd.__name__ if not name else name,
85+ description)
86+ """
7387 return cmd
7488 return wrapper
7589
@@ -85,6 +99,9 @@ def process_options(self, guild: discord.Guild, options: list, auto_convert: dic
8599 :type auto_convert: dict
86100 :return: list
87101 """
102+ if not guild :
103+ self .logger .info ("This command invoke is missing guild. Skipping option process." )
104+ return [x ["value" ] for x in options ]
88105 converters = [guild .get_member , guild .get_role , guild .get_role ]
89106 types = {
90107 "user" : 0 ,
@@ -126,4 +143,5 @@ async def on_socket_response(self, msg):
126143 selected_cmd = self .commands [to_use ["data" ]["name" ]]
127144 ctx = model .SlashContext (self .req , to_use , self ._discord )
128145 args = self .process_options (ctx .guild , to_use ["data" ]["options" ], selected_cmd [1 ]) if "options" in to_use ["data" ] else []
146+ self .logger .debug (f"Command { to_use ['data' ]['name' ]} invoked." )
129147 await selected_cmd [0 ](ctx , * args )
0 commit comments