喂!我是 Wei

Front-End Engineer

Be a Problem Solver.

⌘K

導覽

所有文章緣起互動小功能

文章分類

目錄
概念:Embed 的結構EmbedBuilder 基本用法所有欄位一覽color — 左側顏色條author — 顯示在最頂端的一行title + urldescriptionfields — 多欄位資訊thumbnail — 右上角小圖image — 底部大圖footer + timestamp組合起來:查詢指令回傳 Embed錯誤訊息用 Embed 更清楚即時預覽工具字數限制整理小結

相關文章

Discord Bot 監控與告警:Bot 掛掉時自動發通知到頻道

2026年5月18日

Discord Bot 串接 Groq:打造高速 AI 對話助理

2026年4月1日

Discord Bot 排程任務:node-cron 做每日公告與資料重置

2026年3月31日

最新文章
全部 →
前端 CI/CD 與正式環境除錯:從 Pull Request 到事故排查
2026-06-24
即時資料怎麼選?Polling、SSE、WebSocket 比較
2026-06-23
前端系統設計:如何拆元件、資料流與大型專案架構?
2026-06-22
無障礙不是加 ARIA:語意化 HTML、鍵盤操作與焦點管理
2026-06-21
CSS 與 RWD 面試整理:Flexbox、Grid、定位與層疊脈絡
2026-06-19
← 返回文章列表

Discord Bot Embed:用 EmbedBuilder 打造結構化訊息

2026年3月26日·約 7 分鐘閱讀·
Discord.jsBotNode.js

上一篇的 Select Menu 讓使用者「選」,這篇要讓 Bot 回應得更漂亮—— Embed。

Embed 是 Discord 裡最常用的訊息格式。Bot 回傳的純文字很快就會淹沒在聊天紀錄裡,Embed 有左側顏色條、標題、多欄位可以整齊排列資訊,讀起來一目瞭然。查詢結果、公告、錯誤提示都很適合用它。


概念:Embed 的結構

一個 Embed 從上到下大概長這樣:

Discord Embed 實際外觀截圖

┌──────────────────────────────────────┐ │ [Author Icon] Author Name │◀ author │ │ │ Title (clickable URL) │◀ title / url │ Description │◀ description │ │ │ Field1 Field2 Field3 │◀ fields(inline) │ Field4 (full width) │◀ fields(非 inline) │ │ │ [Large Image] │◀ image │ │ │ [Footer Icon] Footer · Timestamp │◀ footer / timestamp └──────────────────────────────────────┘ ▲ 左側顏色條 = color

Thumbnail 是右上角的小縮圖,會和 Author / Title / Description 並排。


EmbedBuilder 基本用法

安裝這系列用的 discord.js v14 之後,直接從套件 import:

import { EmbedBuilder } from "discord.js";

最陽春的 Embed,只有顏色 + 標題 + 說明:

index.js
const embed = new EmbedBuilder()
  .setColor("#5865F2")
  .setTitle("這是標題")
  .setDescription("這是說明文字,支援 **粗體**、*斜體*、`code`。");
 
await interaction.reply({ embeds: [embed] });

reply 裡的 embeds 是陣列,一則訊息最多可以帶 10 個 Embed,不過實際上通常用一個就夠了。

最基本的 Embed,只有顏色條、標題和 description


所有欄位一覽

color — 左側顏色條

.setColor("#5865F2")          // hex 字串
.setColor(0x5865f2)           // 數字格式
.setColor("Blurple")          // Discord 內建顏色名稱
.setColor("Random")           // 隨機顏色

顏色條在視覺上很重要——成功用綠色、錯誤用紅色、提示用藍色,這樣的慣例讓使用者不用讀文字就能感知訊息的語氣。

author — 顯示在最頂端的一行

.setAuthor({
  name: "Discord Bot",
  iconURL: "https://example.com/avatar.png",   // 左側小圓圖(選填)
  url: "https://example.com",                  // 點擊名稱可跳轉(選填)
})

通常放 Bot 名稱或觸發指令的使用者名稱。

title + url

.setTitle("查詢結果")
.setURL("https://example.com/result")   // 讓標題變成超連結(選填)

description

.setDescription("支援 Discord Markdown:\n**粗體** *斜體* ~~刪除線~~ `程式碼`\n[超連結](https://example.com)")

字數上限 4096 字元,description 是 Embed 裡最能放長文的地方。

fields — 多欄位資訊

.addFields(
  { name: "欄位一", value: "內容", inline: true },
  { name: "欄位二", value: "內容", inline: true },
  { name: "欄位三", value: "內容", inline: true },
  { name: "換行欄位", value: "這個欄位獨佔一整排", inline: false },
)
  • inline: true:同排並列,Discord 會自動換行(同排最多 3 個)
  • inline: false(預設):獨佔一整排
  • 最多 25 個 fields
  • name 上限 256 字元,value 上限 1024 字元
  • name 和 value 都不能是空字串,可以用 "\u200b"(零寬空白)代替空值

inline true 的三欄並排 vs inline false 的獨佔一排

thumbnail — 右上角小圖

.setThumbnail("https://example.com/thumb.png")

image — 底部大圖

.setImage("https://example.com/banner.png")

footer + timestamp

.setFooter({
  text: "資料來源:XXX",
  iconURL: "https://example.com/icon.png",   // 選填
})
.setTimestamp()            // 目前時間
.setTimestamp(new Date())  // 指定時間

組合起來:查詢指令回傳 Embed

以一個 /user 指令為例,查詢使用者資料後回傳結構化訊息:

index.js
import { Client, GatewayIntentBits, EmbedBuilder } from "discord.js";
import "dotenv/config";
 
const client = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
});
 
// ── 指令定義 ──────────────────────────────────────────────────────
const COMMANDS = [
  {
    name: "user",
    description: "查詢使用者資料",
    options: [
      {
        name: "target",
        type: 6,          // USER
        description: "要查詢的使用者",
        required: true,
      },
    ],
  },
];
 
// ── ready:連線後註冊指令 ─────────────────────────────────────────
client.once("ready", async () => {
  console.log(`Bot 已上線:${client.user.tag}`);
  const guild = client.guilds.cache.first();
  await guild.commands.set(COMMANDS);
});
 
// ── interactionCreate ────────────────────────────────────────────
client.on("interactionCreate", async (interaction) => {
  if (!interaction.isChatInputCommand()) return;
 
  if (interaction.commandName === "user") {
    await handleUser(interaction);
  }
});
 
// ── /user handler ────────────────────────────────────────────────
async function handleUser(interaction) {
  const target = interaction.options.getUser("target");
  const member = interaction.guild?.members.cache.get(target.id);
 
  const embed = new EmbedBuilder()
    .setColor("#5865F2")
    .setAuthor({
      name: target.username,
      iconURL: target.displayAvatarURL(),
    })
    .setTitle("使用者資料")
    .setThumbnail(target.displayAvatarURL({ size: 256 }))
    .addFields(
      { name: "ID",       value: target.id,  inline: true },
      {
        name: "帳號建立於",
        value: `<t:${Math.floor(target.createdTimestamp / 1000)}:D>`,
        inline: true,
      },
      {
        name: "加入伺服器",
        value: member
          ? `<t:${Math.floor(member.joinedTimestamp / 1000)}:D>`
          : "未知",
        inline: true,
      },
      {
        name: "身份組",
        value: member?.roles.cache.map((r) => r.toString()).join(" ") || "無",
        inline: false,
      }
    )
    .setFooter({ text: `由 ${interaction.user.username} 查詢` })
    .setTimestamp();
 
  await interaction.reply({ embeds: [embed] });
}
 
client.login(process.env.BOT_TOKEN);

/user 指令回傳的使用者資料 Embed,包含 thumbnail、多欄位、footer 與 timestamp

這裡用了 Discord 的 時間戳記語法 <t:Unix秒數:格式>——Discord 會根據每個用戶的時區自動顯示本地時間,不需要自己做時區轉換。

格式範例輸出
<t:1234567890:D>2009 年 2 月 13 日
<t:1234567890:T>下午 11:31:30
<t:1234567890:R>16 年前
<t:1234567890:F>2009 年 2 月 13 日 下午 11:31:30

錯誤訊息用 Embed 更清楚

純文字的錯誤提示容易被忽略,Embed 版本更容易識別:

// 成功
const successEmbed = new EmbedBuilder()
  .setColor("#57F287")  // Discord 綠色
  .setTitle("✅ 操作成功")
  .setDescription(successMessage);
 
// 錯誤
const errorEmbed = new EmbedBuilder()
  .setColor("#ED4245")  // Discord 紅色
  .setTitle("❌ 發生錯誤")
  .setDescription(errorMessage)
  .setFooter({ text: "請稍後再試,或聯絡管理員" });
 
// 警告
const warnEmbed = new EmbedBuilder()
  .setColor("#FEE75C")  // Discord 黃色
  .setTitle("⚠️ 注意")
  .setDescription(warnMessage);

這三個可以包成工具函式,在整個 Bot 裡統一使用:

utils/embeds.js
import { EmbedBuilder } from "discord.js";
 
export const successEmbed = (msg) =>
  new EmbedBuilder().setColor("#57F287").setTitle("✅ 操作成功").setDescription(msg);
 
export const errorEmbed = (msg) =>
  new EmbedBuilder().setColor("#ED4245").setTitle("❌ 發生錯誤").setDescription(msg);
 
export const warnEmbed = (msg) =>
  new EmbedBuilder().setColor("#FEE75C").setTitle("⚠️ 注意").setDescription(msg);

即時預覽工具

所有欄位填起來試試看,右側會即時渲染成 Discord 風格的 Embed,底部也會自動生成對應的程式碼:

EMBED_BUILDERLIVE
discord.js v14
COLOR
AUTHOR
CONTENT
MEDIA
FIELDS
FOOTER
#general
WEI
My Bot今天 12:00BOT
Discord Bot
Embed 標題

這是 Embed 的說明文字,支援 Markdown。

可以換行,也可以加入 inline code。

欄位一

欄位內容

欄位二

欄位內容

Footer 文字 ·
OUTPUT
import { EmbedBuilder } from "discord.js";

const embed = new EmbedBuilder()
  .setColor("#5865F2")
  .setAuthor({ name: "Discord Bot" })
  .setTitle("Embed 標題")
  .setDescription("這是 Embed 的說明文字,支援 **Markdown**。\n\n可以換行,也可以加入 `inline code`。")
  .setThumbnail("https://ray-blog-nine.vercel.app/images/discord-bot/discord-logo.png")
  .addFields(
    { name: "欄位一", value: "欄位內容", inline: true },
    { name: "欄位二", value: "欄位內容", inline: true }
  )
  .setFooter({ text: "Footer 文字" })
  .setTimestamp();

字數限制整理

Embed 有一個整體上限:所有文字加起來不能超過 6000 字元。個別欄位的上限:

欄位上限
title256 字元
description4096 字元
field.name256 字元
field.value1024 字元
footer.text2048 字元
author.name256 字元
fields 數量最多 25 個
單則訊息 embeds最多 10 個

小結

Embed 本質上就是 EmbedBuilder 的鏈式呼叫,搞清楚每個欄位的位置之後,用起來非常順手。實際開發中最常用到的是:

  1. 查詢結果 — title + fields + thumbnail
  2. 公告通知 — color + title + description + image
  3. 操作回饋 — color(紅 / 綠)+ title + description

下一篇會帶入實際資料層的應用:用 Google Sheets 做後端,建立每日簽到系統——把前面學到的指令、按鈕與 Embed 整合到一個完整功能裡。

分享:XLinkedIn
← 上一篇Discord Bot 下拉選單:StringSelectMenu 完整設計
下一篇 →Google Sheets 當後端?Discord Bot 的輕量資料層