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.
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 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.
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
Slash-command name (lowercase, hyphens only) or trigger phrase, depending on triggerType.
Example: welcome
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
COMMAND for slash, STARTSWITH for chat starts-with, CONTAINS for chat substring, REGEX for full-power matching.
Example: COMMAND
One-line summary shown in the slash-command picker and on the List card.
Multi-role picker. Empty = anyone can run; otherwise members must hold at least one of the listed roles.
Multi-channel picker. Empty = any channel; otherwise the command is only valid in those channels.
When on, the command cannot be invoked in a bot DM. Default on for safety.
Example: On
USER (per member), CHANNEL (per channel), or GUILD (per server) cooldown bucketing.
Example: USER
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.
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.
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
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.
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.
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.