執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

建立一個 Discord 機器人

Discord.js 可直接執行在 Bun 上,無需額外設定。本指南將建置一個響應 /ping 斜槓命令的機器人:你只需註冊一次命令,然後啟動機器人並在你的伺服器中使用它。如果這是你第一次建立機器人,建議在讀到每個程式碼塊時就直接複製。


為你的機器人建立一個資料夾,並使用 bun init 進行初始化。出現提示時選擇預設選項。

terminal
mkdir my-bot
cd my-bot
bun init

將 Discord.js 新增到專案中。

terminal
bun add discord.js

你的機器人需要自己的賬號,你可以在 Discord 的開發者門戶中建立該賬號。開啟 developer portal,登入並建立一個 Application。Discord 會自動為每個新應用新增一個機器人使用者;你可以在 Bot 選項卡中找到它。如果你遇到困難,Discord.js 指南中的設定教程提供了截圖。

從門戶中複製兩個值:

  • Bot 選項卡中的 token:點選 Reset Token 生成它(Discord 只會顯示一次)。它是你的程式碼用於登入的密碼,因此請像對待密碼一樣保護它,不要向他人透露
  • General Information 選項卡中的 Application ID。Discord 使用它將你的命令關聯到此應用

在你邀請機器人之前,它無法在伺服器中執行任何操作。在門戶的 OAuth2 部分,生成一個包含 bot 和 applications.commands 範圍的邀請 URL,開啟該 URL,然後將機器人新增到你管理的伺服器中。斜槓命令需要 applications.commands 範圍,因此請務必包含它。你可以先在自己建立的個人測試伺服器中進行測試;Discord.js 的新增機器人指南提供了帶截圖的操作步驟。


你還需要伺服器的 ID,才能在該伺服器中註冊命令。在 Discord 中,開啟 Settings > Advanced > Developer Mode,然後右鍵單擊伺服器圖示並選擇 Copy Server ID。


將這三個值儲存到 .env.local 中。Bun 會在啟動時讀取這個檔案並將其載入到 process.env,因此你的程式碼裡不會出現任何金鑰。

.env.local
DISCORD_TOKEN=your-bot-token
DISCORD_CLIENT_ID=your-application-id
DISCORD_GUILD_ID=your-server-id

在提交任何內容之前,將 .env.local 新增到 .gitignore。任何讀取到令牌的人都可以控制你的機器人,因此絕不能將令牌提交到版本控制中。

.gitignore
node_modules
.env.local

在任何人能使用命令之前,Discord 必須先知道這個命令。使用一個名為 deploy-commands.ts 的簡短指令碼註冊 /ping。

deploy-commands.ts
import { REST, Routes, SlashCommandBuilder } from "discord.js";

const { DISCORD_TOKEN, DISCORD_CLIENT_ID, DISCORD_GUILD_ID } = process.env;
if (!DISCORD_TOKEN || !DISCORD_CLIENT_ID || !DISCORD_GUILD_ID) {
  throw new Error("在 .env.local 中設定 DISCORD_TOKEN、DISCORD_CLIENT_ID 和 DISCORD_GUILD_ID");
}

// 你想要註冊的命令
const commands = [new SlashCommandBuilder().setName("ping").setDescription("回覆 Pong!").toJSON()];

const rest = new REST().setToken(DISCORD_TOKEN);

// 在你的測試伺服器中註冊它們
await rest.put(Routes.applicationGuildCommands(DISCORD_CLIENT_ID, DISCORD_GUILD_ID), { body: commands });

console.log("已註冊 /ping");

執行一次即可。

terminal
bun run deploy-commands.ts

只有在你新增命令,或者更改命令名稱或描述時,才需要再次執行它,而不是每次機器人啟動時都執行。註冊到你的伺服器而不是全域性註冊,可以讓命令只在你的測試範圍內可用。


接下來是機器人本體。將其儲存為 bot.ts。

bot.ts
import { Client, Events, GatewayIntentBits } from "discord.js";

const { DISCORD_TOKEN } = process.env;
if (!DISCORD_TOKEN) {
  throw new Error("在 .env.local 中設定 DISCORD_TOKEN");
}

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

// 在機器人連線後立即執行一次
client.once(Events.ClientReady, readyClient => {
  console.log(`Logged in as ${readyClient.user.tag}`);
});

// 每次有人使用斜槓命令時執行
client.on(Events.InteractionCreate, async interaction => {
  if (!interaction.isChatInputCommand()) return;

  if (interaction.commandName === "ping") {
    await interaction.reply("Pong!");
  }
});

client.login(DISCORD_TOKEN);

ready 處理器會在機器人連線後輸出一行日誌。之後,只要有人使用斜槓命令,interactionCreate 就會執行;它會確認命令是否為 /ping,並回復 Pong!。


使用 bun run 啟動機器人。

terminal
bun run bot.ts

首次連線需要幾秒鐘。等登入資訊打印出來後,切換到 Discord,在你的伺服器中輸入 /ping。

Text
Logged in as my-bot#1234

機器人會回覆 Pong!。你已經擁有一個可工作的 Discord 機器人了。


要新增另一個命令,只需在 deploy-commands.ts 中定義它,再執行一次指令碼,並在 bot.ts 中為它的名稱新增一個 if 分支。Discord.js 文件涵蓋了命令選項、許可權、按鈕、嵌入訊息以及 API 的其餘部分。


部署時,不需要建置或打包步驟。Bun 會直接執行 bot.ts 及其匯入的每個檔案,因此你可以原樣部署原始碼,並使用開發時相同的 bun run bot.ts 啟動它。

deploy-commands.ts 會在你的測試伺服器中註冊 /ping,這在開發階段是正確的作用範圍。若要將機器人釋出到它加入的每個伺服器中,請改為全域性註冊:將路由改為 Routes.applicationCommands(DISCORD_CLIENT_ID)。全域性註冊不需要伺服器,因此你也可以從指令碼的檢查和 .env.local 中移除 DISCORD_GUILD_ID。

為了讓機器人保持線上,並在崩潰或重啟後恢復執行,請在行程管理器下執行它。