RoomScope

最終更新

Webhook

アラートルールは、アプリ内、メール、Telegram に加えて HTTPS エンドポイントにも配信できます。すべての配信はチャネルのシークレットで署名された JSON の POST です。シークレットはチャネル作成時に一度だけ表示されます。

エンドポイントの設定

  1. ダッシュボードで アラート → ルール → 新しいルール を開き、イベントの種類を選んで、HTTPS の URL を指定した Webhook チャネルを追加します。API キーを使う場合は、同じルールを POST /v1/alerts/rules(スコープ webhook:manage)に送信します。
  2. 署名シークレット(whsec_…)をコピーします。シークレットは webhookSecrets[].signingSecret で、Webhook チャネルごとに 1 つ、一度だけ返されます。エンドポイントと一緒に保管してください。
  3. 10 秒以内に 2xx で応答し、処理は非同期で行ってください。リダイレクトには追従せず、プライベートアドレス、ループバックアドレス、リンクローカルアドレスは拒否されます。
  4. POST /v1/alerts/rules/{id}/test はサンプルの envelope 配信(sourceEventId が test_ で始まるもの)を送信するので、ハンドラーの動作を確認できます。

イベント

ルールは、反応するイベントの種類を eventTypes に列挙します。空の一覧はすべての種類に一致します。アラートの対象として有用なのは次の種類です。

種類発動条件
envelope監視中のルームで宝箱が観測されました。ルールのダイヤモンドの最小値が適用されます。
goodyBag監視中のルームでグッディバッグが観測されました。ルールのダイヤモンドの最小値が適用されます。
gift監視中のルームでギフトが贈られました。すべてのギフトで発動し、ダイヤモンドの最小値は適用されません。

minDiamondCount のデフォルトは 49 で、視聴者 1 人あたり 1.51 ダイヤモンドの下限とあわせて、宝箱とグッディバッグだけを絞り込みます。LIVE の開始・終了イベントはまだ配信されません。

ヘッダー

ヘッダー値
content-typeapplication/json
x-roomscope-alert-id<ruleId>:<eventId>。ボディの alertId と同じ値です。重複排除にはこの値を使ってください。
x-roomscope-timestampこの試行に署名した時刻の Unix 時間(秒)。
x-roomscope-schema-versionペイロードのスキーマバージョン。現在は 2026-11-03(`links` を追加)。
x-roomscope-signaturesha256=<"<timestamp>.<raw body>" の HMAC-SHA256 の 16 進数>。

ペイロード

1 リクエストにつき 1 イベントを、コンパクトな JSON で送信します。diamondCount、peopleCount、unpackAt(Unix 秒)は envelope と goodyBag で設定され、それ以外の種類では null になります。

POST your-endpoint
{  "schemaVersion": "2026-11-03",  "alertId": "8f0c…:evt_…",  "rule": { "id": "8f0c…", "name": "Big treasure boxes" },  "event": {    "type": "envelope",    "sourceEventId": "evt_…",    "roomId": "7432…",    "creatorUniqueId": "room.one",    "region": "VN",    "diamondCount": 5000,    "peopleCount": 120,    "score": 5000,    "unpackAt": 1793520000,    "observedAt": "2026-11-01T10:02:31.123Z"  },  "links": {    "creator": "https://app.toktokdata.live/creators/room.one",    "session": "https://app.toktokdata.live/live?creator=room.one"  },  "occurredAt": "2026-11-01T10:02:31.123Z",  "deliveredAt": "2026-11-01T10:02:33.456Z"}

署名の検証

署名は、完全な whsec_… シークレットを鍵とし、タイムスタンプヘッダー、ドット、生のボディをつなげたもの(<timestamp>.<body>)に対する HMAC-SHA256 です。16 進数のダイジェストが x-roomscope-signature に sha256=<hex> の形式で送信されます。比較は定数時間で行い、リプレイを防ぐため、任意に決めた許容範囲(以下の例では 5 分)を外れたタイムスタンプは拒否してください。

import { createHmac, timingSafeEqual } from "node:crypto"; // rawBody: the exact bytes received, e.g. express.raw({ type: "application/json" }).// secret: the full whsec_… value shown when the webhook channel was created.export function verify(rawBody, headers, secret, toleranceSec = 300) {  const signature = headers["x-roomscope-signature"];  const timestamp = headers["x-roomscope-timestamp"];  if (!signature || !/^\d+$/.test(timestamp ?? "")) return false;  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSec) return false;  const expected =    "sha256=" + createHmac("sha256", secret).update(`${timestamp}.`).update(rawBody).digest("hex");  const a = Buffer.from(signature, "utf8");  const b = Buffer.from(expected, "utf8");  return a.length === b.length && timingSafeEqual(a, b);}
生のボディを使う
JSON の解析は署名の検証に成功してから行い、HMAC は受信したバイト列そのものに対して計算してください。オブジェクトを再シリアライズすると空白やエスケープが変わり、比較が失敗します。

リトライと失敗

  • 300 未満のステータスは成功です。5xx、408、429、ネットワークエラー、タイムアウトはリトライされます。それ以外の 4xx と 3xx は恒久的な失敗です。
  • 1 件の配信の試行は最大 4 回で、間隔を空けずに連続して送信されます。試行ごとに署名し直すため、deliveredAt、タイムスタンプ、署名は毎回変わります。重複排除はボディではなく alertId で行ってください。
  • 配信に成功した alertId は、その後 7 日間は再配信されません。
  • 配信された Webhook 1 件につき 1 クレジットかかります。ワークスペースが受け取れる Webhook は暦月(UTC)あたり最大 100,000 件で、それを超える配信は破棄されます。
  • 失敗した配信はまだダッシュボードに表示されません。監査証跡が必要な場合は、受信したリクエストをログに記録してください。

Telegram とメール

同じルールから、接続済みの Telegram チャットやメールアドレスにも配信できます。これらのチャネルでは署名の処理は不要です。Telegram は アラート → チャネル から接続します。

このページは役に立ちましたか?