@@ -10,12 +10,14 @@ To create an interaction, simply define an asynchronous function and use the `@s
1010Interactions need to be responded to within 3 seconds. To do this, use ` await ctx.send() ` .
1111If your code needs more time, don't worry. You can use ` await ctx.defer() ` to increase the time until you need to respond to the command to 15 minutes.
1212``` python
13+ from interactions import slash_command, SlashContext
14+
1315@slash_command (name = " my_command" , description = " My first command :)" )
14- async def my_command_function (ctx : InteractionContext ):
16+ async def my_command_function (ctx : SlashContext ):
1517 await ctx.send(" Hello World" )
1618
1719@slash_command (name = " my_long_command" , description = " My second command :)" )
18- async def my_long_command_function (ctx : InteractionContext ):
20+ async def my_long_command_function (ctx : SlashContext ):
1921 # need to defer it, otherwise, it fails
2022 await ctx.defer()
2123
@@ -24,7 +26,7 @@ async def my_long_command_function(ctx: InteractionContext):
2426
2527 await ctx.send(" Hello World" )
2628```
27- ??? note
29+ ???+ note
2830 Command names must be lowercase and can only contain ` - ` and ` _ ` as special symbols and must not contain spaces.
2931
3032When testing, it is recommended to use non-global commands, as they sync instantly.
@@ -33,7 +35,7 @@ For that, you can either define `scopes` in every command or set `debug_scope` i
3335You can define non-global commands by passing a list of guild ids to ` scopes ` in the interaction creation.
3436``` python
3537@slash_command (name = " my_command" , description = " My first command :)" , scopes = [870046872864165888 ])
36- async def my_command_function (ctx : InteractionContext ):
38+ async def my_command_function (ctx : SlashContext ):
3739 await ctx.send(" Hello World" )
3840```
3941
@@ -53,16 +55,21 @@ Let's define a basic subcommand:
5355 sub_cmd_name = " command" ,
5456 sub_cmd_description = " My command" ,
5557)
56- async def my_command_function (ctx : InteractionContext ):
58+ async def my_command_function (ctx : SlashContext ):
5759 await ctx.send(" Hello World" )
5860```
5961
60- This will show up in discord as ` /base group command ` . There are two ways to add additional subcommands:
62+ This will show up in discord as ` /base group command ` . There are more ways to add additional subcommands:
6163
6264=== ":one : Decorator"
6365 ```python
64- @my_command_function.subcommand(sub_cmd_name="second_command", sub_cmd_description="My second command")
65- async def my_second_command_function(ctx: InteractionContext):
66+ @my_command_function.subcommand(
67+ group_name="group",
68+ group_description="My command group",
69+ sub_cmd_name="sub",
70+ sub_cmd_description="My subcommand",
71+ )
72+ async def my_second_command_function(ctx: SlashContext):
6673 await ctx.send("Hello World")
6774 ```
6875
@@ -76,12 +83,27 @@ This will show up in discord as `/base group command`. There are two ways to add
7683 sub_cmd_name="second_command",
7784 sub_cmd_description="My second command",
7885 )
79- async def my_second_command_function(ctx: InteractionContext ):
86+ async def my_second_command_function(ctx: SlashContext ):
8087 await ctx.send("Hello World")
8188 ```
8289
8390 **Note:** This is particularly useful if you want to split subcommands into different files.
8491
92+ === ":three : Class Definition"
93+ ```python
94+ base = SlashCommand(name="base", description="My command base")
95+ group = base.group(name="group", description="My command group")
96+
97+ @group.subcommand(sub_cmd_name="second_command", sub_cmd_description="My second command")
98+ async def my_second_command_function(ctx: SlashContext):
99+ await ctx.send("Hello World")
100+ ```
101+
102+ For all of these, the "group" parts are optional, allowing you to do ` /base command ` instead.
103+
104+ ???+ note
105+ You cannot mix group subcommands and non-group subcommands into one base command - you must either use all group subcommands or normal subcommands.
106+
85107
86108## But I Need More Options
87109
@@ -103,14 +125,16 @@ Now that you know all the options you have for options, you can opt into adding
103125
104126You do that by using the ` @slash_option() ` decorator and passing the option name as a function parameter:
105127``` python
128+ from interactions import OptionType
129+
106130@slash_command (name = " my_command" , ... )
107131@slash_option (
108132 name = " integer_option" ,
109133 description = " Integer Option" ,
110134 required = True ,
111135 opt_type = OptionType.INTEGER
112136)
113- async def my_command_function (ctx : InteractionContext , integer_option : int ):
137+ async def my_command_function (ctx : SlashContext , integer_option : int ):
114138 await ctx.send(f " You input { integer_option} " )
115139```
116140
@@ -125,7 +149,7 @@ Always make sure to define all required options first, this is a Discord require
125149 required = False ,
126150 opt_type = OptionType.INTEGER
127151)
128- async def my_command_function (ctx : InteractionContext , integer_option : int = 5 ):
152+ async def my_command_function (ctx : SlashContext , integer_option : int = 5 ):
129153 await ctx.send(f " You input { integer_option} " )
130154```
131155
@@ -143,7 +167,7 @@ If you are using an `OptionType.CHANNEL` option, you can restrict the channel a
143167 opt_type = OptionType.CHANNEL ,
144168 channel_types = [ChannelType.GUILD_TEXT ]
145169)
146- async def my_command_function (ctx : InteractionContext , channel_option : GUILD_TEXT ):
170+ async def my_command_function (ctx : SlashContext , channel_option : GUILD_TEXT ):
147171 await channel_option.send(" This is a text channel in a guild" )
148172
149173 await ctx.send(" ..." )
@@ -160,7 +184,7 @@ You can also set an upper and lower limit for both `OptionType.INTEGER` and `Opt
160184 min_value = 10 ,
161185 max_value = 15
162186)
163- async def my_command_function (ctx : InteractionContext , integer_option : int ):
187+ async def my_command_function (ctx : SlashContext , integer_option : int ):
164188 await ctx.send(f " You input { integer_option} which is always between 10 and 15 " )
165189```
166190
@@ -175,7 +199,7 @@ The same can be done with the length of an option when using `OptionType.STRING`
175199 min_length = 5 ,
176200 max_length = 10
177201)
178- async def my_command_function (ctx : InteractionContext , string_option : str ):
202+ async def my_command_function (ctx : SlashContext , string_option : str ):
179203 await ctx.send(f " You input ` { string_option} ` which is between 5 and 10 characters long " )
180204```
181205
@@ -190,6 +214,8 @@ With choices, the user can no longer freely input whatever they want, instead, t
190214
191215To create a choice, simply fill ` choices ` in ` @slash_option() ` . An option can have up to 25 choices:
192216``` python
217+ from interactions import SlashCommandChoice
218+
193219@slash_command (name = " my_command" , ... )
194220@slash_option (
195221 name = " integer_option" ,
@@ -201,7 +227,7 @@ To create a choice, simply fill `choices` in `@slash_option()`. An option can ha
201227 SlashCommandChoice(name = " Two" , value = 2 )
202228 ]
203229)
204- async def my_command_function (ctx : InteractionContext , integer_option : int ):
230+ async def my_command_function (ctx : SlashContext , integer_option : int ):
205231 await ctx.send(f " You input { integer_option} which is either 1 or 2 " )
206232```
207233
@@ -222,14 +248,16 @@ To use autocomplete options, set `autocomplete=True` in `@slash_option()`:
222248 opt_type = OptionType.STRING ,
223249 autocomplete = True
224250)
225- async def my_command_function (ctx : InteractionContext , string_option : str ):
251+ async def my_command_function (ctx : SlashContext , string_option : str ):
226252 await ctx.send(f " You input { string_option} " )
227253```
228254
229255Then you need to register the autocomplete callback, aka the function Discord calls when users fill in the option.
230256
231257In there, you have three seconds to return whatever choices you want to the user. In this example we will simply return their input with "a", "b" or "c" appended:
232258``` python
259+ from interactions import AutocompleteContext
260+
233261@my_command.autocomplete (" string_option" )
234262async def autocomplete (self , ctx : AutocompleteContext):
235263 # make sure this is done within three seconds
@@ -264,12 +292,14 @@ You are in luck. There are currently four different ways to create interactions,
264292 required=True,
265293 opt_type=OptionType.INTEGER
266294 )
267- async def my_command_function(ctx: InteractionContext , integer_option: int):
295+ async def my_command_function(ctx: SlashContext , integer_option: int):
268296 await ctx.send(f"You input {integer_option}")
269297 ```
270298
271299=== ":two : Single Decorator"
272300 ```python
301+ from interactions import SlashCommandOption
302+
273303 @slash_command(
274304 name="my_command",
275305 description="My first command :)",
@@ -278,24 +308,28 @@ You are in luck. There are currently four different ways to create interactions,
278308 name="integer_option",
279309 description="Integer Option",
280310 required=True,
281- opt_type =OptionType.INTEGER
311+ type =OptionType.INTEGER
282312 )
283313 ]
284314 )
285- async def my_command_function(ctx: InteractionContext , integer_option: int):
315+ async def my_command_function(ctx: SlashContext , integer_option: int):
286316 await ctx.send(f"You input {integer_option}")
287317 ```
288318
289319=== ":three : Function Annotations"
290320 ```python
321+ from interactions import slash_int_option
322+
291323 @slash_command(name="my_command", description="My first command :)")
292- async def my_command_function(ctx: InteractionContext , integer_option: slash_int_option("Integer Option")):
324+ async def my_command_function(ctx: SlashContext , integer_option: slash_int_option("Integer Option")):
293325 await ctx.send(f"You input {integer_option}")
294326 ```
295327
296328=== ":four : Manual Registration"
297329 ```python
298- async def my_command_function(ctx: InteractionContext, integer_option: int):
330+ from interactions import SlashCommandOption
331+
332+ async def my_command_function(ctx: SlashContext, integer_option: int):
299333 await ctx.send(f"You input {integer_option}")
300334
301335 bot.add_interaction(
@@ -307,7 +341,7 @@ You are in luck. There are currently four different ways to create interactions,
307341 name="integer_option",
308342 description="Integer Option",
309343 required=True,
310- opt_type =OptionType.INTEGER
344+ type =OptionType.INTEGER
311345 )
312346 ]
313347 )
@@ -331,20 +365,24 @@ There are two ways to define permissions.
331365
332366=== ":one : Decorators"
333367 ```py
368+ from interactions import Permissions, slash_default_member_permission
369+
334370 @slash_command(name="my_command")
335371 @slash_default_member_permission(Permissions.MANAGE_EVENTS)
336372 @slash_default_member_permission(Permissions.MANAGE_THREADS)
337- async def my_command_function(ctx: InteractionContext ):
373+ async def my_command_function(ctx: SlashContext ):
338374 ...
339375 ```
340376
341377=== ":two : Function Definition"
342378 ```py
379+ from interactions import Permissions
380+
343381 @slash_command(
344382 name="my_command",
345383 default_member_permissions=Permissions.MANAGE_EVENTS | Permissions.MANAGE_THREADS,
346384 )
347- async def my_command_function(ctx: InteractionContext ):
385+ async def my_command_function(ctx: SlashContext ):
348386 ...
349387 ```
350388
@@ -359,7 +397,7 @@ You can also block commands in DMs. To do that, just set `dm_permission` to fals
359397 name = " my_guild_only_command" ,
360398 dm_permission = False ,
361399)
362- async def my_command_function (ctx : InteractionContext ):
400+ async def my_command_function (ctx : SlashContext ):
363401 ...
364402```
365403
@@ -377,40 +415,46 @@ There are a few pre-made checks for you to use, and you can simply create your o
377415 Check that the author is the owner of the bot:
378416
379417 ```py
418+ from interactions import is_owner
419+
380420 @is_owner()
381421 @slash_command(name="my_command")
382- async def my_command_function(ctx: InteractionContext ):
422+ async def my_command_function(ctx: SlashContext ):
383423 ...
384424 ```
385425
386426=== "Custom Check"
387427 Check that the author's name starts with ` a ` :
388428
389429 ```py
430+ from interactions import check
431+
390432 async def my_check(ctx: Context):
391433 return ctx.author.name.startswith("a")
392434
393435 @check(check=my_check)
394436 @slash_command(name="my_command")
395- async def my_command_function(ctx: InteractionContext ):
437+ async def my_command_function(ctx: SlashContext ):
396438 ...
397439 ```
398440
399441=== "Reusing Checks"
400442 You can reuse checks in extensions by adding them to the extension check list
401443
402444 ```py
445+ from interactions import Extension
446+
403447 class MyExtension(Extension):
404448 def __init__(self, bot) -> None:
405449 super().__init__(bot)
406450 self.add_ext_check(is_owner())
407451
408452 @slash_command(name="my_command")
409- async def my_command_function(ctx: InteractionContext ):
453+ async def my_command_function(ctx: SlashContext ):
410454 ...
411455
412456 @slash_command(name="my_command2")
413- async def my_command_function2(ctx: InteractionContext ):
457+ async def my_command_function2(ctx: SlashContext ):
414458 ...
415459
416460 def setup(bot) -> None:
@@ -443,7 +487,7 @@ def my_own_int_option():
443487
444488@slash_command (name = " my_command" , ... )
445489@my_own_int_option ()
446- async def my_command_function (ctx : InteractionContext , integer_option : int ):
490+ async def my_command_function (ctx : SlashContext , integer_option : int ):
447491 await ctx.send(f " You input { integer_option} " )
448492```
449493
@@ -456,6 +500,9 @@ Any error from interactions will trigger `on_command_error`. That includes conte
456500
457501In this example, we are logging the error and responding to the interaction if not done so yet:
458502``` python
503+ from interactions import Client
504+ from interactions.api.events import CommandError
505+
459506class CustomClient (Client ):
460507 @listen (disable_default_listeners = True ) # tell the dispatcher that this replaces the default listener
461508 async def on_command_error (self , event : CommandError):
0 commit comments