RoomScope

Last updated

Webhooks

An alert rule can deliver to an HTTPS endpoint next to in-app, email and Telegram. Deliveries are JSON POSTs signed with a per-rule secret that is shown once when the rule is created.

Setting up an endpoint

  1. In the dashboard open Alerts → Rules → New rule, pick the event types and a minimum diamond value, and add a Webhook channel with your HTTPS URL.
  2. Copy the signing secret from the confirmation. It is shown once; store it with your endpoint.
  3. Respond with any 2xx within a few seconds. Do the work asynchronously.

Events

TypeFires when
live_startA watched creator went live.
giftA gift at or above the rule’s minimum diamond value was sent in a watched room.
envelopeA treasure-box / red-envelope event was observed in a watched room.
goodyBagA goody-bag event was observed in a watched room.

Rules also support pacing so a busy room does not flood your endpoint: when a rule is paced, only the first matching event in the window is delivered.

Payload

One event per request. The data object depends on type; the example shows a gift. Field names in data are Subject to change.

POST your-endpoint
{  "id": "evt_01J9X4R7Q2M8V3K6N5P1T0ZWAB",  "type": "gift",  "createdAt": "2026-11-01T10:02:33Z",  "workspaceId": "ws_…",  "ruleId": "rule_…",  "data": {    "roomKey": "…",    "creatorUid": "7123456789012345678",    "uniqueId": "room.one",    "diamonds": 5000,    "giftName": "…",    "observedAt": "2026-11-01T10:02:31Z"  }}

Verifying signatures

Every delivery is signed with HMAC-SHA256 over the raw request body using the rule’s signing secret. Compute the same digest and compare it in constant time with the value in the signature header (X-RoomScope-Signature header name subject to change). Reject anything that does not match.

import { createHmac, timingSafeEqual } from "node:crypto"; // rawBody must be the exact bytes received, not a re-serialised object.export function verify(rawBody, signatureHeader, secret) {  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");  const given = Buffer.from(signatureHeader ?? "", "utf8");  const want = Buffer.from(expected, "utf8");  return given.length === want.length && timingSafeEqual(given, want);}
Use the raw body
Parse the JSON only after the signature checks out, and compute the HMAC over the exact bytes you received. Re-serialising the object changes whitespace and key order and breaks the comparison.

Retries and failures

  • A non-2xx response or a timeout counts as a failed delivery and is retried with exponential backoff over a bounded window. schedule subject to change
  • Deliveries are idempotent by id: store the ids you have processed and ignore repeats.
  • Every attempt is visible under Alerts → History with its status, so you can see what your endpoint returned.

Telegram and email

The same rule can also deliver to a connected Telegram chat or to an email address; those channels need no signature handling. Connect Telegram from Alerts → Channels.

Was this page helpful?