コンテンツにスキップ

Webhook サーバー

WebhookServer は Ed25519 署名検証付きの HTTP Webhook サーバーです。mixi2 からのイベントを安全に受信できます。

// ESM
import { WebhookServer, EventType } from 'mixi2-js';
import type { EventHandler, Event } from 'mixi2-js';
// CJS
const { WebhookServer, EventType } = require('mixi2-js');
const handler: EventHandler = {
handle: async (event: Event) => {
switch (event.eventType) {
case EventType.POST_CREATED:
console.log("Post created:", event.postCreatedEvent?.post?.text);
break;
case EventType.CHAT_MESSAGE_RECEIVED:
console.log("Chat message:", event.chatMessageReceivedEvent?.message?.text);
break;
}
},
};
// 公開鍵は Base64 からデコード
const publicKey = Buffer.from(process.env.SIGNATURE_PUBLIC_KEY!, "base64");
const server = new WebhookServer({
port: 8080,
publicKey,
handler,
});
await server.start();
console.log("Webhook server started on :8080");
new WebhookServer(options: WebhookServerOptions)
プロパティ 型 必須 デフォルト 説明
publicKey Buffer ○ - Ed25519 公開鍵(Base64 をデコードしたもの)
handler EventHandler ○ - イベントハンドラ
port number - 8080 リッスンポート
syncHandling boolean - false イベントを同期処理するか
メソッド 戻り値 説明
start() Promise<void> サーバーを起動
shutdown() Promise<void> サーバーを停止
address string リッスンアドレス
httpServer http.Server 内部の HTTP サーバーインスタンス
eventHandlerFunc Function イベントハンドラ関数(フレームワーク統合用)
パス メソッド 説明
/events POST イベント受信(署名検証 → protobuf デコード → ハンドラ呼出)
/healthz GET ヘルスチェック(常に 200 OK)
項目 値
署名ヘッダ x-mixi2-application-event-signature(Base64)
タイムスタンプヘッダ x-mixi2-application-event-timestamp(Unix 秒)
署名対象 リクエストボディ + タイムスタンプ
許容時刻ズレ ±300 秒(5 分)
署名失敗レスポンス HTTP 401
成功レスポンス HTTP 204

Developer Platform で Webhook URL を登録して 接続確認を実行 を押すと、3 種類の Ping がランダムな順で送信されます。WebhookServer はそれぞれ期待どおりのレスポンスを自動で返します。

リクエスト レスポンス
正しい署名 HTTP 204
不正な署名 HTTP 401
古いタイムスタンプ HTTP 401
  • HTTPS で公開されていること
  • 有効な CA 証明書を使っていること (自己署名証明書は不可)
  • WebhookServer を使う場合、パスは /events (例: https://YOUR_HOST_NAME/events)。createWebhookHandler では、ハンドラを置いたパスを登録します

1 つのアプリケーションに複数の Webhook URL は設定できません。

項目 値
タイムアウト 3 秒
リトライ回数 最大 3 回
リトライ間隔 30 秒

リトライにより同じイベントが複数回届く場合があるため、ハンドラは冪等に実装してください。重複の除外には EventDeduplicator が使えます。

Vercel、AWS Lambda などレスポンス後にプロセスが終了する環境では syncHandling: true を設定してください。ハンドラの完了まで処理が終わらないため、3 秒以内に完了できる処理が適しています:

const server = new WebhookServer({
port: 8080,
publicKey,
handler,
syncHandling: true,
});
export default server.httpServer;

Workers では wrangler の設定で nodejs_compat を有効にしたうえで、次のどちらかを使います。

  • createWebhookHandler (おすすめ): waitUntil でレスポンス後のハンドラ処理を Workers に引き継げます。使い方は次の節を参照してください
  • WebhookServer: cloudflare:node の httpServerHandler で、Workers に届いたリクエストを node:http のサーバーに渡します。Node.js 向けのコードをそのまま使いたい場合に向いています
import { httpServerHandler } from "cloudflare:node";
import { WebhookServer } from "mixi2-js";
const server = new WebhookServer({
port: 8080,
publicKey: Buffer.from(SIGNATURE_PUBLIC_KEY, "base64"),
handler,
// Workers はレスポンス後に処理を止めることがあるため、ハンドラの完了を待つ
syncHandling: true,
});
await server.start();
export default httpServerHandler({ port: 8080 });

Fetch API で受け取る (createWebhookHandler)

Section titled “Fetch API で受け取る (createWebhookHandler)”

createWebhookHandler は、Fetch API の Request を受け取って Response を返す Webhook ハンドラを作ります。Node.js の HTTP サーバーがない Cloudflare Workers のほか、Deno、Bun、Hono などでも使えます。署名とタイムスタンプの検証、Ping の扱い、レスポンスのステータスは WebhookServer と同じです。

// Cloudflare Workers (wrangler の設定で nodejs_compat を有効にする)
import { createWebhookHandler } from "mixi2-js";
export default {
fetch(request, env, ctx) {
const handleWebhook = createWebhookHandler({
publicKey: env.SIGNATURE_PUBLIC_KEY,
handler,
waitUntil: (promise) => ctx.waitUntil(promise),
});
return handleWebhook(request);
},
};
// Deno / Bun
const handleWebhook = createWebhookHandler({
publicKey: SIGNATURE_PUBLIC_KEY,
handler,
});
Deno.serve(handleWebhook); // Bun では Bun.serve({ fetch: handleWebhook })
// Hono
app.post("/events", (c) => handleWebhook(c.req.raw));
オプション 型 必須 説明
publicKey string | Uint8Array ○ 署名検証用の公開鍵。Developer Platform に表示される Base64 文字列をそのまま渡せます
handler EventHandler ○ イベントハンドラ
syncHandling boolean - true にすると、ハンドラの完了を待ってからレスポンスを返します (デフォルト: false)
waitUntil (promise: Promise<unknown>) => void - レスポンス後のハンドラ処理をランタイムに引き継ぐ関数。Cloudflare Workers では ctx.waitUntil

WebhookServer との違い:

  • パスでの振り分けはしません。POST 以外のメソッドには HTTP 405 を返します
  • syncHandling が false のとき、ハンドラはレスポンスを返した後も動き続けます。レスポンス後に処理が止まるランタイムでは、waitUntil を渡すか syncHandling: true にしてください
  • 署名検証に Web Crypto (crypto.subtle) の Ed25519 を使います。Node.js 20 では ExperimentalWarning が出るため、Node.js では WebhookServer をおすすめします

詳細は 公式ドキュメント を参照してください。