@@ -43,7 +43,7 @@ def add_slash_command(self,
43
43
auto_convert : dict = None ,
44
44
guild_id : int = None ,
45
45
options : list = None ,
46
- subcommand : dict = None ):
46
+ has_subcommands : bool = False ):
47
47
"""
48
48
Registers slash command to SlashCommand.
49
49
@@ -53,7 +53,7 @@ def add_slash_command(self,
53
53
:param auto_convert: Dictionary of how to convert option values. Default ``None``.
54
54
:param guild_id: Guild ID of where the command will be used. Default ``None``, which will be global command.
55
55
:param options: Options of the slash command. This will affect ``auto_convert`` and command data at Discord API. Default ``None``.
56
- :param subcommand: Subcommand if any .
56
+ :param has_subcommands: Whether it has subcommand. Default ``False`` .
57
57
:return: ``None``
58
58
"""
59
59
_cmd = {
@@ -62,11 +62,14 @@ def add_slash_command(self,
62
62
"auto_convert" : auto_convert ,
63
63
"guild_id" : guild_id ,
64
64
"api_options" : options ,
65
- "subcommands " : subcommand
65
+ "has_subcommands " : has_subcommands
66
66
}
67
67
self .commands [cmd .__name__ if not name else name ] = _cmd
68
68
self .logger .debug (f"Added command `{ cmd .__name__ if not name else name } `" )
69
69
70
+ def add_subcommand (self ,):
71
+ pass
72
+
70
73
def slash (self ,
71
74
* ,
72
75
name : str = None ,
@@ -128,6 +131,41 @@ def wrapper(cmd):
128
131
return cmd
129
132
return wrapper
130
133
134
+ def subcommand (self ,
135
+ * ,
136
+ base ,
137
+ subcommand_group = None ,
138
+ name = None ,
139
+ description : str = None ,
140
+ auto_convert : dict = None ,
141
+ guild_id : int = None ):
142
+ """
143
+ Decorator that registers subcommand.
144
+ Unlike discord.py, you don't need base command.
145
+
146
+ Example:
147
+
148
+ .. code-block:: python
149
+ @slash.subcommand(base="group", name="say")
150
+ async def _group_say(ctx, _str):
151
+ await ctx.send(content=_str)
152
+
153
+ .. note::
154
+ Unlike normal slash command, this doesn't support ``options`` arg, since it will be very complicated.\n
155
+ Also, subcommands won't be automatically registered to Discord API even if you set ``auto_register`` to ``True``.
156
+
157
+ :param base: Name of the base command.
158
+ :param subcommand_group: Name of the subcommand group, if any. Default ``None`` which represents there is no sub group.
159
+ :param name: Name of the subcommand. Default name of the coroutine.
160
+ :param description: Description of the subcommand. Default ``None``.
161
+ :param auto_convert: Dictionary of how to convert option values. Default ``None``.
162
+ :param guild_id: Guild ID of where the command will be used. Default ``None``, which will be global command.
163
+ :return:
164
+ """
165
+ def wrapper (cmd ):
166
+ return cmd
167
+ return wrapper
168
+
131
169
def process_options (self , guild : discord .Guild , options : list , auto_convert : dict ) -> list :
132
170
"""
133
171
Processes Role, User, and Channel option types to discord.py's models.
@@ -182,13 +220,25 @@ async def on_socket_response(self, msg):
182
220
if msg ["t" ] != "INTERACTION_CREATE" :
183
221
return
184
222
to_use = msg ["d" ]
223
+ print (to_use )
185
224
if to_use ["data" ]["name" ] in self .commands .keys ():
186
225
selected_cmd = self .commands [to_use ["data" ]["name" ]]
187
226
ctx = model .SlashContext (self .req , to_use , self ._discord )
188
227
if selected_cmd ["guild_id" ]:
189
228
if selected_cmd ["guild_id" ] != ctx .guild .id :
190
229
return
230
+ if selected_cmd ["has_subcommands" ]:
231
+ return await self .handle_subcommand (to_use )
191
232
args = self .process_options (ctx .guild , to_use ["data" ]["options" ], selected_cmd ["auto_convert" ]) \
192
233
if "options" in to_use ["data" ] else []
193
234
self .logger .debug (f"Command { to_use ['data' ]['name' ]} invoked." )
194
235
await selected_cmd ["func" ](ctx , * args )
236
+
237
+ async def handle_subcommand (self , data : dict ):
238
+ """
239
+ Coroutine for handling subcommand.
240
+
241
+ :param data:
242
+ :return:
243
+ """
244
+ pass
0 commit comments