ハウツー · 出典付きの回答
ResendのWebhookの仕組みとは?
ResendのWebhookは、メール、連絡先、ドメイン、サプレッションに関するイベントが発生したときに、JSONのイベントペイロードを含むHTTPS POSTを登録済みのエンドポイントに送信することで機能します。エンドポイントでは、生のリクエストボディに対して署名を検証し、イベントを冪等に処理して、速やかに成功レスポンスを返す必要があります。
ResendのWebhookのワークフロー
ワークフローは、公開HTTPSエンドポイントを作成し、アプリケーションに必要なイベントタイプとともにResendに登録するところから始まります。該当するイベントが発生すると、ResendはJSONペイロードを含むPOSTリクエストを送信します。ペイロードには、email.sent、email.delivered、email.bounced、email.complained などのtype、作成日時、イベント固有のデータが含まれます。すべてのペイロードが同じ構造だと想定せず、typeフィールドに基づいて処理を振り分けてください。
処理の前にリクエストを検証する
リクエストを生のテキストとして読み込み、Webhookの署名シークレットと、svix-id、svix-timestamp、svix-signatureの各ヘッダーを使って検証します。これは、ペイロードを解析したり、それに基づいて処理したりする前に行ってください。JSONを解析してから再びシリアライズするとバイト列が変わり、正当な署名でも検証に失敗することがあります。検証に合格しないリクエストは拒否し、署名シークレットはソースコードではなく、シークレットマネージャーや保護された環境変数で管理してください。
イベント処理を冪等にする
ResendはAt-Least-Once配信を明記しているため、同じイベントがエンドポイントに複数回届くことがあります。svix-idを一意性制約付きで保存し、その識別子がすでに処理済みであればビジネスロジックをスキップしてください。再試行やネットワークの遅延によってイベントの順序が入れ替わることがあるため、到着順にも依存しないでください。順序が重要な場合はイベントのcreated_atの値を使い、古いイベントが誤って新しい状態を上書きしないようにステータスの変化をモデル化します。
すばやく応答し、安全に処理する
イベントを検証して永続的に記録したらHTTP 200を返し、時間のかかる処理はキューやバックグラウンドワーカーで行います。タイムアウトや成功以外のレスポンスは再配信の原因になるため、長い同期ハンドラーは避けられるはずの重複を生みます。取り込み処理と、サプレッションレコードの更新、サポートへの通知、バウンスの記録といった副作用とを分離してください。各副作用も、繰り返し実行しても安全にするか、保存したイベント識別子で保護する必要があります。
再試行、リプレイ、障害からの復旧をテストする
本番環境に移す前に、代表的なイベントタイプでエンドポイントをテストします。無効な署名、重複した識別子、順序の入れ替わったタイムスタンプ、データベースの一時的な障害といったケースも含めてください。Resendは失敗した配信をバックオフのスケジュールに従って再試行し、失敗したWebhookメッセージと成功したWebhookメッセージの両方をリプレイできます。リプレイは障害後の復旧や更新したハンドラーコードの検証に使えますが、復旧によって顧客に影響する副作用が繰り返されないよう、重複排除は有効にしたままにしてください。
よく寄せられる質問
ResendのWebhookエンドポイントはどのレスポンスを返すべきですか?
リクエストを検証し、イベントを永続的に受け付けたらHTTP 200を返してください。時間のかかる処理は非同期で続行し、タイムアウトによってプロバイダーが再試行しないようにします。
生のリクエストボディを保持しなければならないのはなぜですか?
署名は元のリクエストのバイト列を対象としています。JSONを解析して再シリアライズするとそのバイト列が変わる可能性があり、正当なリクエストでも検証に失敗します。
ResendのWebhookイベントが複数回配信されることはありますか?
はい。ResendはAt-Least-Once配信を明記しているため、ハンドラーでイベントの重複を排除する必要があります。通常は、ビジネス上の副作用を適用する前に一意のsvix-idを保存します。
ResendのWebhookイベントは順番どおりに配信されますか?
いいえ。ネットワークの遅延や再試行によって到着順は変わることがあります。アプリケーションで信頼できる順序を再構築する必要がある場合は、イベントのタイムスタンプと状態遷移のルールを使ってください。
失敗したResendのWebhook配信はどのように復旧すればよいですか?
Resendは失敗した配信を自動的に再試行し、手動でのリプレイにも対応しています。まずエンドポイントを修正し、冪等性のチェックを有効にしたまま、必要なイベントをリプレイしてください。
一次情報源
- Webhookの管理 — Resend
- Webhookリクエストの検証 — Resend
- 再試行とリプレイ — Resend
- Webhookのイベントタイプ — Resend