@@ -51,20 +51,26 @@ def add_slash_command(self,
51
51
name : str = None ,
52
52
description : str = None ,
53
53
auto_convert : dict = None ,
54
- guild_ids : list = None ,
54
+ guild_ids : typing . List [ int ] = None ,
55
55
options : list = None ,
56
56
has_subcommands : bool = False ):
57
57
"""
58
58
Registers slash command to SlashCommand.
59
59
60
60
:param cmd: Command Coroutine.
61
+ :type cmd: Coroutine
61
62
:param name: Name of the slash command. Default name of the coroutine.
63
+ :type name: str
62
64
:param description: Description of the slash command. Default ``None``.
65
+ :type description: str
63
66
:param auto_convert: Dictionary of how to convert option values. Default ``None``.
67
+ :type auto_convert: dict
64
68
: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
66
72
:param has_subcommands: Whether it has subcommand. Default ``False``.
67
- :return: ``None``
73
+ :type has_subcommands: bool
68
74
"""
69
75
_cmd = {
70
76
"func" : cmd ,
@@ -84,18 +90,24 @@ def add_subcommand(self,
84
90
name = None ,
85
91
description : str = None ,
86
92
auto_convert : dict = None ,
87
- guild_ids : list = None ):
93
+ guild_ids : typing . List [ int ] = None ):
88
94
"""
89
95
Registers subcommand to SlashCommand.
90
96
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]
99
111
"""
100
112
name = cmd .__name__ if not name else name
101
113
_cmd = {
@@ -118,6 +130,7 @@ def add_subcommand(self,
118
130
self .subcommands [base ][subcommand_group ][name ] = _sub
119
131
else :
120
132
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 } `" )
121
134
122
135
def slash (self ,
123
136
* ,
@@ -200,31 +213,44 @@ def subcommand(self,
200
213
name = None ,
201
214
description : str = None ,
202
215
auto_convert : dict = None ,
203
- guild_ids : int = None ):
216
+ guild_ids : typing . List [ int ] = None ):
204
217
"""
205
218
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.
208
220
209
221
Example:
210
222
211
223
.. code-block:: python
212
224
225
+ # /group say <str>
213
226
@slash.subcommand(base="group", name="say")
214
227
async def _group_say(ctx, _str):
215
228
await ctx.send(content=_str)
216
229
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
+
217
238
.. note::
218
239
Unlike normal slash command, this doesn't support ``options`` arg, since it will be very complicated.\n
219
240
Also, subcommands won't be automatically registered to Discord API even if you set ``auto_register`` to ``True``.
220
241
221
242
:param base: Name of the base command.
243
+ :type base: str
222
244
:param subcommand_group: Name of the subcommand group, if any. Default ``None`` which represents there is no sub group.
245
+ :type subcommand_group: str
223
246
:param name: Name of the subcommand. Default name of the coroutine.
247
+ :type name: str
224
248
:param description: Description of the subcommand. Default ``None``.
249
+ :type description: str
225
250
:param auto_convert: Dictionary of how to convert option values. Default ``None``.
251
+ :type auto_convert: dict
226
252
: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]
228
254
"""
229
255
230
256
def wrapper (cmd ):
@@ -315,15 +341,31 @@ async def on_socket_response(self, msg):
315
341
return await self .handle_subcommand (ctx , to_use )
316
342
args = await self .process_options (ctx .guild , to_use ["data" ]["options" ], selected_cmd ["auto_convert" ]) \
317
343
if "options" in to_use ["data" ] else []
318
- self .logger .debug (f"Command { to_use ['data' ]['name' ]} invoked." )
319
344
await selected_cmd ["func" ](ctx , * args )
320
345
321
346
async def handle_subcommand (self , ctx : model .SlashContext , data : dict ):
322
347
"""
323
348
Coroutine for handling subcommand.
324
- Not implemented.
325
349
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.
328
355
"""
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