喂!我是 Wei

Front-End Engineer

Be a Problem Solver.

⌘K

導覽

所有文章緣起互動小功能

文章分類

目錄
Autocomplete 是什麼?沒有 Autocomplete 時有 Autocomplete 時什麼情況要自己做註冊可 autocomplete 的指令interactionCreate 需要兩段處理常見坑下一篇預告

相關文章

從一條指令到完整互動系統:Slash Commands 設計拆解

2026年3月23日

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

2026年5月18日

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

2026年4月1日

最新文章
全部 →
前端 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 Autocomplete:Slash Command 即時搜尋實戰

2026年3月30日·約 4 分鐘閱讀·
Discord.jsBotAutocompleteSlash CommandsNode.js

上一篇用 Modal 做了完整回饋流程。這篇再往前推一步:為 Slash Command 的 option 欄位加上即時搜尋,讓使用者不必死背指令名稱。


Autocomplete 是什麼?

先看一個對比。假設有個 /help command: 指令:

沒有 Autocomplete 時

command 只是一個普通文字欄位,使用者得把指令名稱完整打完,送出後 Bot 才知道他輸入了什麼。

指令少的時候沒問題,但名稱一多、一長,容易打錯,體驗就會變差。

沒有 Autocomplete — 只有空白文字欄位

有 Autocomplete 時

只要輸入幾個字,Discord 就會顯示 Bot 即時回傳的候選清單,使用者直接點選即可。

有 Autocomplete — 即時顯示候選清單

一句話總結:使用者還在輸入時,Bot 就先把可能的答案列出來。

什麼情況要自己做

通常是文字輸入型的 Slash Command option,才需要你自己處理 Autocomplete。

因為有些 option type,Discord 本身就有內建選擇方式,例如:

  1. USER:直接選成員
  2. CHANNEL:直接選頻道
  3. ROLE:直接選身分組

這些類型很多時候不用你自己再寫 autocomplete。Discord 本身就會彈出對應的選擇器。

ROLE 類型 — Discord 內建身分組選擇器

真正常見要自己處理的,是像 STRING 這種文字型欄位。Discord 不知道你想提供哪些候選值,所以要由 Bot 在 interaction.isAutocomplete() 裡自己回傳。

所以它最適合用在:

  1. 指令很多時的 /help
  2. 文章、標籤、角色、商品名等搜尋
  3. 想避免使用者輸入錯字

註冊可 autocomplete 的指令

以 /help command 為例,把 option 的 autocomplete 設為 true。

commands.js
export const COMMANDS = [
  {
    name: "help",
    description: "查詢指令說明",
    options: [
      {
        name: "command",
        description: "要查詢的指令名稱",
        type: 3, // STRING
        required: true,
        autocomplete: true,
      },
    ],
  },
];

interactionCreate 需要兩段處理

你要同時處理:

  1. interaction.isAutocomplete():回傳候選清單
  2. interaction.isChatInputCommand():真正執行 /help
index.js(節錄)
import { Client, GatewayIntentBits, EmbedBuilder } from "discord.js";
import "dotenv/config";
 
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
 
const HELP_DATA = [
  { name: "ping", description: "測試 Bot 是否在線" },
  { name: "daily", description: "每日簽到" },
  { name: "feedback", description: "提交回饋表單" },
  { name: "ask", description: "向 AI 提問" },
  { name: "reset", description: "清除目前頻道 AI 對話歷史" },
];
 
client.on("interactionCreate", async (interaction) => {
  if (interaction.isAutocomplete()) {
    if (interaction.commandName !== "help") return;
 
    const focused = interaction.options.getFocused().toLowerCase();
    const choices = HELP_DATA
      .filter((item) => item.name.includes(focused))
      .slice(0, 25)
      .map((item) => ({ name: item.name, value: item.name }));
 
    await interaction.respond(choices);
    return;
  }
 
  if (interaction.isChatInputCommand() && interaction.commandName === "help") {
    const commandName = interaction.options.getString("command", true);
    const found = HELP_DATA.find((x) => x.name === commandName);
 
    if (!found) {
      await interaction.reply({ content: "找不到該指令說明。", flags: 64 });
      return;
    }
 
    const embed = new EmbedBuilder()
      .setColor("Aqua")
      .setTitle(`/${found.name}`)
      .setDescription(found.description)
      .setFooter({ text: "輸入 /help 後可直接用 autocomplete 搜尋" });
 
    await interaction.reply({ embeds: [embed], flags: 64 });
  }
});

常見坑

  1. respond 最多 25 筆,超過要 slice(0, 25)。
  2. Autocomplete 不支援太慢的外部查詢,先從記憶體資料做起。
  3. 若候選值是 ID,name 給人看、value 存實際值。
  4. isAutocomplete 與 isChatInputCommand 是兩種不同互動,不要混在同一段邏輯。

下一篇預告

下一篇做排程任務,讓 Bot 不是只等人呼叫,而是每天固定時間自己主動做事。

分享:XLinkedIn
← 上一篇Discord Bot Modal:用彈出表單做完整回饋流程
下一篇 →Discord Bot 排程任務:node-cron 做每日公告與資料重置