Commands¶
Info
If you're new to JDA and Discord Bots in general, please make yourself familiar with the JDA wiki first. We assume that the basic structure of interactions is known.
Slash Commands¶
SlashCommands are defined by annotating a method with @Command
.
The first parameter must always be a CommandEvent
.
The name and other metadata of the command is passed to the annotation.
@Command(value = "example", desc = "This is an example command")
public void onCommand(CommandEvent event) {...}
Sub Commands & Sub Command Groups¶
In contrast to JDA, JDA-Commands doesn't differentiate between slash commands, sub command groups and sub commands. JDA-Commands determines the type automatically based on the command names.
Let's say we have the following commands in our moderation bot:
@Command("delete")
public void onDeleteMessages(CommandEvent event) {...}
@Command("moderation warn")
public void onWarnMember(CommandEvent event) {...}
@Command("moderation kick")
public void onKickMember(CommandEvent event) {...}
@Command("moderation ban")
public void onBanMember(CommandEvent event) {...}
Debugging
JDA-Commands will log this tree on log-level DEBUG
. This might help you with debugging, for example when command
doesn't show up.
In our example the following commands will be registered:
/delete
/moderation warn
/moderation kick
/moderation ban
To simplify things, you can also use the @Interaction
to add a base name to all slash commands in a command controller:
@Interaction("moderation")
public class ModerationCommands {
@Command("warn")
public void onWarnMember(CommandEvent event) {...}
@Command("kick")
public void onKickMember(CommandEvent event) {...}
@Command("ban")
public void onBanMember(CommandEvent event) {...}
}
Command Options¶
You can add command options by simply adding a parameter to the method.
@Command("ban")
public void onBanMember(CommandEvent event, Member target, String reason, int delDays) {
(...)
}
The parameters will automatically be mapped to the correct option type. You can find this mapping here.
Name & Description¶
Use the @Param
annotation to set a name and a description for a command option. By default, the parameter name will be used as the
option name.
@Command("ban")
public void onBanMember(CommandEvent event,
@Param("The member to ban") Member target,
@Param("The reason to ban the member") String reason,
@Param(name = "deletion days", value = "The number of days to delete messages for") int delDays) {
(...)
}
Danger
In order for JDA-Commands to use the parameter name as the command option name, you must enable the -parameters
compiler flag.
If you compile your project with IntelliJ during development go to Settings > Compiler > Java Compiler
and add the -parameters
flag:
Optional¶
In order to make a command option optional, annotate the parameter with @Optional
.
You can also pass a default value that will be used (and type adapted) if no user input is present.
@Command("ban")
public void onBanMember(CommandEvent event, Member target, @Optional String reason, @Optional("7") int delDays) {
(...)
}
Note
Required options must be added before non-required options.
Choices¶
Use the @Choices
annotation to add choices to a command option:
@Command("ban")
public void onBanMember(CommandEvent event,
Member target,
@Choices({"Harassment", "Scam", "Advertising"}) String reason,
int delDays) {
(...)
}
Auto Complete¶
You can add auto complete to a command option by defining an auto complete handler for it by annotating a method with
@AutoComplete
.
Auto Complete handlers are always bound to one or more slash commands.
The slash commands can either be referenced by the:
-
Command Name
If referenced by the command name, the handler will handle any command whose name starts with the given name:
Example
@Command("favourite fruit") public void fruitCommand(CommandEvent event, String fruit) { event.reply("You've chosen: %s", fruit); } @Command("favourite vegetable") public void vegetableCommand(CommandEvent event, String vegetable) { event.reply("You've chosen: %s", vegetable); } @AutoComplete("favourite") //(1)! public void onFavouriteAutoComplete(AutoCompleteEvent event) { event.replyChoices(...); }
- This auto complete handler will receive auto complete events for both
/favourite fruit
and/favourite vegetable
It is also possible to reference the commands by their full name:
- This auto complete handler will receive auto complete events for both
-
Method Name
If referenced by the method name the handler will only handle the slash command of the given method:
Example
@Command("favourite fruit") public void fruitCommand(CommandEvent event, String fruit) { event.reply("You've chosen: %s", fruit); } @AutoComplete("fruitCommand") //(1)! public void onFruitAutoComplete(AutoCompleteEvent event) { event.replyChoices(...); }
- This auto complete handler will only receive auto complete events for
/favourite fruit
!
- This auto complete handler will only receive auto complete events for
Warning
If an auto complete handler doesn't specify any command options, it will be registered implicitly for every command option of the given slash command(s)!
So far we haven't specified which command options should have auto complete, resulting in every command option having auto complete enabled. If you want to avoid that, you have to explicitly state the command options the handler supports:
Example
@Command("favourite food")
public void foodCommand(CommandEvent event, String fruit, String vegetable) {
event.reply("You've chosen: %s and %s", fruit, vegetable);
}
@AutoComplete(vale = "foodCommand", options = "fruit")
public void onFruitAutoComplete(AutoCompleteEvent event) {
event.replyChoices(...);
}
You can have multiple auto complete handler for the same slash command, but each command option can only have exactly one handler. An auto complete handler that explicitly supports a command option will always be called over a handler that is implicitly registered.
Min & Max Value¶
Use the @Min
or @Max
annotation to set the minimum and maximum value for numeral options.
Example
Context Commands¶
Both types of context commands are defined by the same @Command
annotation. The first parameter must always be a CommandEvent
.
The name and other metadata of the command is passed to the annotation.
Message Context¶
For message context commands the second method parameter must be a Message
and the type
must be Command.Type.MESSAGE
.
@Command(value = "Delete this message", type = Command.Type.MESSAGE)
public void onDeleteMessage(CommandEvent event, Message target) { ... }
User Context¶
For user context commands the second method parameter must be a User
and the type
must be Command.Type.USER
.
@Command(value = "Ban this user", type = Command.Type.USER)
public void onBanMember(CommandEvent event, User user) { ... }
Additional Settings¶
Use the @CommandConfig
annotation to configure the following settings. You can either annotate a command method directly or annotate the
interaction controller class. It is also possible to set a
global command config
at the builder:
Global CommandConfig
JDA-Commands will apply clashing CommandConfigs in the following hierarchy:
CommandConfig
method annotationCommandConfig
class annotation- global
CommandConfig
enabledFor¶
Sets the Discord Permissions
a command will be enabled for. By default, a command will be enabled for every permission.
Danger
Guild admins can modify these permissions at any time! If you want to enforce permissions or secure a critical command further you should use the permissions system of JDA-Commands. You can read more about it here.
@CommandConfig(enabledFor = Permission.BAN_MEMBERS)
@Command(value = "example")
public void onCommand(CommandEvent event) {...}
context¶
Sets the InteractionContextTypes
of a command. The default value is InteractionContextType#GUILD
.
@CommandConfig(context = {InteractionContextType#GUILD, InteractionContextType#BOT_DM})
@Command(value = "example")
public void onCommand(CommandEvent event) {...}
integration¶
Sets the IntegrationTypes
of a command. The default value is IntegrationType#GUILD_INSTALL
.
@CommandConfig(integration = {IntegrationType#GUILD_INSTALL, IntegrationType#USER_INSTALL})
@Command(value = "example")
public void onCommand(CommandEvent event) {...}
isNSFW¶
Sets whether a command can only be executed in NSFW channels. The default value is false
.
@CommandConfig(isNSFW = true)
@Command(value = "example")
public void onCommand(CommandEvent event) {...}
scope (Guild & Global Commands)¶
Sets whether a command should be registered as a global
or as a guild
command. The default value is global
.
@CommandConfig(scope = CommandScope.GUILD)
@Command(value = "example")
public void onCommand(CommandEvent event) {...}
When having guild scoped commands you have to use the GuildScopeProvider
to tell JDA-Commands what guilds a command should be registered for.
Let's say we have a paid feature in our bot:
Example
We then need to implement a GuildScopeProvider
to only register this command for guilds that have paid for that feature:
Example
Finally, we have to register our PremiumGuildsProvider
. We can either pass it to the builder:
Example
or simply annotate the PremiumGuildsProvider
class with @Implementation
.
Note
Using the @Implementation
annotation requires the guice integration (shipped by default). You can read more about it here.