ux

Slash Commands, Buttons, and Modals: Better Bot Interactions

Rank.top Team4 min read

Design short, clear Discord workflows with useful defaults, timely replies, and safe permission checks.

Use the smallest interaction that does the job

ControlUse it forExample
Slash commandStarting a task with structured inputs/remind time message
ButtonA clear next actionConfirm, cancel, next page
Select menuChoosing from known optionsPick a channel or category
ModalCollecting longer or structured inputDescribe a bug or submit feedback
Context-menu commandActing on a user or messageReport this message

Use familiar verbs and put required inputs first. Prefer a channel or role picker over asking people to paste an ID. If a command needs several paragraphs of instructions, split it into smaller steps.

Reply before the interaction expires

Discord requires an initial response within three seconds. If work takes longer, defer promptly and then edit the reply. Interaction tokens can be used for follow-ups for 15 minutes. See the interaction response reference.

discord.js · a slower command
await interaction.deferReply({ flags: MessageFlags.Ephemeral });

try {
const result = await createReport();
await interaction.editReply({ content: result.summary });
} catch {
await interaction.editReply({
content: "The report could not be created. Please try again shortly.",
});
}

This handler fragment assumes MessageFlags is imported from discord.js and that createReport has a timeout. Use private replies for account details or setup errors that only the requester needs to see.

Treat every click as a new request

  • Check the user, server, and permissions on the server before applying a change.
  • Use a short-lived identifier for saved interaction state; do not put secrets in custom IDs.
  • Make repeated clicks safe and disable controls once their action is complete.
  • Confirm destructive actions with the target and effect spelled out.
  • Handle expired controls with a clear way to start again.

A hidden button or a command’s default permissions is not enough to authorize a sensitive operation. Permissions may have changed since the message was sent.

Test the awkward cases

Try the flow on mobile, with a long channel name, with missing permissions, and after the bot restarts. Click twice. Open an old message. Cancel halfway through. These cases reveal more than repeatedly testing the happy path.

Keep the final reply specific: “Reminder saved for Friday at 18:00” is more useful than “Success.” For access checks, see Discord permissions explained.

keep reading

More from the blog

All articles