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.
Event handling is how your bot responds to things happening in Discord - messages being sent, users joining servers, reactions being added, and much more.
Adding event listeners
DisGo provides three ways to listen for events:
Function listeners
The simplest approach for single event types:
client , err := disgo . New ( token ,
bot . WithDefaultGateway (),
bot . WithEventListenerFunc ( func ( event * events . MessageCreate ) {
// Handle message creation
}),
)
Channel listeners
Useful for concurrent event processing:
func eventListenerChan () chan <- * events . MessageCreate {
c := make ( chan * events . MessageCreate )
go func () {
defer close ( c )
for event := range c {
if event . Message . Content == "ping" {
_ , _ = event . Client (). Rest . CreateMessage (
event . ChannelID ,
discord . MessageCreate { Content : "pong" },
)
}
}
}()
return c
}
client , err := disgo . New ( token ,
bot . WithDefaultGateway (),
bot . WithEventListenerChan ( eventListenerChan ()),
)
Adapter listeners
Best for handling multiple event types in one place:
type BotEventListener struct {}
func ( l * BotEventListener ) OnMessageCreate ( event * events . MessageCreate ) {
// Handle message creation
}
func ( l * BotEventListener ) OnReactionAdd ( event * events . MessageReactionAdd ) {
// Handle reaction add
}
client , err := disgo . New ( token ,
bot . WithDefaultGateway (),
bot . WithEventListeners ( & BotEventListener {}),
)
Common events
Here are the most commonly used events:
Message events
MessageCreate
MessageUpdate
MessageDelete
func ( event * events . MessageCreate ) {
if event . Message . Author . Bot {
return
}
// Handle new message
}
Interaction events
ApplicationCommandInteractionCreate
ComponentInteractionCreate
ModalSubmitInteractionCreate
func ( event * events . ApplicationCommandInteractionCreate ) {
data := event . SlashCommandInteractionData ()
// Handle slash command
}
Guild events
GuildMemberJoin
GuildMemberLeave
GuildReady
func ( event * events . GuildMemberJoin ) {
// Welcome new member
}
Reaction events
MessageReactionAdd
MessageReactionRemove
func ( event * events . MessageReactionAdd ) {
// Handle reaction added
}
Complete event handling example
package main
import (
" context "
" log/slog "
" os "
" os/signal "
" syscall "
" github.com/disgoorg/disgo "
" github.com/disgoorg/disgo/bot "
" github.com/disgoorg/disgo/discord "
" github.com/disgoorg/disgo/events "
)
var token = os . Getenv ( "disgo_token" )
func main () {
client , err := disgo . New ( token ,
bot . WithDefaultGateway (),
bot . WithEventListenerFunc ( onMessageCreate ),
bot . WithEventListeners ( & events . ListenerAdapter {
OnMessageCreate : onMessageCreate ,
OnReady : onReady ,
OnGuildMemberJoin : onGuildMemberJoin ,
}),
)
if err != nil {
slog . Error ( "error while building disgo instance" , slog . Any ( "err" , err ))
return
}
defer client . Close ( context . TODO ())
if err = client . OpenGateway ( context . TODO ()); err != nil {
slog . Error ( "error while connecting to gateway" , slog . Any ( "err" , err ))
}
slog . Info ( "bot is now running. Press CTRL-C to exit." )
s := make ( chan os . Signal , 1 )
signal . Notify ( s , syscall . SIGINT , syscall . SIGTERM , os . Interrupt )
<- s
}
func onReady ( event * events . Ready ) {
slog . Info ( "Bot is ready!" , slog . String ( "user" , event . User . Tag ()))
}
func onMessageCreate ( event * events . MessageCreate ) {
if event . Message . Author . Bot {
return
}
if event . Message . Content == "ping" {
_ , _ = event . Client (). Rest . CreateMessage (
event . ChannelID ,
discord . MessageCreate { Content : "pong" },
)
}
}
func onGuildMemberJoin ( event * events . GuildMemberJoin ) {
slog . Info ( "New member joined" ,
slog . String ( "user" , event . User . Tag ()),
slog . String ( "guild" , event . GuildID . String ()),
)
}
Gateway intents
To receive events, you need to enable the appropriate gateway intents:
import " github.com/disgoorg/disgo/gateway "
client , err := disgo . New ( token ,
bot . WithGatewayConfigOpts (
gateway . WithIntents (
gateway . IntentGuilds , // Guild events
gateway . IntentGuildMessages , // Message events
gateway . IntentMessageContent , // Access to message content
gateway . IntentGuildMembers , // Member events
gateway . IntentGuildMessageReactions , // Reaction events
),
),
)
Some intents like IntentGuildMembers and IntentMessageContent are privileged and require approval in the Discord Developer Portal for verified bots.
Event filtering
Filter events to only handle relevant ones:
func onMessageCreate ( event * events . MessageCreate ) {
// Ignore bots
if event . Message . Author . Bot {
return
}
// Only handle DMs
if event . GuildID == nil {
return
}
// Only handle specific channels
if event . ChannelID != myChannelID {
return
}
// Handle the event
}
The Ready event
The Ready event fires when your bot successfully connects:
func onReady ( event * events . Ready ) {
slog . Info ( "Logged in as" , slog . String ( "tag" , event . User . Tag ()))
slog . Info ( "Connected to" , slog . Int ( "guilds" , len ( event . Guilds )))
// Set bot activity
client . SetPresence ( context . TODO (),
gateway . WithPlayingActivity ( "with DisGo" ),
gateway . WithOnlineStatus ( discord . OnlineStatusOnline ),
)
}
Error handling in events
Always handle errors properly in event listeners:
func onMessageCreate ( event * events . MessageCreate ) {
_ , err := event . Client (). Rest . CreateMessage (
event . ChannelID ,
discord . MessageCreate { Content : "Hello!" },
)
if err != nil {
event . Client (). Logger . Error (
"failed to send message" ,
slog . Any ( "err" , err ),
slog . String ( "channel" , event . ChannelID . String ()),
)
}
}
Accessing the client
You can access the bot client from any event:
func onMessageCreate ( event * events . MessageCreate ) {
client := event . Client ()
// Access REST API
client . Rest . CreateMessage ( ... )
// Access cache
guild , ok := client . Caches . Guild ( event . GuildID )
// Access logger
client . Logger . Info ( "Processing message" )
}
Using the handler package
The handler package provides organized routing for events:
import " github.com/disgoorg/disgo/handler "
r := handler . New ()
r . SlashCommand ( "/ping" , handlePing )
r . Component ( "/button/{id}" , handleButton )
r . Modal ( "/modal" , handleModal )
client , err := disgo . New ( token ,
bot . WithDefaultGateway (),
bot . WithEventListeners ( r ),
)
Event listener order
Event listeners are called in the order they’re registered:
client , err := disgo . New ( token ,
bot . WithEventListenerFunc ( firstListener ), // Called first
bot . WithEventListenerFunc ( secondListener ), // Called second
bot . WithEventListenerFunc ( thirdListener ), // Called third
)
Available events
Here’s a comprehensive list of available events:
Ready - Bot connected to gateway
MessageCreate - New message created
MessageUpdate - Message edited
MessageDelete - Message deleted
ApplicationCommandInteractionCreate - Slash command used
ComponentInteractionCreate - Button/select menu clicked
ModalSubmitInteractionCreate - Modal submitted
GuildMemberJoin - Member joined guild
GuildMemberLeave - Member left guild
GuildMemberUpdate - Member updated (roles, nickname, etc.)
MessageReactionAdd - Reaction added to message
MessageReactionRemove - Reaction removed from message
VoiceStateUpdate - Voice state changed
ChannelCreate - Channel created
ChannelUpdate - Channel updated
ChannelDelete - Channel deleted
GuildCreate - Guild became available
GuildUpdate - Guild updated
GuildDelete - Guild became unavailable
Best practices
Filter early : Return early from event handlers for irrelevant events
Handle errors : Always log errors from API calls
Don’t block : Keep event handlers fast; use goroutines for long-running tasks
Use appropriate intents : Only request the intents you need
Type assertions : Use type assertions carefully when handling generic events
Context timeouts : Use contexts with timeouts for API calls
Next steps