mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-11 17:13:31 +01:00
245 lines
9.1 KiB
Plaintext
245 lines
9.1 KiB
Plaintext
---
|
||
title: Creating commands
|
||
category: Creating your bot
|
||
---
|
||
|
||
# Creating commands
|
||
|
||
<Alert title="Tip" type="success">
|
||
This page is a follow-up and bases its code on [the previous page](/creating-your-bot/).
|
||
</Alert>
|
||
|
||
<DiscordMessages rounded>
|
||
<DiscordMessage
|
||
interaction={{
|
||
author: {
|
||
avatar:
|
||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||
username: 'Crawl',
|
||
},
|
||
command: 'ping',
|
||
}}
|
||
author={{
|
||
avatar:
|
||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||
username: 'Crawl',
|
||
time: 'Today at 21:00',
|
||
}}
|
||
>
|
||
Pong!
|
||
</DiscordMessage>
|
||
</DiscordMessages>
|
||
|
||
Discord allows developers to register [slash commands](https://discord.com/developers/docs/interactions/application-commands), which provide users a first-class way of interacting directly with your application. Before being able to reply to a command, you must first register it.
|
||
|
||
## Registering commands
|
||
|
||
This section will cover only the bare minimum to get you started, but you can refer to our [in-depth page on registering slash commands](/interactions/slash-commands.md#registering-slash-commands) for further details. It covers guild commands, global commands, options, option types, and choices.
|
||
|
||
### Command deployment script
|
||
|
||
Create a _`deploy-commands.js`_ file in your project directory. This file will be used to register and update the slash commands for your bot application.
|
||
|
||
Since commands only need to be registered once, and updated when the definition (description, options etc) is changed, it's not necessary to connect a whole client to the gateway or do this on every _`ready`_ event. As such, a standalone script using the lighter REST manager is preferred.
|
||
|
||
Below is a deployment script you can use. Focus on these variables:
|
||
|
||
- _`clientId`_: Your application's client id
|
||
- _`guildId`_: Your development server's id
|
||
- _`commands`_: An array of commands to register. The [slash command builder](/popular-topics/builders.md#slash-command-builders) from _`discord.js`_ is used to build the data for your commands
|
||
|
||
<Alert title="Tip" type="success">
|
||
In order to get your application's client id, go to [Discord Developer
|
||
Portal](https://discord.com/developers/applications) and choose your application. Find the id under "Application ID"
|
||
in General Information subpage. To get guild id, open Discord and go to your settings. On the "Advanced" page, turn on
|
||
"Developer Mode". This will enable a "Copy ID" button in the context menu when you right-click on a server icon, a
|
||
user's profile, etc.
|
||
</Alert>
|
||
|
||
<CH.Code>
|
||
|
||
```js deploy-commands.js mark=4,6:10
|
||
const { REST, SlashCommandBuilder, Routes } = require('discord.js');
|
||
const { clientId, guildId, token } = require('./config.json');
|
||
|
||
const commands = [
|
||
new SlashCommandBuilder().setName('ping').setDescription('Replies with pong!'),
|
||
new SlashCommandBuilder().setName('server').setDescription('Replies with server info!'),
|
||
new SlashCommandBuilder().setName('user').setDescription('Replies with user info!'),
|
||
].map((command) => command.toJSON());
|
||
|
||
const rest = new REST({ version: '10' }).setToken(token);
|
||
|
||
rest
|
||
.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands })
|
||
.then((data) => console.log(`Successfully registered ${data.length} application commands.`))
|
||
.catch(console.error);
|
||
```
|
||
|
||
---
|
||
|
||
```json config.json mark=2:3
|
||
{
|
||
"clientId": "123456789012345678",
|
||
"guildId": "876543210987654321",
|
||
"token": "your-token-goes-here"
|
||
}
|
||
```
|
||
|
||
</CH.Code>
|
||
|
||
Once you fill in these values, run _`node deploy-commands.js`_ in your project directory to register your commands to a single guild. It's also possible to [register commands globally](/interactions/slash-commands.md#global-commands).
|
||
|
||
<Alert title="Tip" type="success">
|
||
You only need to run `node deploy-commands.js` once. You should only run it again if you add or edit existing
|
||
commands.
|
||
</Alert>
|
||
|
||
## Replying to commands
|
||
|
||
Once you've registered your commands, you can listen for interactions via <DocsLink path="class/Client?scrollTo=e-interactionCreate" /> in your _`index.js`_ file.
|
||
|
||
You should first check if an interaction is a chat input command via <DocsLink path="class/Interaction?scrollTo=isChatInputCommand" type="method">_`.isChatInputCommand()`_</DocsLink>, and then check the <DocsLink path="class/CommandInteraction?scrollTo=commandName">_`.commandName`_</DocsLink> property to know which command it is. You can respond to interactions with <DocsLink path="class/CommandInteraction?scrollTo=reply">_`.reply()`_</DocsLink>.
|
||
|
||
<CH.Code>
|
||
|
||
```js mark=5:16
|
||
client.once('ready', () => {
|
||
console.log('Ready!');
|
||
});
|
||
|
||
client.on('interactionCreate', async (interaction) => {
|
||
if (!interaction.isChatInputCommand()) return;
|
||
const { commandName } = interaction;
|
||
if (commandName === 'ping') {
|
||
await interaction.reply('Pong!');
|
||
} else if (commandName === 'server') {
|
||
await interaction.reply('Server info.');
|
||
} else if (commandName === 'user') {
|
||
await interaction.reply('User info.');
|
||
}
|
||
});
|
||
client.login(token);
|
||
```
|
||
|
||
</CH.Code>
|
||
|
||
### Server info command
|
||
|
||
Note that servers are referred to as "guilds" in the Discord API and discord.js library. _`interaction.guild`_ refers to the guild the interaction was sent in (a <DocsLink path="class/Guild" /> instance), which exposes properties such as _`.name`_ or _`.memberCount`_.
|
||
|
||
<CH.Code>
|
||
|
||
```js focus=7
|
||
client.on('interactionCreate', async (interaction) => {
|
||
if (!interaction.isChatInputCommand()) return;
|
||
const { commandName } = interaction;
|
||
if (commandName === 'ping') {
|
||
await interaction.reply('Pong!');
|
||
} else if (commandName === 'server') {
|
||
await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`);
|
||
} else if (commandName === 'user') {
|
||
await interaction.reply('User info.');
|
||
}
|
||
});
|
||
```
|
||
|
||
</CH.Code>
|
||
|
||
<DiscordMessages rounded>
|
||
<DiscordMessage
|
||
interaction={{
|
||
author: {
|
||
avatar:
|
||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||
username: 'Crawl',
|
||
},
|
||
command: 'server',
|
||
}}
|
||
author={{
|
||
avatar:
|
||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||
username: 'Crawl',
|
||
time: 'Today at 21:00',
|
||
}}
|
||
>
|
||
<p>Server name: discord.js Guide</p>
|
||
<p>Total members: 2</p>
|
||
</DiscordMessage>
|
||
</DiscordMessages>
|
||
|
||
You could also display the date the server was created, or the server's verification level. You would do those in the same manner – use _`interaction.guild.createdAt`_ or _`interaction.guild.verificationLevel`_, respectively.
|
||
|
||
<Alert title="Tip" type="success">
|
||
Refer to the <DocsLink path="class/Guild" /> documentation for a list of all the available properties and methods!
|
||
</Alert>
|
||
|
||
### User info command
|
||
|
||
A "user" refers to a Discord user. _`interaction.user`_ refers to the user the interaction was sent by (a <DocsLink path="class/User" /> instance), which exposes properties such as _`.tag`_ or _`.id`_.
|
||
|
||
<CH.Code>
|
||
|
||
```js focus=9
|
||
client.on('interactionCreate', async (interaction) => {
|
||
if (!interaction.isChatInputCommand()) return;
|
||
const { commandName } = interaction;
|
||
if (commandName === 'ping') {
|
||
await interaction.reply('Pong!');
|
||
} else if (commandName === 'server') {
|
||
await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`);
|
||
} else if (commandName === 'user') {
|
||
await interaction.reply(`Your tag: ${interaction.user.tag}\nYour id: ${interaction.user.id}`);
|
||
}
|
||
});
|
||
```
|
||
|
||
</CH.Code>
|
||
|
||
<DiscordMessages rounded>
|
||
<DiscordMessage
|
||
interaction={{
|
||
author: {
|
||
avatar:
|
||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||
username: 'Crawl',
|
||
},
|
||
command: 'user',
|
||
}}
|
||
author={{
|
||
avatar:
|
||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||
username: 'Crawl',
|
||
time: 'Today at 21:00',
|
||
}}
|
||
>
|
||
<p>Your tag: User#0001</p>
|
||
<p>Your id: 123456789012345678</p>
|
||
</DiscordMessage>
|
||
</DiscordMessages>
|
||
|
||
<Alert title="Tip" type="success">
|
||
Refer to the <DocsLink path="class/User" /> documentation for a list of all the available properties and methods!
|
||
</Alert>
|
||
|
||
And there you have it!
|
||
|
||
## The problem with if/else if
|
||
|
||
If you don't plan on making more than a couple commands, then using an _`if`_/_`else if`_ chain is fine; however, this isn't always the case. Using a giant _`if`_/_`else if`_ chain will only hinder your development process in the long run.
|
||
|
||
Here's a small list of reasons why you shouldn't do so:
|
||
|
||
- Takes longer to find a piece of code you want;
|
||
- Easier to fall victim to [spaghetti code](https://en.wikipedia.org/wiki/Spaghetti_code);
|
||
- Difficult to maintain as it grows;
|
||
- Difficult to debug;
|
||
- Difficult to organize;
|
||
- General bad practice.
|
||
|
||
Next, we'll be diving into something called a "command handler" – code that makes handling commands easier and much more efficient. This allows you to move your commands into individual files.
|
||
|
||
## Resulting code
|
||
|
||
<ResultingCode />
|