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(debug_guilds=[...]) # specify the guild IDs in debug_guilds

# 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
RobocordBot09/27/2022
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. Notice how we pass the parameter debug_guilds. Global Slash Commands take up to an hour to register, however, if we limit our bot commands to a few specific guilds, we can use them instantly on those guilds. This is useful for testing purposes. Once you have polished up your command and made it all shiny, you can share its shininess with all of the bot's servers by removing this parameter.

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(debug_guilds=[...]) # specify the guild IDs in debug_guilds

# 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:

math = 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
RobocordBot09/27/2022
The sum of 1 and 1 is 2.