Skip to content

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

  1. Start with messages.NewEmbedBuilder.
  2. Add only the fields needed for the message.
  3. Call Build and Validate.
  4. Send it with ctx.ReplyEmbed, ReplyComplex, or a REST payload.
  5. Use AllowedMentions when 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.

go
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)
	}
}

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 Validate after incorporating user input.
  • Treating a color as a CSS string; SetColor takes 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.

Released under the Apache License 2.0.