跳至主要內容

參考資料

Webhook

當貼文送出審核、獲得核准、發布或失敗、檔案準備就緒,或社群帳號需要處理時,你的伺服器會收到一個已簽署的請求。

新增端點

  1. 1

    在 SPREVA 中開啟開發人員,再開啟 Webhook,新增你伺服器的位址,並選擇它要接收的事件。位址必須是公開的,並在 10 秒內以 2xx 狀態碼回應。

  2. 2

    複製端點密鑰。它只會顯示一次,你要用它驗證每個請求的簽章。

  3. 3

    使用傳送測試。它會傳送一個 webhook.test 事件,簽署方式和真正的事件相同,最近的傳送會顯示你的伺服器回應的狀態碼和耗時。

你也可以透過 REST API,用具備 webhooks:write 的金鑰新增端點。

每個請求包含的內容

一個 POST 請求,包含 JSON 本文和四個標頭:

  • x-spreva-event:事件,例如 target.published。
  • x-spreva-event-id:和本文的 id 相同,每次重試和重新傳送時也相同。
  • x-spreva-timestamp:請求簽署的時間,以 Unix 秒數表示。
  • x-spreva-signature:v1= 後面接著簽章。
JSON
{
  "id": "7f3c2d10-0000-4000-8000-000000000000",
  "type": "target.published",
  "createdAt": "2026-10-01T09:00:02.412Z",
  "workspaceId": "0b9f6c1e-0000-4000-8000-000000000001",
  "data": {
    "type": "TargetPublished",
    "workspaceId": "0b9f6c1e-0000-4000-8000-000000000001",
    "postId": "5d2a7c3e-0000-4000-8000-000000000002",
    "targetId": "9a1f4b7d-0000-4000-8000-000000000003",
    "provider": "instagram",
    "remoteId": "17900000000000000",
    "remoteUrl": "https://www.instagram.com/p/EXAMPLE/"
  }
}

data 是事件本身,data.type 是它在 SPREVA 中的名稱。用 data 中的 ID,透過 REST API 取得完整的物件。

事件

端點會收到它選擇的事件。無論選擇了什麼,傳送測試都會傳到端點。

貼文

post.created
已建立貼文
post.review_requested
貼文已送出審核
post.approved
貼文已核准並設定時間
post.changes_requested
審核者附上備註退回貼文
post.scheduled
貼文已設定日期
post.published
貼文已發布到所有帳號
post.partial
貼文在各帳號的結果不一
post.failed
貼文在所有帳號都發布失敗

發布(每個帳號一次)

target.published
一個帳號已發布貼文
target.failed
一個帳號無法發布
target.awaiting_user
某個帳號需要你在它自己的應用程式中完成發布

媒體

media.ready
上傳的檔案已可使用
media.failed
檔案無法處理或生成

社群帳號

connection.expired
社群帳號需要重新連結
connection.revoked
社群帳號撤回了權限

數據分析

analytics.updated
已發布的貼文有新的數據

驗證簽章

簽章是以端點密鑰為金鑰,對時間戳記、一個句點和原始本文計算的 HMAC-SHA256。簽章不符的請求一律拒絕。

JavaScript
import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody: the request body as a string, before any JSON parsing
export function isFromSpreva(rawBody, headers, secret) {
  const signed = headers["x-spreva-timestamp"] + "." + rawBody;
  const expected = Buffer.from("v1=" + createHmac("sha256", secret).update(signed).digest("hex"));
  const received = Buffer.from(headers["x-spreva-signature"] ?? "");
  return received.length === expected.length && timingSafeEqual(received, expected);
}
在進行任何 JSON 剖析之前,用收到的原始本文驗證:剖析後再寫回會改變位元組,簽章就不再相符。

重試和重新傳送

  • 在 10 秒內以 2xx 狀態碼回應。任何其他回應或沒有回應,都會重試最多 5 次:分別在 30 秒、2 分鐘、10 分鐘、1 小時和 6 小時後。
  • 不會追蹤重新導向,所以請使用端點的最終位址。
  • 重試或重新傳送會帶有相同的 x-spreva-event-id:用它忽略已經處理過的事件。
  • 「最近的傳送」中的重新傳送會再次傳送事件,如果你的伺服器仍然失敗也會重試,讓你可以修正端點,而不必重複發布。