BDFD Buttons and Select Menus: $addButton and $newSelectMenu
Add clickable buttons with $addButton and dropdown menus with $newSelectMenu and $addSelectMenuOption in a BDFD command, with a role self-assign example.
In this guide
Standard message text is great, but modern Discord bots are built on Rich Interactions. Adding visual Buttons and Dropdown Select Menus turns your bot into a highly interactive application, removing the need for users to type complex, error-prone parameters.
In this guide, we will learn how to attach functional buttons and select menus to your bot responses using Bot Designer for Discord (BDFD) / Bot Creator.
🔘 Attaching Clickable Buttons ($addButton)
Buttons are interactive attachments that appear at the bottom of any message or embed. A message holds up to 5 rows of 5 buttons (25 buttons at most); a select menu takes a whole row to itself:
$addButton[newRow;customIDOrURL;label;style;(disabled);(emoji);(messageID)]
newRow: (yesorno, alsotrue/false). Set toyesto put this button on a brand new row. Withno, the button joins the last row if that row only holds buttons and has fewer than 5 of them; otherwise a new row is started.customIDOrURL: The unique identifier for this button (e.g.btn_verify, at most 100 characters; two components cannot share the same ID), or anhttp(s)URL when using thelinkstyle.label: The text displayed directly on the button (at most 80 characters). It may be empty only if you give an emoji.style: Required. One of (lowercase):primary(Blurple)secondary(Grey)success(Green)danger(Red)link(Grey with redirect icon, requires anhttp(s)URL instead of a custom ID)
disabled: (Optional,yesorno, defaultno). Set toyesto make the button unclickable.emoji: (Optional) A Unicode emoji (like💻) or a custom emoji written as<:name:id>(<a:name:id>for an animated one).messageID: (Optional) The ID of an existing message to add the button to, instead of the response being built.
🔽 Constructing Dropdown Menus ($newSelectMenu)
Select menus let users pick one or more options from a list. A single menu can contain up to 25 choices. BDFD does not have an $addSelectMenu function: you create the menu with $newSelectMenu, then fill it with $addSelectMenuOption.
Step 1: Initialize the Menu
$newSelectMenu[customID;minValues;maxValues;(placeholder);(messageID)]
customID: Unique identifier for this menu block (at most 100 characters).minValues/maxValues: The minimum (0 to 25) and maximum (1 to 25) options a user must pick; the minimum cannot exceed the maximum. Set both to1for standard single-choice menus.placeholder: (Optional) The grey helper text shown when nothing is selected (at most 150 characters).messageID: (Optional) The ID of an existing message to add the menu to.
Step 2: Populate the Choices
Immediately after initializing the menu, add options using $addSelectMenuOption:
$addSelectMenuOption[menuID;label;value;description;(default);(emoji);(messageID)]
menuID: ThecustomIDof the menu to fill.label/value: The text shown to the user and the value you receive when it is picked (1 to 100 characters each). Values must be unique inside a menu.description: Required argument, but it may be empty (up to 100 characters).default: (Optional,yesorno, defaultno). Only one option of a menu can be the default.emoji: (Optional) Same format as for buttons.
$newSelectMenu[colour_menu;1;1;Pick a colour]
$addSelectMenuOption[colour_menu;Red;red;The red option]
$addSelectMenuOption[colour_menu;Blue;blue;The blue option;yes]
🛠️ Handling Interactions: The Event Workflow
When a user clicks a button or selects an option, Discord triggers an Interaction Event. To process these clicks:
- Give every component a unique
customID. - In Bot Creator, a click that has no dedicated listener is handled by your
interactionCreateevent. - In that event, read the context variables like
((interaction.customId))or((interaction.stringSelect.value))to know what was clicked or chosen.
🏆 Production Example: Role Self-Assign Menu
Let’s build a clean, fully functional self-role assignment embed. Users can click buttons to assign themselves roles without typing any commands!
Initial Command: !roles
Spawns the menu with buttons.
$nomention
$title[🎭 Select Your Roles!]
$color[#6366f1]
$description[
Click the buttons below to assign roles instantly:
* 💻 **Developer Role**
* 🎨 **Designer Role**
]
$addButton[no;role_dev;Developer;primary;no;💻]
$addButton[no;role_design;Designer;success;no;🎨]
The Interaction Handler Command
- Trigger: the
interactionCreateevent; the code tells the buttons apart with their custom IDs (role_devandrole_design). - Code:
$nomention
$if[((interaction.customId))==role_dev]
$giveRole[((interaction.userId));112233445566778899]
$ephemeral
✅ The **Developer** role has been added to your profile!
$endif
$if[((interaction.customId))==role_design]
$giveRole[((interaction.userId));998877665544332211]
$ephemeral
✅ The **Designer** role has been added to your profile!
$endif
[!IMPORTANT] Use $ephemeral at the start of your interaction callback to make the success message private, visible only to the clicking user. This keeps public channels clean!