跳至內容
文件

外送 Webhook:payload 與簽章

將 AutoPSEO 的警示與報表以簽章 JSON 的形式傳送到任何 HTTPS 端點:涵蓋請求標頭、內文欄位、事件類型,以及簽章驗證方式。

帳戶 → Slack、Teams 與 Webhooks → 傳出 Webhooks需要訂閱或試用閱讀時間 3 分鐘

外送 Webhook 會將 AutoPSEO 的警示、排程報表、測試訊息與報表摘要,傳送到由你自行架設的端點。每則訊息都是一個以 HMAC-SHA256 簽章的 JSON POST 請求。你可以用它串接 Zapier、Make、n8n、事件通報工具或自己的程式碼,不需要 Slack 或 Teams 帳號。想找的是把文章送到你網站的 webhook 嗎?那是內容引擎的功能,請參閱內容發布。

新增 Webhook

  1. 在「Outbound webhooks」區塊中,按一下 New webhook。
  2. 為它設定 Name,並貼上端點的 URL。URL 必須是公開的 HTTPS:純 http、localhost、以 .local 或 .internal 結尾的名稱、不含點號的主機名稱,以及私有或 link-local 的 IP 位址都會被拒絕。
  3. 儲存後,複製畫面上顯示的簽署密鑰(signing secret)。此密鑰只會顯示這一次。
  4. 按一下 Send test 傳送 test 事件,接著將排程報表或警示綁定到這個 webhook。

Webhook 請求的內容

每則訊息都是一個 POST 請求,並帶有以下標頭:

標頭值
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1.0
X-AutoPSEO-Event事件類型,例如 traffic_drop
X-AutoPSEO-Signaturesha256= 後接 64 個小寫十六進位字元

以下是某個網域資源在 2026 年 10 月 12 日 06:00 UTC 執行時產生的流量下降警示,為方便閱讀而排版(實際傳送時是精簡的 JSON,且 id 與 site_id 的值皆為虛構):

{
  "id": "9b2e61f04c3a4d7e8f15a0b6c2d39e47",
  "event_type": "traffic_drop",
  "severity": "high",
  "site_id": "4f0c1e9a2b7d4c58",
  "site_url": "sc-domain:example.com",
  "occurred_at": "2026-10-12T06:00:04.183Z",
  "title": "Traffic drop: example.com",
  "text": "Clicks 1,500 vs 2,000 in the previous window (-25.0%).",
  "url": "https://app.autopseo.com/property/sc-domain%3Aexample.com",
  "payload": {
    "fields": [
      { "label": "Metric", "value": "clicks" },
      { "label": "Current", "value": "1,500" },
      { "label": "Baseline", "value": "2,000" },
      { "label": "Window", "value": "7 days (2026-10-05 → 2026-10-11 vs 2026-09-28 → 2026-10-04)" },
      { "label": "Change", "value": "-25.0%" }
    ],
    "table": null,
    "detector": "traffic_drop",
    "window": 7,
    "range": { "start": "2026-10-05", "end": "2026-10-11", "compStart": "2026-09-28", "compEnd": "2026-10-04" },
    "result": {
      "fired": true,
      "metric": "clicks",
      "value": 1500,
      "baseline": 2000,
      "change": -0.25,
      "severity": "high",
      "summary": "Clicks 1,500 vs 2,000 in the previous window (-25.0%)."
    }
  },
  "source": "autopseo"
}

以下頂層欄位在所有事件中都相同:

欄位內容
id隨機產生的 32 字元十六進位字串,每個請求都不同
event_type發生的事件(見下一節)
severity警示為 critical、high、medium 或 low;報表、摘要與測試為 info
site_idAutoPSEO 為該資源指定的 ID;測試與示範資源則為 null
site_urlSearch Console 資源,例如 sc-domain:example.com 或 https://www.example.com/;測試時為 null
occurred_at訊息建立的時間,以 UTC 的 ISO 8601 時間戳記表示
title、textSlack 與 Teams 所顯示的標題與摘要句
urlAutoPSEO 中對應的報表連結;測試時為 null
payload.fields具標籤的數值,在 Slack 中顯示為欄位,在 Teams 中顯示為 facts
payload.table報表與摘要的 columns 和 rows,其他情況為 null
source固定為 autopseo

比率一律以小數表示:change 為 -0.25 代表下降 25%,ctr 為 0.034 代表 3.4%。

事件類型

event_type觸發時機payload 中額外的鍵
traffic_drop、traffic_spike、position_drop、ctr_drop、new_lost_rankings、anomaly、index_flip、rank_drop、audit_regression警示規則觸發時,無論是依排程或透過 Test ruledetector、window、range(日期範圍;index_flip、rank_drop 與 audit_regression 則為 null)、result
scheduled_report排程報表送出時,無論是依排程或透過 Send nowreportType(summary、queries、pages 或 rankings)、range(日期加上 label)、totals、previous
report_summary有人在報表頁面使用 Send to Slack無:數據都在 fields 與 table 中
test有人在 webhook 上按下 Send testsample,固定為 true

result 會重述偵測器所量測的結果:fired、metric、value、baseline、change(無可比較對象時為 null)、severity 與 summary;anomaly 另外還有 z,也就是修正後的 z 分數。totals 與 previous 則包含報表兩個時間區間的 clicks、impressions、ctr 與 position。各偵測器的量測內容,請參閱警示。

如何驗證簽章

簽章是以該 webhook 的簽署密鑰為金鑰,對 AutoPSEO 實際送出的原始位元組計算 HMAC-SHA256,並以 sha256= 加上小寫十六進位表示。驗證步驟如下:

  1. 在進行任何 JSON 解析之前,先讀取原始請求內文。解析後再序列化可能會改變位元組內容。
  2. 對這些位元組計算 HMAC-SHA256,密鑰以文字形式使用:即畫面上顯示的 64 字元字串原樣使用,不要以十六進位解碼。
  3. 在結果前加上 sha256=,再以恆定時間(constant-time)比較函式與 X-AutoPSEO-Signature 標頭比對。
  4. 若兩者不同,就拒絕該請求。否則請立即回應 2xx 狀態碼,耗時的處理留待之後再做。

以下是不需任何相依套件的 Node.js 接收端範例:

import { createServer } from 'node:http';
import { createHmac, timingSafeEqual } from 'node:crypto';

const secret = process.env.AUTOPSEO_WEBHOOK_SECRET;

createServer((req, res) => {
  const chunks = [];
  req.on('data', (chunk) => chunks.push(chunk));
  req.on('end', () => {
    const raw = Buffer.concat(chunks);
    const expected = Buffer.from('sha256=' + createHmac('sha256', secret).update(raw).digest('hex'));
    const received = Buffer.from(String(req.headers['x-autopseo-signature'] || ''));
    if (received.length !== expected.length || !timingSafeEqual(received, expected)) {
      res.writeHead(401).end();
      return;
    }
    res.writeHead(204).end();
    const event = JSON.parse(raw.toString('utf8'));
    console.log(event.event_type, event.severity, event.site_url);
  });
}).listen(8080);

必須先檢查長度,因為當兩個緩衝區長度不同時,Node 的 timingSafeEqual 會拋出例外。

傳送規則

  • 每則訊息只會嘗試傳送一次,逾時時間為 10 秒。任何非 2xx 的回應都視為失敗,並連同狀態碼與回應內文開頭的部分內容,一併記錄在 Delivery history 中。
  • 不會跟隨重新導向。若收到 3xx 回應,會判定為失敗,並提示你改用最終的 URL。
  • 不會依計時器自動重試。失敗的警示不會被標記為已傳送,因此下一次檢查時會重新評估,若仍符合觸發條件就會再次發送:多數偵測器是隔天早上,索引狀態翻轉(index flip)則是下一個小時。失敗的排程報表在同一週期內不會重送,請在修復端點後使用 Send now。
  • id 是依每個請求產生的,因此它代表的是一次傳送,而不是一個事件。若要對警示去重,請組合 event_type、site_url 與 occurred_at 的日期:除非有人執行 Test rule,否則一條規則對每個資源每個 UTC 日最多只會發送一次。

簽署密鑰

AutoPSEO 只會在你儲存 webhook 時顯示一次簽署密鑰,之後列表中不會再顯示。請立即將它與你的接收端設定一同存放,並與其所保護的端點放在一起。

URL 本身是加密儲存的,列表中只會顯示其主機名稱與最後幾個字元。刪除 webhook 時,也會一併刪除所有發送到該 webhook 的規則。如果你想在 Teams 頻道中看到易讀的卡片,而不是 JSON,請使用 Microsoft Teams。

讓你的 SEO 內容自動運行

連結 Search Console 與你的網站,AutoPSEO 會立即掃描並規劃首批主題。無需信用卡。