High-Level Developer Guides
Overview
The high-level API is the application-facing layer of discord.go. It turns gateway events into typed contexts, routes commands and components, provides message and interaction response helpers, and owns the bot lifecycle. A first application normally needs bot, intents, and one or more resource packages; it does not need to decode gateway payloads itself.
This guide assumes a Go module can import the repository module as discord.go. For protocol details, continue with the low-level guides.
Architecture
The main flow is:
bot.Newcreates aBotaround a gateway connection and arest.Client.- Functional options configure intents, routing, presence, cache, logging, and sharding.
Start,Run, orRunContextopens the gateway and dispatches events in handler goroutines.- A
Routermaps slash commands, prefix commands, buttons, selects, modals, and autocomplete requests to handlers. - Typed contexts expose both the event data and convenience methods such as
Reply,Defer,Fetch, andUpdate.
The Bot.Rest field remains the escape hatch for REST endpoints that do not have a context helper. See the REST request guide and endpoint reference when using it directly.
Quick Start
Create main.go in the module root and run it with a bot token. The program is complete and connects to Discord, registers /ping, and waits for a signal.
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),
)
if err := b.Run(); err != nil {
log.Fatal(err)
}
}Install the application in a test guild with the applications.commands scope, export DISCORD_TOKEN, and run go run .. Global command registration can take up to an hour to propagate; use bot.WithGuildCommandSync(guildID) while developing.
Creating/Configuration
Start with bot.New(token, opts...). Useful options include WithIntents, WithPrefix, WithBotName, WithMentionTriggers, WithRouter, WithPresence, WithCache, WithStore, WithLogger, WithErrorHandler, WithGatewayCompression, WithShards, WithMaxHandlerConcurrency, and WithCommandSync. The bot.Config helpers are covered in configuration.md.
Keep the token outside source control. Request only the gateway intents the application actually uses, and enable privileged intents in the Discord Developer Portal before requesting them in code.
Using
Basic: handle a command
Register a command on a Router, attach it with WithRouter, and reply through the interaction context. Errors from response methods should be logged or sent to the bot error handler.
Intermediate: add a component flow
Send a button or select with InteractionCallbackData, then register a route with Router.Button, Router.Select, or their prefix variants. Use InteractionContext.Update when the triggering message should change.
Advanced: combine middleware, cache, jobs, and REST
Use command middleware for authorization and cooldowns, WithCache for cheap lookups, Every for lifecycle-owned periodic work, and Bot.Rest for an endpoint without a convenience method. Keep network work behind a context with a meaningful deadline.
Common Patterns
- Use guild command sync for local development and global sync for release.
- Reply immediately when possible; call
Deferbefore work that may exceed the interaction response window. - Scope component IDs with a stable prefix such as
ticket:close:. - Treat cache hits as hints and use
Fetch*when fresh data is required. - Register
OnErrorand logBot.Stats()so operational failures are visible.
Best Practices
Choose the high-level layer first
Why: it supplies lifecycle, routing, and typed contexts in one place.
Pros: less protocol code, consistent error handling, and faster development.
Cons: protocol-specific features may still require Bot.Rest, gateway, or voice directly.
Use explicit contexts and bounded work
Why: gateway handlers run concurrently and REST calls can outlive an event.
Pros: cancellation is predictable and shutdown is graceful.
Cons: every asynchronous operation needs deliberate context ownership.
Validate before production sync
Why: Discord rejects invalid names, descriptions, and option definitions.
Pros: Router.Validate or CommandE fails locally before a REST request.
Cons: validation does not replace Discord-side permission and installation checks.
Common Mistakes
Incorrect: starting a router without attaching it.
b := bot.New(token)Correct:
b := bot.New(token, bot.WithRouter(router))Incorrect: sending two initial interaction responses.
_ = ctx.Reply("one")
_ = ctx.Reply("two")Correct: send one initial response, then use a follow-up.
if err := ctx.Reply("one"); err != nil {
return
}
_, _ = ctx.Followup("two")API Walkthrough
bot.New(string, ...bot.Option) *bot.Botconstructs a configured bot.bot.Optionisfunc(*bot.Bot)and is applied during construction.bot.NewRouter() *bot.Routercreates command and interaction registries.(*bot.Bot).OnReady(bot.ReadyHandler)observes readiness.(*bot.Bot).OnMessageCreate(bot.MessageHandler)observes user messages.(*bot.Bot).OnInteraction(bot.InteractionHandler)observes all interactions.(*bot.Bot).Run() error,RunContext(context.Context) error, andStart(context.Context) errorbegin execution with different ownership of signals and blocking.(*bot.Bot).Stop(context.Context) error,Wait() error, andDone() <-chan struct{}provide shutdown coordination.(*bot.Bot).Rest *rest.Clientexposes the authenticated REST client.(*bot.Bot).State() bot.BotState,IsReady() bool,WaitReady(context.Context) error,AppID() snowflake.ID, andStats() bot.BotStatsexpose runtime state.
The individual pages below document the feature-specific APIs and complete examples. These are tutorials, not package summaries.
Examples
Related APIs
client.mdfor construction and runtime state.commands.mdfor command and route registration.interactions.mdfor responses and option access.components.mdfor legacy and V2 components.buttons.mdfor custom-ID button flows.modals.mdfor modal forms.collectors.mdfor one-shot waits and jobs.permissions.mdfor authorization middleware.lifecycle.mdfor startup, shutdown, jobs, and reconnects.presence.mdfor status and latency.caching.mdfor cache-backed lookups.resources.mdfor typed REST helpers.embeds.mdfor rich message content.voice.mdfor gateway voice state.errors.mdfor runtime error handling.configuration.mdfor JSON and environment setup.../low-level/gateway/README.mdfor gateway control.../low-level/rest/README.mdfor direct REST usage.