Documentation Index Fetch the complete documentation index at: https://mintlify.com/disgoorg/disgo/llms.txt
Use this file to discover all available pages before exploring further.
Basic concepts
DisGo is built around a modular architecture that separates concerns into distinct components. Understanding these core concepts will help you build robust Discord bots.
Architecture overview
Client The high-level interface that combines all components
Gateway WebSocket connection for real-time events
REST HTTP client for API requests
Events Type-safe event handling system
The Client
The bot.Client is the central component of DisGo. It combines the Gateway, REST API, event system, cache, and optional features like sharding and voice into one cohesive interface.
Client structure
type Client struct {
Token string
ApplicationID snowflake . ID
Logger * slog . Logger
Rest rest . Rest
EventManager EventManager
Gateway gateway . Gateway
ShardManager sharding . ShardManager
HTTPServer httpserver . Server
VoiceManager voice . Manager
Caches cache . Caches
MemberChunkingManager MemberChunkingManager
}
Each component serves a specific purpose and can be configured or replaced independently.
Creating a client
The most common way to create a client is using disgo.New() with configuration options:
client , err := disgo . New ( token ,
// Configure Gateway
bot . WithGatewayConfigOpts (
gateway . WithIntents ( gateway . IntentGuilds , gateway . IntentGuildMessages ),
),
// Add event listeners
bot . WithEventListenerFunc ( myEventHandler ),
// Configure logging
bot . WithLogger ( customLogger ),
// Configure cache
bot . WithCacheConfigOpts ( cache . WithCaches ( cache . FlagsAll )),
)
DisGo uses the functional options pattern for configuration. Each With* function returns a configuration option that modifies the client.
Gateway connection
The Gateway is a WebSocket connection to Discord that allows your bot to receive real-time events. It’s responsible for:
Establishing and maintaining the WebSocket connection
Sending and receiving Gateway messages
Handling heartbeats and reconnection
Managing connection state
Gateway lifecycle
Connect
Open the Gateway connection with client.OpenGateway(ctx).
Identify
The Gateway sends an Identify payload with your token and intents.
Ready
Discord sends a Ready event with your bot’s information and initial state.
Events
Your bot receives events in real-time as they occur.
Heartbeat
The Gateway sends periodic heartbeats to keep the connection alive.
Gateway status
The Gateway progresses through several states:
const (
StatusUnconnected // Initial state
StatusConnecting // Establishing connection
StatusWaitingForHello // Waiting for Hello opcode
StatusIdentifying // Sending Identify
StatusWaitingForReady // Waiting for Ready event
StatusReady // Fully connected and ready
StatusDisconnected // Disconnected
)
Gateway intents
Intents tell Discord which events you want to receive. This reduces bandwidth and improves performance by filtering out unwanted events.
gateway . WithIntents (
gateway . IntentGuilds , // Guild lifecycle events
gateway . IntentGuildMessages , // Message events in guilds
gateway . IntentGuildMessageReactions , // Reaction events
gateway . IntentDirectMessages , // DM events
gateway . IntentMessageContent , // Message content (privileged)
)
Privileged intents (MessageContent, GuildMembers, GuildPresences) must be enabled in the Discord Developer Portal and require approval for verified bots.
REST API
The REST client handles HTTP requests to Discord’s API. It provides methods for:
Creating, updating, and deleting resources
Fetching data from Discord
Managing rate limits automatically
Handling pagination
Access the REST client through client.Rest.
Making REST requests
// Send a message
message , err := client . Rest . CreateMessage (
channelID ,
discord . NewMessageCreateBuilder ().
SetContent ( "Hello, Discord!" ).
SetEmbeds ( myEmbed ).
Build (),
)
// Get guild information
guild , err := client . Rest . GetGuild ( guildID , true )
// Update a role
role , err := client . Rest . UpdateRole (
guildID ,
roleID ,
discord . RoleUpdate {
Name : omit . New ( "New Role Name" ),
Color : omit . New ( 0x FF0000 ),
},
)
Rate limiting
DisGo automatically handles Discord’s rate limits:
Per-route rate limits : Managed automatically per endpoint
Global rate limits : Respected across all requests
Retry-After : Automatically waits when rate limited
// Configure rate limiter behavior
bot . WithRestConfigOpts (
rest . WithRateLimiter ( customRateLimiter ),
)
DisGo queues requests when rate limited, so you don’t need to handle rate limits in your code.
Event system
DisGo’s event system is type-safe and flexible. Events are dispatched when Gateway messages are received, allowing you to react to changes in Discord.
Event types
Common events include:
Event Description MessageCreateNew message sent MessageUpdateMessage edited MessageDeleteMessage deleted GuildCreateGuild became available GuildMemberAddMember joined guild GuildMemberRemoveMember left guild InteractionCreateInteraction received ReadyBot connected and ready
Listening for events
There are several patterns for handling events:
Function listener
Interface listener
Typed listener
Channel listener
// Simple function listener
bot . WithEventListenerFunc ( func ( event * events . MessageCreate ) {
if event . Message . Content == "!hello" {
client . Rest . CreateMessage (
event . ChannelID ,
discord . NewMessageCreateBuilder ().
SetContent ( "Hello!" ).
Build (),
)
}
})
Event data
All events implement the Event interface:
type Event interface {
Client () * bot . Client // Access to the client
SequenceNumber () int // Gateway sequence number
}
Each event type provides specific data:
func handleMessage ( event * events . MessageCreate ) {
// Access message data
content := event . Message . Content
author := event . Message . Author
channelID := event . ChannelID
// Access client
client := event . Client ()
// Send response
client . Rest . CreateMessage ( channelID , ... )
}
Cache system
DisGo includes a built-in cache to store Discord entities locally, reducing API calls and improving performance.
Cached entities
The cache can store:
Guilds and their properties
Channels
Members
Roles
Messages
Users
Voice states
Presences
Configuring caches
client , err := disgo . New ( token ,
bot . WithCacheConfigOpts (
// Cache everything
cache . WithCaches ( cache . FlagsAll ),
// Or select specific caches
cache . WithCaches (
cache . FlagGuilds |
cache . FlagChannels |
cache . FlagMembers ,
),
),
)
Using the cache
// Get from cache
if guild , ok := client . Caches . Guild ( guildID ); ok {
fmt . Println ( "Guild name:" , guild . Name )
}
// Get all guilds
guilds := client . Caches . Guilds ()
// Get channel
if channel , ok := client . Caches . Channel ( channelID ); ok {
fmt . Println ( "Channel name:" , channel . Name ())
}
The cache is automatically updated by Gateway events. You rarely need to manually populate it.
Custom cache implementations
You can provide your own cache implementation:
type MyCache struct {
// Your custom cache logic
}
func ( c * MyCache ) Guild ( id snowflake . ID ) ( discord . Guild , bool ) {
// Custom implementation
}
bot . WithCache ( cache . NewWithCaches ( myCustomCache ))
Sharding
When your bot is in many guilds (typically 2,500+), you need sharding to split the Gateway connection across multiple shards.
Why shard?
Discord requires sharding for large bots
Distributes load across connections
Improves reliability and scalability
Each shard handles a subset of guilds
Using the ShardManager
client , err := disgo . New ( token ,
// Use ShardManager instead of Gateway
bot . WithShardManagerConfigOpts (
// Auto-detect shard count from Discord
sharding . WithAutoSharding (),
// Or specify manually
sharding . WithShardCount ( 4 ),
sharding . WithShardIDs ( 0 , 1 , 2 , 3 ),
// Configure gateway options for all shards
sharding . WithGatewayConfigOpts (
gateway . WithIntents ( gateway . IntentGuilds ),
),
),
)
// Open all shards
if err := client . OpenShardManager ( ctx ); err != nil {
panic ( err )
}
Accessing specific shards
// Get shard for a guild
shard , err := client . Shard ( guildID )
// Get shard by ID
shard := client . ShardManager . Shard ( 0 )
// Iterate all shards
for _ , shard := range client . ShardManager . Shards () {
fmt . Printf ( "Shard %d status: %s \n " , shard . ShardID (), shard . Status ())
}
Discord automatically assigns guilds to shards. You don’t need to manage shard assignment yourself.
HTTP Interactions
For high-traffic bots, you can handle interactions via HTTP instead of the Gateway:
client , err := disgo . New ( token ,
bot . WithHTTPServerConfigOpts (
httpserver . WithURL ( "https://yourbot.com/interactions" ),
httpserver . WithPublicKey ( "your_public_key" ),
),
)
// Start HTTP server
if err := client . HTTPServer . Start (); err != nil {
panic ( err )
}
HTTP interactions:
Reduce Gateway load
Scale horizontally more easily
Required for interaction-only bots
Logging
DisGo uses Go’s standard log/slog package for structured logging:
import " log/slog "
// Create custom logger
logger := slog . New ( slog . NewJSONHandler ( os . Stdout , & slog . HandlerOptions {
Level : slog . LevelDebug ,
}))
client , err := disgo . New ( token ,
bot . WithLogger ( logger ),
)
Log levels:
Debug: Detailed diagnostic information
Info: General informational messages
Warn: Warning messages
Error: Error messages
Next steps
Now that you understand DisGo’s core concepts, explore more advanced topics:
Slash commands Build modern application commands
Message components Create interactive buttons and menus
Voice connections Connect to voice channels
Examples Browse working examples