Skip to content

Interactions

Dynxsty edited this page Nov 13, 2022 · 40 revisions

Slash Commands

Commands

DIH4JDA makes it quite easy to create Slash Commands.
Just let your class extend the SlashCommand class, and you're basically ready to go. Everything about the Command itself, like the CommandData, must be set in the constructor.

public class PingCommand extends SlashCommand {

    public PingCommand() {
        setRegistrationType(RegistrationType.GUILD); // OPTIONAL: a default can be set using DIH4JDA#setDefaultRegistrationType
        setCommandData(Commands.slash("ping", "Pong!"));
    }

    @Override
    public void execute(SlashCommandInteractionEvent event) {
        event.reply("Pong!").queue();
    }

Subcommands

Adding a Subcommand is basically the same procedure. Let's say, we want two separate commands: /fruits apple and /fruits banana.

We achieve that by defining the main command, fruits, and then adding the Subcommands.

public class FruitsCommand extends SlashCommand {

    public FruitsCommand() {
        setCommandData(Commands.slash("fruits", "yum"));
        addSubcommands(new AppleSubcommand(), new BananaSubcommand());
    }

Our Apple Subcommand class should then look like the following:

public class AppleSubcommand extends SlashCommand.Subcommand {

    public AppleSubcommand() {
        setCommandData(new SubcommandData("apple", "yum"));
    }

    @Override
    public void execute(SlashCommandInteractionEvent event) {
        event.reply("Apple!").queue();
    }
}

TLDR; Subcommands work just like regular Slash Commands.
The only difference is, that a Subcommand must extend SlashCommand.Subcommand instead of SlashCommand.

Subcommand Groups

Subcommand Groups are another possibility for nesting commands. With Sub Command Groups, we could create a command structure like this:

fruits
├── red
│   ├── apple
│   └── cherry
└── yellow
    ├── banana
    └── pineapple

Where fruits would be the main Slash Command, the different colors, red and yellow the Subcommand Groups and the actual fruits, apple, cherry, banana & pineapple the Subcommands.

Thus, our class should look like this.

/fruits

public class FruitsCommand extends SlashCommand {

    public FruitsCommand() {
        setCommandData(Commands.slash("fruits", "yum"));
        addSubcommandGroups(
		SubcommandGroup.of(new SubcommandGroupData("red", "the fruit's color"), new AppleSubcommand(), new CherrySubcommand()),
		SubcommandGroup.of(new SubcommandGroupData("yellow", "the fruit's color"), new BananaSubcommand(), new LemonSubcommand())
	);
    }
}

/fruits red apple

public class AppleSubcommand extends SlashCommand.Subcommand {

    public AppleSubcommand() {
        setCommandData(new SubcommandData("apple", "yum"));
    }

    @Override
    public void execute(SlashCommandInteractionEvent event) {
        event.reply("Apples are red!").queue();
    }
}

Context Menu Commands

Creating Context Commands

The process of creating Context Menu Commands is very similar to Slash Commands. First, you have to define what type of Context Command it is, by either extending ContextCommand.User or ContextCommand.Message.

User Context Menus

public class PingContextMenu extends ContextCommand.User {

	public PingContextMenu() {
            setRegistrationType(RegistrationType.GUILD); // OPTIONAL: a default can be set using DIH4JDA#setDefaultRegistrationType
	    setCommandData(Commands.user("Ping"));
	}

	@Override
	public void execute(UserContextInteractionEvent event) {
	    event.reply("Pong!").queue();
	}
}

Message Context Menus

public class PingContextMenu extends ContextCommand.Message {

	public PingContextMenu() {
	    setCommandData(Commands.message("Ping"));
	}

	@Override
	public void execute(MessageContextInteractionEvent event) {
	    event.reply("Pong!").queue();
	}
}

Auto Complete

To enable the Auto Complete handling, all that needs to be done is to implement the AutoCompleteHandler interface and enable autocomplete on one of your commands OptionData

public class PingCommand extends SlashCommand implements AutoCompleteHandler {

 public PingCommand() {
     setCommandData(Commands.slash("ping", "Ping someone")
        .addOption(OptionType.STRING, "user-id", "The user id", false, true));
 }

[...]

This will execute this class's overridden handleAutoComplete method each time the CommandAutoCompleteInteractionEvent is fired for the corresponding command.

Interaction / Component Handlers

The so-called interaction handlers work basically just like the AutoCompleteHandler. All that needs to be done is to extend the one of the interaction handlers:

public class PingCommand implements ButtonHandler {

     public PingCommand() {
         setCommandData([...]);
     }

     @Override
     public void execute(SlashCommandInteractionEvent event) {
	event.reply("test")
            .addActionRow(
 	        Button.secondary(ComponentIdBuilder.build("test-button", 1), "Click me!"),
 		Button.secondary(ComponentIdBuilder.build("test-button", 2), "NO! Click me!")
            ).queue();
     }
 
     @Override
     public void handleButton(ButtonInteractionEvent event, Button button) {
         String[] id = ComponentIdBuilder.split(button.getId());
 	 String content = "";
 	 switch (id[1]) {
 	     case "1": content = "Thanks for not clicking the other button! :)"; break;
 	     case "2": content = "Phew, thanks for clicking me..."; break;
         }
 	 event.reply(content).queue();
    }
 }

After that, you need to bind your chosen button-id (in this case test-button) to the specific class. This is done on the DIH4JDA instance:

DIH4JDA dih4jda = DIH4JDABuilder
        .setJDA(jda) // Your JDA instance
        .build();
dih4jda.addButtonMappings(
	IdMapping.of(new PingCommand(), "test-button", "another-id"),
        IdMapping.of(new TestCommand(), "test")
);

The same works for StringSelectMenus, EntitySelectMenus & Modals!

It is recommended to use the ComponentIdBuilder#build method for consistent component-id building.