コンテンツにスキップ

EventDeduplicator

EventDeduplicator は、同じイベントが複数回届いた場合に内部ハンドラへの二重処理を防ぐミドルウェアです。公式 API 仕様には含まれない、SDK 独自の拡張機能です。

追加インストールは不要です。mixi2-js に同梱されています。

// ESM
import { EventDeduplicator } from 'mixi2-js/helpers';
// CJS
const { EventDeduplicator } = require('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, ... });
import { WebhookServer } from 'mixi2-js';
import { EventDeduplicator, EventRouter } from '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 分)
});
オプションデフォルト説明
maxSizenumber1000記憶する最大イベント数。超過した場合、最も古いエントリを削除
maxAgenumber300000イベント ID を記憶する最大時間(ミリ秒)。経過後は再び通過を許可

他のミドルウェアとの組み合わせ

Section titled “他のミドルウェアとの組み合わせ”

EventDeduplicatorEventHandler を実装しているため、他のミドルウェアと自由に組み合わせられます。

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, ... });
new EventDeduplicator(handler: EventHandler, options?: EventDeduplicatorOptions)
引数説明
handlerEventHandler重複排除後に処理を委譲する内部ハンドラ
optionsEventDeduplicatorOptions?オプション設定
メソッド戻り値説明
handle(event)Promise<void>重複チェックを行い、初回のみ内部ハンドラに委譲