@tiktool/live 2.3.3 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -215,6 +215,58 @@ const tikTokData = await fetchSignedUrl(apiResponse);
215
215
 
216
216
  ---
217
217
 
218
+ ## 🧩 CAPTCHA Solver (Ultra)
219
+
220
+ Solve TikTok CAPTCHAs programmatically. Requires an **Ultra** tier API key.
221
+
222
+ ### `solvePuzzle(apiKey, puzzleB64, pieceB64, serverUrl?)` — Puzzle Slider
223
+
224
+ ```typescript
225
+ import { solvePuzzle } from '@tiktool/live';
226
+
227
+ const result = await solvePuzzle('YOUR_API_KEY', backgroundBase64, pieceBase64);
228
+ console.log(`Slide to X=${result.slideX}px (confidence: ${result.confidence})`);
229
+ ```
230
+
231
+ | Field | Type | Description |
232
+ |-------|------|-------------|
233
+ | `slideX` | `number` | Pixel X position for the slider |
234
+ | `confidence` | `number` | Confidence score (0.0–1.0) |
235
+ | `solveTimeMs` | `number` | Time taken to solve in ms |
236
+
237
+ ### `solveRotate(apiKey, outerB64, innerB64, serverUrl?)` — Rotate Whirl
238
+
239
+ ```typescript
240
+ import { solveRotate } from '@tiktool/live';
241
+
242
+ const result = await solveRotate('YOUR_API_KEY', outerBase64, innerBase64);
243
+ console.log(`Rotate ${result.angle}° (confidence: ${result.confidence})`);
244
+ ```
245
+
246
+ | Field | Type | Description |
247
+ |-------|------|-------------|
248
+ | `angle` | `number` | Rotation angle in degrees (0–360) |
249
+ | `confidence` | `number` | Confidence score (0.0–1.0) |
250
+ | `solveTimeMs` | `number` | Time taken to solve in ms |
251
+
252
+ ### `solveShapes(apiKey, imageB64, serverUrl?)` — 3D Shape Matching
253
+
254
+ ```typescript
255
+ import { solveShapes } from '@tiktool/live';
256
+
257
+ const result = await solveShapes('YOUR_API_KEY', imageBase64);
258
+ console.log(`Match: (${result.point1.x},${result.point1.y}) ↔ (${result.point2.x},${result.point2.y})`);
259
+ ```
260
+
261
+ | Field | Type | Description |
262
+ |-------|------|-------------|
263
+ | `point1` | `{x, y}` | First matching shape center |
264
+ | `point2` | `{x, y}` | Second matching shape center |
265
+ | `confidence` | `number` | Confidence score (0.0–1.0) |
266
+ | `solveTimeMs` | `number` | Time taken to solve in ms |
267
+
268
+ ---
269
+
218
270
  ## 🌐 REST API Endpoints
219
271
 
220
272
  The sign server at `api.tik.tools` exposes a full REST API alongside WebSocket signing. Endpoints use a **sign-and-return** pattern — when called with a `unique_id`, they return instructions for resolving the room ID; when called with a `room_id`, they return a signed URL to fetch data directly from TikTok. Use `callApi()` to handle this automatically.
@@ -241,6 +293,9 @@ The sign server at `api.tik.tools` exposes a full REST API alongside WebSocket s
241
293
  | `GET /webcast/live_analytics/*` | Video list, video detail, user interactions |
242
294
  | `GET /webcast/moderation/*` | Mute and ban management |
243
295
  | `POST /authentication/jwt` | Generate scoped JWT for frontend WebSocket access |
296
+ | `POST /captcha/solve/puzzle` | Solve puzzle slider CAPTCHA (**Ultra**) |
297
+ | `POST /captcha/solve/rotate` | Solve rotate whirl CAPTCHA (**Ultra**) |
298
+ | `POST /captcha/solve/shapes` | Solve 3D shape matching CAPTCHA (**Ultra**) |
244
299
 
245
300
  Full API documentation: **[tik.tools/docs](https://tik.tools/docs)**
246
301
 
@@ -258,6 +313,7 @@ All plans include signatures and full WebSocket support. Higher tiers unlock all
258
313
  | **Daily Requests** | 2,500 | 50,000 | 250,000 |
259
314
  | **WebSocket Connections** | 1 | 50 | 500 |
260
315
  | **Endpoints** | Basic | All | All |
316
+ | **CAPTCHA Solver** | — | — | ✓ |
261
317
  | **Priority Routing** | — | ✓ | ✓ |
262
318
  | **Overage** | — | $0.001/req | $0.0005/req |
263
319
  | **Support** | Community | Email | Dedicated |
package/dist/index.d.mts CHANGED
@@ -175,6 +175,37 @@ interface TikTokLiveOptions {
175
175
  debug?: boolean;
176
176
  webSocketImpl?: any;
177
177
  }
178
+ /** Result from solving a puzzle (slider) CAPTCHA */
179
+ interface PuzzleSolveResult {
180
+ /** X position as proportion (0.0–1.0) of background width */
181
+ slide_x_proportion: number;
182
+ /** Absolute pixel X offset */
183
+ slide_x_px: number;
184
+ /** Confidence score (0.0–1.0) */
185
+ confidence: number;
186
+ }
187
+ /** Result from solving a rotate (whirl) CAPTCHA */
188
+ interface RotateSolveResult {
189
+ /** Rotation angle in degrees (0–360) */
190
+ angle: number;
191
+ /** Confidence score (0.0–1.0) */
192
+ confidence: number;
193
+ }
194
+ /** Result from solving a shapes (3D matching) CAPTCHA */
195
+ interface ShapesSolveResult {
196
+ /** First matching shape center */
197
+ point1: {
198
+ x: number;
199
+ y: number;
200
+ };
201
+ /** Second matching shape center */
202
+ point2: {
203
+ x: number;
204
+ y: number;
205
+ };
206
+ /** Confidence score (0.0–1.0) */
207
+ confidence: number;
208
+ }
178
209
 
179
210
  type Listener = (...args: any[]) => void;
180
211
  declare class TypedEmitter {
@@ -286,4 +317,34 @@ interface CallApiOptions {
286
317
  */
287
318
  declare function callApi(opts: CallApiOptions): Promise<any>;
288
319
 
289
- export { type BaseEvent, type BattleArmiesEvent, type BattleEvent, type BattleTeam, type BattleTeamUser, type CallApiOptions, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type LivePageInfo, type MemberEvent, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type SignedUrlResponse, type SocialEvent, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent, callApi, fetchSignedUrl, resolveLivePage, resolveRoomId };
320
+ /**
321
+ * Solve a puzzle (slider) CAPTCHA using the TikTool solver.
322
+ *
323
+ * @param apiKey - API key for authentication
324
+ * @param puzzleB64 - Base64-encoded background image (PNG/JPEG)
325
+ * @param pieceB64 - Base64-encoded puzzle piece image (PNG/JPEG)
326
+ * @param serverUrl - Custom server URL (default: https://api.tik.tools)
327
+ * @returns Solve result with slide position and confidence
328
+ */
329
+ declare function solvePuzzle(apiKey: string, puzzleB64: string, pieceB64: string, serverUrl?: string): Promise<PuzzleSolveResult>;
330
+ /**
331
+ * Solve a rotate (whirl) CAPTCHA using the TikTool solver.
332
+ *
333
+ * @param apiKey - API key for authentication
334
+ * @param outerB64 - Base64-encoded outer ring image (PNG/JPEG)
335
+ * @param innerB64 - Base64-encoded inner rotated image (PNG/JPEG)
336
+ * @param serverUrl - Custom server URL (default: https://api.tik.tools)
337
+ * @returns Solve result with rotation angle and confidence
338
+ */
339
+ declare function solveRotate(apiKey: string, outerB64: string, innerB64: string, serverUrl?: string): Promise<RotateSolveResult>;
340
+ /**
341
+ * Solve a shapes (3D matching) CAPTCHA using the TikTool solver.
342
+ *
343
+ * @param apiKey - API key for authentication
344
+ * @param imageB64 - Base64-encoded CAPTCHA image with shape grid (PNG/JPEG)
345
+ * @param serverUrl - Custom server URL (default: https://api.tik.tools)
346
+ * @returns Solve result with two matching shape coordinates and confidence
347
+ */
348
+ declare function solveShapes(apiKey: string, imageB64: string, serverUrl?: string): Promise<ShapesSolveResult>;
349
+
350
+ export { type BaseEvent, type BattleArmiesEvent, type BattleEvent, type BattleTeam, type BattleTeamUser, type CallApiOptions, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type LivePageInfo, type MemberEvent, type PuzzleSolveResult, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type RotateSolveResult, type ShapesSolveResult, type SignedUrlResponse, type SocialEvent, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent, callApi, fetchSignedUrl, resolveLivePage, resolveRoomId, solvePuzzle, solveRotate, solveShapes };
package/dist/index.d.ts CHANGED
@@ -175,6 +175,37 @@ interface TikTokLiveOptions {
175
175
  debug?: boolean;
176
176
  webSocketImpl?: any;
177
177
  }
178
+ /** Result from solving a puzzle (slider) CAPTCHA */
179
+ interface PuzzleSolveResult {
180
+ /** X position as proportion (0.0–1.0) of background width */
181
+ slide_x_proportion: number;
182
+ /** Absolute pixel X offset */
183
+ slide_x_px: number;
184
+ /** Confidence score (0.0–1.0) */
185
+ confidence: number;
186
+ }
187
+ /** Result from solving a rotate (whirl) CAPTCHA */
188
+ interface RotateSolveResult {
189
+ /** Rotation angle in degrees (0–360) */
190
+ angle: number;
191
+ /** Confidence score (0.0–1.0) */
192
+ confidence: number;
193
+ }
194
+ /** Result from solving a shapes (3D matching) CAPTCHA */
195
+ interface ShapesSolveResult {
196
+ /** First matching shape center */
197
+ point1: {
198
+ x: number;
199
+ y: number;
200
+ };
201
+ /** Second matching shape center */
202
+ point2: {
203
+ x: number;
204
+ y: number;
205
+ };
206
+ /** Confidence score (0.0–1.0) */
207
+ confidence: number;
208
+ }
178
209
 
179
210
  type Listener = (...args: any[]) => void;
180
211
  declare class TypedEmitter {
@@ -286,4 +317,34 @@ interface CallApiOptions {
286
317
  */
287
318
  declare function callApi(opts: CallApiOptions): Promise<any>;
288
319
 
289
- export { type BaseEvent, type BattleArmiesEvent, type BattleEvent, type BattleTeam, type BattleTeamUser, type CallApiOptions, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type LivePageInfo, type MemberEvent, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type SignedUrlResponse, type SocialEvent, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent, callApi, fetchSignedUrl, resolveLivePage, resolveRoomId };
320
+ /**
321
+ * Solve a puzzle (slider) CAPTCHA using the TikTool solver.
322
+ *
323
+ * @param apiKey - API key for authentication
324
+ * @param puzzleB64 - Base64-encoded background image (PNG/JPEG)
325
+ * @param pieceB64 - Base64-encoded puzzle piece image (PNG/JPEG)
326
+ * @param serverUrl - Custom server URL (default: https://api.tik.tools)
327
+ * @returns Solve result with slide position and confidence
328
+ */
329
+ declare function solvePuzzle(apiKey: string, puzzleB64: string, pieceB64: string, serverUrl?: string): Promise<PuzzleSolveResult>;
330
+ /**
331
+ * Solve a rotate (whirl) CAPTCHA using the TikTool solver.
332
+ *
333
+ * @param apiKey - API key for authentication
334
+ * @param outerB64 - Base64-encoded outer ring image (PNG/JPEG)
335
+ * @param innerB64 - Base64-encoded inner rotated image (PNG/JPEG)
336
+ * @param serverUrl - Custom server URL (default: https://api.tik.tools)
337
+ * @returns Solve result with rotation angle and confidence
338
+ */
339
+ declare function solveRotate(apiKey: string, outerB64: string, innerB64: string, serverUrl?: string): Promise<RotateSolveResult>;
340
+ /**
341
+ * Solve a shapes (3D matching) CAPTCHA using the TikTool solver.
342
+ *
343
+ * @param apiKey - API key for authentication
344
+ * @param imageB64 - Base64-encoded CAPTCHA image with shape grid (PNG/JPEG)
345
+ * @param serverUrl - Custom server URL (default: https://api.tik.tools)
346
+ * @returns Solve result with two matching shape coordinates and confidence
347
+ */
348
+ declare function solveShapes(apiKey: string, imageB64: string, serverUrl?: string): Promise<ShapesSolveResult>;
349
+
350
+ export { type BaseEvent, type BattleArmiesEvent, type BattleEvent, type BattleTeam, type BattleTeamUser, type CallApiOptions, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type LivePageInfo, type MemberEvent, type PuzzleSolveResult, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type RotateSolveResult, type ShapesSolveResult, type SignedUrlResponse, type SocialEvent, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent, callApi, fetchSignedUrl, resolveLivePage, resolveRoomId, solvePuzzle, solveRotate, solveShapes };
package/dist/index.js CHANGED
@@ -34,7 +34,10 @@ __export(index_exports, {
34
34
  callApi: () => callApi,
35
35
  fetchSignedUrl: () => fetchSignedUrl,
36
36
  resolveLivePage: () => resolveLivePage,
37
- resolveRoomId: () => resolveRoomId
37
+ resolveRoomId: () => resolveRoomId,
38
+ solvePuzzle: () => solvePuzzle,
39
+ solveRotate: () => solveRotate,
40
+ solveShapes: () => solveShapes
38
41
  });
39
42
  module.exports = __toCommonJS(index_exports);
40
43
 
@@ -630,6 +633,45 @@ async function callApi(opts) {
630
633
  }
631
634
  return data1;
632
635
  }
636
+ async function solvePuzzle(apiKey, puzzleB64, pieceB64, serverUrl) {
637
+ const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\/$/, "");
638
+ const resp = await fetch(`${base}/captcha/solve/puzzle?apiKey=${encodeURIComponent(apiKey)}`, {
639
+ method: "POST",
640
+ headers: { "Content-Type": "application/json" },
641
+ body: JSON.stringify({ puzzle: puzzleB64, piece: pieceB64 })
642
+ });
643
+ const data = await resp.json();
644
+ if (data.status_code !== 0) {
645
+ throw new Error(data.error || `Solver failed (status ${data.status_code})`);
646
+ }
647
+ return data.data;
648
+ }
649
+ async function solveRotate(apiKey, outerB64, innerB64, serverUrl) {
650
+ const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\/$/, "");
651
+ const resp = await fetch(`${base}/captcha/solve/rotate?apiKey=${encodeURIComponent(apiKey)}`, {
652
+ method: "POST",
653
+ headers: { "Content-Type": "application/json" },
654
+ body: JSON.stringify({ outer: outerB64, inner: innerB64 })
655
+ });
656
+ const data = await resp.json();
657
+ if (data.status_code !== 0) {
658
+ throw new Error(data.error || `Solver failed (status ${data.status_code})`);
659
+ }
660
+ return data.data;
661
+ }
662
+ async function solveShapes(apiKey, imageB64, serverUrl) {
663
+ const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\/$/, "");
664
+ const resp = await fetch(`${base}/captcha/solve/shapes?apiKey=${encodeURIComponent(apiKey)}`, {
665
+ method: "POST",
666
+ headers: { "Content-Type": "application/json" },
667
+ body: JSON.stringify({ image: imageB64 })
668
+ });
669
+ const data = await resp.json();
670
+ if (data.status_code !== 0) {
671
+ throw new Error(data.error || `Solver failed (status ${data.status_code})`);
672
+ }
673
+ return data.data;
674
+ }
633
675
 
634
676
  // src/client.ts
635
677
  var DEFAULT_UA2 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
@@ -668,14 +710,54 @@ var TypedEmitter = class {
668
710
  return this;
669
711
  }
670
712
  };
671
- function gunzipSync(data) {
713
+ async function gunzip(data) {
714
+ if (typeof DecompressionStream !== "undefined") {
715
+ const ds = new DecompressionStream("gzip");
716
+ const writer = ds.writable.getWriter();
717
+ const reader = ds.readable.getReader();
718
+ writer.write(data);
719
+ writer.close();
720
+ const chunks = [];
721
+ while (true) {
722
+ const { done, value } = await reader.read();
723
+ if (done) break;
724
+ chunks.push(value);
725
+ }
726
+ return concatBytes(...chunks);
727
+ }
672
728
  try {
673
- const zlib = require("zlib");
674
- return new Uint8Array(zlib.gunzipSync(data));
729
+ const zlib = await import("zlib");
730
+ return new Promise((resolve, reject) => {
731
+ zlib.gunzip(data, (err, result) => {
732
+ if (err) reject(err);
733
+ else resolve(new Uint8Array(result));
734
+ });
735
+ });
675
736
  } catch {
676
737
  return data;
677
738
  }
678
739
  }
740
+ var _zlib = null;
741
+ var _zlibLoadAttempted = false;
742
+ async function ensureZlib() {
743
+ if (_zlib) return _zlib;
744
+ if (_zlibLoadAttempted) return null;
745
+ _zlibLoadAttempted = true;
746
+ try {
747
+ _zlib = await import("zlib");
748
+ } catch {
749
+ }
750
+ return _zlib;
751
+ }
752
+ ensureZlib();
753
+ function gunzipSync(data) {
754
+ if (!_zlib) return null;
755
+ try {
756
+ return new Uint8Array(_zlib.gunzipSync(data));
757
+ } catch {
758
+ return null;
759
+ }
760
+ }
679
761
  function getWsHost(clusterRegion) {
680
762
  if (!clusterRegion) return "webcast-ws.tiktok.com";
681
763
  const r = clusterRegion.toLowerCase();
@@ -905,7 +987,7 @@ var TikTokLive = class extends TypedEmitter {
905
987
  } catch {
906
988
  }
907
989
  }
908
- handleFrame(buf) {
990
+ async handleFrame(buf) {
909
991
  try {
910
992
  const fields = decodeProto(buf);
911
993
  const idField = fields.find((f) => f.fn === 2 && f.wt === 0);
@@ -919,9 +1001,11 @@ var TikTokLive = class extends TypedEmitter {
919
1001
  if (type === "msg" && binary && binary.length > 0) {
920
1002
  let inner = binary;
921
1003
  if (inner.length > 2 && inner[0] === 31 && inner[1] === 139) {
922
- try {
923
- inner = gunzipSync(inner);
924
- } catch {
1004
+ const syncResult = gunzipSync(inner);
1005
+ if (syncResult) {
1006
+ inner = syncResult;
1007
+ } else {
1008
+ inner = await gunzip(inner);
925
1009
  }
926
1010
  }
927
1011
  const events = parseWebcastResponse(inner);
@@ -977,6 +1061,9 @@ var TikTokLive = class extends TypedEmitter {
977
1061
  callApi,
978
1062
  fetchSignedUrl,
979
1063
  resolveLivePage,
980
- resolveRoomId
1064
+ resolveRoomId,
1065
+ solvePuzzle,
1066
+ solveRotate,
1067
+ solveShapes
981
1068
  });
982
1069
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/proto.ts","../src/api.ts","../src/client.ts"],"sourcesContent":["export { TikTokLive } from './client.js';\r\nexport { resolveLivePage, resolveRoomId, fetchSignedUrl, callApi } from './api.js';\r\nexport type { LivePageInfo, SignedUrlResponse, CallApiOptions } from './api.js';\r\n\r\nexport type {\r\n TikTokLiveOptions,\r\n TikTokLiveEvents,\r\n RoomInfo,\r\n LiveEvent,\r\n BaseEvent,\r\n ChatEvent,\r\n MemberEvent,\r\n LikeEvent,\r\n GiftEvent,\r\n SocialEvent,\r\n RoomUserSeqEvent,\r\n BattleEvent,\r\n BattleArmiesEvent,\r\n BattleTeam,\r\n BattleTeamUser,\r\n SubscribeEvent,\r\n EmoteChatEvent,\r\n EnvelopeEvent,\r\n QuestionEvent,\r\n ControlEvent,\r\n RoomEvent,\r\n LiveIntroEvent,\r\n RankUpdateEvent,\r\n LinkMicEvent,\r\n UnknownEvent,\r\n TikTokUser,\r\n} from './types.js';\r\n","import type { LiveEvent, TikTokUser, BattleTeam, BattleTeamUser } from './types.js';\r\n\r\nconst encoder = new TextEncoder();\r\nconst decoder = new TextDecoder();\r\n\r\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\r\n let totalLength = 0;\r\n for (const arr of arrays) totalLength += arr.length;\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const arr of arrays) {\r\n result.set(arr, offset);\r\n offset += arr.length;\r\n }\r\n return result;\r\n}\r\n\r\nfunction readInt32LE(buf: Uint8Array, offset: number): number {\r\n return buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n (buf[offset + 3] << 24);\r\n}\r\n\r\nfunction readBigInt64LE(buf: Uint8Array, offset: number): bigint {\r\n const lo = BigInt(buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n ((buf[offset + 3] << 24) >>> 0));\r\n const hi = BigInt(buf[offset + 4] |\r\n (buf[offset + 5] << 8) |\r\n (buf[offset + 6] << 16) |\r\n ((buf[offset + 7] << 24) >>> 0));\r\n return (hi << 32n) | (lo & 0xFFFFFFFFn);\r\n}\r\n\r\nexport function decodeVarint(buf: Uint8Array, offset: number): { value: number; offset: number } {\r\n let result = 0, shift = 0;\r\n while (offset < buf.length) {\r\n const byte = buf[offset++];\r\n result |= (byte & 0x7F) << shift;\r\n if ((byte & 0x80) === 0) break;\r\n shift += 7;\r\n }\r\n return { value: result >>> 0, offset };\r\n}\r\n\r\nexport function decodeVarint64(buf: Uint8Array, offset: number): { value: bigint; offset: number } {\r\n let result = 0n, shift = 0n;\r\n while (offset < buf.length) {\r\n const byte = BigInt(buf[offset++]);\r\n result |= (byte & 0x7Fn) << shift;\r\n if ((byte & 0x80n) === 0n) break;\r\n shift += 7n;\r\n }\r\n return { value: result, offset };\r\n}\r\n\r\nexport function encodeVarint(v: number | bigint): Uint8Array {\r\n const bytes: number[] = [];\r\n let n = typeof v === 'bigint' ? v : BigInt(v);\r\n do {\r\n let b = Number(n & 0x7Fn);\r\n n >>= 7n;\r\n if (n > 0n) b |= 0x80;\r\n bytes.push(b);\r\n } while (n > 0n);\r\n return new Uint8Array(bytes);\r\n}\r\n\r\nexport interface ProtoField {\r\n fn: number;\r\n wt: number;\r\n value: Uint8Array | number | bigint;\r\n}\r\n\r\nexport function encodeField(fn: number, wt: number, value: Uint8Array | bigint | number | string): Uint8Array {\r\n const tag = encodeVarint((fn << 3) | wt);\r\n if (wt === 0) {\r\n return concatBytes(tag, encodeVarint(typeof value === 'number' ? BigInt(value) : value as bigint));\r\n }\r\n const data = typeof value === 'string' ? encoder.encode(value) : value as Uint8Array;\r\n return concatBytes(tag, encodeVarint(data.length), data);\r\n}\r\n\r\nexport function decodeProto(buf: Uint8Array): ProtoField[] {\r\n const fields: ProtoField[] = [];\r\n let offset = 0;\r\n while (offset < buf.length) {\r\n const tagResult = decodeVarint(buf, offset);\r\n offset = tagResult.offset;\r\n const fn = tagResult.value >> 3;\r\n const wt = tagResult.value & 7;\r\n if (wt === 0) {\r\n const r = decodeVarint64(buf, offset);\r\n offset = r.offset;\r\n fields.push({ fn, wt, value: r.value });\r\n } else if (wt === 2) {\r\n const lenR = decodeVarint(buf, offset);\r\n offset = lenR.offset;\r\n const data = buf.subarray(offset, offset + lenR.value);\r\n offset += lenR.value;\r\n fields.push({ fn, wt, value: data });\r\n } else if (wt === 1) {\r\n fields.push({ fn, wt, value: readBigInt64LE(buf, offset) });\r\n offset += 8;\r\n } else if (wt === 5) {\r\n fields.push({ fn, wt, value: BigInt(readInt32LE(buf, offset)) });\r\n offset += 4;\r\n } else {\r\n break;\r\n }\r\n }\r\n return fields;\r\n}\r\n\r\nexport function getStr(fields: ProtoField[], fn: number): string {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? decoder.decode(f.value as Uint8Array) : '';\r\n}\r\n\r\nexport function getBytes(fields: ProtoField[], fn: number): Uint8Array | null {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? f.value as Uint8Array : null;\r\n}\r\n\r\nexport function getInt(fields: ProtoField[], fn: number): number {\r\n const f = fields.find(x => x.fn === fn && x.wt === 0);\r\n return f ? Number(f.value) : 0;\r\n}\r\n\r\nexport function getAllBytes(fields: ProtoField[], fn: number): Uint8Array[] {\r\n return fields.filter(x => x.fn === fn && x.wt === 2).map(x => x.value as Uint8Array);\r\n}\r\n\r\nexport function buildHeartbeat(roomId: string): Uint8Array {\r\n const payload = encodeField(1, 0, BigInt(roomId));\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'hb'),\r\n encodeField(8, 2, payload),\r\n );\r\n}\r\n\r\nexport function buildImEnterRoom(roomId: string): Uint8Array {\r\n const inner = concatBytes(\r\n encodeField(1, 0, BigInt(roomId)),\r\n encodeField(4, 0, 12n),\r\n encodeField(5, 2, 'audience'),\r\n encodeField(6, 2, ''),\r\n encodeField(9, 2, ''),\r\n encodeField(10, 2, ''),\r\n );\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'im_enter_room'),\r\n encodeField(8, 2, inner),\r\n );\r\n}\r\n\r\nexport function buildAck(id: bigint): Uint8Array {\r\n return concatBytes(\r\n encodeField(2, 0, id),\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'ack'),\r\n );\r\n}\r\n\r\nfunction parseUser(data: Uint8Array): TikTokUser {\r\n const f = decodeProto(data);\r\n const id = String(getInt(f, 1) || getStr(f, 1));\r\n const nickname = getStr(f, 3) || getStr(f, 2);\r\n const uniqueId = getStr(f, 38) || getStr(f, 4) || getStr(f, 2) || '';\r\n\r\n let profilePicture: string | undefined;\r\n const avatarBuf = getBytes(f, 9) || getBytes(f, 3);\r\n if (avatarBuf) {\r\n try {\r\n const avatarFields = decodeProto(avatarBuf);\r\n const urlBufs = getAllBytes(avatarFields, 1);\r\n if (urlBufs.length > 0) profilePicture = decoder.decode(urlBufs[0]);\r\n } catch { }\r\n }\r\n\r\n const badges: string[] = [];\r\n const badgeBuf = getBytes(f, 64);\r\n if (badgeBuf) {\r\n try {\r\n const badgeFields = decodeProto(badgeBuf);\r\n const badgeItems = getAllBytes(badgeFields, 21);\r\n for (const bi of badgeItems) {\r\n const bf = decodeProto(bi);\r\n const name = getStr(bf, 3) || getStr(bf, 2);\r\n if (name) badges.push(name);\r\n }\r\n } catch { }\r\n }\r\n\r\n return {\r\n id,\r\n nickname,\r\n uniqueId: uniqueId || nickname || id,\r\n profilePictureUrl: profilePicture,\r\n badges: badges.length > 0 ? badges : undefined,\r\n };\r\n}\r\n\r\nfunction parseBattleTeamFromArmies(itemBuf: Uint8Array): BattleTeam {\r\n const f = decodeProto(itemBuf);\r\n const hostUserId = String(getInt(f, 1));\r\n let teamScore = 0;\r\n const users: BattleTeamUser[] = [];\r\n\r\n const groups = getAllBytes(f, 2);\r\n for (const gb of groups) {\r\n try {\r\n const gf = decodeProto(gb);\r\n const points = getInt(gf, 2);\r\n teamScore += points;\r\n\r\n const userBufs = getAllBytes(gf, 1);\r\n for (const ub of userBufs) {\r\n try {\r\n const user = parseUser(ub);\r\n users.push({ user, score: points });\r\n } catch { }\r\n }\r\n } catch { }\r\n }\r\n\r\n return { hostUserId, score: teamScore, users };\r\n}\r\n\r\nexport function parseWebcastMessage(method: string, payload: Uint8Array): LiveEvent {\r\n const f = decodeProto(payload);\r\n const base = { timestamp: Date.now(), msgId: '' };\r\n\r\n const typeBuf = getBytes(f, 1);\r\n if (typeBuf) {\r\n try {\r\n const tf = decodeProto(typeBuf);\r\n const ts = getInt(tf, 4);\r\n if (ts) base.timestamp = ts;\r\n } catch { }\r\n }\r\n\r\n switch (method) {\r\n case 'WebcastChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'chat' as const, user, comment: getStr(f, 3) };\r\n }\r\n\r\n case 'WebcastMemberMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 1;\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('followed')) action = 2;\r\n else if (label.includes('share')) action = 3;\r\n }\r\n }\r\n return { ...base, type: 'member' as const, user, action };\r\n }\r\n\r\n case 'WebcastLikeMessage': {\r\n const userBuf = getBytes(f, 5);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return {\r\n ...base, type: 'like' as const, user,\r\n likeCount: getInt(f, 2),\r\n totalLikes: getInt(f, 3),\r\n };\r\n }\r\n\r\n case 'WebcastGiftMessage': {\r\n const userBuf = getBytes(f, 7);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n const giftId = getInt(f, 2);\r\n const repeatCount = getInt(f, 5);\r\n const repeatEnd = getInt(f, 9) === 1;\r\n\r\n let giftName = '', diamondCount = 0, giftType = 0;\r\n let giftImageUrl = '';\r\n const detailsBuf = getBytes(f, 15);\r\n if (detailsBuf) {\r\n const df = decodeProto(detailsBuf);\r\n giftName = getStr(df, 16) || getStr(df, 2);\r\n diamondCount = getInt(df, 12);\r\n giftType = getInt(df, 11);\r\n\r\n const imgBuf = getBytes(df, 1);\r\n if (imgBuf) {\r\n const imgf = decodeProto(imgBuf);\r\n giftImageUrl = getStr(imgf, 1);\r\n }\r\n }\r\n\r\n let toUserId = '';\r\n const extraBuf = getBytes(f, 23);\r\n if (extraBuf) {\r\n const ef = decodeProto(extraBuf);\r\n toUserId = String(getInt(ef, 8));\r\n }\r\n\r\n const groupId = toUserId || getStr(f, 11);\r\n\r\n return {\r\n ...base, type: 'gift' as const, user, giftId, giftName, diamondCount,\r\n repeatCount, repeatEnd, combo: repeatCount > 1 && !repeatEnd,\r\n giftType, groupId, giftPictureUrl: giftImageUrl,\r\n };\r\n }\r\n\r\n case 'WebcastSocialMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 'follow';\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('share')) action = 'share';\r\n else if (label.includes('follow')) action = 'follow';\r\n const displayType = getStr(df, 1);\r\n if (displayType === 'pm_mt_msg_viewer_share') action = 'share';\r\n }\r\n }\r\n return { ...base, type: 'social' as const, user, action };\r\n }\r\n\r\n case 'WebcastRoomUserSeqMessage': {\r\n const viewerCount = getInt(f, 3) || getInt(f, 2);\r\n const totalViewers = getInt(f, 1) || viewerCount;\r\n return { ...base, type: 'roomUserSeq' as const, totalViewers, viewerCount };\r\n }\r\n\r\n case 'WebcastLinkMicBattle': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const status = getInt(f, 2) || 1;\r\n const battleDuration = getInt(f, 3);\r\n const teams: BattleTeam[] = [];\r\n\r\n const battleUserBufs = getAllBytes(f, 10);\r\n for (const bub of battleUserBufs) {\r\n try {\r\n const bf = decodeProto(bub);\r\n const groupBuf = getBytes(bf, 2);\r\n if (groupBuf) {\r\n const gf = decodeProto(groupBuf);\r\n const linkUserBuf = getBytes(gf, 1);\r\n if (linkUserBuf) {\r\n const user = parseUser(linkUserBuf);\r\n teams.push({\r\n hostUserId: user.id,\r\n score: 0,\r\n users: [{ user, score: 0 }],\r\n });\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n if (teams.length === 0) {\r\n const teamBufs7 = getAllBytes(f, 7);\r\n for (const tb of teamBufs7) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(tb));\r\n } catch { }\r\n }\r\n }\r\n\r\n return { ...base, type: 'battle' as const, battleId, status, battleDuration, teams };\r\n }\r\n\r\n case 'WebcastLinkMicArmies': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const battleStatus = getInt(f, 7);\r\n const teams: BattleTeam[] = [];\r\n\r\n const itemBufs = getAllBytes(f, 3);\r\n for (const ib of itemBufs) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(ib));\r\n } catch { }\r\n }\r\n\r\n return {\r\n ...base, type: 'battleArmies' as const, battleId, teams,\r\n status: battleStatus,\r\n };\r\n }\r\n\r\n case 'WebcastSubNotifyMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'subscribe' as const, user, subMonth: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastEmoteChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let emoteId = '', emoteUrl = '';\r\n const emoteBuf = getBytes(f, 3);\r\n if (emoteBuf) {\r\n const ef = decodeProto(emoteBuf);\r\n emoteId = getStr(ef, 1);\r\n const imageBuf = getBytes(ef, 2);\r\n if (imageBuf) {\r\n const imgFields = decodeProto(imageBuf);\r\n emoteUrl = getStr(imgFields, 1);\r\n }\r\n }\r\n return { ...base, type: 'emoteChat' as const, user, emoteId, emoteUrl };\r\n }\r\n\r\n case 'WebcastEnvelopeMessage': {\r\n const envelopeId = String(getInt(f, 1) || getStr(f, 1));\r\n return { ...base, type: 'envelope' as const, envelopeId, diamondCount: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastQuestionNewMessage': {\r\n let questionText = '', user: TikTokUser = { id: '0', nickname: '', uniqueId: '' };\r\n const detailBuf = getBytes(f, 2);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n questionText = getStr(df, 2);\r\n const userBuf = getBytes(df, 5);\r\n if (userBuf) user = parseUser(userBuf);\r\n }\r\n return { ...base, type: 'question' as const, user, questionText };\r\n }\r\n\r\n case 'WebcastRankUpdateMessage':\r\n case 'WebcastHourlyRankMessage': {\r\n const rankType = getStr(f, 1) || `rank_${getInt(f, 1)}`;\r\n const rankList: Array<{ user: TikTokUser; rank: number; score: number }> = [];\r\n const listBufs = getAllBytes(f, 2);\r\n for (const lb of listBufs) {\r\n try {\r\n const rf = decodeProto(lb);\r\n const userBuf = getBytes(rf, 1);\r\n const rank = getInt(rf, 2);\r\n const score = getInt(rf, 3);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n rankList.push({ user, rank, score });\r\n } catch { }\r\n }\r\n return { ...base, type: 'rankUpdate' as const, rankType, rankList };\r\n }\r\n\r\n case 'WebcastControlMessage':\r\n return { ...base, type: 'control' as const, action: getInt(f, 2) || getInt(f, 1) };\r\n\r\n case 'WebcastRoomMessage':\r\n case 'RoomMessage':\r\n return { ...base, type: 'room' as const, status: getInt(f, 2) };\r\n\r\n case 'WebcastLiveIntroMessage': {\r\n const roomId = String(getInt(f, 2));\r\n const title = getStr(f, 4) || getStr(f, 2);\r\n return { ...base, type: 'liveIntro' as const, roomId, title };\r\n }\r\n\r\n case 'WebcastLinkMicMethod':\r\n case 'WebcastLinkmicBattleTaskMessage': {\r\n const action = getStr(f, 1) || `action_${getInt(f, 1)}`;\r\n const users: TikTokUser[] = [];\r\n const userBufs = getAllBytes(f, 2);\r\n for (const ub of userBufs) {\r\n try { users.push(parseUser(ub)); } catch { }\r\n }\r\n return { ...base, type: 'linkMic' as const, action, users };\r\n }\r\n\r\n default:\r\n return { ...base, type: 'unknown' as const, method };\r\n }\r\n}\r\n\r\nexport function parseWebcastResponse(payload: Uint8Array): LiveEvent[] {\r\n const events: LiveEvent[] = [];\r\n const respFields = decodeProto(payload);\r\n\r\n for (const mf of respFields.filter(f => f.fn === 1 && f.wt === 2)) {\r\n const msgBuf = mf.value as Uint8Array;\r\n const msgFields = decodeProto(msgBuf);\r\n const method = getStr(msgFields, 1);\r\n const innerPayload = getBytes(msgFields, 2);\r\n if (!method || !innerPayload) continue;\r\n\r\n try {\r\n events.push(parseWebcastMessage(method, innerPayload));\r\n } catch { }\r\n }\r\n\r\n return events;\r\n}\r\n","/**\r\n * TikTool API utilities for the sign-and-return API flow.\r\n *\r\n * The API server returns signed URLs instead of fetching TikTok data directly.\r\n * These utilities handle the two-step flow:\r\n * 1. resolve_required — scrape TikTok HTML to get room_id\r\n * 2. fetch_signed_url — use the signed URL to get actual TikTok data\r\n *\r\n * @module\r\n */\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\nconst pageCache = new Map<string, { info: LivePageInfo; ts: number }>();\r\nconst PAGE_CACHE_TTL = 5 * 60 * 1000;\r\n\r\n/**\r\n * Resolved live page metadata from a TikTok live page.\r\n */\r\nexport interface LivePageInfo {\r\n /** Active room ID for the livestream */\r\n roomId: string;\r\n /** Session cookie required for WebSocket authentication */\r\n ttwid: string;\r\n /** Server cluster region (e.g. 'us', 'eu') */\r\n clusterRegion: string;\r\n}\r\n\r\n/**\r\n * Scrape a TikTok live page to extract room metadata.\r\n * Returns the room ID, session cookie, and cluster region.\r\n * Results are cached for 5 minutes. Returns `null` if the user is not live.\r\n */\r\nexport async function resolveLivePage(uniqueId: string): Promise<LivePageInfo | null> {\r\n const clean = uniqueId.replace(/^@/, '');\r\n const cached = pageCache.get(clean);\r\n if (cached && Date.now() - cached.ts < PAGE_CACHE_TTL) {\r\n return cached.info;\r\n }\r\n\r\n try {\r\n const resp = await fetch(`https://www.tiktok.com/@${clean}/live`, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\r\n 'Accept-Language': 'en-US,en;q=0.9',\r\n },\r\n redirect: 'follow',\r\n });\r\n\r\n if (!resp.ok) return null;\r\n\r\n // Extract ttwid session cookie\r\n let ttwid = '';\r\n const setCookies = resp.headers.get('set-cookie') || '';\r\n for (const part of setCookies.split(',')) {\r\n const trimmed = part.trim();\r\n if (trimmed.startsWith('ttwid=')) {\r\n ttwid = trimmed.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n if (!ttwid && typeof (resp.headers as any).getSetCookie === 'function') {\r\n for (const sc of (resp.headers as any).getSetCookie()) {\r\n if (typeof sc === 'string' && sc.startsWith('ttwid=')) {\r\n ttwid = sc.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n }\r\n\r\n const html = await resp.text();\r\n\r\n // Extract roomId from SIGI_STATE JSON block\r\n let roomId = '';\r\n const sigiMatch = html.match(/id=\"SIGI_STATE\"[^>]*>([^<]+)/);\r\n if (sigiMatch) {\r\n try {\r\n const json = JSON.parse(sigiMatch[1]);\r\n const jsonStr = JSON.stringify(json);\r\n const m = jsonStr.match(/\"roomId\"\\s*:\\s*\"(\\d+)\"/);\r\n if (m) roomId = m[1];\r\n } catch { }\r\n }\r\n\r\n // Fallback patterns\r\n if (!roomId) {\r\n const patterns = [\r\n /\"roomId\"\\s*:\\s*\"(\\d+)\"/,\r\n /room_id[=/](\\d{10,})/,\r\n /\"idStr\"\\s*:\\s*\"(\\d{10,})\"/,\r\n ];\r\n for (const p of patterns) {\r\n const m = html.match(p);\r\n if (m) { roomId = m[1]; break; }\r\n }\r\n }\r\n\r\n if (!roomId) return null;\r\n\r\n // Extract cluster region\r\n const crMatch = html.match(/\"clusterRegion\"\\s*:\\s*\"([^\"]+)\"/);\r\n const clusterRegion = crMatch ? crMatch[1] : '';\r\n\r\n const info: LivePageInfo = { roomId, ttwid, clusterRegion };\r\n pageCache.set(clean, { info, ts: Date.now() });\r\n return info;\r\n } catch { }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Resolve a TikTok username to a room ID.\r\n * Returns `null` if the user is not currently live.\r\n * Results are cached for 5 minutes.\r\n */\r\nexport async function resolveRoomId(uniqueId: string): Promise<string | null> {\r\n const info = await resolveLivePage(uniqueId);\r\n return info?.roomId ?? null;\r\n}\r\n\r\nexport interface SignedUrlResponse {\r\n status_code: number;\r\n action?: string;\r\n signed_url: string;\r\n headers: Record<string, string>;\r\n cookies: string;\r\n}\r\n\r\n/**\r\n * Execute a signed-URL API response: fetch the signed URL and return the\r\n * parsed JSON data from TikTok.\r\n */\r\nexport async function fetchSignedUrl(response: SignedUrlResponse): Promise<any> {\r\n if (!response.signed_url) {\r\n return null;\r\n }\r\n\r\n const headers: Record<string, string> = { ...(response.headers || {}) };\r\n if (response.cookies) {\r\n headers['Cookie'] = response.cookies;\r\n }\r\n\r\n const resp = await fetch(response.signed_url, { headers, redirect: 'follow' });\r\n const text = await resp.text();\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport interface CallApiOptions {\r\n /** API server URL (default: https://api.tik.tools) */\r\n serverUrl?: string;\r\n /** API key for authentication */\r\n apiKey: string;\r\n /** API endpoint path (e.g. '/webcast/room_video') */\r\n endpoint: string;\r\n /** TikTok unique_id to resolve */\r\n uniqueId: string;\r\n /** HTTP method (default: POST) */\r\n method?: 'GET' | 'POST';\r\n /** Additional body fields for POST requests */\r\n extraBody?: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Call a TikTool API endpoint, handling the full\r\n * resolve_required → room_id → signed_url → fetch flow automatically.\r\n *\r\n * Returns the actual TikTok data, or `null` if the user is not live.\r\n */\r\nexport async function callApi(opts: CallApiOptions): Promise<any> {\r\n const serverUrl = (opts.serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const isGet = opts.method === 'GET';\r\n const ak = encodeURIComponent(opts.apiKey);\r\n\r\n const url1 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&unique_id=${encodeURIComponent(opts.uniqueId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts1: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ unique_id: opts.uniqueId, ...opts.extraBody }),\r\n };\r\n\r\n const resp1 = await fetch(url1, fetchOpts1);\r\n const data1 = await resp1.json() as any;\r\n\r\n // If the response contains a signed URL to fetch (with or without explicit action),\r\n // follow through and fetch the actual TikTok data\r\n if (data1.signed_url || data1.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data1);\r\n }\r\n\r\n if (data1.status_code === 0 && data1.action !== 'resolve_required') {\r\n return data1;\r\n }\r\n\r\n if (data1.action === 'resolve_required') {\r\n const roomId = await resolveRoomId(opts.uniqueId);\r\n if (!roomId) return null;\r\n\r\n const url2 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&room_id=${encodeURIComponent(roomId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts2: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ room_id: roomId, ...opts.extraBody }),\r\n };\r\n\r\n const resp2 = await fetch(url2, fetchOpts2);\r\n const data2 = await resp2.json() as any;\r\n\r\n if (data2.signed_url || data2.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data2);\r\n }\r\n\r\n return data2;\r\n }\r\n\r\n return data1;\r\n}\r\n","import type { TikTokLiveOptions, TikTokLiveEvents, RoomInfo, LiveEvent } from './types.js';\r\nimport {\r\n concatBytes,\r\n decodeProto,\r\n getStr,\r\n getBytes,\r\n buildHeartbeat,\r\n buildImEnterRoom,\r\n buildAck,\r\n parseWebcastResponse,\r\n} from './proto.js';\r\nimport { resolveLivePage } from './api.js';\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\ntype Listener = (...args: any[]) => void;\r\n\r\nclass TypedEmitter {\r\n private _listeners = new Map<string, Listener[]>();\r\n\r\n on(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event) || [];\r\n arr.push(fn);\r\n this._listeners.set(event, arr);\r\n return this;\r\n }\r\n\r\n once(event: string, fn: Listener): this {\r\n const wrapper: Listener = (...args) => {\r\n this.off(event, wrapper);\r\n fn(...args);\r\n };\r\n return this.on(event, wrapper);\r\n }\r\n\r\n off(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event);\r\n if (arr) {\r\n this._listeners.set(event, arr.filter(l => l !== fn));\r\n }\r\n return this;\r\n }\r\n\r\n emit(event: string, ...args: any[]): boolean {\r\n const arr = this._listeners.get(event);\r\n if (!arr || arr.length === 0) return false;\r\n for (const fn of [...arr]) fn(...args);\r\n return true;\r\n }\r\n\r\n removeAllListeners(event?: string): this {\r\n if (event) this._listeners.delete(event);\r\n else this._listeners.clear();\r\n return this;\r\n }\r\n}\r\n\r\nasync function gunzip(data: Uint8Array): Promise<Uint8Array> {\r\n if (typeof DecompressionStream !== 'undefined') {\r\n const ds = new DecompressionStream('gzip');\r\n const writer = ds.writable.getWriter();\r\n const reader = ds.readable.getReader();\r\n writer.write(data as any);\r\n writer.close();\r\n const chunks: Uint8Array[] = [];\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n chunks.push(value);\r\n }\r\n return concatBytes(...chunks);\r\n }\r\n try {\r\n const zlib = await import('zlib');\r\n return new Promise((resolve, reject) => {\r\n zlib.gunzip(data, (err: Error | null, result: Buffer) => {\r\n if (err) reject(err);\r\n else resolve(new Uint8Array(result));\r\n });\r\n });\r\n } catch {\r\n return data;\r\n }\r\n}\r\n\r\nfunction gunzipSync(data: Uint8Array): Uint8Array {\r\n try {\r\n const zlib = require('zlib');\r\n return new Uint8Array(zlib.gunzipSync(data));\r\n } catch {\r\n return data;\r\n }\r\n}\r\n\r\ntype WebSocketLike = {\r\n readonly readyState: number;\r\n send(data: ArrayBufferLike | string): void;\r\n close(code?: number, reason?: string): void;\r\n onopen: ((ev: any) => void) | null;\r\n onmessage: ((ev: any) => void) | null;\r\n onerror: ((ev: any) => void) | null;\r\n onclose: ((ev: any) => void) | null;\r\n};\r\n\r\ninterface WebSocketConstructor {\r\n new(url: string, protocols?: string | string[]): WebSocketLike;\r\n readonly OPEN: number;\r\n readonly CLOSED: number;\r\n}\r\n\r\nfunction getWsHost(clusterRegion: string): string {\r\n if (!clusterRegion) return 'webcast-ws.tiktok.com';\r\n const r = clusterRegion.toLowerCase();\r\n if (r.startsWith('eu') || r.includes('eu')) return 'webcast-ws.eu.tiktok.com';\r\n if (r.startsWith('us') || r.includes('us')) return 'webcast-ws.us.tiktok.com';\r\n return 'webcast-ws.tiktok.com';\r\n}\r\n\r\nasync function resolveWebSocket(userImpl?: any): Promise<WebSocketConstructor> {\r\n if (userImpl) return userImpl;\r\n\r\n if (typeof globalThis.WebSocket !== 'undefined') {\r\n return globalThis.WebSocket as unknown as WebSocketConstructor;\r\n }\r\n\r\n try {\r\n const ws = await import('ws');\r\n return (ws.default || ws) as unknown as WebSocketConstructor;\r\n } catch {\r\n throw new Error(\r\n 'No WebSocket implementation found. ' +\r\n 'Either use Node.js 22+ (native WebSocket), Cloudflare Workers, or install the \"ws\" package: npm i ws'\r\n );\r\n }\r\n}\r\n\r\nexport class TikTokLive extends TypedEmitter {\r\n private ws: WebSocketLike | null = null;\r\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n private reconnectAttempts = 0;\r\n private intentionalClose = false;\r\n private _connected = false;\r\n private _eventCount = 0;\r\n private _roomId = '';\r\n private _battleHosts = new Map<string, { id: string; nickname: string; uniqueId: string; profilePicture?: string }>();\r\n\r\n private readonly uniqueId: string;\r\n private readonly signServerUrl: string;\r\n private readonly apiKey: string;\r\n private readonly autoReconnect: boolean;\r\n private readonly maxReconnectAttempts: number;\r\n private readonly heartbeatInterval: number;\r\n private readonly debug: boolean;\r\n private readonly webSocketImpl?: any;\r\n private WS!: WebSocketConstructor;\r\n\r\n constructor(options: TikTokLiveOptions) {\r\n super();\r\n this.uniqueId = options.uniqueId.replace(/^@/, '');\r\n this.signServerUrl = (options.signServerUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n if (!options.apiKey) throw new Error('apiKey is required. Get a free key at https://tik.tools');\r\n this.apiKey = options.apiKey;\r\n this.autoReconnect = options.autoReconnect ?? true;\r\n this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\r\n this.heartbeatInterval = options.heartbeatInterval ?? 10_000;\r\n this.debug = options.debug ?? false;\r\n this.webSocketImpl = options.webSocketImpl;\r\n }\r\n\r\n async connect(): Promise<void> {\r\n this.intentionalClose = false;\r\n\r\n if (!this.WS) {\r\n this.WS = await resolveWebSocket(this.webSocketImpl);\r\n }\r\n\r\n const pageInfo = await resolveLivePage(this.uniqueId);\r\n if (!pageInfo) throw new Error(`User @${this.uniqueId} is not currently live`);\r\n if (!pageInfo.ttwid) throw new Error('Failed to obtain session cookie');\r\n\r\n const { roomId, ttwid, clusterRegion } = pageInfo;\r\n this._roomId = roomId;\r\n const wsHost = getWsHost(clusterRegion);\r\n\r\n const wsParams = new URLSearchParams({\r\n version_code: '270000', device_platform: 'web', cookie_enabled: 'true',\r\n screen_width: '1920', screen_height: '1080', browser_language: 'en-US',\r\n browser_platform: 'Win32', browser_name: 'Mozilla',\r\n browser_version: DEFAULT_UA.split('Mozilla/')[1] || '5.0',\r\n browser_online: 'true', tz_name: 'Etc/UTC',\r\n app_name: 'tiktok_web', sup_ws_ds_opt: '1', update_version_code: '2.0.0',\r\n compress: 'gzip', webcast_language: 'en', ws_direct: '1', aid: '1988',\r\n live_id: '12', app_language: 'en', client_enter: '1', room_id: roomId,\r\n identity: 'audience', history_comment_count: '6', last_rtt: '0',\r\n heartbeat_duration: '10000', resp_content_type: 'protobuf', did_rule: '3',\r\n });\r\n\r\n const rawWsUrl = `https://${wsHost}/webcast/im/ws_proxy/ws_reuse_supplement/?${wsParams}`;\r\n const signUrl = `${this.signServerUrl}/webcast/sign_url`;\r\n\r\n let wsUrl: string;\r\n try {\r\n const signResp = await fetch(signUrl, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n },\r\n body: JSON.stringify({ url: rawWsUrl }),\r\n });\r\n const signData = await signResp.json() as Record<string, any>;\r\n\r\n if (signData.status_code === 0 && signData.data?.signed_url) {\r\n wsUrl = (signData.data.signed_url as string).replace(/^https:\\/\\//, 'wss://');\r\n } else {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n } catch {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const connUrl = wsUrl + (wsUrl.includes('?') ? '&' : '?') + `ttwid=${ttwid}`;\r\n\r\n try {\r\n this.ws = new (this.WS as any)(connUrl, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Cookie': `ttwid=${ttwid}`,\r\n 'Origin': 'https://www.tiktok.com',\r\n },\r\n }) as WebSocketLike;\r\n } catch {\r\n this.ws = new this.WS(connUrl) as WebSocketLike;\r\n }\r\n\r\n const ws = this.ws;\r\n let settled = false;\r\n\r\n ws.onopen = () => {\r\n this._connected = true;\r\n this.reconnectAttempts = 0;\r\n\r\n const hb = buildHeartbeat(roomId);\r\n const enter = buildImEnterRoom(roomId);\r\n ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n ws.send(enter.buffer.byteLength === enter.length ? enter.buffer : enter.buffer.slice(enter.byteOffset, enter.byteOffset + enter.byteLength));\r\n this.startHeartbeat(roomId);\r\n\r\n const roomInfo: RoomInfo = {\r\n roomId,\r\n wsHost,\r\n clusterRegion,\r\n connectedAt: new Date().toISOString(),\r\n };\r\n\r\n (this as TypedEmitter).emit('connected');\r\n (this as TypedEmitter).emit('roomInfo', roomInfo);\r\n if (!settled) { settled = true; resolve(); }\r\n };\r\n\r\n ws.onmessage = (event: any) => {\r\n const raw = event.data !== undefined ? event.data : event;\r\n this.handleMessage(raw);\r\n };\r\n\r\n ws.onclose = (event: any) => {\r\n this._connected = false;\r\n this.stopHeartbeat();\r\n\r\n const code = event?.code ?? 1006;\r\n const reason = event?.reason ?? '';\r\n (this as TypedEmitter).emit('disconnected', code, reason?.toString?.() || '');\r\n\r\n if (!this.intentionalClose && this.autoReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {\r\n this.reconnectAttempts++;\r\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30_000);\r\n setTimeout(() => this.connect().catch(e => (this as TypedEmitter).emit('error', e)), delay);\r\n }\r\n };\r\n\r\n ws.onerror = (err: any) => {\r\n (this as TypedEmitter).emit('error', err instanceof Error ? err : new Error(String(err?.message || err)));\r\n if (!settled) { settled = true; reject(err); }\r\n };\r\n\r\n setTimeout(() => {\r\n if (!settled) {\r\n settled = true;\r\n ws.close();\r\n reject(new Error('Connection timeout'));\r\n }\r\n }, 15_000);\r\n });\r\n }\r\n\r\n disconnect(): void {\r\n this.intentionalClose = true;\r\n this.stopHeartbeat();\r\n if (this.ws) {\r\n this.ws.close(1000);\r\n this.ws = null;\r\n }\r\n this._connected = false;\r\n }\r\n\r\n get connected(): boolean {\r\n return this._connected;\r\n }\r\n\r\n get eventCount(): number {\r\n return this._eventCount;\r\n }\r\n\r\n get roomId(): string {\r\n return this._roomId;\r\n }\r\n\r\n override on<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.on(event as string, listener as Listener);\r\n }\r\n\r\n override once<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.once(event as string, listener as Listener);\r\n }\r\n\r\n override off<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.off(event as string, listener as Listener);\r\n }\r\n\r\n override emit<K extends keyof TikTokLiveEvents>(event: K, ...args: Parameters<TikTokLiveEvents[K]>): boolean {\r\n return super.emit(event as string, ...args);\r\n }\r\n\r\n private async handleMessage(raw: any): Promise<void> {\r\n try {\r\n let bytes: Uint8Array;\r\n\r\n if (raw instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw);\r\n } else if (raw instanceof Uint8Array) {\r\n bytes = raw;\r\n } else if (typeof Blob !== 'undefined' && raw instanceof Blob) {\r\n bytes = new Uint8Array(await raw.arrayBuffer());\r\n } else if (raw?.buffer instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);\r\n } else {\r\n return;\r\n }\r\n\r\n this.handleFrame(bytes);\r\n } catch { }\r\n }\r\n\r\n private handleFrame(buf: Uint8Array): void {\r\n try {\r\n const fields = decodeProto(buf);\r\n const idField = fields.find(f => f.fn === 2 && f.wt === 0);\r\n const id = idField ? idField.value as bigint : 0n;\r\n const type = getStr(fields, 7);\r\n const binary = getBytes(fields, 8);\r\n\r\n if (id > 0n && this.ws && (this.ws.readyState === 1)) {\r\n const ack = buildAck(id);\r\n this.ws.send(ack.buffer.byteLength === ack.length ? ack.buffer : ack.buffer.slice(ack.byteOffset, ack.byteOffset + ack.byteLength));\r\n }\r\n\r\n if (type === 'msg' && binary && binary.length > 0) {\r\n let inner = binary;\r\n if (inner.length > 2 && inner[0] === 0x1f && inner[1] === 0x8b) {\r\n try { inner = gunzipSync(inner); } catch { }\r\n }\r\n\r\n const events = parseWebcastResponse(inner);\r\n for (const evt of events) {\r\n this._eventCount++;\r\n\r\n if (evt.type === 'battle') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n team.hostUser = host.user;\r\n }\r\n }\r\n }\r\n\r\n if (evt.type === 'battleArmies') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n team.hostUser = host.user;\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n } else {\r\n const cached = this._battleHosts.get(team.hostUserId);\r\n if (cached) team.hostUser = cached;\r\n }\r\n }\r\n }\r\n\r\n (this as TypedEmitter).emit('event', evt);\r\n (this as TypedEmitter).emit(evt.type, evt as any);\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n private startHeartbeat(roomId: string): void {\r\n this.stopHeartbeat();\r\n this.heartbeatTimer = setInterval(() => {\r\n if (this.ws && this.ws.readyState === 1) {\r\n const hb = buildHeartbeat(roomId);\r\n this.ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n }\r\n }, this.heartbeatInterval);\r\n }\r\n\r\n private stopHeartbeat(): void {\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n this.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["DEFAULT_UA","DEFAULT_SIGN_SERVER","DEFAULT_SIGN_SERVER","DEFAULT_UA"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/proto.ts","../src/api.ts","../src/client.ts"],"sourcesContent":["export { TikTokLive } from './client.js';\r\nexport { resolveLivePage, resolveRoomId, fetchSignedUrl, callApi, solvePuzzle, solveRotate, solveShapes } from './api.js';\r\nexport type { LivePageInfo, SignedUrlResponse, CallApiOptions } from './api.js';\r\n\r\nexport type {\r\n TikTokLiveOptions,\r\n TikTokLiveEvents,\r\n RoomInfo,\r\n LiveEvent,\r\n BaseEvent,\r\n ChatEvent,\r\n MemberEvent,\r\n LikeEvent,\r\n GiftEvent,\r\n SocialEvent,\r\n RoomUserSeqEvent,\r\n BattleEvent,\r\n BattleArmiesEvent,\r\n BattleTeam,\r\n BattleTeamUser,\r\n SubscribeEvent,\r\n EmoteChatEvent,\r\n EnvelopeEvent,\r\n QuestionEvent,\r\n ControlEvent,\r\n RoomEvent,\r\n LiveIntroEvent,\r\n RankUpdateEvent,\r\n LinkMicEvent,\r\n UnknownEvent,\r\n TikTokUser,\r\n PuzzleSolveResult,\r\n RotateSolveResult,\r\n ShapesSolveResult,\r\n} from './types.js';\r\n","import type { LiveEvent, TikTokUser, BattleTeam, BattleTeamUser } from './types.js';\r\n\r\nconst encoder = new TextEncoder();\r\nconst decoder = new TextDecoder();\r\n\r\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\r\n let totalLength = 0;\r\n for (const arr of arrays) totalLength += arr.length;\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const arr of arrays) {\r\n result.set(arr, offset);\r\n offset += arr.length;\r\n }\r\n return result;\r\n}\r\n\r\nfunction readInt32LE(buf: Uint8Array, offset: number): number {\r\n return buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n (buf[offset + 3] << 24);\r\n}\r\n\r\nfunction readBigInt64LE(buf: Uint8Array, offset: number): bigint {\r\n const lo = BigInt(buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n ((buf[offset + 3] << 24) >>> 0));\r\n const hi = BigInt(buf[offset + 4] |\r\n (buf[offset + 5] << 8) |\r\n (buf[offset + 6] << 16) |\r\n ((buf[offset + 7] << 24) >>> 0));\r\n return (hi << 32n) | (lo & 0xFFFFFFFFn);\r\n}\r\n\r\nexport function decodeVarint(buf: Uint8Array, offset: number): { value: number; offset: number } {\r\n let result = 0, shift = 0;\r\n while (offset < buf.length) {\r\n const byte = buf[offset++];\r\n result |= (byte & 0x7F) << shift;\r\n if ((byte & 0x80) === 0) break;\r\n shift += 7;\r\n }\r\n return { value: result >>> 0, offset };\r\n}\r\n\r\nexport function decodeVarint64(buf: Uint8Array, offset: number): { value: bigint; offset: number } {\r\n let result = 0n, shift = 0n;\r\n while (offset < buf.length) {\r\n const byte = BigInt(buf[offset++]);\r\n result |= (byte & 0x7Fn) << shift;\r\n if ((byte & 0x80n) === 0n) break;\r\n shift += 7n;\r\n }\r\n return { value: result, offset };\r\n}\r\n\r\nexport function encodeVarint(v: number | bigint): Uint8Array {\r\n const bytes: number[] = [];\r\n let n = typeof v === 'bigint' ? v : BigInt(v);\r\n do {\r\n let b = Number(n & 0x7Fn);\r\n n >>= 7n;\r\n if (n > 0n) b |= 0x80;\r\n bytes.push(b);\r\n } while (n > 0n);\r\n return new Uint8Array(bytes);\r\n}\r\n\r\nexport interface ProtoField {\r\n fn: number;\r\n wt: number;\r\n value: Uint8Array | number | bigint;\r\n}\r\n\r\nexport function encodeField(fn: number, wt: number, value: Uint8Array | bigint | number | string): Uint8Array {\r\n const tag = encodeVarint((fn << 3) | wt);\r\n if (wt === 0) {\r\n return concatBytes(tag, encodeVarint(typeof value === 'number' ? BigInt(value) : value as bigint));\r\n }\r\n const data = typeof value === 'string' ? encoder.encode(value) : value as Uint8Array;\r\n return concatBytes(tag, encodeVarint(data.length), data);\r\n}\r\n\r\nexport function decodeProto(buf: Uint8Array): ProtoField[] {\r\n const fields: ProtoField[] = [];\r\n let offset = 0;\r\n while (offset < buf.length) {\r\n const tagResult = decodeVarint(buf, offset);\r\n offset = tagResult.offset;\r\n const fn = tagResult.value >> 3;\r\n const wt = tagResult.value & 7;\r\n if (wt === 0) {\r\n const r = decodeVarint64(buf, offset);\r\n offset = r.offset;\r\n fields.push({ fn, wt, value: r.value });\r\n } else if (wt === 2) {\r\n const lenR = decodeVarint(buf, offset);\r\n offset = lenR.offset;\r\n const data = buf.subarray(offset, offset + lenR.value);\r\n offset += lenR.value;\r\n fields.push({ fn, wt, value: data });\r\n } else if (wt === 1) {\r\n fields.push({ fn, wt, value: readBigInt64LE(buf, offset) });\r\n offset += 8;\r\n } else if (wt === 5) {\r\n fields.push({ fn, wt, value: BigInt(readInt32LE(buf, offset)) });\r\n offset += 4;\r\n } else {\r\n break;\r\n }\r\n }\r\n return fields;\r\n}\r\n\r\nexport function getStr(fields: ProtoField[], fn: number): string {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? decoder.decode(f.value as Uint8Array) : '';\r\n}\r\n\r\nexport function getBytes(fields: ProtoField[], fn: number): Uint8Array | null {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? f.value as Uint8Array : null;\r\n}\r\n\r\nexport function getInt(fields: ProtoField[], fn: number): number {\r\n const f = fields.find(x => x.fn === fn && x.wt === 0);\r\n return f ? Number(f.value) : 0;\r\n}\r\n\r\nexport function getAllBytes(fields: ProtoField[], fn: number): Uint8Array[] {\r\n return fields.filter(x => x.fn === fn && x.wt === 2).map(x => x.value as Uint8Array);\r\n}\r\n\r\nexport function buildHeartbeat(roomId: string): Uint8Array {\r\n const payload = encodeField(1, 0, BigInt(roomId));\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'hb'),\r\n encodeField(8, 2, payload),\r\n );\r\n}\r\n\r\nexport function buildImEnterRoom(roomId: string): Uint8Array {\r\n const inner = concatBytes(\r\n encodeField(1, 0, BigInt(roomId)),\r\n encodeField(4, 0, 12n),\r\n encodeField(5, 2, 'audience'),\r\n encodeField(6, 2, ''),\r\n encodeField(9, 2, ''),\r\n encodeField(10, 2, ''),\r\n );\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'im_enter_room'),\r\n encodeField(8, 2, inner),\r\n );\r\n}\r\n\r\nexport function buildAck(id: bigint): Uint8Array {\r\n return concatBytes(\r\n encodeField(2, 0, id),\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'ack'),\r\n );\r\n}\r\n\r\nfunction parseUser(data: Uint8Array): TikTokUser {\r\n const f = decodeProto(data);\r\n const id = String(getInt(f, 1) || getStr(f, 1));\r\n const nickname = getStr(f, 3) || getStr(f, 2);\r\n const uniqueId = getStr(f, 38) || getStr(f, 4) || getStr(f, 2) || '';\r\n\r\n let profilePicture: string | undefined;\r\n const avatarBuf = getBytes(f, 9) || getBytes(f, 3);\r\n if (avatarBuf) {\r\n try {\r\n const avatarFields = decodeProto(avatarBuf);\r\n const urlBufs = getAllBytes(avatarFields, 1);\r\n if (urlBufs.length > 0) profilePicture = decoder.decode(urlBufs[0]);\r\n } catch { }\r\n }\r\n\r\n const badges: string[] = [];\r\n const badgeBuf = getBytes(f, 64);\r\n if (badgeBuf) {\r\n try {\r\n const badgeFields = decodeProto(badgeBuf);\r\n const badgeItems = getAllBytes(badgeFields, 21);\r\n for (const bi of badgeItems) {\r\n const bf = decodeProto(bi);\r\n const name = getStr(bf, 3) || getStr(bf, 2);\r\n if (name) badges.push(name);\r\n }\r\n } catch { }\r\n }\r\n\r\n return {\r\n id,\r\n nickname,\r\n uniqueId: uniqueId || nickname || id,\r\n profilePictureUrl: profilePicture,\r\n badges: badges.length > 0 ? badges : undefined,\r\n };\r\n}\r\n\r\nfunction parseBattleTeamFromArmies(itemBuf: Uint8Array): BattleTeam {\r\n const f = decodeProto(itemBuf);\r\n const hostUserId = String(getInt(f, 1));\r\n let teamScore = 0;\r\n const users: BattleTeamUser[] = [];\r\n\r\n const groups = getAllBytes(f, 2);\r\n for (const gb of groups) {\r\n try {\r\n const gf = decodeProto(gb);\r\n const points = getInt(gf, 2);\r\n teamScore += points;\r\n\r\n const userBufs = getAllBytes(gf, 1);\r\n for (const ub of userBufs) {\r\n try {\r\n const user = parseUser(ub);\r\n users.push({ user, score: points });\r\n } catch { }\r\n }\r\n } catch { }\r\n }\r\n\r\n return { hostUserId, score: teamScore, users };\r\n}\r\n\r\nexport function parseWebcastMessage(method: string, payload: Uint8Array): LiveEvent {\r\n const f = decodeProto(payload);\r\n const base = { timestamp: Date.now(), msgId: '' };\r\n\r\n const typeBuf = getBytes(f, 1);\r\n if (typeBuf) {\r\n try {\r\n const tf = decodeProto(typeBuf);\r\n const ts = getInt(tf, 4);\r\n if (ts) base.timestamp = ts;\r\n } catch { }\r\n }\r\n\r\n switch (method) {\r\n case 'WebcastChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'chat' as const, user, comment: getStr(f, 3) };\r\n }\r\n\r\n case 'WebcastMemberMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 1;\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('followed')) action = 2;\r\n else if (label.includes('share')) action = 3;\r\n }\r\n }\r\n return { ...base, type: 'member' as const, user, action };\r\n }\r\n\r\n case 'WebcastLikeMessage': {\r\n const userBuf = getBytes(f, 5);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return {\r\n ...base, type: 'like' as const, user,\r\n likeCount: getInt(f, 2),\r\n totalLikes: getInt(f, 3),\r\n };\r\n }\r\n\r\n case 'WebcastGiftMessage': {\r\n const userBuf = getBytes(f, 7);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n const giftId = getInt(f, 2);\r\n const repeatCount = getInt(f, 5);\r\n const repeatEnd = getInt(f, 9) === 1;\r\n\r\n let giftName = '', diamondCount = 0, giftType = 0;\r\n let giftImageUrl = '';\r\n const detailsBuf = getBytes(f, 15);\r\n if (detailsBuf) {\r\n const df = decodeProto(detailsBuf);\r\n giftName = getStr(df, 16) || getStr(df, 2);\r\n diamondCount = getInt(df, 12);\r\n giftType = getInt(df, 11);\r\n\r\n const imgBuf = getBytes(df, 1);\r\n if (imgBuf) {\r\n const imgf = decodeProto(imgBuf);\r\n giftImageUrl = getStr(imgf, 1);\r\n }\r\n }\r\n\r\n let toUserId = '';\r\n const extraBuf = getBytes(f, 23);\r\n if (extraBuf) {\r\n const ef = decodeProto(extraBuf);\r\n toUserId = String(getInt(ef, 8));\r\n }\r\n\r\n const groupId = toUserId || getStr(f, 11);\r\n\r\n return {\r\n ...base, type: 'gift' as const, user, giftId, giftName, diamondCount,\r\n repeatCount, repeatEnd, combo: repeatCount > 1 && !repeatEnd,\r\n giftType, groupId, giftPictureUrl: giftImageUrl,\r\n };\r\n }\r\n\r\n case 'WebcastSocialMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 'follow';\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('share')) action = 'share';\r\n else if (label.includes('follow')) action = 'follow';\r\n const displayType = getStr(df, 1);\r\n if (displayType === 'pm_mt_msg_viewer_share') action = 'share';\r\n }\r\n }\r\n return { ...base, type: 'social' as const, user, action };\r\n }\r\n\r\n case 'WebcastRoomUserSeqMessage': {\r\n const viewerCount = getInt(f, 3) || getInt(f, 2);\r\n const totalViewers = getInt(f, 1) || viewerCount;\r\n return { ...base, type: 'roomUserSeq' as const, totalViewers, viewerCount };\r\n }\r\n\r\n case 'WebcastLinkMicBattle': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const status = getInt(f, 2) || 1;\r\n const battleDuration = getInt(f, 3);\r\n const teams: BattleTeam[] = [];\r\n\r\n const battleUserBufs = getAllBytes(f, 10);\r\n for (const bub of battleUserBufs) {\r\n try {\r\n const bf = decodeProto(bub);\r\n const groupBuf = getBytes(bf, 2);\r\n if (groupBuf) {\r\n const gf = decodeProto(groupBuf);\r\n const linkUserBuf = getBytes(gf, 1);\r\n if (linkUserBuf) {\r\n const user = parseUser(linkUserBuf);\r\n teams.push({\r\n hostUserId: user.id,\r\n score: 0,\r\n users: [{ user, score: 0 }],\r\n });\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n if (teams.length === 0) {\r\n const teamBufs7 = getAllBytes(f, 7);\r\n for (const tb of teamBufs7) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(tb));\r\n } catch { }\r\n }\r\n }\r\n\r\n return { ...base, type: 'battle' as const, battleId, status, battleDuration, teams };\r\n }\r\n\r\n case 'WebcastLinkMicArmies': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const battleStatus = getInt(f, 7);\r\n const teams: BattleTeam[] = [];\r\n\r\n const itemBufs = getAllBytes(f, 3);\r\n for (const ib of itemBufs) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(ib));\r\n } catch { }\r\n }\r\n\r\n return {\r\n ...base, type: 'battleArmies' as const, battleId, teams,\r\n status: battleStatus,\r\n };\r\n }\r\n\r\n case 'WebcastSubNotifyMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'subscribe' as const, user, subMonth: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastEmoteChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let emoteId = '', emoteUrl = '';\r\n const emoteBuf = getBytes(f, 3);\r\n if (emoteBuf) {\r\n const ef = decodeProto(emoteBuf);\r\n emoteId = getStr(ef, 1);\r\n const imageBuf = getBytes(ef, 2);\r\n if (imageBuf) {\r\n const imgFields = decodeProto(imageBuf);\r\n emoteUrl = getStr(imgFields, 1);\r\n }\r\n }\r\n return { ...base, type: 'emoteChat' as const, user, emoteId, emoteUrl };\r\n }\r\n\r\n case 'WebcastEnvelopeMessage': {\r\n const envelopeId = String(getInt(f, 1) || getStr(f, 1));\r\n return { ...base, type: 'envelope' as const, envelopeId, diamondCount: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastQuestionNewMessage': {\r\n let questionText = '', user: TikTokUser = { id: '0', nickname: '', uniqueId: '' };\r\n const detailBuf = getBytes(f, 2);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n questionText = getStr(df, 2);\r\n const userBuf = getBytes(df, 5);\r\n if (userBuf) user = parseUser(userBuf);\r\n }\r\n return { ...base, type: 'question' as const, user, questionText };\r\n }\r\n\r\n case 'WebcastRankUpdateMessage':\r\n case 'WebcastHourlyRankMessage': {\r\n const rankType = getStr(f, 1) || `rank_${getInt(f, 1)}`;\r\n const rankList: Array<{ user: TikTokUser; rank: number; score: number }> = [];\r\n const listBufs = getAllBytes(f, 2);\r\n for (const lb of listBufs) {\r\n try {\r\n const rf = decodeProto(lb);\r\n const userBuf = getBytes(rf, 1);\r\n const rank = getInt(rf, 2);\r\n const score = getInt(rf, 3);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n rankList.push({ user, rank, score });\r\n } catch { }\r\n }\r\n return { ...base, type: 'rankUpdate' as const, rankType, rankList };\r\n }\r\n\r\n case 'WebcastControlMessage':\r\n return { ...base, type: 'control' as const, action: getInt(f, 2) || getInt(f, 1) };\r\n\r\n case 'WebcastRoomMessage':\r\n case 'RoomMessage':\r\n return { ...base, type: 'room' as const, status: getInt(f, 2) };\r\n\r\n case 'WebcastLiveIntroMessage': {\r\n const roomId = String(getInt(f, 2));\r\n const title = getStr(f, 4) || getStr(f, 2);\r\n return { ...base, type: 'liveIntro' as const, roomId, title };\r\n }\r\n\r\n case 'WebcastLinkMicMethod':\r\n case 'WebcastLinkmicBattleTaskMessage': {\r\n const action = getStr(f, 1) || `action_${getInt(f, 1)}`;\r\n const users: TikTokUser[] = [];\r\n const userBufs = getAllBytes(f, 2);\r\n for (const ub of userBufs) {\r\n try { users.push(parseUser(ub)); } catch { }\r\n }\r\n return { ...base, type: 'linkMic' as const, action, users };\r\n }\r\n\r\n default:\r\n return { ...base, type: 'unknown' as const, method };\r\n }\r\n}\r\n\r\nexport function parseWebcastResponse(payload: Uint8Array): LiveEvent[] {\r\n const events: LiveEvent[] = [];\r\n const respFields = decodeProto(payload);\r\n\r\n for (const mf of respFields.filter(f => f.fn === 1 && f.wt === 2)) {\r\n const msgBuf = mf.value as Uint8Array;\r\n const msgFields = decodeProto(msgBuf);\r\n const method = getStr(msgFields, 1);\r\n const innerPayload = getBytes(msgFields, 2);\r\n if (!method || !innerPayload) continue;\r\n\r\n try {\r\n events.push(parseWebcastMessage(method, innerPayload));\r\n } catch { }\r\n }\r\n\r\n return events;\r\n}\r\n","/**\r\n * TikTool API utilities for the sign-and-return API flow.\r\n *\r\n * The API server returns signed URLs instead of fetching TikTok data directly.\r\n * These utilities handle the two-step flow:\r\n * 1. resolve_required — scrape TikTok HTML to get room_id\r\n * 2. fetch_signed_url — use the signed URL to get actual TikTok data\r\n *\r\n * @module\r\n */\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\nconst pageCache = new Map<string, { info: LivePageInfo; ts: number }>();\r\nconst PAGE_CACHE_TTL = 5 * 60 * 1000;\r\n\r\n/**\r\n * Resolved live page metadata from a TikTok live page.\r\n */\r\nexport interface LivePageInfo {\r\n /** Active room ID for the livestream */\r\n roomId: string;\r\n /** Session cookie required for WebSocket authentication */\r\n ttwid: string;\r\n /** Server cluster region (e.g. 'us', 'eu') */\r\n clusterRegion: string;\r\n}\r\n\r\n/**\r\n * Scrape a TikTok live page to extract room metadata.\r\n * Returns the room ID, session cookie, and cluster region.\r\n * Results are cached for 5 minutes. Returns `null` if the user is not live.\r\n */\r\nexport async function resolveLivePage(uniqueId: string): Promise<LivePageInfo | null> {\r\n const clean = uniqueId.replace(/^@/, '');\r\n const cached = pageCache.get(clean);\r\n if (cached && Date.now() - cached.ts < PAGE_CACHE_TTL) {\r\n return cached.info;\r\n }\r\n\r\n try {\r\n const resp = await fetch(`https://www.tiktok.com/@${clean}/live`, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\r\n 'Accept-Language': 'en-US,en;q=0.9',\r\n },\r\n redirect: 'follow',\r\n });\r\n\r\n if (!resp.ok) return null;\r\n\r\n // Extract ttwid session cookie\r\n let ttwid = '';\r\n const setCookies = resp.headers.get('set-cookie') || '';\r\n for (const part of setCookies.split(',')) {\r\n const trimmed = part.trim();\r\n if (trimmed.startsWith('ttwid=')) {\r\n ttwid = trimmed.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n if (!ttwid && typeof (resp.headers as any).getSetCookie === 'function') {\r\n for (const sc of (resp.headers as any).getSetCookie()) {\r\n if (typeof sc === 'string' && sc.startsWith('ttwid=')) {\r\n ttwid = sc.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n }\r\n\r\n const html = await resp.text();\r\n\r\n // Extract roomId from SIGI_STATE JSON block\r\n let roomId = '';\r\n const sigiMatch = html.match(/id=\"SIGI_STATE\"[^>]*>([^<]+)/);\r\n if (sigiMatch) {\r\n try {\r\n const json = JSON.parse(sigiMatch[1]);\r\n const jsonStr = JSON.stringify(json);\r\n const m = jsonStr.match(/\"roomId\"\\s*:\\s*\"(\\d+)\"/);\r\n if (m) roomId = m[1];\r\n } catch { }\r\n }\r\n\r\n // Fallback patterns\r\n if (!roomId) {\r\n const patterns = [\r\n /\"roomId\"\\s*:\\s*\"(\\d+)\"/,\r\n /room_id[=/](\\d{10,})/,\r\n /\"idStr\"\\s*:\\s*\"(\\d{10,})\"/,\r\n ];\r\n for (const p of patterns) {\r\n const m = html.match(p);\r\n if (m) { roomId = m[1]; break; }\r\n }\r\n }\r\n\r\n if (!roomId) return null;\r\n\r\n // Extract cluster region\r\n const crMatch = html.match(/\"clusterRegion\"\\s*:\\s*\"([^\"]+)\"/);\r\n const clusterRegion = crMatch ? crMatch[1] : '';\r\n\r\n const info: LivePageInfo = { roomId, ttwid, clusterRegion };\r\n pageCache.set(clean, { info, ts: Date.now() });\r\n return info;\r\n } catch { }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Resolve a TikTok username to a room ID.\r\n * Returns `null` if the user is not currently live.\r\n * Results are cached for 5 minutes.\r\n */\r\nexport async function resolveRoomId(uniqueId: string): Promise<string | null> {\r\n const info = await resolveLivePage(uniqueId);\r\n return info?.roomId ?? null;\r\n}\r\n\r\nexport interface SignedUrlResponse {\r\n status_code: number;\r\n action?: string;\r\n signed_url: string;\r\n headers: Record<string, string>;\r\n cookies: string;\r\n}\r\n\r\n/**\r\n * Execute a signed-URL API response: fetch the signed URL and return the\r\n * parsed JSON data from TikTok.\r\n */\r\nexport async function fetchSignedUrl(response: SignedUrlResponse): Promise<any> {\r\n if (!response.signed_url) {\r\n return null;\r\n }\r\n\r\n const headers: Record<string, string> = { ...(response.headers || {}) };\r\n if (response.cookies) {\r\n headers['Cookie'] = response.cookies;\r\n }\r\n\r\n const resp = await fetch(response.signed_url, { headers, redirect: 'follow' });\r\n const text = await resp.text();\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport interface CallApiOptions {\r\n /** API server URL (default: https://api.tik.tools) */\r\n serverUrl?: string;\r\n /** API key for authentication */\r\n apiKey: string;\r\n /** API endpoint path (e.g. '/webcast/room_video') */\r\n endpoint: string;\r\n /** TikTok unique_id to resolve */\r\n uniqueId: string;\r\n /** HTTP method (default: POST) */\r\n method?: 'GET' | 'POST';\r\n /** Additional body fields for POST requests */\r\n extraBody?: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Call a TikTool API endpoint, handling the full\r\n * resolve_required → room_id → signed_url → fetch flow automatically.\r\n *\r\n * Returns the actual TikTok data, or `null` if the user is not live.\r\n */\r\nexport async function callApi(opts: CallApiOptions): Promise<any> {\r\n const serverUrl = (opts.serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const isGet = opts.method === 'GET';\r\n const ak = encodeURIComponent(opts.apiKey);\r\n\r\n const url1 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&unique_id=${encodeURIComponent(opts.uniqueId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts1: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ unique_id: opts.uniqueId, ...opts.extraBody }),\r\n };\r\n\r\n const resp1 = await fetch(url1, fetchOpts1);\r\n const data1 = await resp1.json() as any;\r\n\r\n // If the response contains a signed URL to fetch (with or without explicit action),\r\n // follow through and fetch the actual TikTok data\r\n if (data1.signed_url || data1.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data1);\r\n }\r\n\r\n if (data1.status_code === 0 && data1.action !== 'resolve_required') {\r\n return data1;\r\n }\r\n\r\n if (data1.action === 'resolve_required') {\r\n const roomId = await resolveRoomId(opts.uniqueId);\r\n if (!roomId) return null;\r\n\r\n const url2 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&room_id=${encodeURIComponent(roomId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts2: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ room_id: roomId, ...opts.extraBody }),\r\n };\r\n\r\n const resp2 = await fetch(url2, fetchOpts2);\r\n const data2 = await resp2.json() as any;\r\n\r\n if (data2.signed_url || data2.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data2);\r\n }\r\n\r\n return data2;\r\n }\r\n\r\n return data1;\r\n}\r\n\r\n// ── CAPTCHA Solver API ──────────────────────────────────────────────\r\n\r\nimport type { PuzzleSolveResult, RotateSolveResult, ShapesSolveResult } from './types.js';\r\n\r\n/**\r\n * Solve a puzzle (slider) CAPTCHA using the TikTool solver.\r\n *\r\n * @param apiKey - API key for authentication\r\n * @param puzzleB64 - Base64-encoded background image (PNG/JPEG)\r\n * @param pieceB64 - Base64-encoded puzzle piece image (PNG/JPEG)\r\n * @param serverUrl - Custom server URL (default: https://api.tik.tools)\r\n * @returns Solve result with slide position and confidence\r\n */\r\nexport async function solvePuzzle(\r\n apiKey: string,\r\n puzzleB64: string,\r\n pieceB64: string,\r\n serverUrl?: string,\r\n): Promise<PuzzleSolveResult> {\r\n const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const resp = await fetch(`${base}/captcha/solve/puzzle?apiKey=${encodeURIComponent(apiKey)}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ puzzle: puzzleB64, piece: pieceB64 }),\r\n });\r\n const data = await resp.json() as any;\r\n if (data.status_code !== 0) {\r\n throw new Error(data.error || `Solver failed (status ${data.status_code})`);\r\n }\r\n return data.data as PuzzleSolveResult;\r\n}\r\n\r\n/**\r\n * Solve a rotate (whirl) CAPTCHA using the TikTool solver.\r\n *\r\n * @param apiKey - API key for authentication\r\n * @param outerB64 - Base64-encoded outer ring image (PNG/JPEG)\r\n * @param innerB64 - Base64-encoded inner rotated image (PNG/JPEG)\r\n * @param serverUrl - Custom server URL (default: https://api.tik.tools)\r\n * @returns Solve result with rotation angle and confidence\r\n */\r\nexport async function solveRotate(\r\n apiKey: string,\r\n outerB64: string,\r\n innerB64: string,\r\n serverUrl?: string,\r\n): Promise<RotateSolveResult> {\r\n const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const resp = await fetch(`${base}/captcha/solve/rotate?apiKey=${encodeURIComponent(apiKey)}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ outer: outerB64, inner: innerB64 }),\r\n });\r\n const data = await resp.json() as any;\r\n if (data.status_code !== 0) {\r\n throw new Error(data.error || `Solver failed (status ${data.status_code})`);\r\n }\r\n return data.data as RotateSolveResult;\r\n}\r\n\r\n/**\r\n * Solve a shapes (3D matching) CAPTCHA using the TikTool solver.\r\n *\r\n * @param apiKey - API key for authentication\r\n * @param imageB64 - Base64-encoded CAPTCHA image with shape grid (PNG/JPEG)\r\n * @param serverUrl - Custom server URL (default: https://api.tik.tools)\r\n * @returns Solve result with two matching shape coordinates and confidence\r\n */\r\nexport async function solveShapes(\r\n apiKey: string,\r\n imageB64: string,\r\n serverUrl?: string,\r\n): Promise<ShapesSolveResult> {\r\n const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const resp = await fetch(`${base}/captcha/solve/shapes?apiKey=${encodeURIComponent(apiKey)}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ image: imageB64 }),\r\n });\r\n const data = await resp.json() as any;\r\n if (data.status_code !== 0) {\r\n throw new Error(data.error || `Solver failed (status ${data.status_code})`);\r\n }\r\n return data.data as ShapesSolveResult;\r\n}\r\n","import type { TikTokLiveOptions, TikTokLiveEvents, RoomInfo, LiveEvent } from './types.js';\r\nimport {\r\n concatBytes,\r\n decodeProto,\r\n getStr,\r\n getBytes,\r\n buildHeartbeat,\r\n buildImEnterRoom,\r\n buildAck,\r\n parseWebcastResponse,\r\n} from './proto.js';\r\nimport { resolveLivePage } from './api.js';\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\ntype Listener = (...args: any[]) => void;\r\n\r\nclass TypedEmitter {\r\n private _listeners = new Map<string, Listener[]>();\r\n\r\n on(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event) || [];\r\n arr.push(fn);\r\n this._listeners.set(event, arr);\r\n return this;\r\n }\r\n\r\n once(event: string, fn: Listener): this {\r\n const wrapper: Listener = (...args) => {\r\n this.off(event, wrapper);\r\n fn(...args);\r\n };\r\n return this.on(event, wrapper);\r\n }\r\n\r\n off(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event);\r\n if (arr) {\r\n this._listeners.set(event, arr.filter(l => l !== fn));\r\n }\r\n return this;\r\n }\r\n\r\n emit(event: string, ...args: any[]): boolean {\r\n const arr = this._listeners.get(event);\r\n if (!arr || arr.length === 0) return false;\r\n for (const fn of [...arr]) fn(...args);\r\n return true;\r\n }\r\n\r\n removeAllListeners(event?: string): this {\r\n if (event) this._listeners.delete(event);\r\n else this._listeners.clear();\r\n return this;\r\n }\r\n}\r\n\r\nasync function gunzip(data: Uint8Array): Promise<Uint8Array> {\r\n if (typeof DecompressionStream !== 'undefined') {\r\n const ds = new DecompressionStream('gzip');\r\n const writer = ds.writable.getWriter();\r\n const reader = ds.readable.getReader();\r\n writer.write(data as any);\r\n writer.close();\r\n const chunks: Uint8Array[] = [];\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n chunks.push(value);\r\n }\r\n return concatBytes(...chunks);\r\n }\r\n try {\r\n const zlib = await import('zlib');\r\n return new Promise((resolve, reject) => {\r\n zlib.gunzip(data, (err: Error | null, result: Buffer) => {\r\n if (err) reject(err);\r\n else resolve(new Uint8Array(result));\r\n });\r\n });\r\n } catch {\r\n return data;\r\n }\r\n}\r\n\r\n// Pre-cache zlib for sync decompression (require fails in ESM)\r\nlet _zlib: any = null;\r\nlet _zlibLoadAttempted = false;\r\n\r\nasync function ensureZlib(): Promise<any> {\r\n if (_zlib) return _zlib;\r\n if (_zlibLoadAttempted) return null;\r\n _zlibLoadAttempted = true;\r\n try {\r\n _zlib = await import('zlib');\r\n } catch { }\r\n return _zlib;\r\n}\r\n\r\n// Attempt to load zlib eagerly at module init\r\nensureZlib();\r\n\r\nfunction gunzipSync(data: Uint8Array): Uint8Array | null {\r\n if (!_zlib) return null; // Signal that sync decompress is unavailable\r\n try {\r\n return new Uint8Array(_zlib.gunzipSync(data));\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\ntype WebSocketLike = {\r\n readonly readyState: number;\r\n send(data: ArrayBufferLike | string): void;\r\n close(code?: number, reason?: string): void;\r\n onopen: ((ev: any) => void) | null;\r\n onmessage: ((ev: any) => void) | null;\r\n onerror: ((ev: any) => void) | null;\r\n onclose: ((ev: any) => void) | null;\r\n};\r\n\r\ninterface WebSocketConstructor {\r\n new(url: string, protocols?: string | string[]): WebSocketLike;\r\n readonly OPEN: number;\r\n readonly CLOSED: number;\r\n}\r\n\r\nfunction getWsHost(clusterRegion: string): string {\r\n if (!clusterRegion) return 'webcast-ws.tiktok.com';\r\n const r = clusterRegion.toLowerCase();\r\n if (r.startsWith('eu') || r.includes('eu')) return 'webcast-ws.eu.tiktok.com';\r\n if (r.startsWith('us') || r.includes('us')) return 'webcast-ws.us.tiktok.com';\r\n return 'webcast-ws.tiktok.com';\r\n}\r\n\r\nasync function resolveWebSocket(userImpl?: any): Promise<WebSocketConstructor> {\r\n if (userImpl) return userImpl;\r\n\r\n if (typeof globalThis.WebSocket !== 'undefined') {\r\n return globalThis.WebSocket as unknown as WebSocketConstructor;\r\n }\r\n\r\n try {\r\n const ws = await import('ws');\r\n return (ws.default || ws) as unknown as WebSocketConstructor;\r\n } catch {\r\n throw new Error(\r\n 'No WebSocket implementation found. ' +\r\n 'Either use Node.js 22+ (native WebSocket), Cloudflare Workers, or install the \"ws\" package: npm i ws'\r\n );\r\n }\r\n}\r\n\r\nexport class TikTokLive extends TypedEmitter {\r\n private ws: WebSocketLike | null = null;\r\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n private reconnectAttempts = 0;\r\n private intentionalClose = false;\r\n private _connected = false;\r\n private _eventCount = 0;\r\n private _roomId = '';\r\n private _battleHosts = new Map<string, { id: string; nickname: string; uniqueId: string; profilePicture?: string }>();\r\n\r\n private readonly uniqueId: string;\r\n private readonly signServerUrl: string;\r\n private readonly apiKey: string;\r\n private readonly autoReconnect: boolean;\r\n private readonly maxReconnectAttempts: number;\r\n private readonly heartbeatInterval: number;\r\n private readonly debug: boolean;\r\n private readonly webSocketImpl?: any;\r\n private WS!: WebSocketConstructor;\r\n\r\n constructor(options: TikTokLiveOptions) {\r\n super();\r\n this.uniqueId = options.uniqueId.replace(/^@/, '');\r\n this.signServerUrl = (options.signServerUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n if (!options.apiKey) throw new Error('apiKey is required. Get a free key at https://tik.tools');\r\n this.apiKey = options.apiKey;\r\n this.autoReconnect = options.autoReconnect ?? true;\r\n this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\r\n this.heartbeatInterval = options.heartbeatInterval ?? 10_000;\r\n this.debug = options.debug ?? false;\r\n this.webSocketImpl = options.webSocketImpl;\r\n }\r\n\r\n async connect(): Promise<void> {\r\n this.intentionalClose = false;\r\n\r\n if (!this.WS) {\r\n this.WS = await resolveWebSocket(this.webSocketImpl);\r\n }\r\n\r\n const pageInfo = await resolveLivePage(this.uniqueId);\r\n if (!pageInfo) throw new Error(`User @${this.uniqueId} is not currently live`);\r\n if (!pageInfo.ttwid) throw new Error('Failed to obtain session cookie');\r\n\r\n const { roomId, ttwid, clusterRegion } = pageInfo;\r\n this._roomId = roomId;\r\n const wsHost = getWsHost(clusterRegion);\r\n\r\n const wsParams = new URLSearchParams({\r\n version_code: '270000', device_platform: 'web', cookie_enabled: 'true',\r\n screen_width: '1920', screen_height: '1080', browser_language: 'en-US',\r\n browser_platform: 'Win32', browser_name: 'Mozilla',\r\n browser_version: DEFAULT_UA.split('Mozilla/')[1] || '5.0',\r\n browser_online: 'true', tz_name: 'Etc/UTC',\r\n app_name: 'tiktok_web', sup_ws_ds_opt: '1', update_version_code: '2.0.0',\r\n compress: 'gzip', webcast_language: 'en', ws_direct: '1', aid: '1988',\r\n live_id: '12', app_language: 'en', client_enter: '1', room_id: roomId,\r\n identity: 'audience', history_comment_count: '6', last_rtt: '0',\r\n heartbeat_duration: '10000', resp_content_type: 'protobuf', did_rule: '3',\r\n });\r\n\r\n const rawWsUrl = `https://${wsHost}/webcast/im/ws_proxy/ws_reuse_supplement/?${wsParams}`;\r\n const signUrl = `${this.signServerUrl}/webcast/sign_url`;\r\n\r\n let wsUrl: string;\r\n try {\r\n const signResp = await fetch(signUrl, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n },\r\n body: JSON.stringify({ url: rawWsUrl }),\r\n });\r\n const signData = await signResp.json() as Record<string, any>;\r\n\r\n if (signData.status_code === 0 && signData.data?.signed_url) {\r\n wsUrl = (signData.data.signed_url as string).replace(/^https:\\/\\//, 'wss://');\r\n } else {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n } catch {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const connUrl = wsUrl + (wsUrl.includes('?') ? '&' : '?') + `ttwid=${ttwid}`;\r\n\r\n try {\r\n this.ws = new (this.WS as any)(connUrl, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Cookie': `ttwid=${ttwid}`,\r\n 'Origin': 'https://www.tiktok.com',\r\n },\r\n }) as WebSocketLike;\r\n } catch {\r\n this.ws = new this.WS(connUrl) as WebSocketLike;\r\n }\r\n\r\n const ws = this.ws;\r\n let settled = false;\r\n\r\n ws.onopen = () => {\r\n this._connected = true;\r\n this.reconnectAttempts = 0;\r\n\r\n const hb = buildHeartbeat(roomId);\r\n const enter = buildImEnterRoom(roomId);\r\n ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n ws.send(enter.buffer.byteLength === enter.length ? enter.buffer : enter.buffer.slice(enter.byteOffset, enter.byteOffset + enter.byteLength));\r\n this.startHeartbeat(roomId);\r\n\r\n const roomInfo: RoomInfo = {\r\n roomId,\r\n wsHost,\r\n clusterRegion,\r\n connectedAt: new Date().toISOString(),\r\n };\r\n\r\n (this as TypedEmitter).emit('connected');\r\n (this as TypedEmitter).emit('roomInfo', roomInfo);\r\n if (!settled) { settled = true; resolve(); }\r\n };\r\n\r\n ws.onmessage = (event: any) => {\r\n const raw = event.data !== undefined ? event.data : event;\r\n this.handleMessage(raw);\r\n };\r\n\r\n ws.onclose = (event: any) => {\r\n this._connected = false;\r\n this.stopHeartbeat();\r\n\r\n const code = event?.code ?? 1006;\r\n const reason = event?.reason ?? '';\r\n (this as TypedEmitter).emit('disconnected', code, reason?.toString?.() || '');\r\n\r\n if (!this.intentionalClose && this.autoReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {\r\n this.reconnectAttempts++;\r\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30_000);\r\n setTimeout(() => this.connect().catch(e => (this as TypedEmitter).emit('error', e)), delay);\r\n }\r\n };\r\n\r\n ws.onerror = (err: any) => {\r\n (this as TypedEmitter).emit('error', err instanceof Error ? err : new Error(String(err?.message || err)));\r\n if (!settled) { settled = true; reject(err); }\r\n };\r\n\r\n setTimeout(() => {\r\n if (!settled) {\r\n settled = true;\r\n ws.close();\r\n reject(new Error('Connection timeout'));\r\n }\r\n }, 15_000);\r\n });\r\n }\r\n\r\n disconnect(): void {\r\n this.intentionalClose = true;\r\n this.stopHeartbeat();\r\n if (this.ws) {\r\n this.ws.close(1000);\r\n this.ws = null;\r\n }\r\n this._connected = false;\r\n }\r\n\r\n get connected(): boolean {\r\n return this._connected;\r\n }\r\n\r\n get eventCount(): number {\r\n return this._eventCount;\r\n }\r\n\r\n get roomId(): string {\r\n return this._roomId;\r\n }\r\n\r\n override on<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.on(event as string, listener as Listener);\r\n }\r\n\r\n override once<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.once(event as string, listener as Listener);\r\n }\r\n\r\n override off<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.off(event as string, listener as Listener);\r\n }\r\n\r\n override emit<K extends keyof TikTokLiveEvents>(event: K, ...args: Parameters<TikTokLiveEvents[K]>): boolean {\r\n return super.emit(event as string, ...args);\r\n }\r\n\r\n private async handleMessage(raw: any): Promise<void> {\r\n try {\r\n let bytes: Uint8Array;\r\n\r\n if (raw instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw);\r\n } else if (raw instanceof Uint8Array) {\r\n bytes = raw;\r\n } else if (typeof Blob !== 'undefined' && raw instanceof Blob) {\r\n bytes = new Uint8Array(await raw.arrayBuffer());\r\n } else if (raw?.buffer instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);\r\n } else {\r\n return;\r\n }\r\n\r\n this.handleFrame(bytes);\r\n } catch { }\r\n }\r\n\r\n private async handleFrame(buf: Uint8Array): Promise<void> {\r\n try {\r\n const fields = decodeProto(buf);\r\n const idField = fields.find(f => f.fn === 2 && f.wt === 0);\r\n const id = idField ? idField.value as bigint : 0n;\r\n const type = getStr(fields, 7);\r\n const binary = getBytes(fields, 8);\r\n\r\n if (id > 0n && this.ws && (this.ws.readyState === 1)) {\r\n const ack = buildAck(id);\r\n this.ws.send(ack.buffer.byteLength === ack.length ? ack.buffer : ack.buffer.slice(ack.byteOffset, ack.byteOffset + ack.byteLength));\r\n }\r\n\r\n if (type === 'msg' && binary && binary.length > 0) {\r\n let inner = binary;\r\n if (inner.length > 2 && inner[0] === 0x1f && inner[1] === 0x8b) {\r\n // Try sync first (fastest, works when zlib is loaded)\r\n const syncResult = gunzipSync(inner);\r\n if (syncResult) {\r\n inner = syncResult;\r\n } else {\r\n // Fallback to async gunzip (uses DecompressionStream or async import)\r\n inner = await gunzip(inner);\r\n }\r\n }\r\n\r\n const events = parseWebcastResponse(inner);\r\n for (const evt of events) {\r\n this._eventCount++;\r\n\r\n if (evt.type === 'battle') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n team.hostUser = host.user;\r\n }\r\n }\r\n }\r\n\r\n if (evt.type === 'battleArmies') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n team.hostUser = host.user;\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n } else {\r\n const cached = this._battleHosts.get(team.hostUserId);\r\n if (cached) team.hostUser = cached;\r\n }\r\n }\r\n }\r\n\r\n (this as TypedEmitter).emit('event', evt);\r\n (this as TypedEmitter).emit(evt.type, evt as any);\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n private startHeartbeat(roomId: string): void {\r\n this.stopHeartbeat();\r\n this.heartbeatTimer = setInterval(() => {\r\n if (this.ws && this.ws.readyState === 1) {\r\n const hb = buildHeartbeat(roomId);\r\n this.ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n }\r\n }, this.heartbeatInterval);\r\n }\r\n\r\n private stopHeartbeat(): void {\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n this.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["DEFAULT_UA","DEFAULT_SIGN_SERVER"]}
package/dist/index.mjs CHANGED
@@ -1,10 +1,3 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
1
  // src/proto.ts
9
2
  var encoder = new TextEncoder();
10
3
  var decoder = new TextDecoder();
@@ -597,6 +590,45 @@ async function callApi(opts) {
597
590
  }
598
591
  return data1;
599
592
  }
593
+ async function solvePuzzle(apiKey, puzzleB64, pieceB64, serverUrl) {
594
+ const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\/$/, "");
595
+ const resp = await fetch(`${base}/captcha/solve/puzzle?apiKey=${encodeURIComponent(apiKey)}`, {
596
+ method: "POST",
597
+ headers: { "Content-Type": "application/json" },
598
+ body: JSON.stringify({ puzzle: puzzleB64, piece: pieceB64 })
599
+ });
600
+ const data = await resp.json();
601
+ if (data.status_code !== 0) {
602
+ throw new Error(data.error || `Solver failed (status ${data.status_code})`);
603
+ }
604
+ return data.data;
605
+ }
606
+ async function solveRotate(apiKey, outerB64, innerB64, serverUrl) {
607
+ const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\/$/, "");
608
+ const resp = await fetch(`${base}/captcha/solve/rotate?apiKey=${encodeURIComponent(apiKey)}`, {
609
+ method: "POST",
610
+ headers: { "Content-Type": "application/json" },
611
+ body: JSON.stringify({ outer: outerB64, inner: innerB64 })
612
+ });
613
+ const data = await resp.json();
614
+ if (data.status_code !== 0) {
615
+ throw new Error(data.error || `Solver failed (status ${data.status_code})`);
616
+ }
617
+ return data.data;
618
+ }
619
+ async function solveShapes(apiKey, imageB64, serverUrl) {
620
+ const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\/$/, "");
621
+ const resp = await fetch(`${base}/captcha/solve/shapes?apiKey=${encodeURIComponent(apiKey)}`, {
622
+ method: "POST",
623
+ headers: { "Content-Type": "application/json" },
624
+ body: JSON.stringify({ image: imageB64 })
625
+ });
626
+ const data = await resp.json();
627
+ if (data.status_code !== 0) {
628
+ throw new Error(data.error || `Solver failed (status ${data.status_code})`);
629
+ }
630
+ return data.data;
631
+ }
600
632
 
601
633
  // src/client.ts
602
634
  var DEFAULT_UA2 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
@@ -635,14 +667,54 @@ var TypedEmitter = class {
635
667
  return this;
636
668
  }
637
669
  };
638
- function gunzipSync(data) {
670
+ async function gunzip(data) {
671
+ if (typeof DecompressionStream !== "undefined") {
672
+ const ds = new DecompressionStream("gzip");
673
+ const writer = ds.writable.getWriter();
674
+ const reader = ds.readable.getReader();
675
+ writer.write(data);
676
+ writer.close();
677
+ const chunks = [];
678
+ while (true) {
679
+ const { done, value } = await reader.read();
680
+ if (done) break;
681
+ chunks.push(value);
682
+ }
683
+ return concatBytes(...chunks);
684
+ }
639
685
  try {
640
- const zlib = __require("zlib");
641
- return new Uint8Array(zlib.gunzipSync(data));
686
+ const zlib = await import("zlib");
687
+ return new Promise((resolve, reject) => {
688
+ zlib.gunzip(data, (err, result) => {
689
+ if (err) reject(err);
690
+ else resolve(new Uint8Array(result));
691
+ });
692
+ });
642
693
  } catch {
643
694
  return data;
644
695
  }
645
696
  }
697
+ var _zlib = null;
698
+ var _zlibLoadAttempted = false;
699
+ async function ensureZlib() {
700
+ if (_zlib) return _zlib;
701
+ if (_zlibLoadAttempted) return null;
702
+ _zlibLoadAttempted = true;
703
+ try {
704
+ _zlib = await import("zlib");
705
+ } catch {
706
+ }
707
+ return _zlib;
708
+ }
709
+ ensureZlib();
710
+ function gunzipSync(data) {
711
+ if (!_zlib) return null;
712
+ try {
713
+ return new Uint8Array(_zlib.gunzipSync(data));
714
+ } catch {
715
+ return null;
716
+ }
717
+ }
646
718
  function getWsHost(clusterRegion) {
647
719
  if (!clusterRegion) return "webcast-ws.tiktok.com";
648
720
  const r = clusterRegion.toLowerCase();
@@ -872,7 +944,7 @@ var TikTokLive = class extends TypedEmitter {
872
944
  } catch {
873
945
  }
874
946
  }
875
- handleFrame(buf) {
947
+ async handleFrame(buf) {
876
948
  try {
877
949
  const fields = decodeProto(buf);
878
950
  const idField = fields.find((f) => f.fn === 2 && f.wt === 0);
@@ -886,9 +958,11 @@ var TikTokLive = class extends TypedEmitter {
886
958
  if (type === "msg" && binary && binary.length > 0) {
887
959
  let inner = binary;
888
960
  if (inner.length > 2 && inner[0] === 31 && inner[1] === 139) {
889
- try {
890
- inner = gunzipSync(inner);
891
- } catch {
961
+ const syncResult = gunzipSync(inner);
962
+ if (syncResult) {
963
+ inner = syncResult;
964
+ } else {
965
+ inner = await gunzip(inner);
892
966
  }
893
967
  }
894
968
  const events = parseWebcastResponse(inner);
@@ -943,6 +1017,9 @@ export {
943
1017
  callApi,
944
1018
  fetchSignedUrl,
945
1019
  resolveLivePage,
946
- resolveRoomId
1020
+ resolveRoomId,
1021
+ solvePuzzle,
1022
+ solveRotate,
1023
+ solveShapes
947
1024
  };
948
1025
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/proto.ts","../src/api.ts","../src/client.ts"],"sourcesContent":["import type { LiveEvent, TikTokUser, BattleTeam, BattleTeamUser } from './types.js';\r\n\r\nconst encoder = new TextEncoder();\r\nconst decoder = new TextDecoder();\r\n\r\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\r\n let totalLength = 0;\r\n for (const arr of arrays) totalLength += arr.length;\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const arr of arrays) {\r\n result.set(arr, offset);\r\n offset += arr.length;\r\n }\r\n return result;\r\n}\r\n\r\nfunction readInt32LE(buf: Uint8Array, offset: number): number {\r\n return buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n (buf[offset + 3] << 24);\r\n}\r\n\r\nfunction readBigInt64LE(buf: Uint8Array, offset: number): bigint {\r\n const lo = BigInt(buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n ((buf[offset + 3] << 24) >>> 0));\r\n const hi = BigInt(buf[offset + 4] |\r\n (buf[offset + 5] << 8) |\r\n (buf[offset + 6] << 16) |\r\n ((buf[offset + 7] << 24) >>> 0));\r\n return (hi << 32n) | (lo & 0xFFFFFFFFn);\r\n}\r\n\r\nexport function decodeVarint(buf: Uint8Array, offset: number): { value: number; offset: number } {\r\n let result = 0, shift = 0;\r\n while (offset < buf.length) {\r\n const byte = buf[offset++];\r\n result |= (byte & 0x7F) << shift;\r\n if ((byte & 0x80) === 0) break;\r\n shift += 7;\r\n }\r\n return { value: result >>> 0, offset };\r\n}\r\n\r\nexport function decodeVarint64(buf: Uint8Array, offset: number): { value: bigint; offset: number } {\r\n let result = 0n, shift = 0n;\r\n while (offset < buf.length) {\r\n const byte = BigInt(buf[offset++]);\r\n result |= (byte & 0x7Fn) << shift;\r\n if ((byte & 0x80n) === 0n) break;\r\n shift += 7n;\r\n }\r\n return { value: result, offset };\r\n}\r\n\r\nexport function encodeVarint(v: number | bigint): Uint8Array {\r\n const bytes: number[] = [];\r\n let n = typeof v === 'bigint' ? v : BigInt(v);\r\n do {\r\n let b = Number(n & 0x7Fn);\r\n n >>= 7n;\r\n if (n > 0n) b |= 0x80;\r\n bytes.push(b);\r\n } while (n > 0n);\r\n return new Uint8Array(bytes);\r\n}\r\n\r\nexport interface ProtoField {\r\n fn: number;\r\n wt: number;\r\n value: Uint8Array | number | bigint;\r\n}\r\n\r\nexport function encodeField(fn: number, wt: number, value: Uint8Array | bigint | number | string): Uint8Array {\r\n const tag = encodeVarint((fn << 3) | wt);\r\n if (wt === 0) {\r\n return concatBytes(tag, encodeVarint(typeof value === 'number' ? BigInt(value) : value as bigint));\r\n }\r\n const data = typeof value === 'string' ? encoder.encode(value) : value as Uint8Array;\r\n return concatBytes(tag, encodeVarint(data.length), data);\r\n}\r\n\r\nexport function decodeProto(buf: Uint8Array): ProtoField[] {\r\n const fields: ProtoField[] = [];\r\n let offset = 0;\r\n while (offset < buf.length) {\r\n const tagResult = decodeVarint(buf, offset);\r\n offset = tagResult.offset;\r\n const fn = tagResult.value >> 3;\r\n const wt = tagResult.value & 7;\r\n if (wt === 0) {\r\n const r = decodeVarint64(buf, offset);\r\n offset = r.offset;\r\n fields.push({ fn, wt, value: r.value });\r\n } else if (wt === 2) {\r\n const lenR = decodeVarint(buf, offset);\r\n offset = lenR.offset;\r\n const data = buf.subarray(offset, offset + lenR.value);\r\n offset += lenR.value;\r\n fields.push({ fn, wt, value: data });\r\n } else if (wt === 1) {\r\n fields.push({ fn, wt, value: readBigInt64LE(buf, offset) });\r\n offset += 8;\r\n } else if (wt === 5) {\r\n fields.push({ fn, wt, value: BigInt(readInt32LE(buf, offset)) });\r\n offset += 4;\r\n } else {\r\n break;\r\n }\r\n }\r\n return fields;\r\n}\r\n\r\nexport function getStr(fields: ProtoField[], fn: number): string {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? decoder.decode(f.value as Uint8Array) : '';\r\n}\r\n\r\nexport function getBytes(fields: ProtoField[], fn: number): Uint8Array | null {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? f.value as Uint8Array : null;\r\n}\r\n\r\nexport function getInt(fields: ProtoField[], fn: number): number {\r\n const f = fields.find(x => x.fn === fn && x.wt === 0);\r\n return f ? Number(f.value) : 0;\r\n}\r\n\r\nexport function getAllBytes(fields: ProtoField[], fn: number): Uint8Array[] {\r\n return fields.filter(x => x.fn === fn && x.wt === 2).map(x => x.value as Uint8Array);\r\n}\r\n\r\nexport function buildHeartbeat(roomId: string): Uint8Array {\r\n const payload = encodeField(1, 0, BigInt(roomId));\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'hb'),\r\n encodeField(8, 2, payload),\r\n );\r\n}\r\n\r\nexport function buildImEnterRoom(roomId: string): Uint8Array {\r\n const inner = concatBytes(\r\n encodeField(1, 0, BigInt(roomId)),\r\n encodeField(4, 0, 12n),\r\n encodeField(5, 2, 'audience'),\r\n encodeField(6, 2, ''),\r\n encodeField(9, 2, ''),\r\n encodeField(10, 2, ''),\r\n );\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'im_enter_room'),\r\n encodeField(8, 2, inner),\r\n );\r\n}\r\n\r\nexport function buildAck(id: bigint): Uint8Array {\r\n return concatBytes(\r\n encodeField(2, 0, id),\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'ack'),\r\n );\r\n}\r\n\r\nfunction parseUser(data: Uint8Array): TikTokUser {\r\n const f = decodeProto(data);\r\n const id = String(getInt(f, 1) || getStr(f, 1));\r\n const nickname = getStr(f, 3) || getStr(f, 2);\r\n const uniqueId = getStr(f, 38) || getStr(f, 4) || getStr(f, 2) || '';\r\n\r\n let profilePicture: string | undefined;\r\n const avatarBuf = getBytes(f, 9) || getBytes(f, 3);\r\n if (avatarBuf) {\r\n try {\r\n const avatarFields = decodeProto(avatarBuf);\r\n const urlBufs = getAllBytes(avatarFields, 1);\r\n if (urlBufs.length > 0) profilePicture = decoder.decode(urlBufs[0]);\r\n } catch { }\r\n }\r\n\r\n const badges: string[] = [];\r\n const badgeBuf = getBytes(f, 64);\r\n if (badgeBuf) {\r\n try {\r\n const badgeFields = decodeProto(badgeBuf);\r\n const badgeItems = getAllBytes(badgeFields, 21);\r\n for (const bi of badgeItems) {\r\n const bf = decodeProto(bi);\r\n const name = getStr(bf, 3) || getStr(bf, 2);\r\n if (name) badges.push(name);\r\n }\r\n } catch { }\r\n }\r\n\r\n return {\r\n id,\r\n nickname,\r\n uniqueId: uniqueId || nickname || id,\r\n profilePictureUrl: profilePicture,\r\n badges: badges.length > 0 ? badges : undefined,\r\n };\r\n}\r\n\r\nfunction parseBattleTeamFromArmies(itemBuf: Uint8Array): BattleTeam {\r\n const f = decodeProto(itemBuf);\r\n const hostUserId = String(getInt(f, 1));\r\n let teamScore = 0;\r\n const users: BattleTeamUser[] = [];\r\n\r\n const groups = getAllBytes(f, 2);\r\n for (const gb of groups) {\r\n try {\r\n const gf = decodeProto(gb);\r\n const points = getInt(gf, 2);\r\n teamScore += points;\r\n\r\n const userBufs = getAllBytes(gf, 1);\r\n for (const ub of userBufs) {\r\n try {\r\n const user = parseUser(ub);\r\n users.push({ user, score: points });\r\n } catch { }\r\n }\r\n } catch { }\r\n }\r\n\r\n return { hostUserId, score: teamScore, users };\r\n}\r\n\r\nexport function parseWebcastMessage(method: string, payload: Uint8Array): LiveEvent {\r\n const f = decodeProto(payload);\r\n const base = { timestamp: Date.now(), msgId: '' };\r\n\r\n const typeBuf = getBytes(f, 1);\r\n if (typeBuf) {\r\n try {\r\n const tf = decodeProto(typeBuf);\r\n const ts = getInt(tf, 4);\r\n if (ts) base.timestamp = ts;\r\n } catch { }\r\n }\r\n\r\n switch (method) {\r\n case 'WebcastChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'chat' as const, user, comment: getStr(f, 3) };\r\n }\r\n\r\n case 'WebcastMemberMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 1;\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('followed')) action = 2;\r\n else if (label.includes('share')) action = 3;\r\n }\r\n }\r\n return { ...base, type: 'member' as const, user, action };\r\n }\r\n\r\n case 'WebcastLikeMessage': {\r\n const userBuf = getBytes(f, 5);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return {\r\n ...base, type: 'like' as const, user,\r\n likeCount: getInt(f, 2),\r\n totalLikes: getInt(f, 3),\r\n };\r\n }\r\n\r\n case 'WebcastGiftMessage': {\r\n const userBuf = getBytes(f, 7);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n const giftId = getInt(f, 2);\r\n const repeatCount = getInt(f, 5);\r\n const repeatEnd = getInt(f, 9) === 1;\r\n\r\n let giftName = '', diamondCount = 0, giftType = 0;\r\n let giftImageUrl = '';\r\n const detailsBuf = getBytes(f, 15);\r\n if (detailsBuf) {\r\n const df = decodeProto(detailsBuf);\r\n giftName = getStr(df, 16) || getStr(df, 2);\r\n diamondCount = getInt(df, 12);\r\n giftType = getInt(df, 11);\r\n\r\n const imgBuf = getBytes(df, 1);\r\n if (imgBuf) {\r\n const imgf = decodeProto(imgBuf);\r\n giftImageUrl = getStr(imgf, 1);\r\n }\r\n }\r\n\r\n let toUserId = '';\r\n const extraBuf = getBytes(f, 23);\r\n if (extraBuf) {\r\n const ef = decodeProto(extraBuf);\r\n toUserId = String(getInt(ef, 8));\r\n }\r\n\r\n const groupId = toUserId || getStr(f, 11);\r\n\r\n return {\r\n ...base, type: 'gift' as const, user, giftId, giftName, diamondCount,\r\n repeatCount, repeatEnd, combo: repeatCount > 1 && !repeatEnd,\r\n giftType, groupId, giftPictureUrl: giftImageUrl,\r\n };\r\n }\r\n\r\n case 'WebcastSocialMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 'follow';\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('share')) action = 'share';\r\n else if (label.includes('follow')) action = 'follow';\r\n const displayType = getStr(df, 1);\r\n if (displayType === 'pm_mt_msg_viewer_share') action = 'share';\r\n }\r\n }\r\n return { ...base, type: 'social' as const, user, action };\r\n }\r\n\r\n case 'WebcastRoomUserSeqMessage': {\r\n const viewerCount = getInt(f, 3) || getInt(f, 2);\r\n const totalViewers = getInt(f, 1) || viewerCount;\r\n return { ...base, type: 'roomUserSeq' as const, totalViewers, viewerCount };\r\n }\r\n\r\n case 'WebcastLinkMicBattle': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const status = getInt(f, 2) || 1;\r\n const battleDuration = getInt(f, 3);\r\n const teams: BattleTeam[] = [];\r\n\r\n const battleUserBufs = getAllBytes(f, 10);\r\n for (const bub of battleUserBufs) {\r\n try {\r\n const bf = decodeProto(bub);\r\n const groupBuf = getBytes(bf, 2);\r\n if (groupBuf) {\r\n const gf = decodeProto(groupBuf);\r\n const linkUserBuf = getBytes(gf, 1);\r\n if (linkUserBuf) {\r\n const user = parseUser(linkUserBuf);\r\n teams.push({\r\n hostUserId: user.id,\r\n score: 0,\r\n users: [{ user, score: 0 }],\r\n });\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n if (teams.length === 0) {\r\n const teamBufs7 = getAllBytes(f, 7);\r\n for (const tb of teamBufs7) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(tb));\r\n } catch { }\r\n }\r\n }\r\n\r\n return { ...base, type: 'battle' as const, battleId, status, battleDuration, teams };\r\n }\r\n\r\n case 'WebcastLinkMicArmies': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const battleStatus = getInt(f, 7);\r\n const teams: BattleTeam[] = [];\r\n\r\n const itemBufs = getAllBytes(f, 3);\r\n for (const ib of itemBufs) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(ib));\r\n } catch { }\r\n }\r\n\r\n return {\r\n ...base, type: 'battleArmies' as const, battleId, teams,\r\n status: battleStatus,\r\n };\r\n }\r\n\r\n case 'WebcastSubNotifyMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'subscribe' as const, user, subMonth: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastEmoteChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let emoteId = '', emoteUrl = '';\r\n const emoteBuf = getBytes(f, 3);\r\n if (emoteBuf) {\r\n const ef = decodeProto(emoteBuf);\r\n emoteId = getStr(ef, 1);\r\n const imageBuf = getBytes(ef, 2);\r\n if (imageBuf) {\r\n const imgFields = decodeProto(imageBuf);\r\n emoteUrl = getStr(imgFields, 1);\r\n }\r\n }\r\n return { ...base, type: 'emoteChat' as const, user, emoteId, emoteUrl };\r\n }\r\n\r\n case 'WebcastEnvelopeMessage': {\r\n const envelopeId = String(getInt(f, 1) || getStr(f, 1));\r\n return { ...base, type: 'envelope' as const, envelopeId, diamondCount: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastQuestionNewMessage': {\r\n let questionText = '', user: TikTokUser = { id: '0', nickname: '', uniqueId: '' };\r\n const detailBuf = getBytes(f, 2);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n questionText = getStr(df, 2);\r\n const userBuf = getBytes(df, 5);\r\n if (userBuf) user = parseUser(userBuf);\r\n }\r\n return { ...base, type: 'question' as const, user, questionText };\r\n }\r\n\r\n case 'WebcastRankUpdateMessage':\r\n case 'WebcastHourlyRankMessage': {\r\n const rankType = getStr(f, 1) || `rank_${getInt(f, 1)}`;\r\n const rankList: Array<{ user: TikTokUser; rank: number; score: number }> = [];\r\n const listBufs = getAllBytes(f, 2);\r\n for (const lb of listBufs) {\r\n try {\r\n const rf = decodeProto(lb);\r\n const userBuf = getBytes(rf, 1);\r\n const rank = getInt(rf, 2);\r\n const score = getInt(rf, 3);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n rankList.push({ user, rank, score });\r\n } catch { }\r\n }\r\n return { ...base, type: 'rankUpdate' as const, rankType, rankList };\r\n }\r\n\r\n case 'WebcastControlMessage':\r\n return { ...base, type: 'control' as const, action: getInt(f, 2) || getInt(f, 1) };\r\n\r\n case 'WebcastRoomMessage':\r\n case 'RoomMessage':\r\n return { ...base, type: 'room' as const, status: getInt(f, 2) };\r\n\r\n case 'WebcastLiveIntroMessage': {\r\n const roomId = String(getInt(f, 2));\r\n const title = getStr(f, 4) || getStr(f, 2);\r\n return { ...base, type: 'liveIntro' as const, roomId, title };\r\n }\r\n\r\n case 'WebcastLinkMicMethod':\r\n case 'WebcastLinkmicBattleTaskMessage': {\r\n const action = getStr(f, 1) || `action_${getInt(f, 1)}`;\r\n const users: TikTokUser[] = [];\r\n const userBufs = getAllBytes(f, 2);\r\n for (const ub of userBufs) {\r\n try { users.push(parseUser(ub)); } catch { }\r\n }\r\n return { ...base, type: 'linkMic' as const, action, users };\r\n }\r\n\r\n default:\r\n return { ...base, type: 'unknown' as const, method };\r\n }\r\n}\r\n\r\nexport function parseWebcastResponse(payload: Uint8Array): LiveEvent[] {\r\n const events: LiveEvent[] = [];\r\n const respFields = decodeProto(payload);\r\n\r\n for (const mf of respFields.filter(f => f.fn === 1 && f.wt === 2)) {\r\n const msgBuf = mf.value as Uint8Array;\r\n const msgFields = decodeProto(msgBuf);\r\n const method = getStr(msgFields, 1);\r\n const innerPayload = getBytes(msgFields, 2);\r\n if (!method || !innerPayload) continue;\r\n\r\n try {\r\n events.push(parseWebcastMessage(method, innerPayload));\r\n } catch { }\r\n }\r\n\r\n return events;\r\n}\r\n","/**\r\n * TikTool API utilities for the sign-and-return API flow.\r\n *\r\n * The API server returns signed URLs instead of fetching TikTok data directly.\r\n * These utilities handle the two-step flow:\r\n * 1. resolve_required — scrape TikTok HTML to get room_id\r\n * 2. fetch_signed_url — use the signed URL to get actual TikTok data\r\n *\r\n * @module\r\n */\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\nconst pageCache = new Map<string, { info: LivePageInfo; ts: number }>();\r\nconst PAGE_CACHE_TTL = 5 * 60 * 1000;\r\n\r\n/**\r\n * Resolved live page metadata from a TikTok live page.\r\n */\r\nexport interface LivePageInfo {\r\n /** Active room ID for the livestream */\r\n roomId: string;\r\n /** Session cookie required for WebSocket authentication */\r\n ttwid: string;\r\n /** Server cluster region (e.g. 'us', 'eu') */\r\n clusterRegion: string;\r\n}\r\n\r\n/**\r\n * Scrape a TikTok live page to extract room metadata.\r\n * Returns the room ID, session cookie, and cluster region.\r\n * Results are cached for 5 minutes. Returns `null` if the user is not live.\r\n */\r\nexport async function resolveLivePage(uniqueId: string): Promise<LivePageInfo | null> {\r\n const clean = uniqueId.replace(/^@/, '');\r\n const cached = pageCache.get(clean);\r\n if (cached && Date.now() - cached.ts < PAGE_CACHE_TTL) {\r\n return cached.info;\r\n }\r\n\r\n try {\r\n const resp = await fetch(`https://www.tiktok.com/@${clean}/live`, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\r\n 'Accept-Language': 'en-US,en;q=0.9',\r\n },\r\n redirect: 'follow',\r\n });\r\n\r\n if (!resp.ok) return null;\r\n\r\n // Extract ttwid session cookie\r\n let ttwid = '';\r\n const setCookies = resp.headers.get('set-cookie') || '';\r\n for (const part of setCookies.split(',')) {\r\n const trimmed = part.trim();\r\n if (trimmed.startsWith('ttwid=')) {\r\n ttwid = trimmed.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n if (!ttwid && typeof (resp.headers as any).getSetCookie === 'function') {\r\n for (const sc of (resp.headers as any).getSetCookie()) {\r\n if (typeof sc === 'string' && sc.startsWith('ttwid=')) {\r\n ttwid = sc.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n }\r\n\r\n const html = await resp.text();\r\n\r\n // Extract roomId from SIGI_STATE JSON block\r\n let roomId = '';\r\n const sigiMatch = html.match(/id=\"SIGI_STATE\"[^>]*>([^<]+)/);\r\n if (sigiMatch) {\r\n try {\r\n const json = JSON.parse(sigiMatch[1]);\r\n const jsonStr = JSON.stringify(json);\r\n const m = jsonStr.match(/\"roomId\"\\s*:\\s*\"(\\d+)\"/);\r\n if (m) roomId = m[1];\r\n } catch { }\r\n }\r\n\r\n // Fallback patterns\r\n if (!roomId) {\r\n const patterns = [\r\n /\"roomId\"\\s*:\\s*\"(\\d+)\"/,\r\n /room_id[=/](\\d{10,})/,\r\n /\"idStr\"\\s*:\\s*\"(\\d{10,})\"/,\r\n ];\r\n for (const p of patterns) {\r\n const m = html.match(p);\r\n if (m) { roomId = m[1]; break; }\r\n }\r\n }\r\n\r\n if (!roomId) return null;\r\n\r\n // Extract cluster region\r\n const crMatch = html.match(/\"clusterRegion\"\\s*:\\s*\"([^\"]+)\"/);\r\n const clusterRegion = crMatch ? crMatch[1] : '';\r\n\r\n const info: LivePageInfo = { roomId, ttwid, clusterRegion };\r\n pageCache.set(clean, { info, ts: Date.now() });\r\n return info;\r\n } catch { }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Resolve a TikTok username to a room ID.\r\n * Returns `null` if the user is not currently live.\r\n * Results are cached for 5 minutes.\r\n */\r\nexport async function resolveRoomId(uniqueId: string): Promise<string | null> {\r\n const info = await resolveLivePage(uniqueId);\r\n return info?.roomId ?? null;\r\n}\r\n\r\nexport interface SignedUrlResponse {\r\n status_code: number;\r\n action?: string;\r\n signed_url: string;\r\n headers: Record<string, string>;\r\n cookies: string;\r\n}\r\n\r\n/**\r\n * Execute a signed-URL API response: fetch the signed URL and return the\r\n * parsed JSON data from TikTok.\r\n */\r\nexport async function fetchSignedUrl(response: SignedUrlResponse): Promise<any> {\r\n if (!response.signed_url) {\r\n return null;\r\n }\r\n\r\n const headers: Record<string, string> = { ...(response.headers || {}) };\r\n if (response.cookies) {\r\n headers['Cookie'] = response.cookies;\r\n }\r\n\r\n const resp = await fetch(response.signed_url, { headers, redirect: 'follow' });\r\n const text = await resp.text();\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport interface CallApiOptions {\r\n /** API server URL (default: https://api.tik.tools) */\r\n serverUrl?: string;\r\n /** API key for authentication */\r\n apiKey: string;\r\n /** API endpoint path (e.g. '/webcast/room_video') */\r\n endpoint: string;\r\n /** TikTok unique_id to resolve */\r\n uniqueId: string;\r\n /** HTTP method (default: POST) */\r\n method?: 'GET' | 'POST';\r\n /** Additional body fields for POST requests */\r\n extraBody?: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Call a TikTool API endpoint, handling the full\r\n * resolve_required → room_id → signed_url → fetch flow automatically.\r\n *\r\n * Returns the actual TikTok data, or `null` if the user is not live.\r\n */\r\nexport async function callApi(opts: CallApiOptions): Promise<any> {\r\n const serverUrl = (opts.serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const isGet = opts.method === 'GET';\r\n const ak = encodeURIComponent(opts.apiKey);\r\n\r\n const url1 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&unique_id=${encodeURIComponent(opts.uniqueId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts1: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ unique_id: opts.uniqueId, ...opts.extraBody }),\r\n };\r\n\r\n const resp1 = await fetch(url1, fetchOpts1);\r\n const data1 = await resp1.json() as any;\r\n\r\n // If the response contains a signed URL to fetch (with or without explicit action),\r\n // follow through and fetch the actual TikTok data\r\n if (data1.signed_url || data1.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data1);\r\n }\r\n\r\n if (data1.status_code === 0 && data1.action !== 'resolve_required') {\r\n return data1;\r\n }\r\n\r\n if (data1.action === 'resolve_required') {\r\n const roomId = await resolveRoomId(opts.uniqueId);\r\n if (!roomId) return null;\r\n\r\n const url2 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&room_id=${encodeURIComponent(roomId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts2: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ room_id: roomId, ...opts.extraBody }),\r\n };\r\n\r\n const resp2 = await fetch(url2, fetchOpts2);\r\n const data2 = await resp2.json() as any;\r\n\r\n if (data2.signed_url || data2.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data2);\r\n }\r\n\r\n return data2;\r\n }\r\n\r\n return data1;\r\n}\r\n","import type { TikTokLiveOptions, TikTokLiveEvents, RoomInfo, LiveEvent } from './types.js';\r\nimport {\r\n concatBytes,\r\n decodeProto,\r\n getStr,\r\n getBytes,\r\n buildHeartbeat,\r\n buildImEnterRoom,\r\n buildAck,\r\n parseWebcastResponse,\r\n} from './proto.js';\r\nimport { resolveLivePage } from './api.js';\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\ntype Listener = (...args: any[]) => void;\r\n\r\nclass TypedEmitter {\r\n private _listeners = new Map<string, Listener[]>();\r\n\r\n on(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event) || [];\r\n arr.push(fn);\r\n this._listeners.set(event, arr);\r\n return this;\r\n }\r\n\r\n once(event: string, fn: Listener): this {\r\n const wrapper: Listener = (...args) => {\r\n this.off(event, wrapper);\r\n fn(...args);\r\n };\r\n return this.on(event, wrapper);\r\n }\r\n\r\n off(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event);\r\n if (arr) {\r\n this._listeners.set(event, arr.filter(l => l !== fn));\r\n }\r\n return this;\r\n }\r\n\r\n emit(event: string, ...args: any[]): boolean {\r\n const arr = this._listeners.get(event);\r\n if (!arr || arr.length === 0) return false;\r\n for (const fn of [...arr]) fn(...args);\r\n return true;\r\n }\r\n\r\n removeAllListeners(event?: string): this {\r\n if (event) this._listeners.delete(event);\r\n else this._listeners.clear();\r\n return this;\r\n }\r\n}\r\n\r\nasync function gunzip(data: Uint8Array): Promise<Uint8Array> {\r\n if (typeof DecompressionStream !== 'undefined') {\r\n const ds = new DecompressionStream('gzip');\r\n const writer = ds.writable.getWriter();\r\n const reader = ds.readable.getReader();\r\n writer.write(data as any);\r\n writer.close();\r\n const chunks: Uint8Array[] = [];\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n chunks.push(value);\r\n }\r\n return concatBytes(...chunks);\r\n }\r\n try {\r\n const zlib = await import('zlib');\r\n return new Promise((resolve, reject) => {\r\n zlib.gunzip(data, (err: Error | null, result: Buffer) => {\r\n if (err) reject(err);\r\n else resolve(new Uint8Array(result));\r\n });\r\n });\r\n } catch {\r\n return data;\r\n }\r\n}\r\n\r\nfunction gunzipSync(data: Uint8Array): Uint8Array {\r\n try {\r\n const zlib = require('zlib');\r\n return new Uint8Array(zlib.gunzipSync(data));\r\n } catch {\r\n return data;\r\n }\r\n}\r\n\r\ntype WebSocketLike = {\r\n readonly readyState: number;\r\n send(data: ArrayBufferLike | string): void;\r\n close(code?: number, reason?: string): void;\r\n onopen: ((ev: any) => void) | null;\r\n onmessage: ((ev: any) => void) | null;\r\n onerror: ((ev: any) => void) | null;\r\n onclose: ((ev: any) => void) | null;\r\n};\r\n\r\ninterface WebSocketConstructor {\r\n new(url: string, protocols?: string | string[]): WebSocketLike;\r\n readonly OPEN: number;\r\n readonly CLOSED: number;\r\n}\r\n\r\nfunction getWsHost(clusterRegion: string): string {\r\n if (!clusterRegion) return 'webcast-ws.tiktok.com';\r\n const r = clusterRegion.toLowerCase();\r\n if (r.startsWith('eu') || r.includes('eu')) return 'webcast-ws.eu.tiktok.com';\r\n if (r.startsWith('us') || r.includes('us')) return 'webcast-ws.us.tiktok.com';\r\n return 'webcast-ws.tiktok.com';\r\n}\r\n\r\nasync function resolveWebSocket(userImpl?: any): Promise<WebSocketConstructor> {\r\n if (userImpl) return userImpl;\r\n\r\n if (typeof globalThis.WebSocket !== 'undefined') {\r\n return globalThis.WebSocket as unknown as WebSocketConstructor;\r\n }\r\n\r\n try {\r\n const ws = await import('ws');\r\n return (ws.default || ws) as unknown as WebSocketConstructor;\r\n } catch {\r\n throw new Error(\r\n 'No WebSocket implementation found. ' +\r\n 'Either use Node.js 22+ (native WebSocket), Cloudflare Workers, or install the \"ws\" package: npm i ws'\r\n );\r\n }\r\n}\r\n\r\nexport class TikTokLive extends TypedEmitter {\r\n private ws: WebSocketLike | null = null;\r\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n private reconnectAttempts = 0;\r\n private intentionalClose = false;\r\n private _connected = false;\r\n private _eventCount = 0;\r\n private _roomId = '';\r\n private _battleHosts = new Map<string, { id: string; nickname: string; uniqueId: string; profilePicture?: string }>();\r\n\r\n private readonly uniqueId: string;\r\n private readonly signServerUrl: string;\r\n private readonly apiKey: string;\r\n private readonly autoReconnect: boolean;\r\n private readonly maxReconnectAttempts: number;\r\n private readonly heartbeatInterval: number;\r\n private readonly debug: boolean;\r\n private readonly webSocketImpl?: any;\r\n private WS!: WebSocketConstructor;\r\n\r\n constructor(options: TikTokLiveOptions) {\r\n super();\r\n this.uniqueId = options.uniqueId.replace(/^@/, '');\r\n this.signServerUrl = (options.signServerUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n if (!options.apiKey) throw new Error('apiKey is required. Get a free key at https://tik.tools');\r\n this.apiKey = options.apiKey;\r\n this.autoReconnect = options.autoReconnect ?? true;\r\n this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\r\n this.heartbeatInterval = options.heartbeatInterval ?? 10_000;\r\n this.debug = options.debug ?? false;\r\n this.webSocketImpl = options.webSocketImpl;\r\n }\r\n\r\n async connect(): Promise<void> {\r\n this.intentionalClose = false;\r\n\r\n if (!this.WS) {\r\n this.WS = await resolveWebSocket(this.webSocketImpl);\r\n }\r\n\r\n const pageInfo = await resolveLivePage(this.uniqueId);\r\n if (!pageInfo) throw new Error(`User @${this.uniqueId} is not currently live`);\r\n if (!pageInfo.ttwid) throw new Error('Failed to obtain session cookie');\r\n\r\n const { roomId, ttwid, clusterRegion } = pageInfo;\r\n this._roomId = roomId;\r\n const wsHost = getWsHost(clusterRegion);\r\n\r\n const wsParams = new URLSearchParams({\r\n version_code: '270000', device_platform: 'web', cookie_enabled: 'true',\r\n screen_width: '1920', screen_height: '1080', browser_language: 'en-US',\r\n browser_platform: 'Win32', browser_name: 'Mozilla',\r\n browser_version: DEFAULT_UA.split('Mozilla/')[1] || '5.0',\r\n browser_online: 'true', tz_name: 'Etc/UTC',\r\n app_name: 'tiktok_web', sup_ws_ds_opt: '1', update_version_code: '2.0.0',\r\n compress: 'gzip', webcast_language: 'en', ws_direct: '1', aid: '1988',\r\n live_id: '12', app_language: 'en', client_enter: '1', room_id: roomId,\r\n identity: 'audience', history_comment_count: '6', last_rtt: '0',\r\n heartbeat_duration: '10000', resp_content_type: 'protobuf', did_rule: '3',\r\n });\r\n\r\n const rawWsUrl = `https://${wsHost}/webcast/im/ws_proxy/ws_reuse_supplement/?${wsParams}`;\r\n const signUrl = `${this.signServerUrl}/webcast/sign_url`;\r\n\r\n let wsUrl: string;\r\n try {\r\n const signResp = await fetch(signUrl, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n },\r\n body: JSON.stringify({ url: rawWsUrl }),\r\n });\r\n const signData = await signResp.json() as Record<string, any>;\r\n\r\n if (signData.status_code === 0 && signData.data?.signed_url) {\r\n wsUrl = (signData.data.signed_url as string).replace(/^https:\\/\\//, 'wss://');\r\n } else {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n } catch {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const connUrl = wsUrl + (wsUrl.includes('?') ? '&' : '?') + `ttwid=${ttwid}`;\r\n\r\n try {\r\n this.ws = new (this.WS as any)(connUrl, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Cookie': `ttwid=${ttwid}`,\r\n 'Origin': 'https://www.tiktok.com',\r\n },\r\n }) as WebSocketLike;\r\n } catch {\r\n this.ws = new this.WS(connUrl) as WebSocketLike;\r\n }\r\n\r\n const ws = this.ws;\r\n let settled = false;\r\n\r\n ws.onopen = () => {\r\n this._connected = true;\r\n this.reconnectAttempts = 0;\r\n\r\n const hb = buildHeartbeat(roomId);\r\n const enter = buildImEnterRoom(roomId);\r\n ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n ws.send(enter.buffer.byteLength === enter.length ? enter.buffer : enter.buffer.slice(enter.byteOffset, enter.byteOffset + enter.byteLength));\r\n this.startHeartbeat(roomId);\r\n\r\n const roomInfo: RoomInfo = {\r\n roomId,\r\n wsHost,\r\n clusterRegion,\r\n connectedAt: new Date().toISOString(),\r\n };\r\n\r\n (this as TypedEmitter).emit('connected');\r\n (this as TypedEmitter).emit('roomInfo', roomInfo);\r\n if (!settled) { settled = true; resolve(); }\r\n };\r\n\r\n ws.onmessage = (event: any) => {\r\n const raw = event.data !== undefined ? event.data : event;\r\n this.handleMessage(raw);\r\n };\r\n\r\n ws.onclose = (event: any) => {\r\n this._connected = false;\r\n this.stopHeartbeat();\r\n\r\n const code = event?.code ?? 1006;\r\n const reason = event?.reason ?? '';\r\n (this as TypedEmitter).emit('disconnected', code, reason?.toString?.() || '');\r\n\r\n if (!this.intentionalClose && this.autoReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {\r\n this.reconnectAttempts++;\r\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30_000);\r\n setTimeout(() => this.connect().catch(e => (this as TypedEmitter).emit('error', e)), delay);\r\n }\r\n };\r\n\r\n ws.onerror = (err: any) => {\r\n (this as TypedEmitter).emit('error', err instanceof Error ? err : new Error(String(err?.message || err)));\r\n if (!settled) { settled = true; reject(err); }\r\n };\r\n\r\n setTimeout(() => {\r\n if (!settled) {\r\n settled = true;\r\n ws.close();\r\n reject(new Error('Connection timeout'));\r\n }\r\n }, 15_000);\r\n });\r\n }\r\n\r\n disconnect(): void {\r\n this.intentionalClose = true;\r\n this.stopHeartbeat();\r\n if (this.ws) {\r\n this.ws.close(1000);\r\n this.ws = null;\r\n }\r\n this._connected = false;\r\n }\r\n\r\n get connected(): boolean {\r\n return this._connected;\r\n }\r\n\r\n get eventCount(): number {\r\n return this._eventCount;\r\n }\r\n\r\n get roomId(): string {\r\n return this._roomId;\r\n }\r\n\r\n override on<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.on(event as string, listener as Listener);\r\n }\r\n\r\n override once<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.once(event as string, listener as Listener);\r\n }\r\n\r\n override off<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.off(event as string, listener as Listener);\r\n }\r\n\r\n override emit<K extends keyof TikTokLiveEvents>(event: K, ...args: Parameters<TikTokLiveEvents[K]>): boolean {\r\n return super.emit(event as string, ...args);\r\n }\r\n\r\n private async handleMessage(raw: any): Promise<void> {\r\n try {\r\n let bytes: Uint8Array;\r\n\r\n if (raw instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw);\r\n } else if (raw instanceof Uint8Array) {\r\n bytes = raw;\r\n } else if (typeof Blob !== 'undefined' && raw instanceof Blob) {\r\n bytes = new Uint8Array(await raw.arrayBuffer());\r\n } else if (raw?.buffer instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);\r\n } else {\r\n return;\r\n }\r\n\r\n this.handleFrame(bytes);\r\n } catch { }\r\n }\r\n\r\n private handleFrame(buf: Uint8Array): void {\r\n try {\r\n const fields = decodeProto(buf);\r\n const idField = fields.find(f => f.fn === 2 && f.wt === 0);\r\n const id = idField ? idField.value as bigint : 0n;\r\n const type = getStr(fields, 7);\r\n const binary = getBytes(fields, 8);\r\n\r\n if (id > 0n && this.ws && (this.ws.readyState === 1)) {\r\n const ack = buildAck(id);\r\n this.ws.send(ack.buffer.byteLength === ack.length ? ack.buffer : ack.buffer.slice(ack.byteOffset, ack.byteOffset + ack.byteLength));\r\n }\r\n\r\n if (type === 'msg' && binary && binary.length > 0) {\r\n let inner = binary;\r\n if (inner.length > 2 && inner[0] === 0x1f && inner[1] === 0x8b) {\r\n try { inner = gunzipSync(inner); } catch { }\r\n }\r\n\r\n const events = parseWebcastResponse(inner);\r\n for (const evt of events) {\r\n this._eventCount++;\r\n\r\n if (evt.type === 'battle') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n team.hostUser = host.user;\r\n }\r\n }\r\n }\r\n\r\n if (evt.type === 'battleArmies') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n team.hostUser = host.user;\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n } else {\r\n const cached = this._battleHosts.get(team.hostUserId);\r\n if (cached) team.hostUser = cached;\r\n }\r\n }\r\n }\r\n\r\n (this as TypedEmitter).emit('event', evt);\r\n (this as TypedEmitter).emit(evt.type, evt as any);\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n private startHeartbeat(roomId: string): void {\r\n this.stopHeartbeat();\r\n this.heartbeatTimer = setInterval(() => {\r\n if (this.ws && this.ws.readyState === 1) {\r\n const hb = buildHeartbeat(roomId);\r\n this.ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n }\r\n }, this.heartbeatInterval);\r\n }\r\n\r\n private stopHeartbeat(): void {\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n this.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["DEFAULT_UA","DEFAULT_SIGN_SERVER","DEFAULT_SIGN_SERVER","DEFAULT_UA"]}
1
+ {"version":3,"sources":["../src/proto.ts","../src/api.ts","../src/client.ts"],"sourcesContent":["import type { LiveEvent, TikTokUser, BattleTeam, BattleTeamUser } from './types.js';\r\n\r\nconst encoder = new TextEncoder();\r\nconst decoder = new TextDecoder();\r\n\r\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\r\n let totalLength = 0;\r\n for (const arr of arrays) totalLength += arr.length;\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const arr of arrays) {\r\n result.set(arr, offset);\r\n offset += arr.length;\r\n }\r\n return result;\r\n}\r\n\r\nfunction readInt32LE(buf: Uint8Array, offset: number): number {\r\n return buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n (buf[offset + 3] << 24);\r\n}\r\n\r\nfunction readBigInt64LE(buf: Uint8Array, offset: number): bigint {\r\n const lo = BigInt(buf[offset] |\r\n (buf[offset + 1] << 8) |\r\n (buf[offset + 2] << 16) |\r\n ((buf[offset + 3] << 24) >>> 0));\r\n const hi = BigInt(buf[offset + 4] |\r\n (buf[offset + 5] << 8) |\r\n (buf[offset + 6] << 16) |\r\n ((buf[offset + 7] << 24) >>> 0));\r\n return (hi << 32n) | (lo & 0xFFFFFFFFn);\r\n}\r\n\r\nexport function decodeVarint(buf: Uint8Array, offset: number): { value: number; offset: number } {\r\n let result = 0, shift = 0;\r\n while (offset < buf.length) {\r\n const byte = buf[offset++];\r\n result |= (byte & 0x7F) << shift;\r\n if ((byte & 0x80) === 0) break;\r\n shift += 7;\r\n }\r\n return { value: result >>> 0, offset };\r\n}\r\n\r\nexport function decodeVarint64(buf: Uint8Array, offset: number): { value: bigint; offset: number } {\r\n let result = 0n, shift = 0n;\r\n while (offset < buf.length) {\r\n const byte = BigInt(buf[offset++]);\r\n result |= (byte & 0x7Fn) << shift;\r\n if ((byte & 0x80n) === 0n) break;\r\n shift += 7n;\r\n }\r\n return { value: result, offset };\r\n}\r\n\r\nexport function encodeVarint(v: number | bigint): Uint8Array {\r\n const bytes: number[] = [];\r\n let n = typeof v === 'bigint' ? v : BigInt(v);\r\n do {\r\n let b = Number(n & 0x7Fn);\r\n n >>= 7n;\r\n if (n > 0n) b |= 0x80;\r\n bytes.push(b);\r\n } while (n > 0n);\r\n return new Uint8Array(bytes);\r\n}\r\n\r\nexport interface ProtoField {\r\n fn: number;\r\n wt: number;\r\n value: Uint8Array | number | bigint;\r\n}\r\n\r\nexport function encodeField(fn: number, wt: number, value: Uint8Array | bigint | number | string): Uint8Array {\r\n const tag = encodeVarint((fn << 3) | wt);\r\n if (wt === 0) {\r\n return concatBytes(tag, encodeVarint(typeof value === 'number' ? BigInt(value) : value as bigint));\r\n }\r\n const data = typeof value === 'string' ? encoder.encode(value) : value as Uint8Array;\r\n return concatBytes(tag, encodeVarint(data.length), data);\r\n}\r\n\r\nexport function decodeProto(buf: Uint8Array): ProtoField[] {\r\n const fields: ProtoField[] = [];\r\n let offset = 0;\r\n while (offset < buf.length) {\r\n const tagResult = decodeVarint(buf, offset);\r\n offset = tagResult.offset;\r\n const fn = tagResult.value >> 3;\r\n const wt = tagResult.value & 7;\r\n if (wt === 0) {\r\n const r = decodeVarint64(buf, offset);\r\n offset = r.offset;\r\n fields.push({ fn, wt, value: r.value });\r\n } else if (wt === 2) {\r\n const lenR = decodeVarint(buf, offset);\r\n offset = lenR.offset;\r\n const data = buf.subarray(offset, offset + lenR.value);\r\n offset += lenR.value;\r\n fields.push({ fn, wt, value: data });\r\n } else if (wt === 1) {\r\n fields.push({ fn, wt, value: readBigInt64LE(buf, offset) });\r\n offset += 8;\r\n } else if (wt === 5) {\r\n fields.push({ fn, wt, value: BigInt(readInt32LE(buf, offset)) });\r\n offset += 4;\r\n } else {\r\n break;\r\n }\r\n }\r\n return fields;\r\n}\r\n\r\nexport function getStr(fields: ProtoField[], fn: number): string {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? decoder.decode(f.value as Uint8Array) : '';\r\n}\r\n\r\nexport function getBytes(fields: ProtoField[], fn: number): Uint8Array | null {\r\n const f = fields.find(x => x.fn === fn && x.wt === 2);\r\n return f ? f.value as Uint8Array : null;\r\n}\r\n\r\nexport function getInt(fields: ProtoField[], fn: number): number {\r\n const f = fields.find(x => x.fn === fn && x.wt === 0);\r\n return f ? Number(f.value) : 0;\r\n}\r\n\r\nexport function getAllBytes(fields: ProtoField[], fn: number): Uint8Array[] {\r\n return fields.filter(x => x.fn === fn && x.wt === 2).map(x => x.value as Uint8Array);\r\n}\r\n\r\nexport function buildHeartbeat(roomId: string): Uint8Array {\r\n const payload = encodeField(1, 0, BigInt(roomId));\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'hb'),\r\n encodeField(8, 2, payload),\r\n );\r\n}\r\n\r\nexport function buildImEnterRoom(roomId: string): Uint8Array {\r\n const inner = concatBytes(\r\n encodeField(1, 0, BigInt(roomId)),\r\n encodeField(4, 0, 12n),\r\n encodeField(5, 2, 'audience'),\r\n encodeField(6, 2, ''),\r\n encodeField(9, 2, ''),\r\n encodeField(10, 2, ''),\r\n );\r\n return concatBytes(\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'im_enter_room'),\r\n encodeField(8, 2, inner),\r\n );\r\n}\r\n\r\nexport function buildAck(id: bigint): Uint8Array {\r\n return concatBytes(\r\n encodeField(2, 0, id),\r\n encodeField(6, 2, 'pb'),\r\n encodeField(7, 2, 'ack'),\r\n );\r\n}\r\n\r\nfunction parseUser(data: Uint8Array): TikTokUser {\r\n const f = decodeProto(data);\r\n const id = String(getInt(f, 1) || getStr(f, 1));\r\n const nickname = getStr(f, 3) || getStr(f, 2);\r\n const uniqueId = getStr(f, 38) || getStr(f, 4) || getStr(f, 2) || '';\r\n\r\n let profilePicture: string | undefined;\r\n const avatarBuf = getBytes(f, 9) || getBytes(f, 3);\r\n if (avatarBuf) {\r\n try {\r\n const avatarFields = decodeProto(avatarBuf);\r\n const urlBufs = getAllBytes(avatarFields, 1);\r\n if (urlBufs.length > 0) profilePicture = decoder.decode(urlBufs[0]);\r\n } catch { }\r\n }\r\n\r\n const badges: string[] = [];\r\n const badgeBuf = getBytes(f, 64);\r\n if (badgeBuf) {\r\n try {\r\n const badgeFields = decodeProto(badgeBuf);\r\n const badgeItems = getAllBytes(badgeFields, 21);\r\n for (const bi of badgeItems) {\r\n const bf = decodeProto(bi);\r\n const name = getStr(bf, 3) || getStr(bf, 2);\r\n if (name) badges.push(name);\r\n }\r\n } catch { }\r\n }\r\n\r\n return {\r\n id,\r\n nickname,\r\n uniqueId: uniqueId || nickname || id,\r\n profilePictureUrl: profilePicture,\r\n badges: badges.length > 0 ? badges : undefined,\r\n };\r\n}\r\n\r\nfunction parseBattleTeamFromArmies(itemBuf: Uint8Array): BattleTeam {\r\n const f = decodeProto(itemBuf);\r\n const hostUserId = String(getInt(f, 1));\r\n let teamScore = 0;\r\n const users: BattleTeamUser[] = [];\r\n\r\n const groups = getAllBytes(f, 2);\r\n for (const gb of groups) {\r\n try {\r\n const gf = decodeProto(gb);\r\n const points = getInt(gf, 2);\r\n teamScore += points;\r\n\r\n const userBufs = getAllBytes(gf, 1);\r\n for (const ub of userBufs) {\r\n try {\r\n const user = parseUser(ub);\r\n users.push({ user, score: points });\r\n } catch { }\r\n }\r\n } catch { }\r\n }\r\n\r\n return { hostUserId, score: teamScore, users };\r\n}\r\n\r\nexport function parseWebcastMessage(method: string, payload: Uint8Array): LiveEvent {\r\n const f = decodeProto(payload);\r\n const base = { timestamp: Date.now(), msgId: '' };\r\n\r\n const typeBuf = getBytes(f, 1);\r\n if (typeBuf) {\r\n try {\r\n const tf = decodeProto(typeBuf);\r\n const ts = getInt(tf, 4);\r\n if (ts) base.timestamp = ts;\r\n } catch { }\r\n }\r\n\r\n switch (method) {\r\n case 'WebcastChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'chat' as const, user, comment: getStr(f, 3) };\r\n }\r\n\r\n case 'WebcastMemberMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 1;\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('followed')) action = 2;\r\n else if (label.includes('share')) action = 3;\r\n }\r\n }\r\n return { ...base, type: 'member' as const, user, action };\r\n }\r\n\r\n case 'WebcastLikeMessage': {\r\n const userBuf = getBytes(f, 5);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return {\r\n ...base, type: 'like' as const, user,\r\n likeCount: getInt(f, 2),\r\n totalLikes: getInt(f, 3),\r\n };\r\n }\r\n\r\n case 'WebcastGiftMessage': {\r\n const userBuf = getBytes(f, 7);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n const giftId = getInt(f, 2);\r\n const repeatCount = getInt(f, 5);\r\n const repeatEnd = getInt(f, 9) === 1;\r\n\r\n let giftName = '', diamondCount = 0, giftType = 0;\r\n let giftImageUrl = '';\r\n const detailsBuf = getBytes(f, 15);\r\n if (detailsBuf) {\r\n const df = decodeProto(detailsBuf);\r\n giftName = getStr(df, 16) || getStr(df, 2);\r\n diamondCount = getInt(df, 12);\r\n giftType = getInt(df, 11);\r\n\r\n const imgBuf = getBytes(df, 1);\r\n if (imgBuf) {\r\n const imgf = decodeProto(imgBuf);\r\n giftImageUrl = getStr(imgf, 1);\r\n }\r\n }\r\n\r\n let toUserId = '';\r\n const extraBuf = getBytes(f, 23);\r\n if (extraBuf) {\r\n const ef = decodeProto(extraBuf);\r\n toUserId = String(getInt(ef, 8));\r\n }\r\n\r\n const groupId = toUserId || getStr(f, 11);\r\n\r\n return {\r\n ...base, type: 'gift' as const, user, giftId, giftName, diamondCount,\r\n repeatCount, repeatEnd, combo: repeatCount > 1 && !repeatEnd,\r\n giftType, groupId, giftPictureUrl: giftImageUrl,\r\n };\r\n }\r\n\r\n case 'WebcastSocialMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let action = 'follow';\r\n const eventBuf = getBytes(f, 1);\r\n if (eventBuf) {\r\n const ef = decodeProto(eventBuf);\r\n const detailBuf = getBytes(ef, 8);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n const label = getStr(df, 2);\r\n if (label.includes('share')) action = 'share';\r\n else if (label.includes('follow')) action = 'follow';\r\n const displayType = getStr(df, 1);\r\n if (displayType === 'pm_mt_msg_viewer_share') action = 'share';\r\n }\r\n }\r\n return { ...base, type: 'social' as const, user, action };\r\n }\r\n\r\n case 'WebcastRoomUserSeqMessage': {\r\n const viewerCount = getInt(f, 3) || getInt(f, 2);\r\n const totalViewers = getInt(f, 1) || viewerCount;\r\n return { ...base, type: 'roomUserSeq' as const, totalViewers, viewerCount };\r\n }\r\n\r\n case 'WebcastLinkMicBattle': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const status = getInt(f, 2) || 1;\r\n const battleDuration = getInt(f, 3);\r\n const teams: BattleTeam[] = [];\r\n\r\n const battleUserBufs = getAllBytes(f, 10);\r\n for (const bub of battleUserBufs) {\r\n try {\r\n const bf = decodeProto(bub);\r\n const groupBuf = getBytes(bf, 2);\r\n if (groupBuf) {\r\n const gf = decodeProto(groupBuf);\r\n const linkUserBuf = getBytes(gf, 1);\r\n if (linkUserBuf) {\r\n const user = parseUser(linkUserBuf);\r\n teams.push({\r\n hostUserId: user.id,\r\n score: 0,\r\n users: [{ user, score: 0 }],\r\n });\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n if (teams.length === 0) {\r\n const teamBufs7 = getAllBytes(f, 7);\r\n for (const tb of teamBufs7) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(tb));\r\n } catch { }\r\n }\r\n }\r\n\r\n return { ...base, type: 'battle' as const, battleId, status, battleDuration, teams };\r\n }\r\n\r\n case 'WebcastLinkMicArmies': {\r\n const battleId = String(getInt(f, 1) || '');\r\n const battleStatus = getInt(f, 7);\r\n const teams: BattleTeam[] = [];\r\n\r\n const itemBufs = getAllBytes(f, 3);\r\n for (const ib of itemBufs) {\r\n try {\r\n teams.push(parseBattleTeamFromArmies(ib));\r\n } catch { }\r\n }\r\n\r\n return {\r\n ...base, type: 'battleArmies' as const, battleId, teams,\r\n status: battleStatus,\r\n };\r\n }\r\n\r\n case 'WebcastSubNotifyMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n return { ...base, type: 'subscribe' as const, user, subMonth: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastEmoteChatMessage': {\r\n const userBuf = getBytes(f, 2);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n let emoteId = '', emoteUrl = '';\r\n const emoteBuf = getBytes(f, 3);\r\n if (emoteBuf) {\r\n const ef = decodeProto(emoteBuf);\r\n emoteId = getStr(ef, 1);\r\n const imageBuf = getBytes(ef, 2);\r\n if (imageBuf) {\r\n const imgFields = decodeProto(imageBuf);\r\n emoteUrl = getStr(imgFields, 1);\r\n }\r\n }\r\n return { ...base, type: 'emoteChat' as const, user, emoteId, emoteUrl };\r\n }\r\n\r\n case 'WebcastEnvelopeMessage': {\r\n const envelopeId = String(getInt(f, 1) || getStr(f, 1));\r\n return { ...base, type: 'envelope' as const, envelopeId, diamondCount: getInt(f, 3) };\r\n }\r\n\r\n case 'WebcastQuestionNewMessage': {\r\n let questionText = '', user: TikTokUser = { id: '0', nickname: '', uniqueId: '' };\r\n const detailBuf = getBytes(f, 2);\r\n if (detailBuf) {\r\n const df = decodeProto(detailBuf);\r\n questionText = getStr(df, 2);\r\n const userBuf = getBytes(df, 5);\r\n if (userBuf) user = parseUser(userBuf);\r\n }\r\n return { ...base, type: 'question' as const, user, questionText };\r\n }\r\n\r\n case 'WebcastRankUpdateMessage':\r\n case 'WebcastHourlyRankMessage': {\r\n const rankType = getStr(f, 1) || `rank_${getInt(f, 1)}`;\r\n const rankList: Array<{ user: TikTokUser; rank: number; score: number }> = [];\r\n const listBufs = getAllBytes(f, 2);\r\n for (const lb of listBufs) {\r\n try {\r\n const rf = decodeProto(lb);\r\n const userBuf = getBytes(rf, 1);\r\n const rank = getInt(rf, 2);\r\n const score = getInt(rf, 3);\r\n const user = userBuf ? parseUser(userBuf) : { id: '0', nickname: '', uniqueId: '' };\r\n rankList.push({ user, rank, score });\r\n } catch { }\r\n }\r\n return { ...base, type: 'rankUpdate' as const, rankType, rankList };\r\n }\r\n\r\n case 'WebcastControlMessage':\r\n return { ...base, type: 'control' as const, action: getInt(f, 2) || getInt(f, 1) };\r\n\r\n case 'WebcastRoomMessage':\r\n case 'RoomMessage':\r\n return { ...base, type: 'room' as const, status: getInt(f, 2) };\r\n\r\n case 'WebcastLiveIntroMessage': {\r\n const roomId = String(getInt(f, 2));\r\n const title = getStr(f, 4) || getStr(f, 2);\r\n return { ...base, type: 'liveIntro' as const, roomId, title };\r\n }\r\n\r\n case 'WebcastLinkMicMethod':\r\n case 'WebcastLinkmicBattleTaskMessage': {\r\n const action = getStr(f, 1) || `action_${getInt(f, 1)}`;\r\n const users: TikTokUser[] = [];\r\n const userBufs = getAllBytes(f, 2);\r\n for (const ub of userBufs) {\r\n try { users.push(parseUser(ub)); } catch { }\r\n }\r\n return { ...base, type: 'linkMic' as const, action, users };\r\n }\r\n\r\n default:\r\n return { ...base, type: 'unknown' as const, method };\r\n }\r\n}\r\n\r\nexport function parseWebcastResponse(payload: Uint8Array): LiveEvent[] {\r\n const events: LiveEvent[] = [];\r\n const respFields = decodeProto(payload);\r\n\r\n for (const mf of respFields.filter(f => f.fn === 1 && f.wt === 2)) {\r\n const msgBuf = mf.value as Uint8Array;\r\n const msgFields = decodeProto(msgBuf);\r\n const method = getStr(msgFields, 1);\r\n const innerPayload = getBytes(msgFields, 2);\r\n if (!method || !innerPayload) continue;\r\n\r\n try {\r\n events.push(parseWebcastMessage(method, innerPayload));\r\n } catch { }\r\n }\r\n\r\n return events;\r\n}\r\n","/**\r\n * TikTool API utilities for the sign-and-return API flow.\r\n *\r\n * The API server returns signed URLs instead of fetching TikTok data directly.\r\n * These utilities handle the two-step flow:\r\n * 1. resolve_required — scrape TikTok HTML to get room_id\r\n * 2. fetch_signed_url — use the signed URL to get actual TikTok data\r\n *\r\n * @module\r\n */\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\nconst pageCache = new Map<string, { info: LivePageInfo; ts: number }>();\r\nconst PAGE_CACHE_TTL = 5 * 60 * 1000;\r\n\r\n/**\r\n * Resolved live page metadata from a TikTok live page.\r\n */\r\nexport interface LivePageInfo {\r\n /** Active room ID for the livestream */\r\n roomId: string;\r\n /** Session cookie required for WebSocket authentication */\r\n ttwid: string;\r\n /** Server cluster region (e.g. 'us', 'eu') */\r\n clusterRegion: string;\r\n}\r\n\r\n/**\r\n * Scrape a TikTok live page to extract room metadata.\r\n * Returns the room ID, session cookie, and cluster region.\r\n * Results are cached for 5 minutes. Returns `null` if the user is not live.\r\n */\r\nexport async function resolveLivePage(uniqueId: string): Promise<LivePageInfo | null> {\r\n const clean = uniqueId.replace(/^@/, '');\r\n const cached = pageCache.get(clean);\r\n if (cached && Date.now() - cached.ts < PAGE_CACHE_TTL) {\r\n return cached.info;\r\n }\r\n\r\n try {\r\n const resp = await fetch(`https://www.tiktok.com/@${clean}/live`, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\r\n 'Accept-Language': 'en-US,en;q=0.9',\r\n },\r\n redirect: 'follow',\r\n });\r\n\r\n if (!resp.ok) return null;\r\n\r\n // Extract ttwid session cookie\r\n let ttwid = '';\r\n const setCookies = resp.headers.get('set-cookie') || '';\r\n for (const part of setCookies.split(',')) {\r\n const trimmed = part.trim();\r\n if (trimmed.startsWith('ttwid=')) {\r\n ttwid = trimmed.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n if (!ttwid && typeof (resp.headers as any).getSetCookie === 'function') {\r\n for (const sc of (resp.headers as any).getSetCookie()) {\r\n if (typeof sc === 'string' && sc.startsWith('ttwid=')) {\r\n ttwid = sc.split(';')[0].split('=').slice(1).join('=');\r\n break;\r\n }\r\n }\r\n }\r\n\r\n const html = await resp.text();\r\n\r\n // Extract roomId from SIGI_STATE JSON block\r\n let roomId = '';\r\n const sigiMatch = html.match(/id=\"SIGI_STATE\"[^>]*>([^<]+)/);\r\n if (sigiMatch) {\r\n try {\r\n const json = JSON.parse(sigiMatch[1]);\r\n const jsonStr = JSON.stringify(json);\r\n const m = jsonStr.match(/\"roomId\"\\s*:\\s*\"(\\d+)\"/);\r\n if (m) roomId = m[1];\r\n } catch { }\r\n }\r\n\r\n // Fallback patterns\r\n if (!roomId) {\r\n const patterns = [\r\n /\"roomId\"\\s*:\\s*\"(\\d+)\"/,\r\n /room_id[=/](\\d{10,})/,\r\n /\"idStr\"\\s*:\\s*\"(\\d{10,})\"/,\r\n ];\r\n for (const p of patterns) {\r\n const m = html.match(p);\r\n if (m) { roomId = m[1]; break; }\r\n }\r\n }\r\n\r\n if (!roomId) return null;\r\n\r\n // Extract cluster region\r\n const crMatch = html.match(/\"clusterRegion\"\\s*:\\s*\"([^\"]+)\"/);\r\n const clusterRegion = crMatch ? crMatch[1] : '';\r\n\r\n const info: LivePageInfo = { roomId, ttwid, clusterRegion };\r\n pageCache.set(clean, { info, ts: Date.now() });\r\n return info;\r\n } catch { }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Resolve a TikTok username to a room ID.\r\n * Returns `null` if the user is not currently live.\r\n * Results are cached for 5 minutes.\r\n */\r\nexport async function resolveRoomId(uniqueId: string): Promise<string | null> {\r\n const info = await resolveLivePage(uniqueId);\r\n return info?.roomId ?? null;\r\n}\r\n\r\nexport interface SignedUrlResponse {\r\n status_code: number;\r\n action?: string;\r\n signed_url: string;\r\n headers: Record<string, string>;\r\n cookies: string;\r\n}\r\n\r\n/**\r\n * Execute a signed-URL API response: fetch the signed URL and return the\r\n * parsed JSON data from TikTok.\r\n */\r\nexport async function fetchSignedUrl(response: SignedUrlResponse): Promise<any> {\r\n if (!response.signed_url) {\r\n return null;\r\n }\r\n\r\n const headers: Record<string, string> = { ...(response.headers || {}) };\r\n if (response.cookies) {\r\n headers['Cookie'] = response.cookies;\r\n }\r\n\r\n const resp = await fetch(response.signed_url, { headers, redirect: 'follow' });\r\n const text = await resp.text();\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport interface CallApiOptions {\r\n /** API server URL (default: https://api.tik.tools) */\r\n serverUrl?: string;\r\n /** API key for authentication */\r\n apiKey: string;\r\n /** API endpoint path (e.g. '/webcast/room_video') */\r\n endpoint: string;\r\n /** TikTok unique_id to resolve */\r\n uniqueId: string;\r\n /** HTTP method (default: POST) */\r\n method?: 'GET' | 'POST';\r\n /** Additional body fields for POST requests */\r\n extraBody?: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Call a TikTool API endpoint, handling the full\r\n * resolve_required → room_id → signed_url → fetch flow automatically.\r\n *\r\n * Returns the actual TikTok data, or `null` if the user is not live.\r\n */\r\nexport async function callApi(opts: CallApiOptions): Promise<any> {\r\n const serverUrl = (opts.serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const isGet = opts.method === 'GET';\r\n const ak = encodeURIComponent(opts.apiKey);\r\n\r\n const url1 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&unique_id=${encodeURIComponent(opts.uniqueId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts1: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ unique_id: opts.uniqueId, ...opts.extraBody }),\r\n };\r\n\r\n const resp1 = await fetch(url1, fetchOpts1);\r\n const data1 = await resp1.json() as any;\r\n\r\n // If the response contains a signed URL to fetch (with or without explicit action),\r\n // follow through and fetch the actual TikTok data\r\n if (data1.signed_url || data1.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data1);\r\n }\r\n\r\n if (data1.status_code === 0 && data1.action !== 'resolve_required') {\r\n return data1;\r\n }\r\n\r\n if (data1.action === 'resolve_required') {\r\n const roomId = await resolveRoomId(opts.uniqueId);\r\n if (!roomId) return null;\r\n\r\n const url2 = isGet\r\n ? `${serverUrl}${opts.endpoint}?apiKey=${ak}&room_id=${encodeURIComponent(roomId)}`\r\n : `${serverUrl}${opts.endpoint}?apiKey=${ak}`;\r\n\r\n const fetchOpts2: RequestInit = isGet\r\n ? {}\r\n : {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ room_id: roomId, ...opts.extraBody }),\r\n };\r\n\r\n const resp2 = await fetch(url2, fetchOpts2);\r\n const data2 = await resp2.json() as any;\r\n\r\n if (data2.signed_url || data2.action === 'fetch_signed_url') {\r\n return fetchSignedUrl(data2);\r\n }\r\n\r\n return data2;\r\n }\r\n\r\n return data1;\r\n}\r\n\r\n// ── CAPTCHA Solver API ──────────────────────────────────────────────\r\n\r\nimport type { PuzzleSolveResult, RotateSolveResult, ShapesSolveResult } from './types.js';\r\n\r\n/**\r\n * Solve a puzzle (slider) CAPTCHA using the TikTool solver.\r\n *\r\n * @param apiKey - API key for authentication\r\n * @param puzzleB64 - Base64-encoded background image (PNG/JPEG)\r\n * @param pieceB64 - Base64-encoded puzzle piece image (PNG/JPEG)\r\n * @param serverUrl - Custom server URL (default: https://api.tik.tools)\r\n * @returns Solve result with slide position and confidence\r\n */\r\nexport async function solvePuzzle(\r\n apiKey: string,\r\n puzzleB64: string,\r\n pieceB64: string,\r\n serverUrl?: string,\r\n): Promise<PuzzleSolveResult> {\r\n const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const resp = await fetch(`${base}/captcha/solve/puzzle?apiKey=${encodeURIComponent(apiKey)}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ puzzle: puzzleB64, piece: pieceB64 }),\r\n });\r\n const data = await resp.json() as any;\r\n if (data.status_code !== 0) {\r\n throw new Error(data.error || `Solver failed (status ${data.status_code})`);\r\n }\r\n return data.data as PuzzleSolveResult;\r\n}\r\n\r\n/**\r\n * Solve a rotate (whirl) CAPTCHA using the TikTool solver.\r\n *\r\n * @param apiKey - API key for authentication\r\n * @param outerB64 - Base64-encoded outer ring image (PNG/JPEG)\r\n * @param innerB64 - Base64-encoded inner rotated image (PNG/JPEG)\r\n * @param serverUrl - Custom server URL (default: https://api.tik.tools)\r\n * @returns Solve result with rotation angle and confidence\r\n */\r\nexport async function solveRotate(\r\n apiKey: string,\r\n outerB64: string,\r\n innerB64: string,\r\n serverUrl?: string,\r\n): Promise<RotateSolveResult> {\r\n const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const resp = await fetch(`${base}/captcha/solve/rotate?apiKey=${encodeURIComponent(apiKey)}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ outer: outerB64, inner: innerB64 }),\r\n });\r\n const data = await resp.json() as any;\r\n if (data.status_code !== 0) {\r\n throw new Error(data.error || `Solver failed (status ${data.status_code})`);\r\n }\r\n return data.data as RotateSolveResult;\r\n}\r\n\r\n/**\r\n * Solve a shapes (3D matching) CAPTCHA using the TikTool solver.\r\n *\r\n * @param apiKey - API key for authentication\r\n * @param imageB64 - Base64-encoded CAPTCHA image with shape grid (PNG/JPEG)\r\n * @param serverUrl - Custom server URL (default: https://api.tik.tools)\r\n * @returns Solve result with two matching shape coordinates and confidence\r\n */\r\nexport async function solveShapes(\r\n apiKey: string,\r\n imageB64: string,\r\n serverUrl?: string,\r\n): Promise<ShapesSolveResult> {\r\n const base = (serverUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n const resp = await fetch(`${base}/captcha/solve/shapes?apiKey=${encodeURIComponent(apiKey)}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ image: imageB64 }),\r\n });\r\n const data = await resp.json() as any;\r\n if (data.status_code !== 0) {\r\n throw new Error(data.error || `Solver failed (status ${data.status_code})`);\r\n }\r\n return data.data as ShapesSolveResult;\r\n}\r\n","import type { TikTokLiveOptions, TikTokLiveEvents, RoomInfo, LiveEvent } from './types.js';\r\nimport {\r\n concatBytes,\r\n decodeProto,\r\n getStr,\r\n getBytes,\r\n buildHeartbeat,\r\n buildImEnterRoom,\r\n buildAck,\r\n parseWebcastResponse,\r\n} from './proto.js';\r\nimport { resolveLivePage } from './api.js';\r\n\r\nconst DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';\r\nconst DEFAULT_SIGN_SERVER = 'https://api.tik.tools';\r\n\r\ntype Listener = (...args: any[]) => void;\r\n\r\nclass TypedEmitter {\r\n private _listeners = new Map<string, Listener[]>();\r\n\r\n on(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event) || [];\r\n arr.push(fn);\r\n this._listeners.set(event, arr);\r\n return this;\r\n }\r\n\r\n once(event: string, fn: Listener): this {\r\n const wrapper: Listener = (...args) => {\r\n this.off(event, wrapper);\r\n fn(...args);\r\n };\r\n return this.on(event, wrapper);\r\n }\r\n\r\n off(event: string, fn: Listener): this {\r\n const arr = this._listeners.get(event);\r\n if (arr) {\r\n this._listeners.set(event, arr.filter(l => l !== fn));\r\n }\r\n return this;\r\n }\r\n\r\n emit(event: string, ...args: any[]): boolean {\r\n const arr = this._listeners.get(event);\r\n if (!arr || arr.length === 0) return false;\r\n for (const fn of [...arr]) fn(...args);\r\n return true;\r\n }\r\n\r\n removeAllListeners(event?: string): this {\r\n if (event) this._listeners.delete(event);\r\n else this._listeners.clear();\r\n return this;\r\n }\r\n}\r\n\r\nasync function gunzip(data: Uint8Array): Promise<Uint8Array> {\r\n if (typeof DecompressionStream !== 'undefined') {\r\n const ds = new DecompressionStream('gzip');\r\n const writer = ds.writable.getWriter();\r\n const reader = ds.readable.getReader();\r\n writer.write(data as any);\r\n writer.close();\r\n const chunks: Uint8Array[] = [];\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n chunks.push(value);\r\n }\r\n return concatBytes(...chunks);\r\n }\r\n try {\r\n const zlib = await import('zlib');\r\n return new Promise((resolve, reject) => {\r\n zlib.gunzip(data, (err: Error | null, result: Buffer) => {\r\n if (err) reject(err);\r\n else resolve(new Uint8Array(result));\r\n });\r\n });\r\n } catch {\r\n return data;\r\n }\r\n}\r\n\r\n// Pre-cache zlib for sync decompression (require fails in ESM)\r\nlet _zlib: any = null;\r\nlet _zlibLoadAttempted = false;\r\n\r\nasync function ensureZlib(): Promise<any> {\r\n if (_zlib) return _zlib;\r\n if (_zlibLoadAttempted) return null;\r\n _zlibLoadAttempted = true;\r\n try {\r\n _zlib = await import('zlib');\r\n } catch { }\r\n return _zlib;\r\n}\r\n\r\n// Attempt to load zlib eagerly at module init\r\nensureZlib();\r\n\r\nfunction gunzipSync(data: Uint8Array): Uint8Array | null {\r\n if (!_zlib) return null; // Signal that sync decompress is unavailable\r\n try {\r\n return new Uint8Array(_zlib.gunzipSync(data));\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\ntype WebSocketLike = {\r\n readonly readyState: number;\r\n send(data: ArrayBufferLike | string): void;\r\n close(code?: number, reason?: string): void;\r\n onopen: ((ev: any) => void) | null;\r\n onmessage: ((ev: any) => void) | null;\r\n onerror: ((ev: any) => void) | null;\r\n onclose: ((ev: any) => void) | null;\r\n};\r\n\r\ninterface WebSocketConstructor {\r\n new(url: string, protocols?: string | string[]): WebSocketLike;\r\n readonly OPEN: number;\r\n readonly CLOSED: number;\r\n}\r\n\r\nfunction getWsHost(clusterRegion: string): string {\r\n if (!clusterRegion) return 'webcast-ws.tiktok.com';\r\n const r = clusterRegion.toLowerCase();\r\n if (r.startsWith('eu') || r.includes('eu')) return 'webcast-ws.eu.tiktok.com';\r\n if (r.startsWith('us') || r.includes('us')) return 'webcast-ws.us.tiktok.com';\r\n return 'webcast-ws.tiktok.com';\r\n}\r\n\r\nasync function resolveWebSocket(userImpl?: any): Promise<WebSocketConstructor> {\r\n if (userImpl) return userImpl;\r\n\r\n if (typeof globalThis.WebSocket !== 'undefined') {\r\n return globalThis.WebSocket as unknown as WebSocketConstructor;\r\n }\r\n\r\n try {\r\n const ws = await import('ws');\r\n return (ws.default || ws) as unknown as WebSocketConstructor;\r\n } catch {\r\n throw new Error(\r\n 'No WebSocket implementation found. ' +\r\n 'Either use Node.js 22+ (native WebSocket), Cloudflare Workers, or install the \"ws\" package: npm i ws'\r\n );\r\n }\r\n}\r\n\r\nexport class TikTokLive extends TypedEmitter {\r\n private ws: WebSocketLike | null = null;\r\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n private reconnectAttempts = 0;\r\n private intentionalClose = false;\r\n private _connected = false;\r\n private _eventCount = 0;\r\n private _roomId = '';\r\n private _battleHosts = new Map<string, { id: string; nickname: string; uniqueId: string; profilePicture?: string }>();\r\n\r\n private readonly uniqueId: string;\r\n private readonly signServerUrl: string;\r\n private readonly apiKey: string;\r\n private readonly autoReconnect: boolean;\r\n private readonly maxReconnectAttempts: number;\r\n private readonly heartbeatInterval: number;\r\n private readonly debug: boolean;\r\n private readonly webSocketImpl?: any;\r\n private WS!: WebSocketConstructor;\r\n\r\n constructor(options: TikTokLiveOptions) {\r\n super();\r\n this.uniqueId = options.uniqueId.replace(/^@/, '');\r\n this.signServerUrl = (options.signServerUrl || DEFAULT_SIGN_SERVER).replace(/\\/$/, '');\r\n if (!options.apiKey) throw new Error('apiKey is required. Get a free key at https://tik.tools');\r\n this.apiKey = options.apiKey;\r\n this.autoReconnect = options.autoReconnect ?? true;\r\n this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\r\n this.heartbeatInterval = options.heartbeatInterval ?? 10_000;\r\n this.debug = options.debug ?? false;\r\n this.webSocketImpl = options.webSocketImpl;\r\n }\r\n\r\n async connect(): Promise<void> {\r\n this.intentionalClose = false;\r\n\r\n if (!this.WS) {\r\n this.WS = await resolveWebSocket(this.webSocketImpl);\r\n }\r\n\r\n const pageInfo = await resolveLivePage(this.uniqueId);\r\n if (!pageInfo) throw new Error(`User @${this.uniqueId} is not currently live`);\r\n if (!pageInfo.ttwid) throw new Error('Failed to obtain session cookie');\r\n\r\n const { roomId, ttwid, clusterRegion } = pageInfo;\r\n this._roomId = roomId;\r\n const wsHost = getWsHost(clusterRegion);\r\n\r\n const wsParams = new URLSearchParams({\r\n version_code: '270000', device_platform: 'web', cookie_enabled: 'true',\r\n screen_width: '1920', screen_height: '1080', browser_language: 'en-US',\r\n browser_platform: 'Win32', browser_name: 'Mozilla',\r\n browser_version: DEFAULT_UA.split('Mozilla/')[1] || '5.0',\r\n browser_online: 'true', tz_name: 'Etc/UTC',\r\n app_name: 'tiktok_web', sup_ws_ds_opt: '1', update_version_code: '2.0.0',\r\n compress: 'gzip', webcast_language: 'en', ws_direct: '1', aid: '1988',\r\n live_id: '12', app_language: 'en', client_enter: '1', room_id: roomId,\r\n identity: 'audience', history_comment_count: '6', last_rtt: '0',\r\n heartbeat_duration: '10000', resp_content_type: 'protobuf', did_rule: '3',\r\n });\r\n\r\n const rawWsUrl = `https://${wsHost}/webcast/im/ws_proxy/ws_reuse_supplement/?${wsParams}`;\r\n const signUrl = `${this.signServerUrl}/webcast/sign_url`;\r\n\r\n let wsUrl: string;\r\n try {\r\n const signResp = await fetch(signUrl, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n },\r\n body: JSON.stringify({ url: rawWsUrl }),\r\n });\r\n const signData = await signResp.json() as Record<string, any>;\r\n\r\n if (signData.status_code === 0 && signData.data?.signed_url) {\r\n wsUrl = (signData.data.signed_url as string).replace(/^https:\\/\\//, 'wss://');\r\n } else {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n } catch {\r\n wsUrl = rawWsUrl.replace(/^https:\\/\\//, 'wss://');\r\n }\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const connUrl = wsUrl + (wsUrl.includes('?') ? '&' : '?') + `ttwid=${ttwid}`;\r\n\r\n try {\r\n this.ws = new (this.WS as any)(connUrl, {\r\n headers: {\r\n 'User-Agent': DEFAULT_UA,\r\n 'Cookie': `ttwid=${ttwid}`,\r\n 'Origin': 'https://www.tiktok.com',\r\n },\r\n }) as WebSocketLike;\r\n } catch {\r\n this.ws = new this.WS(connUrl) as WebSocketLike;\r\n }\r\n\r\n const ws = this.ws;\r\n let settled = false;\r\n\r\n ws.onopen = () => {\r\n this._connected = true;\r\n this.reconnectAttempts = 0;\r\n\r\n const hb = buildHeartbeat(roomId);\r\n const enter = buildImEnterRoom(roomId);\r\n ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n ws.send(enter.buffer.byteLength === enter.length ? enter.buffer : enter.buffer.slice(enter.byteOffset, enter.byteOffset + enter.byteLength));\r\n this.startHeartbeat(roomId);\r\n\r\n const roomInfo: RoomInfo = {\r\n roomId,\r\n wsHost,\r\n clusterRegion,\r\n connectedAt: new Date().toISOString(),\r\n };\r\n\r\n (this as TypedEmitter).emit('connected');\r\n (this as TypedEmitter).emit('roomInfo', roomInfo);\r\n if (!settled) { settled = true; resolve(); }\r\n };\r\n\r\n ws.onmessage = (event: any) => {\r\n const raw = event.data !== undefined ? event.data : event;\r\n this.handleMessage(raw);\r\n };\r\n\r\n ws.onclose = (event: any) => {\r\n this._connected = false;\r\n this.stopHeartbeat();\r\n\r\n const code = event?.code ?? 1006;\r\n const reason = event?.reason ?? '';\r\n (this as TypedEmitter).emit('disconnected', code, reason?.toString?.() || '');\r\n\r\n if (!this.intentionalClose && this.autoReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {\r\n this.reconnectAttempts++;\r\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30_000);\r\n setTimeout(() => this.connect().catch(e => (this as TypedEmitter).emit('error', e)), delay);\r\n }\r\n };\r\n\r\n ws.onerror = (err: any) => {\r\n (this as TypedEmitter).emit('error', err instanceof Error ? err : new Error(String(err?.message || err)));\r\n if (!settled) { settled = true; reject(err); }\r\n };\r\n\r\n setTimeout(() => {\r\n if (!settled) {\r\n settled = true;\r\n ws.close();\r\n reject(new Error('Connection timeout'));\r\n }\r\n }, 15_000);\r\n });\r\n }\r\n\r\n disconnect(): void {\r\n this.intentionalClose = true;\r\n this.stopHeartbeat();\r\n if (this.ws) {\r\n this.ws.close(1000);\r\n this.ws = null;\r\n }\r\n this._connected = false;\r\n }\r\n\r\n get connected(): boolean {\r\n return this._connected;\r\n }\r\n\r\n get eventCount(): number {\r\n return this._eventCount;\r\n }\r\n\r\n get roomId(): string {\r\n return this._roomId;\r\n }\r\n\r\n override on<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.on(event as string, listener as Listener);\r\n }\r\n\r\n override once<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.once(event as string, listener as Listener);\r\n }\r\n\r\n override off<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this {\r\n return super.off(event as string, listener as Listener);\r\n }\r\n\r\n override emit<K extends keyof TikTokLiveEvents>(event: K, ...args: Parameters<TikTokLiveEvents[K]>): boolean {\r\n return super.emit(event as string, ...args);\r\n }\r\n\r\n private async handleMessage(raw: any): Promise<void> {\r\n try {\r\n let bytes: Uint8Array;\r\n\r\n if (raw instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw);\r\n } else if (raw instanceof Uint8Array) {\r\n bytes = raw;\r\n } else if (typeof Blob !== 'undefined' && raw instanceof Blob) {\r\n bytes = new Uint8Array(await raw.arrayBuffer());\r\n } else if (raw?.buffer instanceof ArrayBuffer) {\r\n bytes = new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);\r\n } else {\r\n return;\r\n }\r\n\r\n this.handleFrame(bytes);\r\n } catch { }\r\n }\r\n\r\n private async handleFrame(buf: Uint8Array): Promise<void> {\r\n try {\r\n const fields = decodeProto(buf);\r\n const idField = fields.find(f => f.fn === 2 && f.wt === 0);\r\n const id = idField ? idField.value as bigint : 0n;\r\n const type = getStr(fields, 7);\r\n const binary = getBytes(fields, 8);\r\n\r\n if (id > 0n && this.ws && (this.ws.readyState === 1)) {\r\n const ack = buildAck(id);\r\n this.ws.send(ack.buffer.byteLength === ack.length ? ack.buffer : ack.buffer.slice(ack.byteOffset, ack.byteOffset + ack.byteLength));\r\n }\r\n\r\n if (type === 'msg' && binary && binary.length > 0) {\r\n let inner = binary;\r\n if (inner.length > 2 && inner[0] === 0x1f && inner[1] === 0x8b) {\r\n // Try sync first (fastest, works when zlib is loaded)\r\n const syncResult = gunzipSync(inner);\r\n if (syncResult) {\r\n inner = syncResult;\r\n } else {\r\n // Fallback to async gunzip (uses DecompressionStream or async import)\r\n inner = await gunzip(inner);\r\n }\r\n }\r\n\r\n const events = parseWebcastResponse(inner);\r\n for (const evt of events) {\r\n this._eventCount++;\r\n\r\n if (evt.type === 'battle') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n team.hostUser = host.user;\r\n }\r\n }\r\n }\r\n\r\n if (evt.type === 'battleArmies') {\r\n for (const team of evt.teams) {\r\n const host = team.users.find(u => u.user.id === team.hostUserId);\r\n if (host) {\r\n team.hostUser = host.user;\r\n this._battleHosts.set(team.hostUserId, host.user);\r\n } else {\r\n const cached = this._battleHosts.get(team.hostUserId);\r\n if (cached) team.hostUser = cached;\r\n }\r\n }\r\n }\r\n\r\n (this as TypedEmitter).emit('event', evt);\r\n (this as TypedEmitter).emit(evt.type, evt as any);\r\n }\r\n }\r\n } catch { }\r\n }\r\n\r\n private startHeartbeat(roomId: string): void {\r\n this.stopHeartbeat();\r\n this.heartbeatTimer = setInterval(() => {\r\n if (this.ws && this.ws.readyState === 1) {\r\n const hb = buildHeartbeat(roomId);\r\n this.ws.send(hb.buffer.byteLength === hb.length ? hb.buffer : hb.buffer.slice(hb.byteOffset, hb.byteOffset + hb.byteLength));\r\n }\r\n }, this.heartbeatInterval);\r\n }\r\n\r\n private stopHeartbeat(): void {\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n this.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["DEFAULT_UA","DEFAULT_SIGN_SERVER"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiktool/live",
3
- "version": "2.3.3",
3
+ "version": "2.4.0",
4
4
  "description": "TikTok LIVE API SDK — Real-time chat, gifts, battles, follows, likes & 18+ event types from any TikTok livestream via WebSocket. Zero dependencies. Works in Node.js, Bun, Deno, Cloudflare Workers & Durable Objects.",
5
5
  "author": "TikTool <hello@tik.tools>",
6
6
  "license": "MIT",
@@ -82,4 +82,4 @@
82
82
  "engines": {
83
83
  "node": ">=18"
84
84
  }
85
- }
85
+ }