Skip to main content

📜 Commands

Slash Commands are one of the primary ways to use your Discord Bot. They allow users to interact with your bot by typing / followed by the command name, maybe some options, and hitting enter.

Building Slash Commands is streamlined with Robo.js, which also handles automatic registration.

Creating Slash Commands

Create a file in your project's src/commands folder named after your Slash Command.

src/commands/ping.js
export default (interaction) => {
interaction.reply('Pong!')
}

That's it! Your /ping command is fully set up—give it a try!

tip

Don't see your new command? Try restarting your Discord Client to refresh your cache.

Alternatively, you can also return your reply directly.

src/commands/ping.js
export default async () => {
return 'Pong!'
}

This kicks in Sage Mode—a hidden power that handles interactions and defers slow async functions!

Subcommands and Subcommand Groups

Wanna go deeper? Make a folder inside src/commands with the parent command name and its own files.

src/commands/channel/lock.js
export default async (interaction) => {
const everyoneRole = interaction.guild.roles.everyone
await interaction.channel.permissionOverwrites.edit(everyoneRole, {
SendMessages: false,
AddReactions: false
})

return 'This channel is now locked!'
}

We can go even deeper with Subcommand Groups. Just add another folder inside the parent command folder.

src/commands/bot/status/idle.js
import { client } from 'robo.js'

export default async (interaction) => {
await client.user.setPresence({
status: 'idle'
})

return "I'm now idle!"
}

Pretty cool, right? Literally just folders and files!

src
└── commands
├── channel
│ └── lock.js
└── bot
└── status
└── idle.js

Customizing Commands

Give your commands some context with descriptions. You can do this by exporting a config object from your command file.

export const config = {
description: 'Responds with Pong!'
}

For TypeScript users, you can add typings for both the config object and the command result.

commands/ping.ts
import type { CommandConfig, CommandResult } from 'robo.js'

export const config: CommandConfig = {
description: 'Responds with Pong!'
}

export default (): CommandResult => {
return 'Pong!'
}

The `` object also lets you customize stuff like locale translations, Sage options, and command timeouts. To understand more about the available uration options, check out the configuration section.

Command Options

Robo.js allows you to further customize your commands with options. You can define these options in your config object and then access their values in your command function.

commands/ping.js
export const config = {
description: 'Responds with Pong!',
options: [
{
name: 'loud',
description: 'Respond loudly?',
type: 'boolean'
}
]
}

export default (interaction) => {
const loud = interaction.options.get('loud')?.value as boolean
return loud ? 'PONG!!!' : 'Pong!'
}

You can also use a second parameter next to the interaction object to access the options directly. These are automatically parsed and passed to your command function, with full type support too!

export const config = {
description: 'Responds with Pong!',
options: [
{
name: 'loud',
description: 'Respond loudly?',
type: 'boolean'
}
]
}

export default (interaction, options) => {
return options.loud ? 'PONG!!!' : 'Pong!'
}

Want to explore more options? Check the configuration section.

DM Permission

Control whether your command is accessible in direct messages with dmPermission. Setting this to true allows users to use the command in DMs with the bot, while false restricts it.

export const config = {
// ... other configuration options
dmPermission: false // Restricts this command in DMs
}

Default Member Permissions

Use defaultMemberPermissions to define server-based permissions for your command. This field accepts PermissionFlagsBits from Discord.js, allowing you to specify which roles or permissions are needed to access the command in a server context.

import { PermissionFlagsBits } from 'discord.js'

export const config = {
// ... other configuration options
defaultMemberPermissions: PermissionFlagsBits.KickMembers // Only users who can kick members can use this command
}
warning

Remember, server admins can adjust these default permissions for their own servers. Also, due to a Discord quirk, default permissions might not apply as expected to subcommands.

Autocomplete

Autocomplete can take your commands to the next level by providing suggestions as users type. You can implement autocomplete by exporting an autocomplete function in your command file.

commands/choosa-a-color.js
export const config = {
description: 'Chooses a color',
options: [
{
name: 'color',
description: 'Your favorite color',
type: 'string',
autocomplete: true
}
]
}

const colors = ['red', 'green', 'blue', 'yellow', 'black', 'white', 'pink', 'purple', 'brown']

export default (interaction) => {
return `You chose ${interaction.options.get('color')?.value}`
}

export const autocomplete = (interaction) => {
const colorQuery = interaction.options.get('color')?.value
const filtered = colors.filter((color) => color.startsWith(colorQuery))
return filtered.map((colors) => ({ name: colors, value: colors }))
}

In this example, the autocomplete function returns an array of colors that start with the user's input, providing a dynamic and responsive user experience.

Note: the type of the Interaction is: AutocompleteInteraction

Command Registration

The cherry on top? You don't need to manually register your commands. Robo.js handles it for you when you run robo dev or robo build, automatically! However, if things go sideways for some reason, you can use the --force flag to force registration.

Terminal
npx robo build --force

This will also clean up any commands that are no longer in your commands directory. Pretty neat, right?

User Installs

Robo.js now supports commands for user-installed apps! You will need to set experimental userInstall to true in your config file to enable this feature.

/config/robo.mjs
export default {
// ... other config options
experimental: {
userInstall: true
}
}

With this enabled, users can install your app and use its commands anywhere!

tip

Make sure you update your install settings in the Discord Developer Portal to allow user installs.