在前一篇我們準備好了 Discord 基本的一些東西與設定,接下來當然要繼續聊 Discord 的部分囉~
前一篇我們分別認識了官方所提供的註冊指令到 Bot 的程式碼,以及登入 Discord Bot 的程式碼,但實際上來講就這樣嗎?不,其實還有很多東西可以講,就讓我們專注於 Discord Bot 的方便吧!
首先我們先看一下前一篇寫的程式碼:
// index.js
const { Client, Intents } = require('discord.js'); // 引入 discord.js 套件
// 實例化 Client
const client = new Client({
intents: [
Intents.FLAGS.GUILDS
]
});
// 當機器人準備好時
client.once('ready', () => {
console.log('Ready!');
});
// 登入機器人
client.login(TOKEN);
我們先專注於 const client = new Client({ ... })
這裡面的物件
// ... 略過其他程式碼
const client = new Client({
intents: [
Intents.FLAGS.GUILDS
]
});
// ... 略過其他程式碼
首先 const client = new Client({ ... })
這行是在建立一個新的 Discord.js 物件,你可以想像它就像是一個接入 Discord API 的橋樑,讓我們可以透過程式碼去操作 Discord。
而裡面是傳入一些地方,先講講 intents
這個參數,這個參數非常的重要,會影響你的機器人可以做哪些事情。
問題來了,intents
主要是幹嘛的呢?簡單來說就是告知 Discord 我們會有哪些「意圖」,例如:我們的機器人會需要接收伺服器的訊息,那麼我們就需要告知 Discord 我們會需要接收伺服器的訊息,這樣 Discord 才會將伺服器的訊息傳送給我們的機器人。
這邊我先舉例一下我先前寫的程式碼:
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
我們可以看到 intents
接收了一個陣列,裡面放了三個參數,這三個參數分別是:
GatewayIntentBits.Guilds
:可以接收伺服器相關的事件,例如:使用者加入伺服器、使用者離開伺服器等等。GatewayIntentBits.GuildMembers
:可以接收伺服器內的聊天訊息事件,例如:使用者傳送訊息、使用者編輯訊息等等。GatewayIntentBits.MessageContent
:這個比較特別一點,這是在告知機器人我們需要接收訊息的內容,例如:使用者傳送的訊息內容、使用者編輯的訊息內容等等,這個跟前面的 GatewayIntentBits.GuildMembers
不同的地方在於,GatewayIntentBits.GuildMembers
只會告知我們使用者傳送了訊息,但不會告知我們訊息的內容,所以我們需要另外告知 Discord 我們需要接收訊息的內容。當然不只有這些,還有...
GatewayIntentBits.GuildMessageReactions
:可以接收伺服器內的反應事件,例如:使用者給予訊息反應、使用者移除訊息反應等等。GatewayIntentBits.DirectMessages
:可以接收私人訊息事件,例如:使用者傳送私人訊息、使用者編輯私人訊息等等。GatewayIntentBits.DirectMessageReactions
:可以接收私人訊息的反應事件,例如:使用者給予私人訊息反應、使用者移除私人訊息反應等等。GatewayIntentBits.DirectMessageTyping
:可以接收私人訊息的打字事件,例如:使用者正在打字、使用者停止打字等等。當然這邊只列出一些而已,其他部分可以參考 Discord.js 官方文件。
partials
有一點特別,它也是 new Client
時會傳入的參數之一:
const { Client, GatewayIntentBits, Partials } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
partials: [
Partials.Channel
],
});
partials
這個參數是用來告知 Discord 我們需要接收哪些「部分」的資料,例如:我們需要接收哪些訊息的內容、哪些訊息的反應等等。
那為什麼要特別設定這個呢?主要原因是因為 Discord 會將一些資料分成兩個部分,一個是完整的資料,另一個是部分的資料,例如:我們需要接收訊息的內容,但 Discord 會將訊息的內容分成兩個部分,一個是完整的訊息內容,另一個是部分的訊息內容,這樣就會造成我們無法取得完整的訊息內容,所以我們需要告知 Discord 我們需要接收完整的訊息內容。
那麼我們大致上了解了 Partials
的用途後,就先這樣繼續往下吧~有需要我們再來聊這個。
接下來我們就來聊聊 Discord 的方法與事件,這邊我們就先來看看 Discord 的方法吧!
我們在範例程式碼中,其實有看到 Client
實例化後,做了一些事情...
// index.js
const { Client, Intents } = require('discord.js'); // 引入 discord.js 套件
// 實例化 Client
const client = new Client({
// ... 略過其他程式碼
});
// 當機器人準備好時
client.once('ready', () => {
// ... 略過其他程式碼
});
// 登入機器人
client.login(TOKEN);
分別是...
once
註冊了一個事件,但這個事件只會觸發一次。login
登入機器人,就是登入機器人的意思。但實際上來講,方法不只有這些,詳細可以看 Discord.js 官方文件。
但最常見的莫過於 on
與 once
,這兩個方法都是用來註冊事件的,但 on
會持續監聽事件,而 once
則只會監聽一次事件。
講完這些方法後,接下來當然是要聊聊事件了,我們先來看看前面的程式碼:
client.once('ready', () => {
// ... 略過其他程式碼
});
這邊我們可以看到 once
監聽了一個事件,也就是 ready
事件,這個事件是在機器人準備好時觸發的,所以當機器人準備好時,就會觸發這個事件。
那麼 client.on
跟 client.once
哪裡來的呢?如果你有去翻 Discord.js 官方文件,你會發現你只找得到 client.login
這個方法,但沒有 client.on
與 client.once
這兩個方法,那這兩個方法是哪裡來的呢?
其實主要是來自 EventEmitter
這個類別,EventEmitter
這個類別是 Node.js 內建的類別,而 Client
這個類別繼承了 EventEmitter
這個類別,所以我們才可以使用 client.on
與 client.once
這兩個方法,你可以在這邊 EventEmitter 看到。
那麼 once
跟 on
裡面的事件除了 ready
之外,還有哪些呢?其實非常的多,而且上面寫法也不是唯一的寫法,你可以這樣寫:
const {
Client,
GatewayIntentBits,
Partials,
Events,
} = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
partials: [
Partials.Channel,
],
});
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
client.login(TOKEN);
這邊我們可以看到 once
裡面的事件變成了 Events.ClientReady
,這是因為 Events
這個物件是 Discord.js 提供的,裡面包含了所有的事件,你可以在這邊 Events 看到。
那寫字串跟使用 Events
有什麼差嗎?其實我認為沒差很多,只是差別在於你可以直接透過 Events
下拉選單,就可以看到所有的事件,而不用去翻文件,這樣比較方便而已
實際上 Events
也是傳入相對應的字串而已,底下是我翻出來的原始碼:
export enum Events {
ClientReady = 'ready',
MessageCreate = 'messageCreate',
MessageDelete = 'messageDelete',
MessageUpdate = 'messageUpdate',
// ... 略過其他程式碼
}
所以不論你寫...
client.once('ready', () => {
console.log('Ready!');
});
或是...
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
兩者都是相同的結果,只是一個不用特別去查文件,直接下拉就可以選。
接下來我們先來寫一點小東西好了,我們來試著寫監聽訊息的事件,然後輸出到終端機上:
// index.js
const {
Client,
GatewayIntentBits,
Partials,
Events,
} = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
partials: [
Partials.Channel,
],
});
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
// 監聽訊息事件,請使用 on 作為持續監聽事件
client.on(Events.MessageCreate, (message) => {
console.log('[有人說:」',message.content);
});
client.login(TOKEN);
接著透過 node index.js
啟動後,你在頻道上發送一個訊息就可以看到終端機上輸出了,如下圖:
很簡單吧?那我們這一篇也先到這邊結束好了,我們下一篇繼續聊 Discord 的部分。