從零開始的Discord機器人(4) - 改善事件架構

本篇會將改善目前Discord機器人的事件架構,使其更易於擴充與維護。

  在上一篇中,我們改善了關於指令部分的架構。而這次我們要接著改善監聽事件的寫法,讓機器人更容易維護與擴充。

1. 一樣從事件本體開始

  首先,我們一樣要先來處理事件本體的部分。

  跟上一篇一樣,到目前為止我們的監聽事件也全都寫在index.js裡。所以接下來我們要做的事情是把事件都拆分成各自的檔案。

  新增一個events資料夾,這個資料夾會用來存放所有事件的檔案。目前我們有ClientReady與InteractionCreate兩種事件,因此我們在events內新增ready.js與interactionCreate.js兩個檔案。

  接下來以ready.js為例,我們一樣使用module.exports來匯出所有需要的東西,只不過內容會和指令有一點點不一樣,完整的檔案會長這樣:

module.exports = {
    name: 'ready',
    once: true,
    async execute (client) {
        console.log (`歡迎登入 ${client.user.username}`);
    }
}

  監聽事件和指令一樣,都是在execute內執行相應的動作。你可能注意到這邊有多一個once,你可以使用client.on ()來註冊事件,或是使用client.once ()來註冊最多只會觸發一次的事件,ClientReady就是屬於這種事件,所以這裡使用once。

  根據這個格式,接下來我們來完成interactionCreate.js:

module.exports = {
    name: 'interactionCreate',
    async execute (interaction) {
        let reaction;
        if (interaction.isChatInputCommand()) {
            reaction = interaction.client.commands.get(interaction.commandName);
        }

        try {
            if (interaction.replied) return
            reaction.execute(interaction);
        }
        catch (error) {
            console.error(error);
        }
    }
}

2. 只剩註冊事件了

  前面我們已經把事件都拆開來了,接下來也和指令一樣,要取得events資料夾內的所有事件並一一註冊。事件相比指令單純許多,所以這邊就不另外使用function處理了。註冊事件的部分會長這樣:

const eventsPath = path.join (__dirname, 'events');
const eventFiles = fs.readdirSync (eventsPath).filter (file => file.endsWith ('.js'));

for (const file of eventFiles) {
    const filePath = path.join (eventsPath, file);
    const event = require (filePath);
    if (event.once) {
        client.once (event.name, (...args) => event.execute (...args));
    }
    else {
        client.on (event.name, (...args) => event.execute (...args));
    }
}

  到這裡,我們的改善工作已經完成,之後如果想要增加監聽的事件,只要在events資料夾內按照上面的格式新增檔案即可。你可以開始運行你的機器人了。

3. 接下來要做的事情

  本系列有關機器人的基礎架構已經完成,到現在已經可以寫出一隻完整的機器人了。所以後續的內容會偏向介紹其他可以玩的功能,例如按鈕、表單、下拉式選單等Components,或是能夠讓機器人的回應更加美觀的Embeds等。

  感謝你看到這邊,我們下次見。