CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-dv8tion--jda

Java Discord API - A comprehensive Java library for building Discord bots and applications

Pending
Overview
Eval results
Files

interactions.mddocs/

Interaction System

Modern Discord interactions including slash commands, buttons, select menus, modals, and context menus with full builder pattern support.

Capabilities

Slash Command Interactions

Modern command system using Discord's native slash command interface.

/**
 * Represents a slash command interaction.
 */
interface SlashCommandInteraction extends IReplyCallback {
    /** Get command name */
    String getName();
    
    /** Get full command string with options */
    String getCommandString();
    
    /** Get command ID */
    long getCommandIdLong();
    String getCommandId();
    
    /** Get subcommand name (if used) */
    String getSubcommandName();
    
    /** Get subcommand group name (if used) */
    String getSubcommandGroup();
    
    /** Get all command options */
    List<OptionMapping> getOptions();
    
    /** Get option by name */
    OptionMapping getOption(String name);
    
    /** Get option by name with type checking */
    OptionMapping getOption(String name, OptionType type);
    
    /** Get options for subcommand */
    List<OptionMapping> getOptionsByName(String name);
    
    /** Get options by type */
    List<OptionMapping> getOptionsByType(OptionType type);
}

/**
 * Represents an option value in a slash command.
 */
interface OptionMapping {
    /** Get option name */
    String getName();
    
    /** Get option type */
    OptionType getType();
    
    /** Get raw string value */
    String getAsString();
    
    /** Get as boolean */
    boolean getAsBoolean();
    
    /** Get as long */
    long getAsLong();
    
    /** Get as double */
    double getAsDouble();
    
    /** Get as snowflake */
    IMentionable getAsMentionable();
    
    /** Get as user */
    User getAsUser();
    
    /** Get as member */
    Member getAsMember();
    
    /** Get as role */
    Role getAsRole();
    
    /** Get as channel */
    GuildChannel getAsChannel();
    
    /** Get as message channel */
    MessageChannel getAsMessageChannel();
    
    /** Get as attachment */
    Message.Attachment getAsAttachment();
}

/**
 * Utility class for creating command data.
 */
class Commands {
    /** Create slash command */
    static SlashCommandData slash(String name, String description);
    
    /** Create user context menu command */
    static CommandData user(String name);
    
    /** Create message context menu command */
    static CommandData message(String name);
}

/**
 * Builder for slash command data.
 */
interface SlashCommandData extends CommandData {
    /** Add string option */
    SlashCommandData addOption(OptionType type, String name, String description);
    SlashCommandData addOption(OptionType type, String name, String description, boolean required);
    SlashCommandData addOption(OptionType type, String name, String description, boolean required, boolean autoComplete);
    
    /** Add options */
    SlashCommandData addOptions(OptionData... options);
    SlashCommandData addOptions(Collection<? extends OptionData> options);
    
    /** Add subcommand */
    SlashCommandData addSubcommands(SubcommandData... subcommands);
    SlashCommandData addSubcommands(Collection<? extends SubcommandData> subcommands);
    
    /** Add subcommand group */
    SlashCommandData addSubcommandGroups(SubcommandGroupData... groups);
    SlashCommandData addSubcommandGroups(Collection<? extends SubcommandGroupData> groups);
}

/**
 * Builder for command options.
 */
class OptionData {
    /** Create option */
    OptionData(OptionType type, String name, String description);
    OptionData(OptionType type, String name, String description, boolean required);
    OptionData(OptionType type, String name, String description, boolean required, boolean autoComplete);
    
    /** Set option as required */
    OptionData setRequired(boolean required);
    
    /** Set option as auto-complete */
    OptionData setAutoComplete(boolean autoComplete);
    
    /** Add string choice */
    OptionData addChoice(String name, String value);
    
    /** Add number choice */
    OptionData addChoice(String name, long value);
    OptionData addChoice(String name, double value);
    
    /** Add choices */
    OptionData addChoices(Command.Choice... choices);
    OptionData addChoices(Collection<? extends Command.Choice> choices);
    
    /** Set channel types (for channel options) */
    OptionData setChannelTypes(ChannelType... channelTypes);
    OptionData setChannelTypes(Collection<ChannelType> channelTypes);
    
    /** Set number range */
    OptionData setRequiredRange(long min, long max);
    OptionData setRequiredRange(double min, double max);
    
    /** Set string length range */
    OptionData setRequiredLength(int min, int max);
}

Usage Examples:

import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;

// Register slash commands
jda.updateCommands().addCommands(
    Commands.slash("ping", "Check bot latency"),
    Commands.slash("userinfo", "Get information about a user")
        .addOption(OptionType.USER, "user", "Target user", false),
    Commands.slash("ban", "Ban a user from the server")
        .addOption(OptionType.USER, "user", "User to ban", true)
        .addOption(OptionType.STRING, "reason", "Reason for ban", false)
        .addOption(OptionType.INTEGER, "days", "Days of messages to delete", false)
        .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.BAN_MEMBERS)),
    Commands.slash("poll", "Create a poll")
        .addOption(OptionType.STRING, "question", "Poll question", true)
        .addOption(OptionType.STRING, "option1", "First option", true)
        .addOption(OptionType.STRING, "option2", "Second option", true)
        .addOption(OptionType.STRING, "option3", "Third option", false)
).queue();

// Handle slash command interactions
public class SlashCommandHandler extends ListenerAdapter {
    @Override
    public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
        switch (event.getName()) {
            case "ping" -> {
                long gatewayPing = event.getJDA().getGatewayPing();
                event.reply("Gateway ping: " + gatewayPing + "ms").queue();
            }
            case "userinfo" -> {
                User target = event.getOption("user", event.getUser(), OptionMapping::getAsUser);
                Member member = event.getGuild().getMember(target);
                
                EmbedBuilder embed = new EmbedBuilder()
                    .setTitle("User Information")
                    .addField("Username", target.getName(), true)
                    .addField("ID", target.getId(), true)
                    .addField("Created", target.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME), false)
                    .setThumbnail(target.getEffectiveAvatarUrl());
                
                if (member != null) {
                    embed.addField("Joined", member.getTimeJoined().format(DateTimeFormatter.RFC_1123_DATE_TIME), false);
                    embed.addField("Roles", member.getRoles().stream()
                        .map(Role::getAsMention)
                        .collect(Collectors.joining(", ")), false);
                }
                
                event.replyEmbeds(embed.build()).queue();
            }
            case "ban" -> {
                User target = event.getOption("user", OptionMapping::getAsUser);
                String reason = event.getOption("reason", "No reason provided", OptionMapping::getAsString);
                int days = event.getOption("days", 0, OptionMapping::getAsInt);
                
                event.getGuild().ban(target, days, TimeUnit.DAYS)
                    .reason(reason)
                    .queue(
                        success -> event.reply("Successfully banned " + target.getAsTag()).setEphemeral(true).queue(),
                        error -> event.reply("Failed to ban user: " + error.getMessage()).setEphemeral(true).queue()
                    );
            }
        }
    }
}

Button Interactions

Interactive button components in messages for user interaction.

/**
 * Represents a button interaction event.
 */
interface ButtonInteraction extends IMessageEditCallback {
    /** Get button that was clicked */
    Button getButton();
    
    /** Get button component ID */
    String getComponentId();
    
    /** Get message containing the button */
    Message getMessage();
    
    /** Get button style */
    ButtonStyle getStyle();
    
    /** Get button label */
    String getLabel();
    
    /** Get button emoji */
    Emoji getEmoji();
}

/**
 * Button component builder.
 */
class Button {
    /** Create primary button */
    static Button primary(String id, String label);
    static Button primary(String id, Emoji emoji);
    static Button primary(String id, String label, Emoji emoji);
    
    /** Create secondary button */
    static Button secondary(String id, String label);
    static Button secondary(String id, Emoji emoji);
    static Button secondary(String id, String label, Emoji emoji);
    
    /** Create success button (green) */
    static Button success(String id, String label);
    static Button success(String id, Emoji emoji);
    static Button success(String id, String label, Emoji emoji);
    
    /** Create danger button (red) */
    static Button danger(String id, String label);
    static Button danger(String id, Emoji emoji);
    static Button danger(String id, String label, Emoji emoji);
    
    /** Create link button */
    static Button link(String url, String label);
    static Button link(String url, Emoji emoji);
    static Button link(String url, String label, Emoji emoji);
    
    /** Get button properties */
    String getId();
    String getLabel();
    ButtonStyle getStyle();
    Emoji getEmoji();
    String getUrl();
    boolean isDisabled();
    
    /** Create disabled/enabled versions */
    Button asDisabled();
    Button asEnabled();
    
    /** Modify button properties */
    Button withId(String id);
    Button withLabel(String label);
    Button withEmoji(Emoji emoji);
    Button withStyle(ButtonStyle style);
    Button withUrl(String url);
    Button withDisabled(boolean disabled);
}

Usage Examples:

import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;

// Send message with buttons
Button acceptButton = Button.success("accept", "Accept");
Button declineButton = Button.danger("decline", "Decline");
Button infoButton = Button.secondary("info", "More Info");

channel.sendMessage("Do you want to join the event?")
    .setComponents(ActionRow.of(acceptButton, declineButton, infoButton))
    .queue();

// Handle button interactions
public class ButtonHandler extends ListenerAdapter {
    @Override
    public void onButtonInteraction(ButtonInteractionEvent event) {
        String componentId = event.getComponentId();
        
        switch (componentId) {
            case "accept" -> {
                event.reply("✅ You have accepted the invitation!").setEphemeral(true).queue();
                
                // Disable the buttons after interaction
                List<ActionRow> updatedRows = event.getMessage().getActionRows().stream()
                    .map(row -> ActionRow.of(row.getComponents().stream()
                        .map(component -> {
                            if (component instanceof Button button) {
                                return button.asDisabled();
                            }
                            return component;
                        })
                        .collect(Collectors.toList())))
                    .collect(Collectors.toList());
                
                event.getHook().editOriginalComponents(updatedRows).queue();
            }
            case "decline" -> {
                event.reply("❌ You have declined the invitation.").setEphemeral(true).queue();
            }
            case "info" -> {
                EmbedBuilder embed = new EmbedBuilder()
                    .setTitle("Event Information")
                    .setDescription("This is a community gaming event")
                    .addField("Date", "Tomorrow at 8 PM", true)
                    .addField("Duration", "2 hours", true)
                    .setColor(Color.BLUE);
                
                event.replyEmbeds(embed.build()).setEphemeral(true).queue();
            }
        }
    }
}

Select Menu Interactions

Dropdown selection components for multiple choice interactions.

/**
 * Represents a select menu interaction.
 */
interface SelectMenuInteraction extends IMessageEditCallback {
    /** Get selected values */
    List<String> getValues();
    
    /** Get selected options */
    List<SelectOption> getSelectedOptions();
    
    /** Get select menu component */
    SelectMenu getSelectMenu();
    
    /** Get component ID */
    String getComponentId();
    
    /** Get message containing the select menu */
    Message getMessage();
}

/**
 * String select menu builder.
 */
class StringSelectMenu {
    /** Create string select menu builder */
    static StringSelectMenu.Builder create(String customId);
    
    static class Builder {
        /** Set placeholder text */
        Builder setPlaceholder(String placeholder);
        
        /** Set value range */
        Builder setRequiredRange(int min, int max);
        Builder setMinValues(int min);
        Builder setMaxValues(int max);
        
        /** Add option */
        Builder addOption(String label, String value);
        Builder addOption(String label, String value, String description);
        Builder addOption(String label, String value, String description, Emoji emoji);
        Builder addOption(String label, String value, String description, boolean defaultValue);
        
        /** Add options */
        Builder addOptions(SelectOption... options);
        Builder addOptions(Collection<? extends SelectOption> options);
        
        /** Set as disabled */
        Builder setDisabled(boolean disabled);
        
        /** Build the select menu */
        StringSelectMenu build();
    }
}

/**
 * Entity select menu for Discord entities.
 */
class EntitySelectMenu {
    /** Create entity select menu builder */
    static EntitySelectMenu.Builder create(String customId, SelectTarget target);
    
    enum SelectTarget {
        USER, ROLE, MENTIONABLE, CHANNEL
    }
    
    static class Builder {
        /** Set placeholder text */
        Builder setPlaceholder(String placeholder);
        
        /** Set value range */
        Builder setRequiredRange(int min, int max);
        Builder setMinValues(int min);
        Builder setMaxValues(int max);
        
        /** Set channel types (for channel select) */
        Builder setChannelTypes(ChannelType... types);
        Builder setChannelTypes(Collection<ChannelType> types);
        
        /** Set default values */
        Builder setDefaultValues(SelectOption... options);
        Builder setDefaultValues(Collection<? extends SelectOption> options);
        
        /** Set as disabled */
        Builder setDisabled(boolean disabled);
        
        /** Build the select menu */
        EntitySelectMenu build();
    }
}

/**
 * Select option builder.
 */
class SelectOption {
    /** Create select option */
    static SelectOption of(String label, String value);
    static SelectOption of(String label, String value, String description);
    static SelectOption of(String label, String value, String description, Emoji emoji);
    
    /** Get option properties */
    String getLabel();
    String getValue();
    String getDescription();
    Emoji getEmoji();
    boolean isDefault();
    
    /** Create modified versions */
    SelectOption withLabel(String label);
    SelectOption withValue(String value);
    SelectOption withDescription(String description);
    SelectOption withEmoji(Emoji emoji);
    SelectOption withDefault(boolean defaultValue);
}

Usage Examples:

import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;

// Create select menu
StringSelectMenu gameMenu = StringSelectMenu.create("game-select")
    .setPlaceholder("Choose your favorite games")
    .setRequiredRange(1, 3)
    .addOptions(
        SelectOption.of("Minecraft", "minecraft")
            .withDescription("Block building sandbox game")
            .withEmoji(Emoji.fromUnicode("🧱")),
        SelectOption.of("Valorant", "valorant")
            .withDescription("Tactical shooter game")
            .withEmoji(Emoji.fromUnicode("🔫")),
        SelectOption.of("League of Legends", "lol")
            .withDescription("MOBA game")
            .withEmoji(Emoji.fromUnicode("⚔️")),
        SelectOption.of("Among Us", "amongus")
            .withDescription("Social deduction game")
            .withEmoji(Emoji.fromUnicode("👾"))
    )
    .build();

channel.sendMessage("What games do you play?")
    .setComponents(ActionRow.of(gameMenu))
    .queue();

// Handle select menu interactions
public class SelectMenuHandler extends ListenerAdapter {
    @Override
    public void onStringSelectInteraction(StringSelectInteractionEvent event) {
        if (event.getComponentId().equals("game-select")) {
            List<String> selectedGames = event.getValues();
            
            String response = "You selected: " + String.join(", ", selectedGames);
            
            // Get role assignments based on games
            List<Role> rolesToAdd = new ArrayList<>();
            Guild guild = event.getGuild();
            
            for (String game : selectedGames) {
                Role gameRole = guild.getRolesByName(game + "-player", true).stream()
                    .findFirst()
                    .orElse(null);
                if (gameRole != null) {
                    rolesToAdd.add(gameRole);
                }
            }
            
            if (!rolesToAdd.isEmpty()) {
                Member member = event.getMember();
                guild.modifyMemberRoles(member, rolesToAdd, null)
                    .queue(success -> {
                        event.reply(response + "\n🎮 Game roles have been assigned!").setEphemeral(true).queue();
                    });
            } else {
                event.reply(response).setEphemeral(true).queue();
            }
        }
    }
}

Modal Interactions

Form-based interactions for collecting user input through text fields.

/**
 * Represents a modal form interaction.
 */
interface ModalInteraction extends IReplyCallback {
    /** Get modal ID */
    String getModalId();
    
    /** Get value by component ID */
    ModalMapping getValue(String id);
    
    /** Get all input values */
    List<ModalMapping> getValues();
}

/**
 * Represents a modal input value.
 */
interface ModalMapping {
    /** Get component ID */
    String getId();
    
    /** Get input type */
    TextInput.InputType getType();
    
    /** Get input value */
    String getAsString();
}

/**
 * Modal builder.
 */
class Modal {
    /** Create modal builder */
    static Modal.Builder create(String id, String title);
    
    static class Builder {
        /** Add text input component */
        Builder addActionRows(ActionRow... actionRows);
        Builder addActionRows(Collection<? extends ActionRow> actionRows);
        
        /** Add components */
        Builder addComponents(ItemComponent... components);
        
        /** Build the modal */
        Modal build();
    }
}

/**
 * Text input component for modals.
 */
class TextInput {
    /** Create short text input */
    static TextInput.Builder create(String id, String label, InputType style);
    
    enum InputType {
        SHORT, PARAGRAPH
    }
    
    static class Builder {
        /** Set placeholder text */
        Builder setPlaceholder(String placeholder);
        
        /** Set as required */
        Builder setRequired(boolean required);
        
        /** Set default value */
        Builder setValue(String value);
        
        /** Set length range */
        Builder setRequiredRange(int min, int max);
        Builder setMinLength(int min);
        Builder setMaxLength(int max);
        
        /** Build the text input */
        TextInput build();
    }
}

Usage Examples:

import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;

// Create and show modal
public void showFeedbackModal(SlashCommandInteractionEvent event) {
    TextInput subject = TextInput.create("subject", "Subject", TextInputStyle.SHORT)
        .setPlaceholder("Brief summary of your feedback")
        .setMaxLength(100)
        .setRequired(true)
        .build();
    
    TextInput feedback = TextInput.create("feedback", "Feedback", TextInputStyle.PARAGRAPH)
        .setPlaceholder("Detailed feedback...")
        .setMaxLength(1000)
        .setRequired(true)
        .build();
    
    Modal modal = Modal.create("feedback-modal", "Submit Feedback")
        .addActionRows(ActionRow.of(subject), ActionRow.of(feedback))
        .build();
    
    event.replyModal(modal).queue();
}

// Handle modal interactions
public class ModalHandler extends ListenerAdapter {
    @Override
    public void onModalInteraction(ModalInteractionEvent event) {
        if (event.getModalId().equals("feedback-modal")) {
            String subject = event.getValue("subject").getAsString();
            String feedback = event.getValue("feedback").getAsString();
            
            // Process feedback
            EmbedBuilder embed = new EmbedBuilder()
                .setTitle("Feedback Received")
                .addField("Subject", subject, false)
                .addField("Feedback", feedback, false)
                .addField("User", event.getUser().getAsTag(), true)
                .addField("Guild", event.getGuild().getName(), true)
                .setTimestamp(Instant.now())
                .setColor(Color.GREEN);
            
            // Send to feedback channel
            TextChannel feedbackChannel = event.getGuild().getTextChannelsByName("feedback", true).stream()
                .findFirst()
                .orElse(null);
            
            if (feedbackChannel != null) {
                feedbackChannel.sendMessageEmbeds(embed.build()).queue();
            }
            
            event.reply("Thank you for your feedback! We'll review it soon.").setEphemeral(true).queue();
        }
    }
}

Context Menu Commands

Right-click context menu commands for users and messages.

/**
 * User context menu interaction.
 */
interface UserContextInteraction extends IReplyCallback {
    /** Get target user */
    User getTarget();
    
    /** Get target member */
    Member getTargetMember();
}

/**
 * Message context menu interaction.
 */
interface MessageContextInteraction extends IReplyCallback {
    /** Get target message */
    Message getTarget();
}

Usage Examples:

// Register context menu commands
jda.updateCommands().addCommands(
    Commands.user("Get Avatar"),
    Commands.message("Report Message")
).queue();

// Handle context menu interactions
public class ContextMenuHandler extends ListenerAdapter {
    @Override
    public void onUserContextInteraction(UserContextInteractionEvent event) {
        if (event.getName().equals("Get Avatar")) {
            User target = event.getTarget();
            
            EmbedBuilder embed = new EmbedBuilder()
                .setTitle(target.getName() + "'s Avatar")
                .setImage(target.getEffectiveAvatarUrl() + "?size=256")
                .setColor(Color.BLUE);
            
            event.replyEmbeds(embed.build()).queue();
        }
    }
    
    @Override
    public void onMessageContextInteraction(MessageContextInteractionEvent event) {
        if (event.getName().equals("Report Message")) {
            Message target = event.getTarget();
            
            // Create report modal
            TextInput reason = TextInput.create("reason", "Reason", TextInputStyle.PARAGRAPH)
                .setPlaceholder("Why are you reporting this message?")
                .setRequired(true)
                .build();
            
            Modal modal = Modal.create("report-modal", "Report Message")
                .addActionRows(ActionRow.of(reason))
                .build();
            
            event.replyModal(modal).queue();
        }
    }
}

Types

// Option types for slash commands
enum OptionType {
    SUB_COMMAND, SUB_COMMAND_GROUP, STRING, INTEGER, BOOLEAN, USER, CHANNEL, ROLE, MENTIONABLE, NUMBER, ATTACHMENT
}

// Button styles
enum ButtonStyle {
    PRIMARY, SECONDARY, SUCCESS, DANGER, LINK
}

// Text input styles
enum TextInputStyle {
    SHORT, PARAGRAPH
}

// Interaction context types
enum InteractionContextType {
    GUILD, BOT_DM, PRIVATE_CHANNEL
}

// Default member permissions
class DefaultMemberPermissions {
    static DefaultMemberPermissions ENABLED;
    static DefaultMemberPermissions DISABLED;
    
    static DefaultMemberPermissions enabledFor(Permission... permissions);
    static DefaultMemberPermissions enabledFor(Collection<Permission> permissions);
}

Install with Tessl CLI

npx tessl i tessl/maven-net-dv8tion--jda

docs

audio.md

core-management.md

entities.md

events.md

index.md

interactions.md

messaging.md

restactions.md

sharding.md

tile.json