EventDeduplicator
EventDeduplicator は、同じイベントが複数回届いた場合に内部ハンドラへの二重処理を防ぐミドルウェアです。公式 API 仕様には含まれない、SDK 独自の拡張機能です。
インストール
Section titled “インストール”追加インストールは不要です。mixi2-js に同梱されています。
// ESMimport { EventDeduplicator } from 'mixi2-js/helpers';// CJSconst { EventDeduplicator } = require('mixi2-js/helpers');import { EventDeduplicator } from '@otoneko1102/mixi2-js/helpers';なぜ EventDeduplicator を使うのか?
Section titled “なぜ EventDeduplicator を使うのか?”公式ドキュメントにも記載の通り、Webhook 方式ではリトライにより同じイベントが複数回届くことがあります。
Webhook 方式では、配信失敗時に最大 3 回までリトライされます。リトライにより同じイベントが複数回届く可能性があります。
EventDeduplicator を挟むだけで、重複した eventId を持つイベントを自動的にスキップします。
// ❌ 重複処理の可能性const server = new WebhookServer({ handler: myHandler, ... });
// ✅ 重複を自動スキップconst dedup = new EventDeduplicator(myHandler);const server = new WebhookServer({ handler: dedup, ... });基本的な使い方
Section titled “基本的な使い方”import { WebhookServer } from 'mixi2-js';import { EventDeduplicator, EventRouter } from 'mixi2-js/helpers';import { WebhookServer } from '@otoneko1102/mixi2-js';import { EventDeduplicator, EventRouter } from '@otoneko1102/mixi2-js/helpers';const router = new EventRouter();
router.on(EventType.POST_CREATED, async (event) => { // このハンドラは同じ eventId では最大 1 回しか呼ばれない const post = event.postCreatedEvent?.post; await client.createPost({ text: `受け取りました: ${post?.text}`, inReplyToPostId: post?.postId, });});
const dedup = new EventDeduplicator(router);
const server = new WebhookServer({ port: 8080, publicKey: Buffer.from(process.env.SIGNATURE_PUBLIC_KEY!, "base64"), handler: dedup,});
await server.start();const dedup = new EventDeduplicator(handler, { maxSize: 1000, // 記憶する最大イベント数(デフォルト: 1000) maxAge: 300_000, // 記憶する最大時間(ミリ秒, デフォルト: 5 分)});| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
maxSize | number | 1000 | 記憶する最大イベント数。超過した場合、最も古いエントリを削除 |
maxAge | number | 300000 | イベント ID を記憶する最大時間(ミリ秒)。経過後は再び通過を許可 |
他のミドルウェアとの組み合わせ
Section titled “他のミドルウェアとの組み合わせ”EventDeduplicator は EventHandler を実装しているため、他のミドルウェアと自由に組み合わせられます。
import { EventDeduplicator, EventRouter, ReasonFilter } from 'mixi2-js/helpers';import { EventReason } from 'mixi2-js';
const router = new EventRouter();// ... ルーターにハンドラを登録 ...
// ReasonFilter → EventDeduplicator の順でラップconst filter = new ReasonFilter(router, [EventReason.POST_MENTIONED]);const dedup = new EventDeduplicator(filter);
// webhook に渡すconst server = new WebhookServer({ handler: dedup, ... });API リファレンス
Section titled “API リファレンス”コンストラクタ
Section titled “コンストラクタ”new EventDeduplicator(handler: EventHandler, options?: EventDeduplicatorOptions)| 引数 | 型 | 説明 |
|---|---|---|
handler | EventHandler | 重複排除後に処理を委譲する内部ハンドラ |
options | EventDeduplicatorOptions? | オプション設定 |
| メソッド | 戻り値 | 説明 |
|---|---|---|
handle(event) | Promise<void> | 重複チェックを行い、初回のみ内部ハンドラに委譲 |