Skip to main content

Slash Commands

On March 24, 2021, Discord added Slash Commands to Discord as an easier, more efficient, and better way of using bot commands. Pycord has implemented Slash Commands into the library, so it's simple, efficient, and familiar.

info

Remember that Slash Commands require your bot to be invited with the application.commands scope or Slash Commands will not show up. Bots already in the guild can simply be invited again with the scope; there is no need to kick the bot.

Syntax

Let's create a simple Slash Command.

import discord

bot = discord.Bot()

# we need to limit the guilds for testing purposes
# so other users wouldn't see the command that we're testing

@bot.command(description="Sends the bot's latency.") # this decorator makes a slash command
async def ping(ctx): # a slash command will be created with the name "ping"
await ctx.respond(f"Pong! Latency is {bot.latency}")

bot.run("TOKEN")
BobDotComused /ping
RobocordBot04/21/2024
Pong! Latency is 335ms.

Let's go through the code.

First, we import Pycord's discord package.

Next, we create a discord.Bot object and assign it to a variable bot.

We then go ahead and use the @bot.command decorator, which registers a new Slash Command. We pass a description parameter to give a description to the Slash Command. We can also pass a name parameter to change the Slash Command's name. By default, the name of the Slash Command will be the name of the function, in this case, /ping.

We create an async function called ping with parameters ctx, which, when called, sends the bot's ping/latency using ctx.respond.

Subcommand Groups

You might want to group certain commands together to make them more organised. A command group is exactly what it sounds like, a group of individual Slash Commands together.

In order to make a Slash Command group, you can use the bot.create_group function.

import discord

bot = discord.Bot()

# create Slash Command group with bot.create_group
greetings = bot.create_group("greetings", "Greet people")

@greetings.command()
async def hello(ctx):
await ctx.respond(f"Hello, {ctx.author}!")

@greetings.command()
async def bye(ctx):
await ctx.respond(f"Bye, {ctx.author}!")

bot.run("TOKEN")

Or, you can instead manually make a SlashCommandGroup class like so:

import discord

math = discord.SlashCommandGroup("math", "Math related commands")

@math.command()
async def add(ctx, num1: int, num2: int):
sum = num1 + num2
await ctx.respond(f"{num1} plus {num2} is {sum}.")

@math.command()
async def subtract(ctx, num1: int, num2: int):
sum = num1 - num2
await ctx.respond(f"{num1} minus {num2} is {sum}.")

# you'll have to manually add the manually created Slash Command group
bot.add_application_command(math)

Here's what the registered subcommands will look like in the Slash Command Menu:

Picture of the subcommands in the Slash Command Menu

You'll notice that there's the name of the Slash Command Group and then the name of the subcommand separated by a space.

Sub-groups

We've made a subcommand group, but did you know that you could create a group inside another?

from discord import SlashCommandGroup
from math import sqrt

math = SlashCommandGroup("math", "Math related commands")
advanced = math.create_subgroup("advanced", "Advanced math commands")

@advanced.command()
async def square_root(ctx, x: int):
await ctx.respond(sqrt(x))

bot.add_application_command(math)

The command created above can be invoked by typing /math advanced square_root.

Options & Option Types

Whenever you're using Slash Commands, you might notice that you can specify parameters that the user has to set or can optionally set. These are called Options.

Since you want different inputs from Options, you'll have to specify the type for that Option. There are a few ways of doing this.

You could use Type Annotations and let Pycord figure out the option type, like shown below.

import discord

bot = discord.Bot()

@bot.command()
# pycord will figure out the types for you
async def add(ctx, first: discord.Option(int), second: discord.Option(int)):
# you can use them as they were actual integers
sum = first + second
await ctx.respond(f"The sum of {first} and {second} is {sum}.")

bot.run("TOKEN")
BobDotComused /add
RobocordBot04/21/2024
The sum of 1 and 1 is 2.

Autocomplete

Discord's autocomplete allows developers to determine option choices that are used in a slash command option. You can do this by defining a function:

async def get_animal_types(ctx: discord.AutocompleteContext):
"""
Here we will check if 'ctx.options['animal_type']' is a marine or land animal and return respective option choices
"""
animal_type = ctx.options['animal_type']
if animal_type == 'Marine':
return ['Whale', 'Shark', 'Fish', 'Octopus', 'Turtle']
else: # is land animal
return ['Snake', 'Wolf', 'Lizard', 'Lion', 'Bird']

@bot.slash_command(name="animal")
async def animal_command(
ctx: discord.ApplicationContext,
animal_type: discord.Option(str, choices=['Marine', 'Land']),
animal: discord.Option(str, autocomplete=discord.utils.basic_autocomplete(get_animal_types))
):
await ctx.respond(f'You picked an animal type of `{animal_type}` that led you to pick `{animal}`!')
BobDotComused /animal
RobocordBot04/21/2024
You picked an animal type of Marine that led you to pick Shark!
danger

Autocomplete can only be used with slash commands.