SDK reference
LiveBridgeGame handlers, event shapes, viewer privacy, the forbidden list and the sandbox CSP.
The LiveBridge SDK
Load it with exactly this line (before the game script). Do not copy or bundle the SDK: serve swaps this URL for a local copy, and in production it is LiveBridge's own.
<script src="https://livebridge.vn/sdk/livebridge.js"></script>
<script>
const game = new LiveBridgeGame({
onAction(actionId, event, rule) { /* a gift the streamer mapped to one of your actions */ },
onGift(event) { /* EVERY gift, mapped or not */ },
onChat(comment, user, event) {},
onFollow(user, event) {},
onShare(user, event) {},
onMember(user, event) {}, // someone joined the room
onLike(user, event) {}, // event.like.count = likes in this batch
});
</script>All handlers (all optional):
onReady(config, actionMap): the SDK has read the manifest and the gift mapping.configis your manifest.json. `actionMap` can be `null` if the first read failed (network error, 429): the mapping then arrives later throughonConfig. Never assumeactionMapis set.onConfig(actionMap): the streamer just saved the gift mapping (no page reload), or the mapping arrived late afteronReady.onAction(actionId, event, rule): a gift matched a rule.rulehasactionId,amount(default 1), andgiftNameorminDiamonds/maxDiamonds.onGift(event): every gift. Always called, also whenonActionis.onChat(comment, user, event),onFollow(user, event),onShare(user, event),onMember(user, event),onLike(user, event).onEvent(event): every raw event (gifts, chat, ...).onConnect(),onDisconnect(): socket opened / closed. The SDK reconnects after a few seconds unless the link was revoked.onTikTokStatus("connected" | "connecting" | "ended" | "disconnected"): state of the streamer's TikTok room. The socket can be open while the streamer has not pressed connect for TikTok.apiOrigin(optional): only needed if you self-host the SDK. Do not.- Helpers:
LiveBridgeGame.resolveGiftAction(actionMap, event),LiveBridgeGame.getDiamonds(event)(=diamondCount x repeatCount),LiveBridgeGame.getUser(event);game.destroy()stops it.
Event shape (after the privacy filter; optional fields may be missing, check before using):
{ type: "gift", seq, ts, channel,
user: { id, uniqueId, nickname, avatar, roles?: { moderator, subscriber, follower, member } },
gift: { id, name, diamondCount, repeatCount, icon? } } // chat: chat: { comment }
// like: like: { count, total? }gift.icon is always "" for developer games (the CSP blocks gift images from the TikTok CDN and LiveBridge has no gift-image proxy yet): draw your own gift icons if you need them.
Gift mapping rules: exact gift name > diamond range (diamondCount x repeatCount within minDiamonds..maxDiamonds) > the rule whose actionId is "default". The streamer can change the mapping at any time, so always handle onGift for unmapped gifts too.
Privacy (the streamer chooses per game). Names and avatars are sent by default. When the streamer turns names off: user.id becomes anon-<16 hex>, user.uniqueId becomes viewer-<4 hex>, user.nickname becomes Viewer #<4 hex>; each viewer always gets the same code within one room and game. user.avatar is an image URL through the LiveBridge proxy (https://livebridge.vn/api/avatar?u=<uniqueId>&s=96, allowed by the CSP; the proxy answers a default image when it has none), never a TikTok CDN URL. When avatars are off, and also when names are off (the proxy URL carries the real name): user.avatar is "". The game must look right in both cases (for example an initial letter instead of an avatar).
Token mode. The game only has ?t=. Without ?t= the SDK runs in demo mode (no connection, no error). A revoked link (the streamer pressed "Disconnect this game", changed TikTok account, an admin took the game down) closes the socket with code 4003: the SDK stops for good and calls onDisconnect; show "Link expired, reopen the game from LiveBridge". window.__LIVEBRIDGE__.status is idle, open, closed or revoked.
Create `new LiveBridgeGame({...})` as soon as the page loads, not after a click. The automatic checker opens the game in a real browser and waits for status open.
Forbidden
- No network access outside `connectOrigins` (fetch, XHR, WebSocket, images, fonts beyond what the CSP section allows). If you need your own API, declare its origin in
connectOrigins. - Never store or send viewer data anywhere else: names, avatars, ids and comments are for display inside the game only; do not write them to localStorage, cookies, IndexedDB or your own server, and do not put them in URLs.
- Never ask for, read or use `?key=` or the streamer's connection code (room key). The game only receives
?t=. - Do not assume a keyboard or mouse: the game is used while the streamer is live, and the players are viewers acting through gifts and chat.
- No external analytics (Google Analytics, Sentry, Mixpanel, ...), no iframes or ad scripts.
- Viewer data is untrusted: show it with
textContent, neverinnerHTML,evalordocument.write. - No illegal, sexual, extreme-violence, hateful or real-money gambling content. LiveBridge may take a game down at any time (see the developer terms).
- Use relative paths (
game.js,./img/a.png), never starting with/: the game runs underhttps://<game-id>.<sandbox domain>/v/<version>/.
CSP (the sandbox content security policy)
Every game file is served with this CSP; serve applies the same one so you see problems early:
default-src 'self'.- Scripts: the game's own files, LiveBridge's
/sdk/, inline scripts, WebAssembly ('wasm-unsafe-eval'), and the CDNshttps://cdnjs.cloudflare.com,https://cdn.jsdelivr.net,https://unpkg.com. - Network calls (
fetch, XHR, WebSocket): the game itself, the LiveBridge API, andconnectOrigins. - Images, audio, video, fonts: the game's files,
data:,blob:, the LiveBridge API, the three CDNs andconnectOrigins(https). Google Fonts is allowed (CSS fromfonts.googleapis.com, fonts fromfonts.gstatic.com). - Web Workers: the game's files or
blob:. No<object>,<base>,<form action>. - The game can be embedded in OBS and the dashboard (no
frame-ancestors), but cannot embed outside pages.