Skip to content

Sending Embeds

Embeds are rich message attachments that can contain a title, description, fields, images, and more. This guide shows how to build one and send it as a reply to a message.

This guide uses the onMessage event. To match on message.content in your handler, add "MessageContent" to your intents - it is a privileged intent that must also be enabled in the Discord Developer Portal under your application’s Bot tab.

Embeds are constructed with builders.embed.embed. The :setType() call is required - use "Rich" for standard bot embeds.

local embed = builders.embed.embed.new()
:setType("Rich")
:setTitle("Hello from discord-luau!")
:setDescription("This is an embed sent by a Luau bot.")
:setColor(0x5865F2)
:addField(
builders.embed.field.new()
:setName("Field One")
:setValue("Some value here")
:build()
)
:addField(
builders.embed.field.new()
:setName("Inline Field")
:setValue("This field is inline")
:setIsInline(true)
:build()
)
:setFooter(
builders.embed.footer.new()
:setText("Sent via discord-luau")
:build()
)
:build()
ElementLimit
Title256 characters
Description4096 characters
FieldsUp to 25 per embed
Footer text2048 characters
Embeds per messageUp to 10

Attach the built embed to a builders.message.message using :addEmbed(), then reply to the incoming message.

local discord = require("@self/../luau_packages/discord")
local classes = require("@self/../luau_packages/classes")
local builders = require("@self/../luau_packages/builders")
local env = require("@self/../.env")
local bot = discord.bot.new({
token = env.DISCORD_BOT_TOKEN,
intents = builders.intents.new({ "Guilds", "GuildMessages" }):build(),
reconnect = true,
})
bot.onMessage:listen(function(message: classes.Message)
if message.content ~= "!embed" then
return
end
local embed = builders.embed.embed.new()
:setType("Rich")
:setTitle("Hello!")
:setDescription("Here is your embed.")
:setColor(0x5865F2)
:setFooter(
builders.embed.footer.new()
:setText("discord-luau")
:build()
)
:build()
message:replyAsync(
builders.message.message.new()
:addEmbed(embed)
:build()
):await()
end)
bot.onAllShardsReady:listenOnce(function()
print(`Bot '{bot.user.username}' is online!`)
end)
bot:connectAsync():await()

Colors are plain integers. You can write hex literals directly in Luau:

:setColor(0xFF0000) -- red
:setColor(0x00FF00) -- green
:setColor(0x0000FF) -- blue
:setColor(0x5865F2) -- Discord blurple
Full script
local discord = require("@self/../luau_packages/discord")
local classes = require("@self/../luau_packages/classes")
local builders = require("@self/../luau_packages/builders")
local env = require("@self/../.env")
local bot = discord.bot.new({
token = env.DISCORD_BOT_TOKEN,
intents = builders.intents.new({ "Guilds", "GuildMessages" }):build(),
reconnect = true,
})
bot.onMessage:listen(function(message: classes.Message)
if message.content ~= "!embed" then
return
end
local embed = builders.embed.embed.new()
:setType("Rich")
:setTitle("Hello!")
:setDescription("Here is your embed.")
:setColor(0x5865F2)
:addField(
builders.embed.field.new()
:setName("Field One")
:setValue("Some value here")
:build()
)
:setFooter(
builders.embed.footer.new()
:setText("discord-luau")
:build()
)
:build()
message:replyAsync(
builders.message.message.new()
:addEmbed(embed)
:build()
):await()
end)
bot.onAllShardsReady:listenOnce(function()
print(`Bot '{bot.user.username}' is online!`)
end)
bot:connectAsync():await()
  • Bot - the discord.bot class, gateway connection and event emitters
  • Embed builder - builders.embed.embed, constructs embed payloads
  • Embed Field builder - builders.embed.field, adds fields to an embed
  • Embed Footer builder - builders.embed.footer, sets the embed footer
  • Message builder - builders.message.message, wraps embeds for sending
  • Message class - classes.Message, the object passed to onMessage handlers
  • Futures - the FutureLike async primitive returned by async calls