iT邦幫忙

2022 iThome 鐵人賽

DAY 5
3

Day 5 實作 Ping 和 Timing 模組

昨天完全沒有寫到程式,今天就多寫一些吧。

今天來簡單實作一下類 Koa 的 middlewares pipeline。

目標

import { Bot } from "pure-cat";
import { Timing } from "pure-cat-module-timing";
import { Ping } from "pure-cat-module-ping";

new Bot()
    .use(new Timing())
    .use(new Ping())
    .start()
    .then(() => console.log("Bot started!"));

今天的目標是要實作一個 Bot 類別,它可以使用 use 方法來加入一個 module,並且可以使用 start 方法來啟動這個 bot。

目前我有先把 pure-catpure-cat-module-timing 以及 pure-cat-module-ping 這三個 package 發布到 npm 上了,有興趣的可以用 pnpm install pure-cat pure-cat-module-timing pure-cat-module-ping 來安裝試試。

❯ node dist/index.js

Bot started!
message 1021803560297566318: 534.193ms
dm 1021803576063950958: 565.008ms

DM

GM

實作

Timing Module

首先我們來實作一個 Timing module,它會輸出 Bot 處理每個訊息所花的時間(包含跟 Discord API 的通訊時間)。

與在 Koa 中使用 middleware 不同的是,我們需要在 Timing module 中實作 messagedm 這兩個方法,這兩個方法會在 Bot 收到訊息時被呼叫。

被呼叫時,執行以下步驟:

  1. 記錄當前時間 A
  2. await next() 呼叫下一個 module 相同的事件處理器,並等待它執行完畢
  3. 再次記錄當前時間 B,並輸出 BA 的差值,即為處理時間

在這裡,next 呼叫的就會是在 Timing 後面加入的 Ping

import { BaseModule, CallNextModule, Module } from "pure-cat";
import { GatewayIntentBits, Message } from "discord.js";

export class Timing extends BaseModule implements Module {
    name = "timing";
    intents = [
        GatewayIntentBits.DirectMessages,
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
    ];

    async message(message: Message<true>, next: CallNextModule): Promise<void> {
        console.time(`message ${message.id}`);
        await next();
        console.timeEnd(`message ${message.id}`);
    }

    async dm(message: Message<false>, next: CallNextModule): Promise<void> {
        console.time(`dm ${message.id}`);
        await next();
        console.timeEnd(`dm ${message.id}`);
    }
}

Ping Module

Ping module 的功能是當 Bot 收到訊息時,如果訊息內容是 ping,則回覆 pong
就跟前天簡單做出來的 Bot 功能一樣。

作為最後一個 module,呼叫 next 時會立刻返回。

import { BaseModule, CallNextModule, Module } from "pure-cat";
import { GatewayIntentBits, Message } from "discord.js";

export class Ping extends BaseModule implements Module {
    name = "ping";
    intents = [
        GatewayIntentBits.MessageContent,
        GatewayIntentBits.DirectMessages,
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
    ];

    async message(message: Message<true>, next: CallNextModule): Promise<void> {
        if (message.content === "ping") {
            await message.reply("pong (guild message)");
        }
        await next();
    }

    async dm(message: Message<false>, next: CallNextModule): Promise<void> {
        if (message.content === "ping") {
            await message.reply("pong (direct message)");
        }
        await next();
    }
}

Ok! 這樣就完成了。

明天會繼續講 Bot (框架的部分) 的實作。


每日鐵人賽熱門 Top 10 (2022-09-20)

以 2022/09/19 20:00 ~ 2022/09/20 20:00 文章觀看數增加值排名

誤差: 1 小時

  1. +593 「全端挑戰」學習Mern全端開發概念與動態網站開發流程懶人包
    • 作者: SamKo
    • 系列:自己做一個價值幾十萬的動態網站,學會Mern開發、前台UI設計各式觀念與各式Lib、typescript你該學會的前端技術
  2. +558 Scss與React Component的動態實作Navbar與Header
    • 作者: SamKo
    • 系列:自己做一個價值幾十萬的動態網站,學會Mern開發、前台UI設計各式觀念與各式Lib、typescript你該學會的前端技術
  3. +546 D01 - 沒時間解釋了,快上車!
    • 作者: 鱈魚
    • 系列:派對動物嗨起來!
  4. +515 了解Scss與React Component與首頁概念圖與UI實作
    • 作者: SamKo
    • 系列:自己做一個價值幾十萬的動態網站,學會Mern開發、前台UI設計各式觀念與各式Lib、typescript你該學會的前端技術
  5. +454 Case 01 Admin 帳號
    • 作者: mark_mew
    • 系列:IT 鬼故事
  6. +354 Case 02 系統外包
    • 作者: mark_mew
    • 系列:IT 鬼故事
  7. +291 Case 03 放在 DMZ 的資料庫
    • 作者: mark_mew
    • 系列:IT 鬼故事
  8. +289 製作動態網站第一步從了解useState與它的用法開始
    • 作者: SamKo
    • 系列:自己做一個價值幾十萬的動態網站,學會Mern開發、前台UI設計各式觀念與各式Lib、typescript你該學會的前端技術
  9. +273 Case 04 意料之外的變更
    • 作者: mark_mew
    • 系列:IT 鬼故事
  10. +232 智慧屋展示
    • 作者: joulongleu
    • 系列:地圖物聯

今天的瀏覽增加數又回到了正常值。榜單上多了個鬼故事系列,看起來是有人在接手資料庫維運時遇到了些麻煩呢。


上一篇
Day 4 模組化
下一篇
Day 6 模組 Pipeline
系列文
Discord Bot with TypeScript: Framework, Database, and Modules30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言