コンテンツへスキップ
ドキュメント

アウトバウンド Webhook:ペイロードと署名

AutoPSEO のアラートとレポートを、署名付き JSON として任意の HTTPS エンドポイントで受信できます。リクエストヘッダー、本文のフィールド、イベントタイプ、署名の検証方法を説明します。

アカウント → Slack、Teams、Webhook → 送信Webhookサブスクリプションまたはトライアルが必要読了まで3分

アウトバウンド Webhook は、AutoPSEO のアラート、定期レポート、テストメッセージ、レポートサマリーを、お客様が運用するエンドポイントに送信する機能です。メッセージ 1 件につき JSON の POST を 1 回送り、HMAC-SHA256 で署名します。Zapier、Make、n8n、インシデント管理ツール、自社のコードなどと連携できます。Slack や Teams のアカウントは必要ありません。記事をサイトに配信する Webhook をお探しの場合、それはコンテンツエンジンの機能です。コンテンツ配信をご覧ください。

Webhook を追加する

  1. Outbound webhooks セクションで New webhook をクリックします。
  2. Name を入力し、エンドポイントの URL を貼り付けます。URL は公開された HTTPS である必要があります。プレーンな http、localhost、.local や .internal で終わる名前、ドットを含まないホスト、プライベートまたはリンクローカルの IP アドレスは使用できません。
  3. 保存後に表示される署名シークレットをコピーします。表示されるのは、このとき 1 回だけです。
  4. Send test をクリックして test イベントを送信し、続いて定期レポートやアラートを Webhook に関連付けます。

Webhook リクエストの内容

すべてのメッセージは、次のヘッダーを持つ POST リクエストです。

ヘッダー値
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1.0
X-AutoPSEO-Eventイベントタイプ(例: traffic_drop)
X-AutoPSEO-Signaturesha256= に続く 64 文字の小文字 16 進数

以下は、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 文字の 16 進数文字列。リクエストごとに新しく生成されます
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.fieldsSlack ではフィールド、Teams ではファクトとして表示されるラベル付きの値
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 rule による実行)detector、window、range(日付。index_flip、rank_drop、audit_regression では null)、result
scheduled_report定期レポートが送信されたとき(スケジュール実行、または Send now による実行)reportType(summary、queries、pages、rankings)、range(日付と label)、totals、previous
report_summaryレポートページで Send to Slack を使用したときなし。数値は fields と table に含まれます
testWebhook で Send test をクリックしたときsample(常に true)

result には、検出器が計測した内容が含まれます。fired、metric、value、baseline、change(比較対象がない場合は null)、severity、summary に加え、anomaly では修正 z スコアである z も含まれます。totals と previous には、レポートの 2 つの期間それぞれについて clicks、impressions、ctr、position が入ります。各検出器が何を計測するかは、アラートで説明しています。

署名の検証方法

署名は、AutoPSEO が送信したバイト列そのものに対する HMAC-SHA256 です。Webhook の署名シークレットを鍵として計算し、sha256= と小文字の 16 進数を連結した形式で記載されます。検証の手順は次のとおりです。

  1. JSON をパースする前に、リクエスト本文を生のまま読み取ります。パースして再びシリアライズすると、バイト列が変わる場合があります。
  2. そのバイト列に対して HMAC-SHA256 を計算します。シークレットは、表示された 64 文字の文字列をそのままテキストとして使います。16 進数としてデコードしないでください。
  3. 計算結果の先頭に sha256= を付け、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 は、2 つのバッファの長さが異なると例外をスローするため、先に長さを比較しています。

配信のルール

  • 各メッセージの送信は 1 回のみで、タイムアウトは 10 秒です。2xx 以外の応答はすべて失敗として扱われ、ステータスコードとレスポンス本文の冒頭部分が Delivery history に記録されます。
  • リダイレクトには追従しません。3xx の応答は失敗となり、最終的な URL を使用するよう案内するメモが残ります。
  • タイマーによる再試行は行いません。送信に失敗したアラートは送信済みとして記録されないため、次回のチェックで再度評価され、まだ発火していれば送信されます。ほとんどの検出器では翌朝、インデックス状態の変化(index_flip)では次の 1 時間後です。送信に失敗した定期レポートは、同じ期間内に再送されません。エンドポイントを修正したあとで Send now を使用してください。
  • id はリクエストごとに作成されるため、イベントではなく配信を識別する値です。アラートの重複を排除するには、event_type、site_url、occurred_at の日付を組み合わせてください。ルールが同じプロパティに送信するのは、UTC の 1 日につき最大 1 回です。ただし、誰かが Test rule を実行した場合は除きます。

署名シークレット

署名シークレットが表示されるのは、Webhook を保存したときの 1 回だけで、一覧には二度と表示されません。受信側の設定に、保護対象のエンドポイントとあわせて、すぐに保管してください。

URL 自体は暗号化されて保存され、一覧にはホスト名と末尾の数文字だけが表示されます。Webhook を削除すると、その Webhook に送信するルールもすべて削除されます。JSON ではなく、Teams チャンネルに読みやすいカードとして表示したい場合は、Microsoft Teams をご利用ください。

SEOコンテンツを自動運転に

Search Consoleとサイトを接続してください。AutoPSEOがサイトをスキャンし、最初のトピックをすぐに計画します。クレジットカードは不要です。