SlashCommand
The SlashCommand class builds a Discord application (/) command definition. It's a thin, object-based wrapper around discord.js's SlashCommandBuilder; you describe the command as plain data, and SlashCommand does the chaining for you. The result is passed as data to client.slash().
Constructor
const { SlashCommand } = require("syntx.js");
new SlashCommand(options);Options
| Option | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The command name shown after /. |
description | string | Yes | Shown to users in Discord's command picker. |
name_localizations | object | No | Per-locale names, e.g. { "es-ES": "saludo" }. |
description_localizations | object | No | Per-locale descriptions. |
options | Option[] | No | Top-level options. Cannot be combined with subcommands/groups. |
subcommands | Subcommand[] | No | A flat list of subcommands. |
groups | Group[] | No | Subcommands organized into named groups. |
scope | "global" | "guild" | No (default "global") | Where registerSlashCommands() publishes the command. |
nsfw | boolean | No (default false) | Restricts the command to age-restricted channels. |
integrationTypes | ("guild" | "user")[] | No | Where the app can be installed and still use this command. |
contexts | ("guild" | "bot_dm" | "private_channel")[] | No | Where the command can be used. |
defaultMemberPermissions | PermissionResolvable | No | Permissions a member needs by default to see/use the command. |
const ping = new SlashCommand({
name: "ping",
description: "Replies with the bot latency",
});Warning
You cannot pass options together with subcommands or groups on the same command; Discord does not allow mixing top-level options with subcommands. Pick one.
Adding options
Push objects into options. Every option type shares name, description, and required (default false); some types add extra fields.
type | Builder used | Extra fields |
|---|---|---|
string | addStringOption | choices, min_length, max_length, autocomplete |
integer | addIntegerOption | choices, min_value, max_value, autocomplete |
number | addNumberOption | choices, min_value, max_value, autocomplete |
boolean | addBooleanOption | — |
user | addUserOption | — |
channel | addChannelOption | channel_types |
role | addRoleOption | — |
mentionable | addMentionableOption | — |
attachment | addAttachmentOption | — |
new SlashCommand({
name: "echo",
description: "Repeats your message",
options: [
{
name: "message",
description: "Text to repeat",
type: "string",
required: true,
max_length: 200,
},
],
});Tip
choices accepts plain values (["red", "green", "blue"]) or { name, value } objects when the label shown to users should differ from the value your code receives.
Warning
Setting autocomplete: true on an option means Discord will call your command's autocomplete handler instead of using choices; don't set both on the same option.
Subcommands
new SlashCommand({
name: "role",
description: "Manage roles",
subcommands: [
{
name: "add",
description: "Add a role to a member",
options: [
{ name: "user", description: "The member", type: "user", required: true },
{ name: "role", description: "The role to add", type: "role", required: true },
],
},
{
name: "remove",
description: "Remove a role from a member",
options: [
{ name: "user", description: "The member", type: "user", required: true },
{ name: "role", description: "The role to remove", type: "role", required: true },
],
},
],
});Note
Inside execute, read which subcommand was used with interaction.options.getSubcommand().
Subcommand groups
For larger commands, organize subcommands into named groups (/settings welcome enable, /settings welcome channel, and so on):
new SlashCommand({
name: "settings",
description: "Configure the server",
groups: [
{
name: "welcome",
description: "Welcome message settings",
subcommands: [
{ name: "enable", description: "Turn the welcome message on" },
{
name: "channel",
description: "Set the welcome channel",
options: [
{ name: "channel", description: "Target channel", type: "channel", required: true },
],
},
],
},
],
});Scope: global vs guild
| Scope | Propagation | Where it's used |
|---|---|---|
"global" (default) | Up to ~1 hour | Every server (and DMs, if contexts allows it) the bot is in |
"guild" | Instant | A single server, passed as guildId to registerSlashCommands() |
new SlashCommand({
name: "debug",
description: "Developer-only debug command",
scope: "guild",
});Tip
Keep commands you're actively building set to scope: "guild" for instant feedback while testing, then switch to "global" once they're ready to ship.
Registering it
A SlashCommand instance only describes the command; pass it to client.slash() and then call client.registerSlashCommands() to publish it:
client.slash({
data: ping,
execute: async (interaction) => {
await interaction.reply("Pong!");
},
});
await client.registerSlashCommands({ showLoad: true });toJSON()
Returns the raw payload discord.js sends to the Discord API (SlashCommandBuilder#toJSON()). registerSlashCommands() calls this internally; you'll rarely need it yourself, but it's useful for inspecting exactly what will be sent.
console.log(ping.toJSON());