Deploying Commands
Overview
Deploying Commands means sending application-command definitions to Discord. discord.go can synchronize a router automatically after READY, but a release pipeline may prefer an explicit REST deployment. This page shows guild bulk overwrite, the fast development path, and the distinction between guild and global commands.
Architecture
Command deployment is a REST operation separate from command handling. rest.BulkOverwriteGuildCommands replaces the complete command set for one guild. rest.BulkOverwriteGlobalCommands replaces the global set. Automatic router sync performs the same kind of operation after the bot connects; a deployment job can use a REST client without opening a Gateway session.
Prerequisites
- A bot token with access to the application.
- A valid guild ID for development deployment.
applications.commandsinstalled in the guild.- Go
1.26.4or newer.
Quick Start
Save this complete deployment program as main.go in a deployment module. It overwrites the commands in DISCORD_GUILD_ID:
export DISCORD_TOKEN='replace-with-a-bot-token'
export DISCORD_GUILD_ID='123456789012345678'2
package main
import (
"context"
"log"
"os"
"time"
"github.com/discord-go/discord.go/interactions"
"github.com/discord-go/discord.go/rest"
"github.com/discord-go/discord.go/snowflake"
)
func main() {
token := os.Getenv("DISCORD_TOKEN")
if token == "" {
log.Fatal("DISCORD_TOKEN is required")
}
guildID, err := snowflake.Parse(os.Getenv("DISCORD_GUILD_ID"))
if err != nil || guildID == 0 {
log.Fatal("DISCORD_GUILD_ID must be a valid snowflake")
}
typ := interactions.ApplicationCommandTypeChatInput
commands := []rest.CreateCommandParams{
{Name: "ping", Description: "Check whether the bot is online", Type: &typ},
}
client := rest.New(token, nil, nil)
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
application, err := client.GetCurrentApplication(ctx)
if err != nil {
log.Fatalf("get application: %v", err)
}
deployed, err := client.BulkOverwriteGuildCommands(ctx, application.ID, guildID, commands)
if err != nil {
log.Fatalf("deploy commands: %v", err)
}
log.Printf("deployed %d commands to guild %s", len(deployed), guildID)
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Creating/Using
For a bot process, attach a router and let bot.WithGuildCommandSync synchronize during development. For a release job, build a deterministic slice of rest.CreateCommandParams, resolve the application ID with GetCurrentApplication, and call one bulk-overwrite method. Bulk overwrite removes commands not present in the submitted slice, which makes deletion intentional and reviewable.
Guild commands appear quickly and are ideal for testing. Global commands are visible across installed guilds but changes can take up to an hour to propagate. Do not use a production global application as a test registry.
Common Patterns
- Use
bot.WithGuildCommandSyncfor local development. - Use
bot.WithCommandSyncDisabledwhen an external deploy job owns registration. - Use
rest.BulkOverwriteGuildCommandsfor a complete test-guild registry. - Use
rest.BulkOverwriteGlobalCommandsfor a released application registry. - Use
GetGuildApplicationCommandsorGetGlobalApplicationCommandsto inspect deployed state. - Use a context timeout for every deployment request.
Best Practices
- Deploy the complete intended set, not a partial list, with bulk overwrite.
- Keep deployment and runtime credentials protected in CI.
- Verify application and guild IDs before making destructive synchronization calls.
- Review command schema changes as carefully as code changes.
- Use separate applications for staging and production.
Common Mistakes
Incorrect
client.BulkOverwriteGlobalCommands(context.Background(), appID, commands)Correct
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_, err := client.BulkOverwriteGlobalCommands(ctx, appID, commands)
if err != nil {
log.Printf("deploy commands: %v", err)
}2
3
4
5
6
Incorrect
commands := []rest.CreateCommandParams{newCommand}
client.BulkOverwriteGuildCommands(ctx, appID, guildID, commands)2
Correct
commands := allCommandsForThisRelease()
deployed, err := client.BulkOverwriteGuildCommands(ctx, appID, guildID, commands)2
Bulk overwrite treats the slice as the source of truth; omitting a command deletes it from that scope.
API Walkthrough
rest.Newcreates a bot-authenticated REST client.GetCurrentApplicationresolves the application ID through/applications/@me.rest.CreateCommandParamsis the wire shape for a command definition.BulkOverwriteGuildCommandsreplaces a guild command set.BulkOverwriteGlobalCommandsreplaces a global command set.GetGuildApplicationCommandsandGetGlobalApplicationCommandsinspect deployed commands.bot.WithCommandSyncDisabledprevents automatic synchronization in a runtime bot.bot.WithGuildCommandSyncselects fast automatic guild synchronization.
Examples
- Adding Your App uses automatic guild sync.
- Creating Commands builds command options.
- Slash Commands explains global propagation.
- REST command source lists all deployment methods.