Overview
Custom Commands Dashboard

A drag-and-drop builder for slash commands and text triggers

The Custom Commands page lets you assemble a command from twelve step types — text replies, embeds, branches, lookups, role gates — with drafts you can iterate on and publish atomically. Live analytics tell you which commands earn their keep and which to retire.

Path
DashboardServerCommands
Module
Custom Commands
Required permission
customcommands.view

Before you build a command

Custom Commands is a Pro feature. The page header carries a PRO chip linking to billing if you are on Free.

  • Custom Commands module enabled in Server Settings (or guild is on Custom-Host).
  • You hold customcommands.view to read the page; customcommands.edit to save drafts; customcommands.publish to push live.
  • Server is on Pro — the module is gated by tier.
  • You know whether you want a slash command, a chat trigger (startswith / contains / regex), or both — the trigger type is the first thing you pick.

The four tabs

List
Builder
Analytics
Audit
List
Every command on the server in a sortable card grid, with enable toggles.
Builder
The drag-and-drop step editor where new and existing commands are authored.
Analytics
Invocations, failures, p95 latency and a top-commands chart.
Audit
Every create/update/publish/rollback event with actor and diff.

List tab — your command catalogue

The default landing tab. A grid of cards, one per command. Click any to open it in the Builder tab.

What each card shows

  • Command name with trigger type pill (COMMAND / STARTSWITH / CONTAINS / REGEX).
  • A short description if you wrote one.
  • Live status: Published, Draft, Disabled.
  • Enable/disable toggle that takes effect immediately.
  • Quick stats: invocations and failures over the last 7 days.
  • Action menu: duplicate, delete, copy ID, open in builder.
Drafts and publishes live side by side
A command with both a published version and an unpublished draft shows two chips on its card. The published version keeps running for users while you edit the draft on the Builder tab. Hit Publish to swap them atomically.

Builder tab — the step editor

The Builder is split into three columns: a metadata panel on the left, the step list in the centre, and a preview/validation panel on the right.

Left column — command metadata

nameText input

Slash-command name (lowercase, hyphens only) or trigger phrase, depending on triggerType.

Example: welcome

triggerText input

The actual phrase users type. For COMMAND it is /name; for STARTSWITH/CONTAINS it is a substring; for REGEX it is a JavaScript regular expression.

Example: !welcome

triggerTypeDropdown

COMMAND for slash, STARTSWITH for chat starts-with, CONTAINS for chat substring, REGEX for full-power matching.

Example: COMMAND

descriptionText input

One-line summary shown in the slash-command picker and on the List card.

who_can_runRole picker

Multi-role picker. Empty = anyone can run; otherwise members must hold at least one of the listed roles.

where_can_runChannel picker

Multi-channel picker. Empty = any channel; otherwise the command is only valid in those channels.

deny_in_dmsToggle

When on, the command cannot be invoked in a bot DM. Default on for safety.

Example: On

cooldown_scopeDropdown

USER (per member), CHANNEL (per channel), or GUILD (per server) cooldown bucketing.

Example: USER

cooldown_duration_msDuration

How long after a successful run the next invocation is rate-limited.

Example: 3000

Centre column — the step list

The heart of the builder. Drag step cards from the palette into the list. Each step has its own configuration form. Run order is top to bottom; steps can be reordered by drag handle.

Right column — preview and validation

  • Live preview of every embed and text reply at the moment you edit them.
  • Validation panel — red dots on broken steps (missing channel, invalid regex, undefined variable).
  • Variables side-panel — every variable the command reads or writes.
  • Two save buttons: Save Draft (always available) and Publish (only enabled when zero validation errors).

The twelve step kinds

Every command is a list of these. Click + in the step palette to add one.

Reply steps

  • RESPOND_TEXT — plain message in the channel where the command was invoked.
  • RESPOND_EMBED — full Discord embed (title, description, fields, colour, image, footer).
  • RESPOND_EPHEMERAL — only the invoker sees the reply. Useful for slash commands that confirm an action.

Side-effect steps

  • ADD_REACTION — add an emoji to the invoking message (only valid for chat triggers).
  • SEND_TO_CHANNEL — post to a different channel from the one the command ran in.
  • WARN_USER — issue a soft warning recorded in the moderation module.

Control-flow steps

  • IF — branch on a condition; nests other steps under "then" and "else".
  • SWITCH — multi-branch on a variable's value. Cleaner than nested IFs.
  • STOP — early return. Useful inside an IF when a precondition is missing.

Data steps

  • SET_VAR — write to a variable (per-run, per-user, or per-guild scope).
  • FORMAT — string template that fills variables and writes the result back to a variable.
  • LOOKUP — fetch by key from the variables store; populates a temp variable for downstream steps.
Order matters; FORMAT-then-RESPOND is the common pattern
Most commands you build will be: SET_VAR or LOOKUP to gather data → FORMAT to compose a string → RESPOND_TEXT or RESPOND_EMBED to send it. IF and SWITCH gate sub-steps based on what was looked up.

Trigger types in detail

COMMAND
Discord slash command. Registered with Discord on publish; appears in the / picker. Best for first-class commands.
STARTSWITH
Plain-text chat trigger. Fires when a message begins with the configured phrase. Cheap, but less discoverable for users.
CONTAINS
Fires when the configured phrase appears anywhere in the message. Use sparingly — a 3-letter substring will match a lot.
REGEX
Full JavaScript regular expression. Required for complex pattern matching. Validation runs your regex on a sample on every save.

Save Draft vs. Publish

Two save buttons in the top-right of the Builder. They behave very differently.

Save Draft

  • Always enabled — drafts can be invalid.
  • Persists your work without affecting the live command.
  • You can keep editing across days; the draft sticks.
  • Multiple authors editing the same draft last-write-wins; coordinate via the audit log.

Publish

  • Only enabled when the validation panel is fully green.
  • Atomically swaps draft → published. Users see the new behaviour on the next invocation.
  • For COMMAND triggers, also re-registers with Discord — there can be a 1-2 minute delay before slash users see the new options.
  • The previous published version is preserved on the audit log for one-click rollback.

Analytics tab

A focused dashboard for command performance. Stats and charts only — no editing.

KPI tiles

  • Invocations — total successful runs in the window.
  • Failures — runs that errored out. Click for breakdown by step kind.
  • Avg execution time — mean wall-clock duration in milliseconds.
  • p95 execution time — slowest 5% of runs. The number to optimise if your commands feel laggy.

Charts

  • Invocations-over-time line chart for the selected window (24h / 7d / 30d).
  • Top commands bar chart — usage leaderboard.
  • Sortable table with all commands by uses, with failure rate and p95 columns.
Retire bottom-quartile commands
Most servers accumulate dead commands. Sort the table by 30-day uses ascending — anything with single-digit invocations is a candidate for deletion. Less choice in the slash picker means more discoverability for the commands that matter.

Audit tab

Paginated table of every command lifecycle event. Same columns as elsewhere on the dashboard.

Action types you will see

  • CREATED — command first saved as draft.
  • UPDATED — draft saved with changes.
  • PUBLISHED — draft pushed live. Diff shows old-vs-new step list.
  • DELETED — command removed.
  • ROLLED_BACK — restored from a previous published version.
  • TOGGLED — enable/disable toggle flipped on the List card.

Common tasks

1

Build your first slash command

A simple /ping that replies pong with the bot latency.

Open CommandsBuilder.

  • Left column: name = ping, trigger = ping, triggerType = COMMAND, description = "Latency check".
  • Centre column: drag a RESPOND_TEXT step. Set its content to "Pong! {{ms}}ms" — variables auto-resolve.
  • Right column: validation should be all green. Click Publish.
  • Wait 1-2 minutes for Discord to register the slash. Try /ping in your server.
2

Add a role gate to an existing command

  • List tab → click the command card to open it in Builder.
  • Left column → who_can_run → pick the roles allowed (e.g., Mods, Admins).
  • Optional: keep the command public but add an early IF step that checks role and STOPs if missing — this lets you customise the rejection message.
  • Save Draft, then Publish.
3

Roll back a publish that broke something

  • Audit tab → find the most recent PUBLISHED row for the command.
  • Click the entry; the right-side panel shows the diff and a Rollback button.
  • Confirm. The previous version is restored as the live publish; your faulty draft is preserved unchanged so you can fix it.
  • Open the command in Builder, repair, Publish again.

Troubleshooting

Slash command not appearing in the / picker
Discord caches slash registrations for 1-2 minutes after publish. If after 5 minutes it still does not appear, check the Audit tab to confirm PUBLISHED actually fired. Trigger types other than COMMAND do not register with Discord and will never appear in the / picker.
Command runs but says nothing
You have steps but no RESPOND_*. Builder validation will warn you on save; the command technically succeeds (and counts as an invocation) but produces no output. Add a RESPOND_TEXT, RESPOND_EMBED, or RESPOND_EPHEMERAL step.
REGEX trigger matches things you didn't intend
Test your regex on the right-column preview field before publishing. A common mistake is forgetting to anchor — ^!hi$ versus !hi are very different. Validation will refuse a regex that errors on parse, but it will not catch over-broad patterns.
Cooldown reset is per scope, not per command
USER scope means the same user can run any of their commands (across the server) once per cooldown window only if they share buckets. Most users do not need to think about this — leave on USER, leave duration at 3 seconds.