Creating Your App
Overview
This section adapts the Discord.js guide's Creating Your App topics to discord.go. It explains how to organize a Go bot, define commands, route invocations, synchronize command schemas, and handle Gateway events. Start with Project Setup if the application is empty.
Architecture
A discord.go application normally has a small main package that loads configuration, creates one bot.Router, registers commands, creates one bot.Bot, registers event observers, and starts the lifecycle. The router handles slash commands and prefix commands. The bot handles Gateway events and exposes Rest for operations that need an explicit API call. Discord receives command definitions through REST, then sends command invocations back through the Gateway.
Prerequisites
- Complete the setup pages.
- Use Go
1.26.4or newer. - Have a bot token and an installed test application.
- Know the test guild ID if using fast guild synchronization.
Quick Start
Save this complete program as main.go in a Go module and run it from the module root:
export DISCORD_TOKEN='replace-with-a-bot-token'
go run .package main
import (
"log"
"os"
"github.com/discord-go/discord.go/bot"
"github.com/discord-go/discord.go/intents"
)
func main() {
token := os.Getenv("DISCORD_TOKEN")
if token == "" {
log.Fatal("DISCORD_TOKEN is required")
}
router := bot.NewRouter()
router.Command("ping", "Check whether the bot is online", func(ctx *bot.InteractionContext) {
if err := ctx.Reply("Pong."); err != nil {
log.Printf("reply: %v", err)
}
})
b := bot.New(token,
bot.WithIntents(intents.Guilds),
bot.WithRouter(router),
)
b.OnReady(func(ctx *bot.ReadyContext) {
log.Printf("ready as %s", ctx.User.Username)
})
if err := b.Run(); err != nil {
log.Fatal(err)
}
}Creating/Using
Create definitions before starting the bot. router.Command registers a slash command and its handler. bot.WithRouter makes the bot synchronize those definitions after READY. For a larger application, keep command registration in feature functions and pass the same router to each function; do not create a new router per command.
Common Patterns
- Keep
mainresponsible for wiring and feature packages responsible for registration. - Use
router.CommandEorrouter.MustCommandto validate static definitions during startup. - Use
bot.GuildOnly,bot.RequirePermissions, andbot.Cooldownas route middleware. - Defer an interaction before slow REST or database work.
- Use a guild sync target while developing and explicit REST deployment in CI or a release job.
Best Practices
- Keep command names lower-case and descriptions meaningful.
- Treat options, custom IDs, and context-menu targets as untrusted input.
- Keep one deterministic command registry per deployment.
- Log command names and IDs, but do not log tokens or sensitive option values.
- Make handlers safe for concurrent execution and return all response errors to a logger.
Common Mistakes
Incorrect
router := bot.NewRouter()
b := bot.New(token, bot.WithRouter(bot.NewRouter()))
router.Command("ping", "Check the bot", handler)Correct
router := bot.NewRouter()
router.Command("ping", "Check the bot", handler)
b := bot.New(token, bot.WithRouter(router))Incorrect
router.Command("Ping", "", handler)Correct
router.Command("ping", "Check whether the bot is online", handler)The router normalizes names to lower-case, but router.Validate still requires valid Discord names and non-empty chat-input descriptions.
API Walkthrough
bot.NewRoutercreates the registry.router.Commandregisters a slash command.router.Prefixregisters a message command when message content is enabled.router.Useapplies middleware to slash commands.router.Validatechecks the command registry without connecting.bot.WithRouterattaches the registry to the bot.bot.WithCommandSyncorbot.WithGuildCommandSyncselects synchronization behavior.
Examples
- Project Setup separates wiring from registration.
- Creating Commands defines options and handlers.
- Handling Commands covers acknowledgements and follow-ups.
- Deploying Commands uses the REST API explicitly.
- Handling Events observes Gateway lifecycle and guild events.
- Slash Commands contains a larger command catalog.