Reactions
Overview
Reactions are message events plus REST operations. Enable intents.GuildMessageReactions for guild reaction events, use Bot.OnMessageReactionAdd for a typed handler, and call b.Rest methods to add, list, or remove reactions. The event payload includes IDs and an emoji; it does not provide every related resource inline.
Tutorial: Seed And Observe A Reaction
- Enable guild reaction intent in the Portal and
bot.WithIntents. - Send a message and use
CreateReactionwhen the bot should react itself. - Handle
ReactionContextevents without assuming the actor is cached. - Compare
Emoji.NameorEmoji.IDsafely; custom emoji names are optional. - Use a bounded context for REST calls and avoid reaction loops.
Complete Runnable Example
Copy to examples/reactions/main.go, set DISCORD_TOKEN, and run it. Invoke /react, then add a thumbs-up reaction to the created message.
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("react", "Create a message for a reaction workflow", func(ctx *bot.InteractionContext) {
if err := ctx.Reply("React to this message with a thumbs-up."); err != nil {
log.Printf("reaction prompt: %v", err)
return
}
message, err := ctx.GetReply()
if err != nil {
log.Printf("fetch reaction prompt: %v", err)
return
}
if err := ctx.Bot.Rest.CreateReaction(ctx.Context(), message.ChannelID, message.ID, "👍"); err != nil {
log.Printf("seed reaction: %v", err)
}
})
b := bot.New(token,
bot.WithIntents(intents.Guilds|intents.GuildMessageReactions),
bot.WithRouter(router),
)
b.OnMessageReactionAdd(func(ctx *bot.ReactionContext) {
if ctx.Emoji.Name == nil || *ctx.Emoji.Name != "👍" {
return
}
log.Printf("thumbs-up message=%s user=%s", ctx.MessageID.String(), ctx.UserID.String())
if err := ctx.Bot.Rest.CreateReaction(ctx.Context(), ctx.ChannelID(), ctx.MessageID, "✅"); err != nil {
log.Printf("reaction acknowledgement: %v", err)
}
})
if err := b.Run(); err != nil {
log.Fatal(err)
}
}REST Operations
CreateReaction(ctx, channelID, messageID, emoji)adds the bot's reaction.DeleteOwnReactionremoves the bot's reaction.GetReactionsorGetReactionsPagelists users for one emoji.DeleteUserReactionremoves a user's reaction and requires the appropriate moderation authority.DeleteAllReactionsandDeleteAllReactionsForEmojiremove reactions with stronger permissions and should be guarded.
Unicode emoji can be passed as text. Custom emoji require the format Discord's endpoint accepts, commonly name:id; validate or construct it from trusted emoji data rather than accepting arbitrary path text.
Common Mistakes
- Omitting
GuildMessageReactionsand expecting add events. - Dereferencing
ctx.Emoji.Namewhen it is nil for a custom emoji. - Reacting to the bot's own acknowledgement and creating a loop.
- Treating the event's
UserIDas a full cachedusers.User. - Performing bulk reaction deletion without a permission guard.
Expected Result
/react sends a prompt and adds a bot thumbs-up. A user thumbs-up is logged and gets a check-mark reaction from the bot.