Embeds
Overview
An embed is structured rich content attached to a message or interaction response. messages.EmbedBuilder creates titles, descriptions, colors, timestamps, fields, authors, footers, thumbnails, and images. Call Embed.Validate before sending generated content so size errors are caught locally.
Tutorial: Build A Valid Embed
- Start with
messages.NewEmbedBuilder. - Add only the fields needed for the message.
- Call
BuildandValidate. - Send it with
ctx.ReplyEmbed,ReplyComplex, or a REST payload. - Use
AllowedMentionswhen generated text includes user-controlled content.
The current validator checks title, description, footer, author, field, and total-character constraints. It does not validate remote URLs or every Discord policy, so those remain application responsibilities.
Complete Runnable Example
Copy to examples/embeds/main.go, set DISCORD_TOKEN, and run it. Invoke /status.
package main
import (
"log"
"os"
"time"
"github.com/discord-go/discord.go/bot"
"github.com/discord-go/discord.go/intents"
"github.com/discord-go/discord.go/messages"
)
func main() {
token := os.Getenv("DISCORD_TOKEN")
if token == "" {
log.Fatal("DISCORD_TOKEN is required")
}
router := bot.NewRouter()
router.Command("status", "Show a rich status message", func(ctx *bot.InteractionContext) {
embed := messages.NewEmbedBuilder().
SetTitle("Service status").
SetDescription("The bot is connected and accepting interactions.").
SetURL("https://discord.com/developers/docs").
SetColor(0x5865F2).
SetTimestamp(time.Now()).
SetThumbnail("https://cdn.discordapp.com/embed/avatars/0.png").
AddField("Gateway", "connected", true).
AddField("Response mode", "interaction callback", true).
SetFooter("Generated by discord.go", "").
Build()
if err := embed.Validate(); err != nil {
log.Printf("invalid embed: %v", err)
_ = ctx.ReplyEphemeral("The status message is invalid.")
return
}
if err := ctx.ReplyEmbed(embed); err != nil {
log.Printf("embed response: %v", err)
}
})
b := bot.New(token, bot.WithIntents(intents.Guilds), bot.WithRouter(router))
if err := b.Run(); err != nil {
log.Fatal(err)
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Embed Versus Components V2
Embeds and Components V2 are separate message representations. Use ctx.ReplyEmbed for an ordinary embed. Use InteractionCallbackData with messages.FlagIsComponentsV2 and typed display components for a V2 layout. Do not add the V2 flag casually to an embed-only response.
For an uploaded image, set EmbedImage.URL to attachment://filename and send the matching rest.File with ReplyComplexWithFiles. Keep the filename fixed and validate file size before upload.
Common Mistakes
- Building more than 25 fields or exceeding field and total-character limits.
- Forgetting to call
Validateafter incorporating user input. - Treating a color as a CSS string;
SetColortakes an integer RGB value. - Including arbitrary user text without controlling allowed mentions.
- Mixing Components V2 assumptions into a regular embed response.
Expected Result
/status returns a validated embed with a title link, timestamp, thumbnail, fields, and footer.