SocialHub.AI
開発者センター · オープンな拡張性

Webhook

独自のシステムを Flash イベントにサブスクライブします。関心のあるイベントの HTTPS エンドポイントを登録すると、Flash は各イベントが起動した瞬間に署名付きの薄いペイロードを配信します (ポーリングや夜間のエクスポートはありません)。署名は 標準 Webhook 仕様に従い、配信はバックオフで再試行され、すべての試行がログに記録されます。

ステップ 1 — 購読する

エンドポイントを登録する

webhooks:manage スコープを保持する Bearer fl_live_ キーを使用して Webhook エンドポイントを作成します。そこに配信したい HTTPS url と eventTypes のリストを投稿します。 。それは安全に保管されます。すべての配送を確認するために必要です。

curl -X POST https://flash.socialhub.ai/api/v2/webhooks \
  -H "Authorization: Bearer fl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.your-app.com/flash",
    "description": "prod ingest",
    "eventTypes": ["member.created", "loyalty.tier_upgraded"]
  }'

# 201 Created
# {
#   "data": {
#     "id": "whe_...",
#     "url": "https://hooks.your-app.com/flash",
#     "eventTypes": ["member.created", "loyalty.tier_upgraded"],
#     "status": "active",
#     "secret": "whsec_..."   <-- shown ONCE, store it now
#   }
# }

後で GET /api/v2/webhooks (リスト、シークレットなし)、PATCH /api/v2/webhooks/{id} (URL / イベント / ステータスを変更するか、{ "action": "rotate_secret" } を送信してシークレットをロールする)、および DELETE /api/v2/webhooks/{id} を使用してエンドポイントを管理します。 [設定] → [Webhook] から配信の登録、テスト ping、および再生を行うこともできます。

ステップ 2 — イベントを検出する

イベントカタログ

どのイベントに参加できるかを API に問い合わせてください。このカタログは、ライブ オートメーション トリガーの信頼できる情報源から派生しているため、今日実際に発生したイベントのみをライフサイクル ステージ (獲得、エンゲージメント、ロイヤリティ、保持、コマース、擁護) ごとにグループ化し、それぞれにイベント キー、説明、サンプル ペイロードとともにリストします。応答には、共有ペイロード エンベロープと署名ヘッダーも文書化されています。

curl https://flash.socialhub.ai/api/v2/events/catalog \
  -H "Authorization: Bearer fl_live_..."

# { "data": { "events": [
#     { "event": "member.created", "label": "Member created",
#       "stage": "acquisition", "examplePayload": { ... } },
#     { "event": "loyalty.tier_upgraded", "label": "Tier upgraded",
#       "stage": "loyalty", "examplePayload": { ... } },
#     ...
#   ],
#   "payload": { "schema": { ... }, "headers": { ... } }
# } }

サブスクライブするときに、イベントの event キーを eventTypes 配列に直接入れます。 webhooks:manage スコープが必要です。

配送

薄い、非 PII ペイロード

どの配達にも同じ小さな封筒が入っています。 idイベント type、 created_at timestampコンパクト data ブロック。ペイロード 個人データは一切含まれません — メールアドレス、名前、電話番号、住所は不要です。会員の詳細が必要な場合は、認証済みの方法で取得してください。 API 使用 member_refこれにより、個人情報は会員記録にのみ保持され、Webhookログには含まれません。

POST https://hooks.your-app.com/flash
webhook-id:        evt_a1b2c3...              # stable across retries — dedupe on this
webhook-timestamp: 1767225600                 # unix seconds
webhook-signature: v1,K5x0mF...==             # base64 HMAC-SHA256 (may be space-separated during rotation)
Content-Type:      application/json

{
  "id": "evt_a1b2c3...",
  "type": "loyalty.tier_upgraded",
  "created_at": "2026-01-01T00:00:00.000Z",
  "data": {
    "resource_id": "mbr_...",
    "member_ref": "mbr_...",     // opaque member id — fetch PII via the API
    "tier": "Gold",              // present on loyalty / tier events
    "amount_band": "100-500"     // coarse band on commerce events — never the exact amount
  }
}
安全

すべての署名を検証する

Flash は、標準 Webhook (HMAC-SHA256) を使用して、エンドポイントの whsec_ シークレットで各配信に署名します。 {webhook-id}.{webhook-timestamp}.{body} で署名を再計算し、定数時間で webhook-signature ヘッダーと比較します。一致しないものはすべて拒否し、リプレイに対して防御するには古すぎる webhook-timestamp を拒否します。署名キーは、仕様に従って、whsec_ プレフィックスの後のシークレットの Base64 デコードされたバイトです。シークレットのローテーション中、ヘッダーにはスペースで区切られた複数の v1,… 値が含まれます。いずれか が一致する場合に配信を受け入れます。

import crypto from "node:crypto";

// req.body must be the RAW, unparsed request body string.
function verifyFlashWebhook(headers, rawBody, whsec) {
  const id = headers["webhook-id"];
  const ts = headers["webhook-timestamp"];
  const sigHeader = headers["webhook-signature"]; // "v1,<b64> v1,<b64> ..."

  // reject stale deliveries (5 min tolerance)
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;

  const key = Buffer.from(whsec.replace(/^whsec_/, ""), "base64");
  const expected = crypto
    .createHmac("sha256", key)
    .update(`${id}.${ts}.${rawBody}`)
    .digest("base64");

  return sigHeader
    .split(" ")
    .map((p) => p.split(",")[1])
    .some((sig) =>
      sig &&
      sig.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)),
    );
}
信頼性

再試行、冪等性、配信ログ

2xxを早く返してください

任意の 2xx で確認応答し、非同期で作業を実行します。 429、5xx、タイムアウト、または接続エラーは再試行可能として扱われます。

バックオフによる自動再試行

再試行可能な失敗は、指数関数的なフル ジッター バックオフを使用して再試行されます。 3xx または 429 以外の 4xx は永続的な失敗として扱われ、再試行されません。

webhook-idによる重複排除

id は再試行しても同一であるため、少なくとも 1 回の配信は安全です。繰り返される webhook-id はすでに処理されたものとして扱います。

配信ログ&リプレイ

すべての試行は記録されます。再試行がすべて終了すると、配信は無効とマークされます。 [設定] → [Webhook] から配信を検査して再生できます。