@@ -10,12 +10,14 @@ To create an interaction, simply define an asynchronous function and use the `@s
10
10
Interactions need to be responded to within 3 seconds. To do this, use ` await ctx.send() ` .
11
11
If 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.
12
12
``` python
13
+ from interactions import slash_command, SlashContext
14
+
13
15
@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 ):
15
17
await ctx.send(" Hello World" )
16
18
17
19
@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 ):
19
21
# need to defer it, otherwise, it fails
20
22
await ctx.defer()
21
23
@@ -24,7 +26,7 @@ async def my_long_command_function(ctx: InteractionContext):
24
26
25
27
await ctx.send(" Hello World" )
26
28
```
27
- ??? note
29
+ ???+ note
28
30
Command names must be lowercase and can only contain ` - ` and ` _ ` as special symbols and must not contain spaces.
29
31
30
32
When 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
33
35
You can define non-global commands by passing a list of guild ids to ` scopes ` in the interaction creation.
34
36
``` python
35
37
@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 ):
37
39
await ctx.send(" Hello World" )
38
40
```
39
41
@@ -53,16 +55,21 @@ Let's define a basic subcommand:
53
55
sub_cmd_name = " command" ,
54
56
sub_cmd_description = " My command" ,
55
57
)
56
- async def my_command_function (ctx : InteractionContext ):
58
+ async def my_command_function (ctx : SlashContext ):
57
59
await ctx.send(" Hello World" )
58
60
```
59
61
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:
61
63
62
64
=== ":one : Decorator"
63
65
```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):
66
73
await ctx.send("Hello World")
67
74
```
68
75
@@ -76,12 +83,27 @@ This will show up in discord as `/base group command`. There are two ways to add
76
83
sub_cmd_name="second_command",
77
84
sub_cmd_description="My second command",
78
85
)
79
- async def my_second_command_function(ctx: InteractionContext ):
86
+ async def my_second_command_function(ctx: SlashContext ):
80
87
await ctx.send("Hello World")
81
88
```
82
89
83
90
**Note:** This is particularly useful if you want to split subcommands into different files.
84
91
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
+
85
107
86
108
## But I Need More Options
87
109
@@ -103,14 +125,16 @@ Now that you know all the options you have for options, you can opt into adding
103
125
104
126
You do that by using the ` @slash_option() ` decorator and passing the option name as a function parameter:
105
127
``` python
128
+ from interactions import OptionType
129
+
106
130
@slash_command (name = " my_command" , ... )
107
131
@slash_option (
108
132
name = " integer_option" ,
109
133
description = " Integer Option" ,
110
134
required = True ,
111
135
opt_type = OptionType.INTEGER
112
136
)
113
- async def my_command_function (ctx : InteractionContext , integer_option : int ):
137
+ async def my_command_function (ctx : SlashContext , integer_option : int ):
114
138
await ctx.send(f " You input { integer_option} " )
115
139
```
116
140
@@ -125,7 +149,7 @@ Always make sure to define all required options first, this is a Discord require
125
149
required = False ,
126
150
opt_type = OptionType.INTEGER
127
151
)
128
- async def my_command_function (ctx : InteractionContext , integer_option : int = 5 ):
152
+ async def my_command_function (ctx : SlashContext , integer_option : int = 5 ):
129
153
await ctx.send(f " You input { integer_option} " )
130
154
```
131
155
@@ -143,7 +167,7 @@ If you are using an `OptionType.CHANNEL` option, you can restrict the channel a
143
167
opt_type = OptionType.CHANNEL ,
144
168
channel_types = [ChannelType.GUILD_TEXT ]
145
169
)
146
- async def my_command_function (ctx : InteractionContext , channel_option : GUILD_TEXT ):
170
+ async def my_command_function (ctx : SlashContext , channel_option : GUILD_TEXT ):
147
171
await channel_option.send(" This is a text channel in a guild" )
148
172
149
173
await ctx.send(" ..." )
@@ -160,7 +184,7 @@ You can also set an upper and lower limit for both `OptionType.INTEGER` and `Opt
160
184
min_value = 10 ,
161
185
max_value = 15
162
186
)
163
- async def my_command_function (ctx : InteractionContext , integer_option : int ):
187
+ async def my_command_function (ctx : SlashContext , integer_option : int ):
164
188
await ctx.send(f " You input { integer_option} which is always between 10 and 15 " )
165
189
```
166
190
@@ -175,7 +199,7 @@ The same can be done with the length of an option when using `OptionType.STRING`
175
199
min_length = 5 ,
176
200
max_length = 10
177
201
)
178
- async def my_command_function (ctx : InteractionContext , string_option : str ):
202
+ async def my_command_function (ctx : SlashContext , string_option : str ):
179
203
await ctx.send(f " You input ` { string_option} ` which is between 5 and 10 characters long " )
180
204
```
181
205
@@ -190,6 +214,8 @@ With choices, the user can no longer freely input whatever they want, instead, t
190
214
191
215
To create a choice, simply fill ` choices ` in ` @slash_option() ` . An option can have up to 25 choices:
192
216
``` python
217
+ from interactions import SlashCommandChoice
218
+
193
219
@slash_command (name = " my_command" , ... )
194
220
@slash_option (
195
221
name = " integer_option" ,
@@ -201,7 +227,7 @@ To create a choice, simply fill `choices` in `@slash_option()`. An option can ha
201
227
SlashCommandChoice(name = " Two" , value = 2 )
202
228
]
203
229
)
204
- async def my_command_function (ctx : InteractionContext , integer_option : int ):
230
+ async def my_command_function (ctx : SlashContext , integer_option : int ):
205
231
await ctx.send(f " You input { integer_option} which is either 1 or 2 " )
206
232
```
207
233
@@ -222,14 +248,16 @@ To use autocomplete options, set `autocomplete=True` in `@slash_option()`:
222
248
opt_type = OptionType.STRING ,
223
249
autocomplete = True
224
250
)
225
- async def my_command_function (ctx : InteractionContext , string_option : str ):
251
+ async def my_command_function (ctx : SlashContext , string_option : str ):
226
252
await ctx.send(f " You input { string_option} " )
227
253
```
228
254
229
255
Then you need to register the autocomplete callback, aka the function Discord calls when users fill in the option.
230
256
231
257
In 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:
232
258
``` python
259
+ from interactions import AutocompleteContext
260
+
233
261
@my_command.autocomplete (" string_option" )
234
262
async def autocomplete (self , ctx : AutocompleteContext):
235
263
# 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,
264
292
required=True,
265
293
opt_type=OptionType.INTEGER
266
294
)
267
- async def my_command_function(ctx: InteractionContext , integer_option: int):
295
+ async def my_command_function(ctx: SlashContext , integer_option: int):
268
296
await ctx.send(f"You input {integer_option}")
269
297
```
270
298
271
299
=== ":two : Single Decorator"
272
300
```python
301
+ from interactions import SlashCommandOption
302
+
273
303
@slash_command(
274
304
name="my_command",
275
305
description="My first command :)",
@@ -278,24 +308,28 @@ You are in luck. There are currently four different ways to create interactions,
278
308
name="integer_option",
279
309
description="Integer Option",
280
310
required=True,
281
- opt_type =OptionType.INTEGER
311
+ type =OptionType.INTEGER
282
312
)
283
313
]
284
314
)
285
- async def my_command_function(ctx: InteractionContext , integer_option: int):
315
+ async def my_command_function(ctx: SlashContext , integer_option: int):
286
316
await ctx.send(f"You input {integer_option}")
287
317
```
288
318
289
319
=== ":three : Function Annotations"
290
320
```python
321
+ from interactions import slash_int_option
322
+
291
323
@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")):
293
325
await ctx.send(f"You input {integer_option}")
294
326
```
295
327
296
328
=== ":four : Manual Registration"
297
329
```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):
299
333
await ctx.send(f"You input {integer_option}")
300
334
301
335
bot.add_interaction(
@@ -307,7 +341,7 @@ You are in luck. There are currently four different ways to create interactions,
307
341
name="integer_option",
308
342
description="Integer Option",
309
343
required=True,
310
- opt_type =OptionType.INTEGER
344
+ type =OptionType.INTEGER
311
345
)
312
346
]
313
347
)
@@ -331,20 +365,24 @@ There are two ways to define permissions.
331
365
332
366
=== ":one : Decorators"
333
367
```py
368
+ from interactions import Permissions, slash_default_member_permission
369
+
334
370
@slash_command(name="my_command")
335
371
@slash_default_member_permission(Permissions.MANAGE_EVENTS)
336
372
@slash_default_member_permission(Permissions.MANAGE_THREADS)
337
- async def my_command_function(ctx: InteractionContext ):
373
+ async def my_command_function(ctx: SlashContext ):
338
374
...
339
375
```
340
376
341
377
=== ":two : Function Definition"
342
378
```py
379
+ from interactions import Permissions
380
+
343
381
@slash_command(
344
382
name="my_command",
345
383
default_member_permissions=Permissions.MANAGE_EVENTS | Permissions.MANAGE_THREADS,
346
384
)
347
- async def my_command_function(ctx: InteractionContext ):
385
+ async def my_command_function(ctx: SlashContext ):
348
386
...
349
387
```
350
388
@@ -359,7 +397,7 @@ You can also block commands in DMs. To do that, just set `dm_permission` to fals
359
397
name = " my_guild_only_command" ,
360
398
dm_permission = False ,
361
399
)
362
- async def my_command_function (ctx : InteractionContext ):
400
+ async def my_command_function (ctx : SlashContext ):
363
401
...
364
402
```
365
403
@@ -377,40 +415,46 @@ There are a few pre-made checks for you to use, and you can simply create your o
377
415
Check that the author is the owner of the bot:
378
416
379
417
```py
418
+ from interactions import is_owner
419
+
380
420
@is_owner()
381
421
@slash_command(name="my_command")
382
- async def my_command_function(ctx: InteractionContext ):
422
+ async def my_command_function(ctx: SlashContext ):
383
423
...
384
424
```
385
425
386
426
=== "Custom Check"
387
427
Check that the author's name starts with ` a ` :
388
428
389
429
```py
430
+ from interactions import check
431
+
390
432
async def my_check(ctx: Context):
391
433
return ctx.author.name.startswith("a")
392
434
393
435
@check(check=my_check)
394
436
@slash_command(name="my_command")
395
- async def my_command_function(ctx: InteractionContext ):
437
+ async def my_command_function(ctx: SlashContext ):
396
438
...
397
439
```
398
440
399
441
=== "Reusing Checks"
400
442
You can reuse checks in extensions by adding them to the extension check list
401
443
402
444
```py
445
+ from interactions import Extension
446
+
403
447
class MyExtension(Extension):
404
448
def __init__(self, bot) -> None:
405
449
super().__init__(bot)
406
450
self.add_ext_check(is_owner())
407
451
408
452
@slash_command(name="my_command")
409
- async def my_command_function(ctx: InteractionContext ):
453
+ async def my_command_function(ctx: SlashContext ):
410
454
...
411
455
412
456
@slash_command(name="my_command2")
413
- async def my_command_function2(ctx: InteractionContext ):
457
+ async def my_command_function2(ctx: SlashContext ):
414
458
...
415
459
416
460
def setup(bot) -> None:
@@ -443,7 +487,7 @@ def my_own_int_option():
443
487
444
488
@slash_command (name = " my_command" , ... )
445
489
@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 ):
447
491
await ctx.send(f " You input { integer_option} " )
448
492
```
449
493
@@ -456,6 +500,9 @@ Any error from interactions will trigger `on_command_error`. That includes conte
456
500
457
501
In this example, we are logging the error and responding to the interaction if not done so yet:
458
502
``` python
503
+ from interactions import Client
504
+ from interactions.api.events import CommandError
505
+
459
506
class CustomClient (Client ):
460
507
@listen (disable_default_listeners = True ) # tell the dispatcher that this replaces the default listener
461
508
async def on_command_error (self , event : CommandError):
0 commit comments