Registering commands
guidePush structure and builder commands to Discord with update, register and unregister, and read back what's already there.
This page covers the three effects that push slash, context and builder commands to Discord, and reading back what's already registered. You're assumed to have a bot named "my-bot" logged in and at least one command declared, structure or builder.
How registration works
Nothing reaches Discord on its own: a slash command structure and a new slash command builder are both just models until a script runs one of three effects on them.
Effect | Does | Use when |
|---|---|---|
Replaces the whole list (a PUT): anything missing from the given commands is removed | Startup sync, pushing every command at once | |
Upserts by name: adds or replaces, leaves the rest of the list alone | Adding or editing one command without touching the others | |
Removes one command, by object, name or id, or all of them | Retiring a command, or clearing a list |
on guild ready: update the discord commands (all structured application commands) in event-guild
all structured application commands collects every slash command, user command and message command structure into one list, so a builder command joins the same call: update the discord commands (all structured application commands) and {_roll} in event-guild. Every one of the three effects blocks until Discord answers and never takes await; a failure on Discord's side goes through the error layer.
update [the] [discord] [application] command[s] [to] %applicationcommands% (globally (in|for|of|on) [the] [bot] %-bot%|in [the] [guild] %-guild%)Replaces every application command of a bot (globally) or of a guild with the given ones: what is not in the list is removed from Discord. This is the one call to make from 'on ready' / 'on guild ready'.Guild or global
in event-guild applies immediately and is scoped to that one guild; globally in event-bot applies to every guild the bot is in, but can take up to an hour to show up for users. Guild registration belongs in on guild ready, which fires for every guild the bot is in (including ones it joins later); global registration belongs in on ready, which fires once. See Starting a bot for how the two lifecycle events differ.
on ready: set {_ping} to a new slash command named "ping" with description "Pong!" update the discord commands {_ping} globally in event-bot
Pushing the same command both ways makes Discord show it twice: guild-scoped and global commands are separate lists, not one merged into the other. Discord also limits how often a guild's whole list can be replaced with update: 200 times a day.
Adding and removing one command
register and unregister change one command without replacing the whole list.
on guild ready: set {_roll} to a new slash command named "roll" with description "Roll a dice" register the discord command {_roll} in event-guild
register also takes several commands at once: register the discord commands {_a} and {_b} globally in event-bot. unregister accepts a command object, a name, or a raw id, and a shorthand for everything:
unregister the discord command "ping" from event-guild unregister the discord command {_roll} from event-guild unregister all the discord commands from event-guild
A command object with a known command id is deleted directly; a name is looked up among the registered commands first, so it costs an extra request.
register [the] [discord] [application] command[s] %applicationcommands% (globally (in|for|of|on) [the] [bot] %-bot%|in [the] [guild] %-guild%)Adds or replaces (by name) one or more application commands of a bot (globally) or of a guild, leaving the other registered commands alone. Use 'update the discord commands' to replace the whole list.Reading what Discord has
registered commands of asks Discord for the live list of a guild or a bot's global commands, as regular command objects with their command id already set. It's a retrieve, so it needs await:
await set {_cmds::*} to registered commands of event-guild loop {_cmds::*}: send "%name of loop-value% (%command id of loop-value%, %command type of loop-value%)" to console
A retrieved command can be edited and pushed back with register, upserting it by name:
await set {_cmds::*} to registered commands of event-guild loop {_cmds::*}: if name of loop-value is "roll": set disabled of loop-value to true register the discord command loop-value in event-guild
[all [of]] [the] registered [discord] [application] commands (of|from|in) [the] %bot/guild%The application commands currently registered on Discord: globally for a bot, or for one guild. They come back as regular command objects (with their 'command id'), so they can be edited and pushed again.Reload and shutdown
A slash command or context command structure is a model, not a live registration: reloading a script swaps the model, and the command already pushed to Discord keeps working, bound to whichever model matches its full path at the time it's used. on cooldown cooldowns are part of that model, so a reload also resets them.
Removing a structure from a script, unloading it, or shutting the bot down never deletes the matching command from Discord. It stays visible and answerable (through the generic events, if nothing else) until the next update drops it from the list, or an explicit unregister removes it.
Errors you may see
Message (console) | Cause | Fix |
|---|---|---|
the bot 'x' is not connected, it cannot manage commands yet |
| wait for |
no bot or guild to manage commands in (the variable is not set) | the | check the variable is set before the effect runs |
expected a bot (global commands) or a guild, got x |
| pass |
'registered commands of' asks Discord and requires 'await' to be read |
| wrap the read in |
A Discord error naming code | a pushed command breaks one of Discord's own limits (name length, duplicate option names, too many choices...) | check the command against Discord's limits; the error names the exact field |