Slash Commands Tutorial for Discord.JS v13 - #4

discord.js v13 Sep 03, 2021

Slash commands are a new feature in Discord that helps organize and manage commands. In this article we you will learn everything about slash commands using Discord JS v13. This includes how to create/delete them as well as how to handle responses.

If you want to check out other Discord.JS tutorials check out our articles and YouTube videos.

The corresponding YouTube video for this blog post can be found here.

Prerequisites:

  • A Discord bot which we cover how to make here.
  • An understanding of JavaScript basics.
    • If you are new to JavaScript then check out my complete JavaScript course. The first hour is on YouTube for free here.

Need help?

If you have any questions you can ask in our Discord community. Be sure to read the "how-to-ask-for-help" channel near the top of the server.


Table of Contents

  1. Registering Slash Commands
  2. Responding to Slash Commands
  3. Deferring Replies
  4. A Better way to use Slash Commands
  5. Complete Source Code

Step 1) Registering Slash Commands

As mentioned in the prerequisites it is assumed that you already have a Discord bot. If you don't then you can learn how to make one here.

Before we register a slash command it is important to know of global and guild based slash commands. When developing you should always use guild based slash commands as they will register instantly. Global slash commands may take up to an hour to register on all servers your bot is in.

First get your test server's guild ID and store it in a variable like so:

const guildId = '879296318395277352' // Use your guild ID instead
const guild = client.guilds.cache.get(guildId)

Now we can access the command manager for either that specific guild or for our application. Our application's command handler is used to register global commands.

let commands
if (guild) {
  commands = guild.commands
else {
  commands = client.application?.commands
}
Now that we have our command manager we can register a simple "add" command which will add two numbers and reply with the sum:

commands?.create({
  name: 'add',
  description: 'Adds two numbers',
  options: [
    {
      name: 'number1',
      description: 'The first number.',
      required: true,
      type: DiscordJS.Constants.ApplicationCommandOptionTypes.NUMBER,
    },
    {
      name: 'number2',
      description: 'The second number.',
      required: true,
      type: DiscordJS.Constants.ApplicationCommandOptionTypes.NUMBER,
    },
  ],
})
After restarting our bot we should see "/add" in our test guild like so:
 
Because we specified "INTEGER" as the type we can only provide whole numbers. Entering anything else like a string will not allow the command to run. If we do provide two integers then it will say "This interaction failed":
 
This is because we are not yet listening for when a new interaction is created.

Step 2) Responding to Slash Commands

Now that we have a slash command created, we need to listen for when it is ran. We can do this with the interactionCreate event on our client object like so:

// Listen for when interactions are created
client.on('interactionCreate', (interactionInteraction=> {
  // There are multiple types of interactions
  // Make sure this is a command
  if (!interaction.isCommand()) {
    return
  }
  // Access the name of the command and the given arguments
  const { commandNameoptions } = interaction
  // Perform the addition if the user is running the "add" command
  if (commandName === 'add') {
    const num1 = options.getInteger('number1') || 0
    const num2 = options.getInteger('number2') || 0
    const sum = `The sum is ${num1 + num2}`
    interaction.reply({
      content: sum,
      ephemeral: true // Only the user can see this reply
    })
  }
})
Now we can use the "/add" command and it will reply with the correct sum.

Step 3) Deferring Replies

Slash commands must have a reply within 3 seconds by default, otherwise they will fail like we saw at the start of this tutorial. In some use cases you may need more than 3 seconds to fetch relevant information to reply with. This is where deferring replies comes in. When we defer a reply we now have up to 15 minutes to reply to the interaction. Here is an example:

 Note: Your interactionCreate callback must be asynchronous.

await interaction.deferReply({
  ephemeral: true// Only the user can see the reply
})
// Wait 7 seconds for dramatic effect
await new Promise((resolve=> setTimeout(resolve1000 * 7))
// Use editReply() to display the sum
const sum = `The sum is ${num1 + num2}`
interaction.editReply({
  content: sum,
})

Keep in mind that ephemeral is now sent in the deferReply() call and not when we are sending the content.


Step 4) A Better way to use Slash Commands

In the next article and video tutorial I will show you a much easier way to use Slash Commands using WOKCommands which is a command handler I wrote for Discord bots.


Complete Source Code

Save time by accessing all of our Discord.JS tutorial source code by becoming a YouTube member for as little as $2.99. Learn about all of the perks we offer here.

Already a member? Download the source code here.

Close

50% Complete

Two Step

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.