Interaction Commands aka. Slash Commands
There are a lot of convenient methods which aim to make your life easier with i.e., not being able to have an invalid configuration of your builder. Therefore, the following examples will only show the usage with the convenient methods.
💡 Creating a Command
There are 2 different types of Commands:
- Global | Available for every Server once your Bot gets invited: Created with
- Server | Only available on the specific Server: Created with
Let's get started with the most basic command, a ping command.
SlashCommand command = SlashCommand.with("ping", "Checks the functionality of this command") .createGlobal(api) .join();
That's all you have to do!
Let's have a look at a more complex command which involves nearly all possibilities:
SlashCommand command = SlashCommand.with("channel", "A command dedicated to channels", Arrays.asList( SlashCommandOption.createWithOptions(SlashCommandOptionType.SUB_COMMAND_GROUP, "edit", "Edits a channel", Arrays.asList( SlashCommandOption.createWithOptions(SlashCommandOptionType.SUB_COMMAND, "allow", "Allows a permission to a user for a channel", Arrays.asList( SlashCommandOption.create(SlashCommandOptionType.CHANNEL, "channel", "The channel to modify", true), SlashCommandOption.create(SlashCommandOptionType.USER, "user", "The user which permissions should be changed", true), SlashCommandOption.createWithChoices(SlashCommandOptionType.DECIMAL, "permission", "The permission to allow", true, Arrays.asList( SlashCommandOptionChoice.create("manage", 0), SlashCommandOptionChoice.create("show", 1))) )))))) .createGlobal(api) .join();
Let that sink in first!
What are we doing here?
- We create a base command called
- It has a SUB_COMMAND_GROUP called
editwhich basically is just a folder where you can put your commands in.
- There's a SUB_COMMAND called
allowwhich is our actual command. Therefore, our complete argument looks like
channel edit allow.
- The SUB_COMMAND has 3 arguments:
- The channel which should be edited.
- The user which permissions should be changed.
- A predefined list of available permissions the command executor can choose of.
📔 Notes on creating commands:
You can only mark the last argument as being not required. This means it can be optionally set by the command executor. In the above example you could i.e. set the
PERMISSIONS argument to
Your command has to follow these structures in order to be successfully created:
VALID command | |__ subcommand | |__ subcommand ---- command | |__ subcommand-group | |__ subcommand | |__ subcommand-group | |__ subcommand ---- VALID command | |__ subcommand-group | |__ subcommand | |__ subcommand ------- INVALID command | |__ subcommand-group | |__ subcommand-group | |__ subcommand-group | |__ subcommand-group ---- INVALID command | |__ subcommand | |__ subcommand-group | |__ subcommand | |__ subcommand-group
⤵️ Get your commands
All global commands:
Set<SlashCommand> commands = api.getGlobalSlashCommands().join();
All commands only available on a single server:
Server server = ...; Set<SlashCommand> commands = api.getServerSlashCommands(server).join();
Getting all commands from a server only contains the commands you have created on this specific server. Therefore, the returned list does not include any global command!
🔨 Updating Commands
When updating your commands you only have to include what you actually want to change. The following updater will change the previous created command and change its base name from
SlashCommand updatedCommand = new SlashCommandUpdater(commandId) .setName("channels") .updateGlobal(api) .join();
✍️ Bulk overwriting commands
If you have to update / create multiple commands at once it advised to use the batch updater to only have to do 1 request.
DiscordApi api = ...; Set<SlashCommandBuilder> builders = new HashSet<>(); builders.add(new SlashCommandBuilder().setName("server").setDescription("A command for the server")); builders.add(new SlashCommandBuilder().setName("permission").setDescription("A command for permissions")); api.bulkOverwriteGlobalApplicationCommands(builders).join();
Permissions exist to enable / disable the usage of your commands for certain things. These things may be:
When you create a command you can specify which permissions are required to use it. In addition to the required permissions, you can also specify whether the command should be available in DMs.
SlashCommand.with("ping","Ping!") .setDefaultEnabledForPermissions(PermissionType.ADMINISTRATOR, PermissionType.BAN_MEMBERS) //.setDefaultDisabled() Effectively the same as setDefaultEnabledForPermissions(PermissionType.ADMINISTRATOR) but this will lead to the default type by Discord. .setEnabledInDms(false) .createGlobal(api) .join();
Once your bot has been invited to a server, you can not change the permissions afterwards on this server. Then it's up to the server administrators / owner to correctly set up the commands for users / roles / channels.
Registering a command
- Server commands are specific to the server you specify when making them. Server commands are not available in DMs. Command names are unique per application within each scope (global and server). That means:
- Your app cannot have two global commands with the same name
- Your app cannot have two server commands within the same name on the same guild
- Your app can have a global and guild command with the same name
- Multiple apps can have commands with the same names
- An app can have up to 100 top-level global commands with unique names
- An app can have up to an additional 100 server commands per server
- An app can have up to 25 subcommand groups on a top-level command
- An app can have up to 25 subcommands within a subcommand group
- Commands can have up to 25 options
- Options can have up to 25 choices
- Maximum of 4000 characters for combined name, description, and value properties for each command and its subcommands and groups
- Limitations on nesting subcommands and groups
- Global rate limit of 200 slash command creates per day per server