-
-
Notifications
You must be signed in to change notification settings - Fork 23
Command to SlashCommand Migration
With the introduction of SlashCommands, it's all the new hype and everyone wants to do them. How do you convert your existing bot over?
A few methods have been removed in favor of their SlashCommand counterparts. These being:
-
this.aliases
andgetAliases()
- Slash Commands don't support aliases. No alternatives. -
this.arguments
andgetArguments()
andgetArgs()
- Removed in favor of Options and OptionData (see migrating arguments below)
The first thing you will need to is to update your JDA-Chewtils to 1.20 or later.
Next, perform the following changes:
- Make your Command class extend
com.jagrosh.jdautilities.command.SlashCommand
, notcom.jagrosh.jdautilities.command.Command
. - Change the
protected void execute(CommandEvent commandEvent) {
to sayprotected void execute(SlashCommandEvent commandEvent) {
- Append
.queue();
to anyevent.reply()
s you do. - Remove any of the
this.x
methods mentioned above.
If you have no errors, great! You are done with the initial command class conversion, but you may run into even more issues.
Because getArgs() is gone, you will need to convert any arguments you plan on handing over to the new this.options
and OptionData included in JDA.
For example, if you accept one argument, such as an input for an 8ball command, you would have something like this:
public class EightBallCommand extends Command {
public EightBallCommand() {
this.name = "8ball";
this.help = "Ask the 8 ball a question!";
this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS};
this.guildOnly = false;
}
@Override
protected void execute(CommandEvent commandEvent) {
// Get the question, doesn't matter what they said but we'll send it back to them
String question = commandEvent.getArgs();
// Pick a number between 0 and 2 inclusive
int response = rand.nextInt(3);
EmbedBuilder e = new EmbedBuilder();
e.setTitle(":question: Question");
e.setDescription(question);
String answer = null;
// Finish and send embed
e.addField(":8ball: 8ball says", "My Response Here", false);
commandEvent.reply(e.build());
}
}
(Full code found here: https://github.com/Chewbotcca/Discord/blob/a9e585a672224306d7e7812ea433fc4990e7a8f8/src/main/java/pw/chew/chewbotcca/commands/fun/EightBallCommand.java)
As you can tell, we use commandEvent.getArgs()
to get the argument. This won't work anymore, instead, we will need to instantiate an OptionData object and set the details there.
OptionData data = new OptionData(OptionType.STRING, "input", "the input to ask the eight ball")
.setRequired(true);
This adds a new input called "input" and with the description that will show below the input. Additionally, it makes it required, not to let the user use the command without providing input.
To add this, we would put it in the constructor:
...
public EightBallCommand() {
this.name = "8ball";
this.help = "Ask the 8 ball a question!";
this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS};
this.guildOnly = false;
OptionData data = new OptionData(OptionType.STRING, "input", "the input to ask the eight ball")
.setRequired(true);
List<OptionData> dataList = new ArrayList<>();
dataList.add(data);
this.options = data;
}
...
Then, later on in our code, we can grab the input.
String question = commandEvent.getArgs();
becomes:
String question = commandEvent.getOption("input").getAsString();
Then the rest of the command function would work fine.
Our final code should look like this:
public class EightBallCommand extends SlashCommand {
public EightBallCommand() {
this.name = "8ball";
this.help = "Ask the 8 ball a question!";
this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS};
this.guildOnly = false;
OptionData data = new OptionData(OptionType.STRING, "input", "the input to ask the eight ball")
.setRequired(true);
List<OptionData> dataList = new ArrayList<>();
dataList.add(data);
this.options = data;
}
@Override
protected void execute(CommandEvent commandEvent) {
// Get the question, doesn't matter what they said but we'll send it back to them
String question = commandEvent.getOption("input").getAsString();
// Pick a number between 0 and 2 inclusive
int response = rand.nextInt(3);
EmbedBuilder e = new EmbedBuilder();
e.setTitle(":question: Question");
e.setDescription(question);
String answer = null;
// Finish and send embed
e.addField(":8ball: 8ball says", "My Response Here", false);
commandEvent.reply(e.build()).queue();
}
}
Because SlashCommands are incompatible with Commands, you will need to add them differently.
Instead of doing something like this:
client.addCommand(new EightBallCommand());
We need to add it using the new addSlashCommand function:
client.addSlashCommand(new EightBallCommand());
This will upsert the command on boot and, if shut down properly (via JDA#shutdown()
), it will be removed when it's shut down.
- SlashCommands in JDA-Chewtils
- Context Menus in JDA-Chewtils (Chewtils 2.0+)
- User-Installed Apps (Chewtils 2.1-SNAPSHOT)