Webhooks
Langgan sistem anda sendiri untuk peristiwa Flash. Daftarkan titik akhir HTTPS untuk peristiwa yang anda minati dan Flash memberikan muatan nipis yang ditandatangani sebaik sahaja setiap satu diaktifkan — tiada tinjauan pendapat, tiada eksport setiap malam. Tandatangan mengikut spesifikasi Standard Webhooks, penghantaran cuba semula dengan undur dan setiap percubaan direkodkan.
Daftar titik akhir
Cipta titik akhir webhook dengan kunci Bearer fl_live_ yang memegang skop webhooks:manage. Siarkan HTTPS url dan senarai eventTypes yang anda mahu dihantar ke sana. Rahsia tandatangan dalam respons dan tidak akan pernah lagi — simpannya dengan selamat; anda memerlukannya untuk mengesahkan setiap penghantaran.
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
# }
# }Urus titik akhir kemudian dengan GET /api/v2/webhooks (senarai, tiada rahsia), PATCH /api/v2/webhooks/{id} (tukar url / peristiwa / status, atau hantar { "action": "rotate_secret" } untuk melancarkan rahsia), dan DELETE /api/v2/webhooks/{id}. Anda juga boleh mendaftar, menguji ping dan memainkan semula penghantaran daripada Tetapan → Webhooks.
Katalog acara
Tanya API acara mana yang boleh anda langgan. Katalog ini diperoleh daripada sumber kebenaran pencetus automasi langsung, jadi ia menyenaraikan hanya acara yang benar-benar dilancarkan hari ini — dikumpulkan mengikut peringkat kitaran hayat (pemerolehan, penglibatan, kesetiaan, pengekalan, perdagangan, advokasi) — setiap satu dengan kunci acaranya, penerangan dan muatan contoh. Respons tersebut juga mendokumentasikan sampul muatan kongsi dan pengepala tandatangan.
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": { ... } }
# } }Letakkan kunci event acara terus ke dalam eventTypes array apabila anda melanggan. Memerlukan skop webhooks:manage.
Muatan nipis dan bukan PII
Setiap penghantaran membawa sampul surat kecil yang sama: id yang stabil, peristiwa type, created_at timestamp dan blok data yang padat. Muatan tidak pernah mengandungi data peribadi — tiada e-mel, nama, telefon atau alamat. Apabila anda memerlukan butiran ahli, dapatkannya kembali melalui API yang disahkan menggunakan member_ref. Ini memastikan PII berada pada rekod ahli dan tidak berada di luar log webhook anda.
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
}
}Sahkan setiap tandatangan
Flash menandatangani setiap penghantaran dengan rahsia whsec_ titik akhir anda menggunakan Standard Webhooks (HMAC-SHA256). Kira semula tandatangan pada {webhook-id}.{webhook-timestamp}.{body} dan bandingkannya, dalam masa yang tetap, dengan pengepala webhook-signature. Tolak apa-apa yang tidak sepadan, dan tolak webhook-timestamp yang terlalu lama untuk dipertahankan daripada ulangan. Kunci tandatangan ialah bait rahsia yang dinyahkod base64 selepas awalan whsec_, mengikut spesifikasi. Semasa putaran rahsia, pengepala membawa berbilang nilai v1,… yang dipisahkan ruang — terima penghantaran jika mana-mana sepadan.
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)),
);
}Percubaan semula, idempotency & log penghantaran
Pulangan 2xx dengan cepat
Akui dengan mana-mana 2xx dan lakukan kerja anda secara tak segerak. 429, 5xx, tamat masa atau ralat sambungan dianggap boleh dicuba semula.
Cuba semula automatik dengan undur
Kegagalan yang boleh dicuba semula dicuba semula dengan undur eksponen dan jitter penuh. 3xx atau 4xx bukan-429 dianggap sebagai kegagalan kekal dan tidak dicuba semula.
Nyahdupe mengikut webhook-id
id adalah sama merentasi percubaan semula, jadi penghantaran sekurang-kurangnya sekali adalah selamat: anggap webhook-id yang berulang sebagai telah dikendalikan.
Log penghantaran & ulangan
Setiap percubaan direkodkan. Jika percubaan semula kehabisan, penghantaran ditanda mati; anda boleh memeriksa dan memainkan semula penghantaran daripada Tetapan → Webhooks.