logo

Constatic

Discord Bot BaseResponders

Select menu

How to reply discord select menus

Creating a Responder for a Selection Menu

It is possible to create a Responder that can accept several types of select menus, see an example:

command.ts
// ...
const row = createRow(
    new StringSelectMenuBuilder({
        customId: "select/fruits",
        placeholder: "Select fruits",
        options: [
            { emoji: "🍎", label: "Apple", value: "apple" },
            { emoji: "πŸ‰", label: "Melon", value: "melon" },
            { emoji: "🍊", label: "Orange", value: "orange" }
        ]
    })
);
interaction.reply({ flags: ["Ephemeral"], components: [row] });
// ...

Above is the code to send a common selection menu as a response to a command. Just below you can see a Responder with ResponderType.StringSelect in the types, so that the run function of this Responder will be executed when someone selects from this selection menu:

responder.ts
createResponder({
    customId: "select/fruits",

    types: [ResponderType.StringSelect], cache: "cached",
    async run(interaction) {
        const selected = interaction.values[0];
        interaction.update({ flags: ["Ephemeral"], content: `${selected} Selected`, components: [] });
    },
});

You can combine several different types of select menus:

responder.ts
createResponder({
    customId: "ban/user", cache: "cached",
    types: [
        ResponderType.StringSelect,
        ResponderType.UserSelect,
    ],
    async run(interaction) {
        const { guild, values: [selected] } = interaction;
 
        await interaction.update({});
 
        if (interaction.isUserSelectMenu()){
            const member = guild.members.get(selected);
            await member.ban(); 
        } else {
            const member = guild.members.cache.find(m => m.user.username === selected);
            await member.ban(); 
        }
 
        await interaction.editReply({ 
            flags: ["Ephemeral"], components: [] 
            content: `${userMention(selected)} was banned!`, 
        });
    },
});

Below are all the types of select menus:

Select MenuResponderType
StringsResponderType.StringSelect
UsersResponderType.UserSelect
ChannelsResponderType.ChannelSelect
RolesResponderType.RoleSelect
MentionsResponderType.MentionableSelect

It is possible to combine with any type, this way you can have a button, a select menu and a modal with the same customId and they will all be answered in this function, just do the checks:

responder.ts
createResponder({
    customId: "menus/main", cache: "cached",
    types: [
        ResponderType.Button,
        ResponderType.StringSelect,
        ResponderType.ModalComponent,
    ],
    async run(interaction) {
        switch (true) {
            case interaction.isButton():
                console.log("BotΓ£o")
                return;
            case interaction.isStringSelect():
                console.log("Menu de seleção", interaction.values);
                return;
            default:
                console.log("Modal", interaction.fields);
                return;
        }
    },
});

On this page