Discord Bot 程式設計
現成機器人(見 熱門機器人)處理不了客製化需求時,就要自己寫程式控制機器人行為。開始寫程式前,先在 開發者入口與 Webhook 完成申請應用程式、拿到機器人權杖(Token)、產生邀請連結——這一頁接著講怎麼寫程式:選函式庫、Intents、基本指令與 Slash Commands,以及上線部署的選項。
選一套函式庫
Discord 官方沒有指定語言,社群維護的函式庫都是包裝官方 REST API 與 WebSocket 事件,常用兩套:
| 語言 | 函式庫 | 適合情境 |
|---|---|---|
| Python | discord.py | 語法直覺、文件完整,第一次寫機器人的常見選擇 |
| JavaScript/Node.js | discord.js | 生態系大、與 Node 後端或既有 Web 專案整合方便 |
兩者概念相通:用事件(Event)回應「機器人上線」「收到訊息」,用指令(Command)回應使用者輸入。學會一套之後,換另一套只是語法差異。
Intents(意圖)是什麼
新版 Discord API 預設不會把訊息內容、成員列表等較敏感的事件送給機器人,需要明確宣告要用哪些 Intent,兩個地方都要開:
- Developer Portal:進入應用程式的「Bot」分頁,開啟需要的 Privileged Gateway Intents(例如
MESSAGE CONTENT INTENT)。 - 程式碼:初始化機器人時宣告對應的 Intents,沒宣告的事件即使 Portal 開了也收不到。
import discord
intents = discord.Intents.default()
intents.message_content = True # 需要讀取訊息內容時才開
client = discord.Client(intents=intents)
const { Client, GatewayIntentBits } = require("discord.js");
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent, // 需要讀取訊息內容時才開
],
});
最小可運作的機器人
兩套函式庫的骨架都一樣:機器人上線後印出訊息,收到 !ping 就回覆 Pong!。
import discord
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
@client.event
async def on_ready():
print(f"已登入為 {client.user}")
@client.event
async def on_message(message):
if message.author == client.user:
return # 避免機器人回應自己
if message.content == "!ping":
await message.channel.send("Pong!")
client.run("你的機器人權杖")
const { Client, GatewayIntentBits } = require("discord.js");
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
client.once("ready", () => {
console.log(`已登入為 ${client.user.tag}`);
});
client.on("messageCreate", (message) => {
if (message.author.bot) return; // 避免機器人回應自己
if (message.content === "!ping") {
message.channel.send("Pong!");
}
});
client.login("你的機器人權杖");
機器人權杖不能外流
權杖(Token)等同機器人的密碼,不要寫死在會上傳到 GitHub 的程式碼裡,改用環境變數(例如 .env 檔搭配 python-dotenv 或 Node 的 dotenv)讀取,並把 .env 加進 .gitignore。
Slash Commands(斜線指令)
!ping 這種「前綴指令」仍能用,但 Discord 目前主推斜線指令(輸入 / 會跳出提示、有參數型別檢查,體驗更好)。斜線指令要先向 Discord 註冊,再監聽對應的互動(Interaction)事件:
from discord import app_commands
import discord
intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)
@tree.command(name="ping", description="測試機器人是否還活著")
async def ping(interaction: discord.Interaction):
await interaction.response.send_message("Pong!")
@client.event
async def on_ready():
await tree.sync() # 把指令同步註冊到 Discord
print(f"已登入為 {client.user}")
client.run("你的機器人權杖")
const { Client, GatewayIntentBits, SlashCommandBuilder } = require("discord.js");
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once("ready", () => {
console.log(`已登入為 ${client.user.tag}`);
});
client.on("interactionCreate", async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === "ping") {
await interaction.reply("Pong!");
}
});
client.login("你的機器人權杖");
指令定義(SlashCommandBuilder/app_commands)需要另外用 Discord 的 REST API 註冊一次,之後才會出現在斜線選單裡;兩套函式庫的官方文件都有完整的註冊範例,第一次設定照著文件跑一遍即可。
上線與部署
- 本機測試:先在自己電腦執行,用一個測試用的私人伺服器驗證指令行為,確認沒問題再正式上線。
- 持續運作:機器人程式需要「一直開著」才能持續在線,筆電睡眠或關機都會讓機器人離線。小型專案常見作法是部署到免費或低價的雲端平台(例如 Railway、Render,或簡易的 VPS),讓程式全天執行。
- 版本管理:程式碼建議搭配 Git 做版本控管,方便追蹤修改紀錄與回滾錯誤的部署。
推薦影音
Code a Discord Bot with Python - Host for Free in the Cloud
從 Developer Portal 申請機器人開始,用 Python/discord.py 實作基本指令並免費部署上雲端,適合第一次寫 Discord 機器人的人。
Code a Discord Bot with JavaScript - Host for Free in the Cloud
同系列的 JavaScript/discord.js 版本,涵蓋建立應用程式、撰寫指令與部署流程。