SteveSignalsDocs

Webhook

再試行と失敗

成功の基準、9 回の再試行スケジュール、Retry-After、410、停止した配信、再配信、自動無効化、エンドポイントを冪等にする方法を説明します。

Signals は、失敗した POST を決まったスケジュールで約 3 日間再試行します。スケジュールが尽きると、配信は**停止(再配信可能)**になります。何も失われません。アプリや API から再配信できます。このページでは、各段階を説明します。

成功の基準

エンドポイントが 10 秒以内に 2xx のステータスを返すと、配信は成功です。

それ以外はすべて失敗です。4xx や 5xx、3xx のリダイレクト、タイムアウト、接続エラーが該当します。Signals はレスポンスを最大 4 KB まで読み、内容は無視します。

ボディを保存したら、すぐに 200 を返してください。ページの読み取りは、その後バックグラウンドジョブで行います。処理が遅くてタイムアウトすると、同じ POST がもう一度届きます。

再試行スケジュール

1 つの配信は最大 9 回試行されます。待ち時間は、前回の失敗から数えます。多くのエンドポイントが同じ秒に再試行しないよう、各待ち時間は ±10 % ずれます。

試行タイミング
1すぐに
21 回目の失敗から 1 分後
32 回目から 5 分後
43 回目から 30 分後
54 回目から 2 時間後
65 回目から 6 時間後
76 回目から 12 時間後
87 回目から 24 時間後
98 回目から 24 時間後

合計で約 2.9 日です。9 回目も失敗すると、配信は**停止(再配信可能)**になります。履歴には残り、再配信できます。

各試行のヘッダー:

  • Signals-Webhook-Id は、1 つの配信のすべての試行で同じです。ボディの webhookId も同じです。
  • Signals-Delivery-Attempt は 1 から 9 まで数えます。
  • ボディには同じ実行、件数、トークンが入り、sentAt だけが新しくなります。
  • Signals-Signature は、試行ごとに新しいタイムスタンプで署名し直されます。

応答の扱い

あなたの応答Signals の動作
2xx配信済み。完了です。
410 Goneすぐに止めます。配信は停止(再配信可能)になり、Webhook は無効になって「サーバーが 410 Gone を返したため、この URL への送信を停止しました。サーバーを修正してから再度有効にしてください。」と表示されます。
Retry-After 付きの 429 または 503スケジュールどおりの待ち時間と Retry-After の時間(最大 1 時間)を比べ、長いほうだけ待ってから URL をもう一度呼びます。Retry-After で待ち時間が短くなることはありません。
その他の 4xxスケジュールどおり再試行します。署名チェックの失敗やパスの誤りが多い原因です。
5xx、408、タイムアウト、ネットワークエラースケジュールどおり再試行します。
3xxスケジュールどおり再試行します。リダイレクトには追従しません。
ブロックされた URLすぐに**停止(再配信可能)**になります。ホスト名がプライベートまたは内部のアドレスに解決されました。

URL の復旧待ち

ある URL への配信が 1 件失敗すると、Signals は次の試行時刻まで、その URL への他の待機中の配信の呼び出しを止めます。それらには URL の復旧待ちと表示されます。リクエストは行われず、スキップされた試行は回数に数えられません。1 回成功すると、URL への送信が再開されます。

失敗の種類

配信履歴シートには、実行ごとに 1 行、失敗した配信ごとに 1 つのラベルが表示されます。

アプリのラベル種類起きたこと対処
HTTP エラーhttp_statusサーバーが 5xx、408、413、429 を返しました。ステータスコードが表示されます。ログを確認してください。
サーバーが拒否しました(4xx)client_errorサーバーがその他の 4xx(400、401、404 など)を返しました。署名のコード、パス、前段の認証を確認してください。
URL が存在しません(410)goneサーバーが 410 を返しました。Webhook は無効になります。エンドポイントを修正し、再度有効にするを押してください。
タイムアウトtimeout10 秒以内に応答がありませんでした。先に応答し、処理は後で行ってください。
ネットワークエラーnetworkSignals が接続できませんでした。DNS の失敗、接続の拒否、TLS のエラーなどです。DNS レコード、証明書、ファイアウォールを確認してください。
リダイレクト(追従しません)redirectサーバーが 3xx を返しました。Webhook に最終的な URL を保存してください。http から https、www へのリダイレクトに注意してください。
URL がブロックされましたunsafe_url送信時に、ホスト名がプライベートまたは内部のアドレスに解決されました。公開ホスト名を使ってください。
URL の復旧待ちendpoint_unavailableこの URL への最近の配信が失敗したため、Signals が呼び出しを止めています。リクエストは行われず、試行回数も使われていません。エンドポイントを修正してください。1 回成功すると解除されます。
イベントが存在しませんevent_missing実行のイベントがなくなりました。たとえば、プロジェクトが削除された場合です。対処は不要です。
Webhook が一時停止されましたpaused配信の処理中に Webhook が一時停止されました。再開すると送られます。

ステータスのラベル

ステータス意味
待機中次の試行を待っています。Webhook が一時停止中のときもこの状態です。
送信中現在送信中です。
配信済みエンドポイントが 2xx を返しました。
失敗スケジュール外で、2xx なしに終了しました。たとえば、実行のイベントがなくなった場合です。再配信できます。
停止(再配信可能)9 回の試行がすべて失敗した、サーバーが 410 を返した、または URL がブロックされました。再配信できます。
再配信済み再配信によって、新しい配信に置き換えられました。

停止した配信

停止した配信は、実行と件数を保持しています。Signals が自動で送り直すことはありません。再配信するか、無効になった Webhook を再度有効にするか(停止した配信が自動で再配信されます)を、あなたが選びます。

自動無効化

Signals は次の 2 つの場合に Webhook を無効にし、送信を止めます。テスト配信は数えません。

  • 3 日間成功がない。 バナーには「3日間一度も配信に成功しなかったため、この URL への送信を停止しました。サーバーを修正してから再度有効にしてください。」と表示されます。
  • サーバーが 410 を返した。 すぐに無効になります。上記をご覧ください。

Steve チームが Webhook を停止した場合、バナーには「この Webhook は Steve チームが停止しました。準備ができたら再度有効にしてください。」と表示されます。

エンドポイントを修正してから、再度有効にするをクリックします。Signals は止まった位置から続けます。無効だった間に終わった実行が古い順に送られ、停止した配信ももう一度キューに入ります。管理 API で resume: "now" を送ると、その間の実行をスキップできます。

再配信

行のメニューから配信履歴を見るを開きます。

  • 失敗した行の再送は、同じ配信をもう一度試します。webhookId は変わらず、試行回数は数え直しになります。行は再配信済みになりません。
  • 停止した行の再配信は、その実行を新しい配信として送ります。テスト配信にはこのボタンはありません。
  • シートの上部にある停止した配信を再配信で、Webhook のすべての停止した配信を再配信します。失敗した行は対象外です。
  • API でも再配信でき、実行、時刻、失敗のステータスでも選べます: POST /api/public/v1/webhooks/{id}/replay。テストと管理をご覧ください。
  • 再送と再配信には有効な Webhook が必要です。

再配信は新しい配信です。新しい webhookId を持ち、試行回数は 1 から数え直し、ページトークンも新しくなって、さらに 30 日間有効です。元の行は再配信済みになります。イベントは同じで、eventId も同じです。

配信履歴シート
配信履歴シート。停止した行には、エラーのラベルと再配信ボタンが表示されます。

履歴は配信を 30 日間保持し、その後削除します。

エンドポイントを冪等にする

同じ POST が複数回届くことがあります。サーバーが処理済みなのにタイムアウトした場合や、リクエストの途中で一時停止した場合です。再配信では、同じ実行が新しい webhookId で届きます。再送では、webhookId は変わりません。2 つのキーを使ってください。

キー場所防げるもの
webhookIdボディと Signals-Webhook-Id ヘッダー1 つの配信の再試行。POST 全体をスキップします。
eventIdページの各要素それ以外すべて。再配信、同じページの 2 回の読み取り、ループ途中のクラッシュ。
  • 処理した webhookId を保存し、既知の POST はスキップします。
  • 各 eventId は、メモリ上のセットではなく一意インデックスで保存します。保存済みのイベントはスキップします。
  • ボディを保存したら 200 を返します。4xx や 5xx を返すと、Signals は POST をもう一度送ります。
  • 副作用(CRM へのメモ作成、Slack への投稿など)は eventId のチェックの後に、できれば同じトランザクションで行ってください。

ループの全体は実行のイベントを読むにあります。