Skip to content

Webhook連携

SORI APIのWebhookは、SORIプラットフォーム内で発生する主要なイベントを自社システムに通知します。エンドポイントを接続することで、キャンペーン活動、デバイス認証、管理操作をほぼリアルタイムに処理できます。

概要

SORI APIは、重要なイベントが発生した直後に構造化されたJSONペイロードを配信するWebhook機能を提供します。WebhookはSORI Consoleで設定でき、次のカテゴリをサポートします:

  • キャンペーンイベント(`campaign.*`) デバイスでキャンペーンが認識されたときや、ユーザーがアクションURLに遷移したときにトリガーされます。
  • 認証イベント(`authentication`) デバイスがSORIの認証フローを完了したときに発生します。
  • 管理イベント(`admin.material.*`) コンソールでマテリアルを作成・更新・削除した際に送信される任意の通知です。

リアルタイム通知によって以下が可能になります:

  • インスタント分析 活動が起きた瞬間にキャンペーン指標を追跡・分析します。
  • 認証監査 デバイスのログインを自社のセッション記録と突合します。
  • 不正検知 異常なパターンを即座に検出します。
  • ライブダッシュボード 最新データでダッシュボードを更新します。

Webhookの設定

SORIでは、Webhookエンドポイントを次の2通りで構成できます。

グローバルWebhook URL

  • 設定セクションで設定します。
  • 既定で全キャンペーンに適用されます。
  • キャンペーンが個別URLを指定しない場合のフォールバックとして機能します。

キャンペーン固有のWebhook URL

  • 各キャンペーンの詳細設定で構成します。
  • 該当キャンペーンではグローバルURLより優先されます。
  • キャンペーンごとに異なる処理が必要な場合に便利です。

イベント購読(設定 → Webhooks)

アカウント設定では、どのイベントカテゴリを受信するかを選択できます。

  • キャンペーンイベント: campaign.* 通知(インプレッションとクリック活動)を購読します。
  • 認証イベント: デバイスログイン時に送信される authentication イベントを購読します。
  • 管理イベント: コンソールから送信される admin.material.* 通知を購読します。

新規アカウントではキャンペーンイベントと認証イベントが既定で有効です。管理者はチェックボックスをいつでも変更でき、以後のWebhook配信に即時反映されます。

Webhookを設定する手順

  1. Webhookイベントを受信するHTTPSエンドポイントを準備します。
  2. 次のいずれかを構成します。
    • 設定画面でグローバルWebhook URLを登録する。
    • 各キャンペーンの設定で個別のWebhook URLを登録する。
  3. 設定 → Webhooks で受信したいイベントカテゴリを選択します。
  4. JSON形式のPOSTリクエストを受け取り、5秒以内に応答できるようエンドポイントを実装します。

イベントタイプ

各Webhookペイロードには正規化された event フィールドと、後方互換性のための event_type フィールドが含まれます。新規実装では event を基準に処理することを推奨します。

キャンペーンインプレッションイベント(campaign.impression

キャンペーンがユーザーのデバイスに表示されたときに送信されます。キャンペーンイベント を有効にすると受信できます。

キャンペーンクリックイベント(campaign.click

ユーザーがキャンペーンをタップしてアクションURLに遷移したときに送信されます。キャンペーンイベント を有効にすると受信できます。

認証イベント(authentication

デバイスがSORIでの認証を完了した後に送信されます。認証リクエストのクエリパラメーターが metadata に含まれるため、自社のセッションIDなどと突合できます。

Webhookイベントの処理

Webhookイベントを受信すると、イベントの詳細を含むJSONペイロードが送信されます。以下に各イベントタイプの例を示します。null のフィールドは値がない場合は省略される場合があります。

インプレッションイベントの例:

json
{
  "event": "campaign.impression",
  "event_type": "campaign.impression",
  "account_id": "acc_123456",
  "created_at": "2025-10-14T05:25:12.421Z",
  "activity_id": "act_7890",
  "campaign_id": "cmp_1234",
  "campaign_name": "Fall Promotion",
  "material_id": "mat_5678",
  "material_name": "Audio Spot 15s",
  "device_id": "device_abc",
  "platform": "Android",
  "metadata": {
    "session": "abcd-1234"
  },
  "geolocation": {
    "viewer_country": "United States",
    "viewer_region": "Michigan",
    "viewer_city": "Ann Arbor"
  },
  "timestamp": "2025-10-14T05:25:12.421Z"
}

クリックイベントの例:

json
{
  "event": "campaign.click",
  "event_type": "campaign.click",
  "account_id": "acc_123456",
  "created_at": "2025-10-14T05:26:03.009Z",
  "activity_id": "act_7890",
  "campaign_id": "cmp_1234",
  "campaign_name": "Fall Promotion",
  "material_id": "mat_5678",
  "device_id": "device_abc",
  "platform": "Android",
  "metadata": {
    "session": "abcd-1234",
    "utm_source": "push"
  },
  "geolocation": {
    "viewer_country": "United States",
    "viewer_region": "Michigan",
    "viewer_city": "Ann Arbor"
  },
  "timestamp": "2025-10-14T05:26:03.009Z"
}

認証イベントの例:

json
{
  "event": "authentication",
  "event_type": "authentication",
  "account_id": "acc_123456",
  "created_at": "2025-10-14T05:15:44.832Z",
  "device_id": "device_abc",
  "platform": "Android",
  "metadata": {
    "app_version": "1.8.0",
    "session": "abcd-1234"
  },
  "geolocation": {
    "viewer_country": "United States",
    "viewer_region": "Michigan",
    "viewer_city": "Ann Arbor"
  },
  "timestamp": "2025-10-14T05:15:44.832Z"
}

カスタムメタデータ

metadata フィールドは、キャンペーンイベントではSDKから送信されるキーと値、認証イベントでは認証リクエストのクエリパラメーターが格納されるマップです。ユーザーやデバイスを識別したり、追加のコンテキストを渡したりするために利用できます。このフィールドは任意です。詳細はMetadata Providerを参照してください。

位置情報について

位置情報は geolocation オブジェクトの中に含まれます。このデータはCloudFrontのGeoIP推定に基づくため、常に正確とは限りません。値が取得できない場合は Unknown が返されます。

レスポンス要件

Webhookエンドポイントでは次の点を満たしてください。

  • 2xx ステータスコードで受信を確認する。
  • 可能であれば非同期で処理し、処理待ちでブロックしない。
  • タイムスタンプやアクティビティIDを利用して冪等に処理する。
  • タイムアウトを避けるため 5秒以内 に応答する。

セキュリティ考慮事項

  • 可能な限りHTTPSを使用してデータを保護してください。
  • 受信したペイロードの構造と event 値を検証してください。
  • Webhook URLは機密情報として取り扱ってください。
  • app_idsecret_key を設定している場合は、ペイロードのコピーを用いて X-SORI-Signature ヘッダーを検証し、真正性を確認してください。

エラーハンドリング

エンドポイントがイベントを受信できない場合、SORI API Serverは次のように動作します。

  • 失敗した配信を 最大3回 再試行します。
  • 再試行の間隔には指数バックオフを適用します。
  • すべての再試行が失敗した場合はイベントを破棄します。

実装例

Python(FastAPI)

python
from fastapi import FastAPI, Request

app = FastAPI()

@app.post("/webhook")
async def webhook(request: Request):
    payload = await request.json()
    event = payload.get("event") or payload.get("event_type")

    if event == "campaign.impression":
        # インプレッションイベントの処理
        pass
    elif event == "campaign.click":
        # クリックイベントの処理
        pass
    elif event == "authentication":
        # 認証イベントの処理
        pass

    return {"status": "success"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=3000)

Node.js(Express)

typescript
import express from "express";

const app = express();
app.use(express.json());

app.post("/webhook", (req, res) => {
  const payload = req.body;
  const event = payload.event || payload.event_type;

  if (event === "campaign.impression") {
    // インプレッションイベントの処理
  } else if (event === "campaign.click") {
    // クリックイベントの処理
  } else if (event === "authentication") {
    // 認証イベントの処理
  }

  res.status(200).send({ status: "success" });
});

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});