Configuration
Overview
The bot package supports application-owned startup configuration from a JSON file or conventional environment variables. Config contains the token and basic gateway and command settings; functional options remain available for transports, logging, caches, stores, and test infrastructure.
Architecture
LoadConfig(path) reads and unmarshals one JSON file. ConfigFromEnv() reads environment variables and returns a value without an error channel, so malformed optional values are ignored and remain at their zero value. NewFromConfig maps non-zero configuration fields to bot.Option values and calls New.
The token is application secret material. Configuration files should be local or secret-managed, and environment values should not be printed in logs.
Quick Start
This complete program uses environment configuration and adds a router option.
package main
import (
"log"
"github.com/discord-go/discord.go/bot"
)
func main() {
config := bot.ConfigFromEnv()
if config.Token == "" {
log.Fatal("set DISCORD_TOKEN or TOKEN")
}
router := bot.NewRouter()
router.Command("ping", "Check configuration", func(ctx *bot.InteractionContext) {
if err := ctx.Reply("Configured"); err != nil {
log.Printf("reply: %v", err)
}
})
b := bot.NewFromConfig(config, bot.WithRouter(router))
if err := b.Run(); err != nil {
log.Fatal(err)
}
}Run with DISCORD_TOKEN=... BOT_PREFIX=! go run .. An unset Intents keeps the constructor defaults (bot.DefaultIntents); a non-zero value replaces them entirely, and NewFromConfig logs a warning when the replacement drops a privileged intent such as MessageContent.
Creating/Configuration
bot.Config fields are Token, Prefix, BotName, MentionTriggers, Intents, GatewayCapabilities, Shards, AutomaticShards, Compression, Presence, and CommandSync.
JSON uses token, prefix, bot_name, mention_triggers, intents, gateway_capabilities, shards, automatic_shards, compression, presence, and command_sync. CommandSyncConfig.Mode is numeric JSON because it is a Go integer enum; use 0 for global, 1 for guild, and 2 for disabled.
Environment names are TOKEN or DISCORD_TOKEN, BOT_PREFIX, BOT_NAME, BOT_MENTION_TRIGGERS, BOT_INTENTS, BOT_GATEWAY_CAPABILITIES, BOT_SHARDS, BOT_AUTOMATIC_SHARDS, and BOT_GATEWAY_COMPRESSION. Boolean values use Go's strconv.ParseBool forms; intents and gateway capabilities are decimal bitfields (GatewayCapabilities holds gateway.Capability bits such as CapabilityChannelObfuscation, 1 << 15).
Using
Basic: environment
Call ConfigFromEnv, check Token, optionally apply programmatic defaults, and pass the result to NewFromConfig.
Intermediate: JSON
Write a JSON file without secrets in source control, call LoadConfig, check the returned error, and pass the result to NewFromConfig.
Advanced: layered configuration
Load a base JSON config, then override fields from a deployment environment or append functional options for infrastructure concerns. Avoid silently replacing a secure token with an empty environment variable.
Intents
bot.New starts from bot.DefaultIntents(): Guilds | GuildMessages | MessageContent. Two options control the final set:
WithIntents(intents.Intent)adds to the defaults. Calling it multiple times unions the sets, so a bot that requests more events never loses the defaults by accident.WithIntentsExclusive(intents.Intent)replaces the defaults entirely. Use it to opt out ofMessageContentor to pin an exact set. Every privileged intent the replacement drops (GuildMembers,GuildPresences,MessageContent) is logged, because the gateway then stops delivering its events without returning an error; message content arrives empty withoutMessageContent.
A non-zero Config.Intents (JSON intents, env BOT_INTENTS) replaces the defaults the same way WithIntentsExclusive does.
// Defaults plus voice tracking and member events.
b := bot.New(token, bot.WithIntents(intents.GuildVoiceStates|intents.GuildMembers))
// Exactly these intents, nothing else (logs when MessageContent is lost).
b = bot.New(token, bot.WithIntentsExclusive(intents.Guilds))Common Patterns
- Validate the token explicitly before
NewFromConfigorRun.StartreturnsErrInvalidTokenif the token does not have three dot-separated segments. - Use guild command sync in a development config and global sync in production.
- Keep intent declarations close to the feature that needs them; extend the defaults with
WithIntentsand replace them only withWithIntentsExclusive. - Use
WithRESTClient,WithLogger, andWithErrorHandleras options after loading application config. - Document which configuration source wins when multiple sources are used.
Best Practices
Keep secrets out of JSON committed to Git
Why: repository history is difficult to clean after a token leak.
Pros: safer review and simpler rotation.
Cons: deployment requires a secret manager or environment injection.
Validate configuration at startup
Why: ConfigFromEnv intentionally ignores malformed optional values.
Pros: failures happen before a partial gateway run.
Cons: the application owns validation rules for IDs, intents, and deployment policy.
Use explicit environment names
Why: ConfigFromEnv checks both TOKEN and DISCORD_TOKEN and can hide a typo if an old variable remains present.
Pros: predictable deployment behavior.
Cons: a small amount of environment documentation is required.
Common Mistakes
Incorrect: assuming BOT_INTENTS accepts names.
BOT_INTENTS=Guilds go run .Correct: provide the decimal bitfield or set intents in Go.
BOT_INTENTS=513 go run .Incorrect: ignoring a JSON load error.
config, _ := bot.LoadConfig("bot.json")Correct:
config, err := bot.LoadConfig("bot.json")
if err != nil {
return err
}API Walkthrough
Configis the JSON/environment value object with token, trigger, intent, gateway-capability, shard, compression, presence, and command-sync fields.LoadConfig(path string) (Config, error)reads a JSON file.ConfigFromEnv() Configreads the documented environment variables and returns zero values for missing or unparsable optional fields.NewFromConfig(config Config, opts ...Option) *Botconverts configuration to a bot and applies additional options.CommandSyncConfigcontainsMode,GuildID, andTimeout.CommandSyncGlobal,CommandSyncGuild, andCommandSyncDisabledselect automatic global, guild, or no synchronization.WithPrefix,WithBotName,WithMentionTriggers,WithShards,WithGatewayCompression,WithGatewayCapabilities,WithPresence, andWithCommandSyncare the equivalent direct options.WithIntentsadds to the default intents andWithIntentsExclusivereplaces them (see Intents).
Examples
Related APIs
client.mdfor functional options.commands.mdfor command sync behavior.presence.mdfor presence configuration.