@tiktool/live 2.3.4 → 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 +56 -0
- package/dist/index.d.mts +62 -1
- package/dist/index.d.ts +62 -1
- package/dist/index.js +47 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +43 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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
|
-
|
|
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
|
-
|
|
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";
|
|
@@ -1019,6 +1061,9 @@ var TikTokLive = class extends TypedEmitter {
|
|
|
1019
1061
|
callApi,
|
|
1020
1062
|
fetchSignedUrl,
|
|
1021
1063
|
resolveLivePage,
|
|
1022
|
-
resolveRoomId
|
|
1064
|
+
resolveRoomId,
|
|
1065
|
+
solvePuzzle,
|
|
1066
|
+
solveRotate,
|
|
1067
|
+
solveShapes
|
|
1023
1068
|
});
|
|
1024
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\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"]}
|
|
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
|
@@ -590,6 +590,45 @@ async function callApi(opts) {
|
|
|
590
590
|
}
|
|
591
591
|
return data1;
|
|
592
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
|
+
}
|
|
593
632
|
|
|
594
633
|
// src/client.ts
|
|
595
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";
|
|
@@ -978,6 +1017,9 @@ export {
|
|
|
978
1017
|
callApi,
|
|
979
1018
|
fetchSignedUrl,
|
|
980
1019
|
resolveLivePage,
|
|
981
|
-
resolveRoomId
|
|
1020
|
+
resolveRoomId,
|
|
1021
|
+
solvePuzzle,
|
|
1022
|
+
solveRotate,
|
|
1023
|
+
solveShapes
|
|
982
1024
|
};
|
|
983
1025
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -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\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"]}
|
|
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
|
+
"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
|
+
}
|