@@ -51,20 +51,26 @@ def add_slash_command(self,
5151 name : str = None ,
5252 description : str = None ,
5353 auto_convert : dict = None ,
54- guild_ids : list = None ,
54+ guild_ids : typing . List [ int ] = None ,
5555 options : list = None ,
5656 has_subcommands : bool = False ):
5757 """
5858 Registers slash command to SlashCommand.
5959
6060 :param cmd: Command Coroutine.
61+ :type cmd: Coroutine
6162 :param name: Name of the slash command. Default name of the coroutine.
63+ :type name: str
6264 :param description: Description of the slash command. Default ``None``.
65+ :type description: str
6366 :param auto_convert: Dictionary of how to convert option values. Default ``None``.
67+ :type auto_convert: dict
6468 :param guild_ids: List of Guild ID of where the command will be used. Default ``None``, which will be global command.
65- :param options: Options of the slash command. This will affect ``auto_convert`` and command data at Discord API. Default ``None``.
69+ :type guild_ids: List[int]
70+ :param options: Options of the slash command.
71+ :type options: list
6672 :param has_subcommands: Whether it has subcommand. Default ``False``.
67- :return: ``None``
73+ :type has_subcommands: bool
6874 """
6975 _cmd = {
7076 "func" : cmd ,
@@ -84,18 +90,24 @@ def add_subcommand(self,
8490 name = None ,
8591 description : str = None ,
8692 auto_convert : dict = None ,
87- guild_ids : list = None ):
93+ guild_ids : typing . List [ int ] = None ):
8894 """
8995 Registers subcommand to SlashCommand.
9096
91- :param cmd:
92- :param base:
93- :param subcommand_group:
94- :param name:
95- :param description:
96- :param auto_convert:
97- :param guild_ids:
98- :return:
97+ :param cmd: Subcommand Coroutine.
98+ :type cmd: Coroutine
99+ :param base: Name of the base command.
100+ :type base: str
101+ :param subcommand_group: Name of the subcommand group, if any. Default ``None`` which represents there is no sub group.
102+ :type subcommand_group: str
103+ :param name: Name of the subcommand. Default name of the coroutine.
104+ :type name: str
105+ :param description: Description of the subcommand. Default ``None``.
106+ :type description: str
107+ :param auto_convert: Dictionary of how to convert option values. Default ``None``.
108+ :type auto_convert: dict
109+ :param guild_ids: List of guild ID of where the command will be used. Default ``None``, which will be global command.
110+ :type guild_ids: List[int]
99111 """
100112 name = cmd .__name__ if not name else name
101113 _cmd = {
@@ -118,6 +130,7 @@ def add_subcommand(self,
118130 self .subcommands [base ][subcommand_group ][name ] = _sub
119131 else :
120132 self .subcommands [base ][name ] = _sub
133+ self .logger .debug (f"Added subcommand `{ base } { subcommand_group if subcommand_group else '' } { cmd .__name__ if not name else name } `" )
121134
122135 def slash (self ,
123136 * ,
@@ -200,31 +213,44 @@ def subcommand(self,
200213 name = None ,
201214 description : str = None ,
202215 auto_convert : dict = None ,
203- guild_ids : int = None ):
216+ guild_ids : typing . List [ int ] = None ):
204217 """
205218 Decorator that registers subcommand.\n
206- Unlike discord.py, you don't need base command.\n
207- Not implemented.
219+ Unlike discord.py, you don't need base command.
208220
209221 Example:
210222
211223 .. code-block:: python
212224
225+ # /group say <str>
213226 @slash.subcommand(base="group", name="say")
214227 async def _group_say(ctx, _str):
215228 await ctx.send(content=_str)
216229
230+ # /group kick user <user>
231+ @slash.subcommand(base="group",
232+ subcommand_group="kick",
233+ name="user",
234+ auto_convert={"user": "user"})
235+ async def _group_kick_user(ctx, user):
236+ ...
237+
217238 .. note::
218239 Unlike normal slash command, this doesn't support ``options`` arg, since it will be very complicated.\n
219240 Also, subcommands won't be automatically registered to Discord API even if you set ``auto_register`` to ``True``.
220241
221242 :param base: Name of the base command.
243+ :type base: str
222244 :param subcommand_group: Name of the subcommand group, if any. Default ``None`` which represents there is no sub group.
245+ :type subcommand_group: str
223246 :param name: Name of the subcommand. Default name of the coroutine.
247+ :type name: str
224248 :param description: Description of the subcommand. Default ``None``.
249+ :type description: str
225250 :param auto_convert: Dictionary of how to convert option values. Default ``None``.
251+ :type auto_convert: dict
226252 :param guild_ids: List of guild ID of where the command will be used. Default ``None``, which will be global command.
227- :return:
253+ :type guild_ids: List[int]
228254 """
229255
230256 def wrapper (cmd ):
@@ -315,15 +341,31 @@ async def on_socket_response(self, msg):
315341 return await self .handle_subcommand (ctx , to_use )
316342 args = await self .process_options (ctx .guild , to_use ["data" ]["options" ], selected_cmd ["auto_convert" ]) \
317343 if "options" in to_use ["data" ] else []
318- self .logger .debug (f"Command { to_use ['data' ]['name' ]} invoked." )
319344 await selected_cmd ["func" ](ctx , * args )
320345
321346 async def handle_subcommand (self , ctx : model .SlashContext , data : dict ):
322347 """
323348 Coroutine for handling subcommand.
324- Not implemented.
325349
326- :param ctx:
327- :param data:
350+ .. warning::
351+ Do not manually call this.
352+
353+ :param ctx: :class:`.model.SlashContext` instance.
354+ :param data: Gateway message.
328355 """
329- pass
356+ base = self .subcommands [data ["data" ]["name" ]]
357+ sub = data ["data" ]["options" ][0 ]
358+ sub_name = sub ["name" ]
359+ sub_opts = sub ["options" ] if "options" in sub else []
360+ for x in sub_opts :
361+ if "options" in x .keys ():
362+ sub_group = x ["name" ]
363+ selected = base [sub_name ][sub_group ]
364+ args = await self .process_options (ctx .guild , x ["options" ], selected ["auto_convert" ]) \
365+ if "options" in x .keys () else []
366+ await selected ["func" ](ctx , * args )
367+ return
368+ selected = base [sub_name ]
369+ args = await self .process_options (ctx .guild , sub_opts , selected ["auto_convert" ]) \
370+ if sub ["options" ] else []
371+ await selected ["func" ](ctx , * args )
0 commit comments