RoomScope

최종 업데이트

Webhook

알림 규칙은 앱 내 알림, 이메일, Telegram과 함께 HTTPS 엔드포인트로도 전송할 수 있습니다. 모든 전송은 채널의 secret으로 서명된 JSON POST이며, 이 secret은 채널을 만들 때 한 번만 표시됩니다.

엔드포인트 설정

  1. 대시보드에서 알림 → 규칙 → 새 규칙을 열고 이벤트 유형을 선택한 뒤 HTTPS URL로 Webhook 채널을 추가하세요. API key를 사용한다면 같은 규칙을 POST /v1/alerts/rules(스코프 webhook:manage)로 보내세요.
  2. 서명 secret(whsec_…)을 복사하세요. 이 값은 webhook 채널마다 하나씩 webhookSecrets[].signingSecret에 한 번만 반환됩니다. 엔드포인트와 함께 보관하세요.
  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진수 값>.

페이로드

요청 하나에 이벤트 하나가 압축된 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_… secret을 키로 사용해, 타임스탬프 헤더, 점, 원본 본문을 이어 붙인 값(<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는 영구 실패로 처리합니다.
  • 전송은 최대 4번 시도되며, 시도 사이에 지연 없이 연달아 보냅니다. 시도할 때마다 다시 서명하므로 deliveredAt, 타임스탬프, 서명이 바뀝니다. 본문이 아니라 alertId로 중복을 제거하세요.
  • 전송에 성공한 alertId는 7일 동안 다시 전송되지 않습니다.
  • 전송된 webhook마다 1 크레딧이 듭니다. 워크스페이스는 달력 월(UTC)마다 최대 100,000개의 webhook을 받을 수 있으며, 이를 넘는 전송은 버려집니다.
  • 실패한 전송은 아직 대시보드에 표시되지 않습니다. 감사 기록이 필요하면 수신한 요청을 직접 로그로 남기세요.

Telegram과 이메일

같은 규칙으로 연결된 Telegram 채팅이나 이메일 주소에도 전송할 수 있으며, 이 채널들은 서명을 처리할 필요가 없습니다. Telegram은 알림 → 채널에서 연결하세요.

이 페이지가 도움이 되었나요?