Creating Application Commands
Application Commands is the first entrypoint to Discord's interactions. This tutorial will walk through creating commands which make simple responses.
The code in this tutorial should be placed where the ...
is in the code
copied from Getting set up: between defining app =
and
calling uvicorn.run()
.
Starting with commands
To get a feel for how commands are defined, you can start by recreating
Discord's native /shrug
command. This command takes no options and responds
with the text '¯\_(ツ)_/¯'
.
Start by defining an asynchronous shrug()
function decorated by
@app.command()
. The function should take one argument being the interaction,
which contains contextual information about how it was called:
@app.command()
async def shrug(interaction: CommandInteraction) -> None:
...
Next, give the function a docstring. The library reads the docstring's first line as the description for the command:
@app.command()
async def shrug(interaction: CommandInteraction) -> None:
"""Responds with shrugging ASCII art."""
...
This is all the boilerplate necessary to define the command. Now, respond to
the interaction by awaiting interaction.respond()
with the shrugging
ASCII art as the first positional argument:
@app.command()
async def shrug(interaction: CommandInteraction) -> None:
"""Responds with shrugging ASCII art."""
await interaction.respond('¯\_(ツ)_/¯')
Save the file and restart the server. After a short while of waiting, Discord
will have updated and you should be able to invoke the command with /shrug
.
Defining subcommands
This tutorial will introduce many more commands. To organize all commands,
create a group to contain them all. Compared to commands which are created with
a decorator, groups are created by calling .group()
with the name and
description of the group.
Create a group called text
and change @app.command()
to @text.command()
so that the command gets registered under the group. The new name for the
command is now /text shrug
:
text = app.group('text', 'Group of text manipulation commands')
# Note that it says 'text' and not 'app', otherwise it'd
# just register a normal command
@text.command()
async def shrug(interaction: CommandInteraction) -> None:
"""Responds with shrugging ASCII art."""
await interaction.respond('¯\_(ツ)_/¯')
This is all it takes to create a subcommand! Try invoking the command again,
but this time with /text shrug
.
Nested subcommads
Discord also allows nesting one level deeper - making subcommand groups.
In preparation for another command which responds with ASCII art, create an
art
subcommand group and move the shrug
command below it:
text = app.group('text', 'Group of text manipulation commands')
art = text.group('art', 'Group of commands for ASCII art')
@art.command()
async def shrug(interaction: CommandInteraction) -> None:
"""Responds with shrugging ASCII art."""
await interaction.respond('¯\_(ツ)_/¯')
Now that you have the subcommand group ready, create another subcommand called
tableflip
which replicates the equivalent native /tableflip
command and
responds with '(╯°□°)╯︵ ┻━┻'
:
text = app.group('text', 'Group of text manipulation commands')
art = text.group('art', 'Group of commands for ASCII art')
@art.command()
async def shrug(interaction: CommandInteraction) -> None:
"""Responds with shrugging ASCII art."""
await interaction.respond('¯\_(ツ)_/¯')
@art.command()
async def tableflip(interaction: CommandInteraction) -> None:
"""Responds with a tableflip ASGII art."""
await interaction.respond('(╯°□°)╯︵ ┻━┻')
With the above code, you have now created two subcommands:
/text art shrug
and /text art tableflip
.
If you want to read an in-depth explanation of defining commands and nesting subcommands, see Anatomy of a command, otherwise continue with the tutorial to learn more about command options.