FLARES LLC
FLARES LLC

Technical document

メッセージWebhook連携の境界と再送設計

メッセージサービスとの連携では、Webhookを受け取った瞬間にすべての処理を終わらせようとすると、失敗時の再送や重複に弱くなります。受信と業務処理の境界を分けることが重要です。 メッセージWebhookはリアルタイムに見えますが、再送、順序逆転、重複、外部API制限を前提にした非同期境界として設計すべきです。
外部連携 / Webhook約10分公開日 2026年7月5日更新日 2026年7月5日
メッセージWebhook連携の境界と再送設計のアイキャッチ

Summary

この文書の要点

  • Webhook受信では署名検証とイベント保存を優先する。
  • 外部イベントIDで重複を防ぐ。
  • Webhook受信は短く終え、重い処理はキューへ渡して再試行できるようにする。
  • message_idやevent_idで冪等性を確保し、同じ通知を二重処理しない。

どこが設計の難所か

Webhook内でDB更新、通知、返信、ファイル取得まで同期実行すると、外部サービスのタイムアウトに間に合わないことがあります。失敗時に再送されると、同じ通知や登録が二重に実行される危険があります。

外部サービスのWebhookは、署名、リトライ、イベント形式、応答時間の制約を持ちます。アプリ側では内部ユーザーと外部ユーザーIDの紐づけ、ブロックや連携解除も扱う必要があります。

メッセージ連携では、受信したイベントへすぐ返信したくなります。しかし外部サービスからの再送やタイムアウト、アプリ側の処理遅延があると、同期処理は脆くなります。まず受け取った事実を保存することが重要です。

境界をどう切るか

受信エンドポイントでは、署名検証、イベントID保存、最小限の正規化だけを行い、業務処理はキューへ渡します。内部処理では、イベント種別ごとにハンドラを分け、冪等性を保ちます。

設計では、Webhook入口、イベント保存、業務処理、返信送信を分けます。入口では署名検証と重複チェックだけを行い、処理キューへ渡します。業務処理は再実行しても同じ結果になるようにします。

実装で効く細部

DBには外部イベント、外部ユーザー紐づけ、処理状態、最終エラーを保存します。返信が必要な処理は、送信ログを持ち、同じイベントに対して同じ返信を二重送信しないようにします。

HonoやLaravel側では、eventsテーブルにevent_id、source_id、type、payload_hash、received_at、statusを保存します。返信や外部API呼び出しはoutboxテーブルに積み、送信成功、失敗、再試行回数を管理します。

  • 署名検証に失敗したpayloadは処理せず、必要な範囲で監査ログだけ残す。
  • 同じevent_idの再送は既存処理結果を見て成功応答にできるようにする。
  • 返信送信はoutbox patternで管理し、業務更新と送信要求を同じトランザクションに入れる。

壊れ方を観測する

検証では、署名不正、同一イベント再送、処理途中失敗、外部ユーザー未紐づけ、ブロック済みユーザーのケースを確認します。Webhook受信のレスポンス時間も測ります。

検証では、同一イベント再送、順序逆転、返信API失敗、キュー再試行、署名不一致を確認します。ローカルでは保存済みpayloadを再投入できるCLIを用意すると、障害調査が容易になります。

捨てた選択肢とトレードオフ

キューに分けると処理完了まで遅延が出ます。即時返信が必要な操作では、受信時に返すメッセージを限定し、重い処理は後続通知に回すなどUXとの調整が必要です。

同期返信は実装が短く体験も分かりやすい一方、外部APIの遅延に巻き込まれます。非同期化すると状態管理は増えますが、再試行と監査がしやすくなります。重要な業務処理ほど非同期境界を置く価値があります。

現場に残す判断軸

Webhook連携では、受け取ることと処理することを分けるだけで堅牢性が上がります。署名検証、イベント保存、冪等処理を基本にすれば、外部サービスの再送にも対応しやすくなります。

Webhook連携では、速く返すことと確実に処理することを分けます。受信記録とoutboxを持つだけで、再送に強い連携へ変わります。

Technical documents

技術文書を増やしていきます。

AI、クラウド、業務アプリ開発、要件定義、運用設計に関する考え方を、今後も文書として整理します。

技術文書一覧へ