一、今天的學習目標
二、/add的目的
在新增行程時需要知道行程名稱、日期、時間這三個資訊
所以需要另外建立一個 /add 指令,讓使用者可以輸入這些資料。
三、建立 /add 指令
我參考了我前一天製作的/ping指令。並依照那個邏輯去創建一個/add的指令。一樣是在deploy-commands.js中創建新的一個new SlashCommandBuilder(),建立/add的指令物件,並加入指令說明,讓 Discord 知道這個指令的基本資訊。
四、加入 title、date、time 三個輸入欄位
建立/add指令後,需要使用者輸入行程相關資料,因此需要使用.addStringOption()建立三個文字欄位。這裡學到一個語法叫「箭頭函式 Arrow Function」,並使用method chaining,因為每個方法執行後都會回傳同一個 builder 物件,所以可以直接繼續呼叫下一個方法。
Arrow Function基本格式:
參數 => 執行內容
option => option.setName("title")
第一個欄位是title用來輸入行程名稱
第二個欄位是date用來輸入日期
第三個欄位是time用來輸入時間
四、將指令註冊到 Discord
前面都只是先把 /ping、/add 和輸入欄位整理到 commands 裡,目前這些都還只存在自己的程式中。
接下來需要透過 Discord API,把 commands 送到指定的伺服器,Discord 才會真的出現這些 Slash Command。
1.先從 .env 讀取 Discord Bot 的 Token、Application ID 和伺服器 ID,讓後面的指令註冊程式可以使用這些資料。
2.接著建立一個 REST 物件,讓程式可以透過 Discord API 傳送請求。
.setToken(token) 則是把剛剛從 .env 讀取的 Bot Token 放進去,讓 Discord 知道是哪個 Bot 在發送請求。
3.接著建立 deployCommands() 函式,使用 rest.put() 把前面建立好的 commands 傳送到指定的 Discord Application 和伺服器。Routes.applicationGuildCommands(clientId, guildId) 用來指定要註冊到哪個 Application 和 Guild,而 { body: commands } 則是把指令資料一起送出。最後呼叫 deployCommands(),才會真正執行這個註冊流程。
五、實際測試結果
執行 node deploy-commands.js 後,成功讀取 .env 中的三個環境變數,並顯示『指令註冊成功』,代表 /ping 和 /add 的指令設定已成功註冊到 Discord。
接下來回到 Discord,實際輸入 /add 測試指令是否成功出現。
輸入 /add 後,成功出現 title、date、time 三個輸入欄位。
六、今日修改的完整程式碼
以下是今天完成後的 deploy-commands.js 完整程式碼
require("dotenv").config();
const { REST, Routes, SlashCommandBuilder } = require("discord.js");
const commands = [
new SlashCommandBuilder()
.setName("ping")
.setDescription("測試機器人是否正常運作"),
new SlashCommandBuilder()
.setName("add")
.setDescription("新增行程")
.addStringOption(option =>//加一個文字輸入欄位
option
.setName("title")//設定標題名稱
.setDescription("輸入行程名稱")//給人看的說明
.setRequired(true)//設定為必填欄位
)
.addStringOption(option =>
option
.setName("date")
.setDescription("輸入日期,例如 20260930")
.setRequired(true)
)
.addStringOption(option =>
option
.setName("time")
.setDescription("輸入時間,例如 1400")
.setRequired(true)
)
].map(command => command.toJSON());
const token = process.env.DISCORD_TOKEN;
const clientId = process.env.CLIENT_ID;
const guildId = process.env.GUILD_ID;
const rest = new REST({ version: "10" }).setToken(token);
async function deployCommands() {
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands }
);
console.log("指令註冊成功");
}
deployCommands();