@tiktool/live 2.4.4 → 2.4.6
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 +119 -363
- package/dist/index.d.mts +324 -135
- package/dist/index.d.ts +324 -135
- package/dist/index.js +491 -402
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +489 -395
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -28
package/dist/index.d.ts
CHANGED
|
@@ -1,28 +1,22 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
|
|
1
3
|
interface TikTokUser {
|
|
2
4
|
id: string;
|
|
3
5
|
nickname: string;
|
|
4
6
|
uniqueId: string;
|
|
5
|
-
|
|
7
|
+
profilePicture?: string;
|
|
6
8
|
profilePictureUrl?: string;
|
|
7
|
-
followRole?: number;
|
|
8
9
|
badges?: string[];
|
|
9
|
-
level?: number;
|
|
10
10
|
}
|
|
11
11
|
interface BaseEvent {
|
|
12
12
|
type: string;
|
|
13
13
|
timestamp: number;
|
|
14
14
|
msgId: string;
|
|
15
15
|
}
|
|
16
|
-
interface ChatEmote {
|
|
17
|
-
id: string;
|
|
18
|
-
url: string;
|
|
19
|
-
name: string;
|
|
20
|
-
}
|
|
21
16
|
interface ChatEvent extends BaseEvent {
|
|
22
17
|
type: 'chat';
|
|
23
18
|
user: TikTokUser;
|
|
24
19
|
comment: string;
|
|
25
|
-
emotes?: ChatEmote[];
|
|
26
20
|
}
|
|
27
21
|
interface MemberEvent extends BaseEvent {
|
|
28
22
|
type: 'member';
|
|
@@ -64,9 +58,9 @@ interface BattleTeamUser {
|
|
|
64
58
|
}
|
|
65
59
|
interface BattleTeam {
|
|
66
60
|
hostUserId: string;
|
|
67
|
-
hostUser?: TikTokUser;
|
|
68
61
|
score: number;
|
|
69
62
|
users: BattleTeamUser[];
|
|
63
|
+
hostUser?: TikTokUser;
|
|
70
64
|
}
|
|
71
65
|
interface BattleEvent extends BaseEvent {
|
|
72
66
|
type: 'battle';
|
|
@@ -74,12 +68,43 @@ interface BattleEvent extends BaseEvent {
|
|
|
74
68
|
status: number;
|
|
75
69
|
battleDuration: number;
|
|
76
70
|
teams: BattleTeam[];
|
|
71
|
+
battleSettings?: {
|
|
72
|
+
startTimeMs?: number;
|
|
73
|
+
duration?: number;
|
|
74
|
+
endTimeMs?: number;
|
|
75
|
+
};
|
|
77
76
|
}
|
|
78
77
|
interface BattleArmiesEvent extends BaseEvent {
|
|
79
78
|
type: 'battleArmies';
|
|
80
79
|
battleId: string;
|
|
81
80
|
status: number;
|
|
82
81
|
teams: BattleTeam[];
|
|
82
|
+
battleSettings?: {
|
|
83
|
+
startTimeMs?: number;
|
|
84
|
+
duration?: number;
|
|
85
|
+
endTimeMs?: number;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
interface BattleTaskEvent extends BaseEvent {
|
|
89
|
+
type: 'battleTask';
|
|
90
|
+
taskAction: number;
|
|
91
|
+
battleRefId: string;
|
|
92
|
+
missionType: string;
|
|
93
|
+
multiplier: number;
|
|
94
|
+
missionDuration: number;
|
|
95
|
+
missionTarget: number;
|
|
96
|
+
remainingSeconds: number;
|
|
97
|
+
endTimestampS: number;
|
|
98
|
+
timerType: number;
|
|
99
|
+
}
|
|
100
|
+
interface BarrageEvent extends BaseEvent {
|
|
101
|
+
type: 'barrage';
|
|
102
|
+
msgType: number;
|
|
103
|
+
subType: number;
|
|
104
|
+
displayType: number;
|
|
105
|
+
duration: number;
|
|
106
|
+
defaultPattern: string;
|
|
107
|
+
content: string;
|
|
83
108
|
}
|
|
84
109
|
interface SubscribeEvent extends BaseEvent {
|
|
85
110
|
type: 'subscribe';
|
|
@@ -91,6 +116,7 @@ interface EmoteChatEvent extends BaseEvent {
|
|
|
91
116
|
user: TikTokUser;
|
|
92
117
|
emoteId: string;
|
|
93
118
|
emoteUrl: string;
|
|
119
|
+
emoteName?: string;
|
|
94
120
|
}
|
|
95
121
|
interface EnvelopeEvent extends BaseEvent {
|
|
96
122
|
type: 'envelope';
|
|
@@ -133,7 +159,7 @@ interface UnknownEvent extends BaseEvent {
|
|
|
133
159
|
type: 'unknown';
|
|
134
160
|
method: string;
|
|
135
161
|
}
|
|
136
|
-
type LiveEvent = ChatEvent | MemberEvent | LikeEvent | GiftEvent | SocialEvent | RoomUserSeqEvent | BattleEvent | BattleArmiesEvent | SubscribeEvent | EmoteChatEvent | EnvelopeEvent | QuestionEvent | ControlEvent | RoomEvent | LiveIntroEvent | RankUpdateEvent | LinkMicEvent | UnknownEvent;
|
|
162
|
+
type LiveEvent = ChatEvent | MemberEvent | LikeEvent | GiftEvent | SocialEvent | RoomUserSeqEvent | BattleEvent | BattleArmiesEvent | BattleTaskEvent | BarrageEvent | SubscribeEvent | EmoteChatEvent | EnvelopeEvent | QuestionEvent | ControlEvent | RoomEvent | LiveIntroEvent | RankUpdateEvent | LinkMicEvent | UnknownEvent;
|
|
137
163
|
interface TikTokLiveEvents {
|
|
138
164
|
connected: () => void;
|
|
139
165
|
disconnected: (code: number, reason: string) => void;
|
|
@@ -147,6 +173,8 @@ interface TikTokLiveEvents {
|
|
|
147
173
|
roomUserSeq: (event: RoomUserSeqEvent) => void;
|
|
148
174
|
battle: (event: BattleEvent) => void;
|
|
149
175
|
battleArmies: (event: BattleArmiesEvent) => void;
|
|
176
|
+
battleTask: (event: BattleTaskEvent) => void;
|
|
177
|
+
barrage: (event: BarrageEvent) => void;
|
|
150
178
|
subscribe: (event: SubscribeEvent) => void;
|
|
151
179
|
emoteChat: (event: EmoteChatEvent) => void;
|
|
152
180
|
envelope: (event: EnvelopeEvent) => void;
|
|
@@ -164,6 +192,7 @@ interface RoomInfo {
|
|
|
164
192
|
wsHost: string;
|
|
165
193
|
clusterRegion: string;
|
|
166
194
|
connectedAt: string;
|
|
195
|
+
ownerUserId?: string;
|
|
167
196
|
}
|
|
168
197
|
interface TikTokLiveOptions {
|
|
169
198
|
uniqueId: string;
|
|
@@ -174,49 +203,155 @@ interface TikTokLiveOptions {
|
|
|
174
203
|
heartbeatInterval?: number;
|
|
175
204
|
debug?: boolean;
|
|
176
205
|
webSocketImpl?: any;
|
|
206
|
+
/**
|
|
207
|
+
* TikTok browser session ID cookie for authenticated connections.
|
|
208
|
+
* Enables ranklist API access and authenticated WebSocket features.
|
|
209
|
+
* Obtain from the user's tiktok.com browser cookies.
|
|
210
|
+
*/
|
|
211
|
+
sessionId?: string;
|
|
212
|
+
/**
|
|
213
|
+
* TikTok target IDC region (e.g. 'useast5').
|
|
214
|
+
* Required when sessionId is provided — must match the account's region.
|
|
215
|
+
*/
|
|
216
|
+
ttTargetIdc?: string;
|
|
217
|
+
}
|
|
218
|
+
interface RanklistUser {
|
|
219
|
+
/** TikTok user ID */
|
|
220
|
+
id_str: string;
|
|
221
|
+
/** Display name */
|
|
222
|
+
nickname: string;
|
|
223
|
+
/** Username (@handle) */
|
|
224
|
+
display_id?: string;
|
|
225
|
+
unique_id?: string;
|
|
226
|
+
/** Avatar thumbnail URLs */
|
|
227
|
+
avatar_thumb?: {
|
|
228
|
+
url_list: string[];
|
|
229
|
+
};
|
|
230
|
+
/** Full avatar URLs */
|
|
231
|
+
avatar_medium?: {
|
|
232
|
+
url_list: string[];
|
|
233
|
+
};
|
|
234
|
+
/** Follower info */
|
|
235
|
+
follow_info?: {
|
|
236
|
+
follow_status: number;
|
|
237
|
+
follower_count: number;
|
|
238
|
+
following_count: number;
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Entry from online_audience endpoint (in-room top gifters).
|
|
243
|
+
* Has explicit `rank` (1-based) and `score` fields.
|
|
244
|
+
*/
|
|
245
|
+
interface OnlineAudienceEntry {
|
|
246
|
+
rank: number;
|
|
247
|
+
score: number;
|
|
248
|
+
user: RanklistUser;
|
|
177
249
|
}
|
|
178
|
-
/**
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
250
|
+
/**
|
|
251
|
+
* Entry from anchor/rank_list endpoint (leaderboard/gifter rankings).
|
|
252
|
+
* Position is the array index. Uses `value` (not `score`).
|
|
253
|
+
*/
|
|
254
|
+
interface AnchorRankListEntry {
|
|
255
|
+
/** Gift value (diamonds/coins) */
|
|
256
|
+
value: number;
|
|
257
|
+
/** Rank category type (e.g. 3 = gifter) */
|
|
258
|
+
rank_type: number;
|
|
259
|
+
/** Time period type (e.g. 1 = hourly) */
|
|
260
|
+
rank_time_type: number;
|
|
261
|
+
/** Auto-thanks message configured by anchor */
|
|
262
|
+
auto_thanks_message?: string;
|
|
263
|
+
/** Schema URL for navigation */
|
|
264
|
+
schema_url?: string;
|
|
265
|
+
/** Highlight DM share status */
|
|
266
|
+
highlight_dm_share_status?: number;
|
|
267
|
+
/** Ranked user data */
|
|
268
|
+
user: RanklistUser;
|
|
269
|
+
}
|
|
270
|
+
interface RanklistSelfInfo {
|
|
271
|
+
rank: number;
|
|
272
|
+
score: number;
|
|
273
|
+
gap_description?: string;
|
|
274
|
+
}
|
|
275
|
+
/** Response from "online_audience" sub-endpoint — in-room top gifters */
|
|
276
|
+
interface OnlineAudienceResponse {
|
|
277
|
+
status_code: number;
|
|
278
|
+
data: {
|
|
279
|
+
ranks: OnlineAudienceEntry[];
|
|
280
|
+
self_info?: RanklistSelfInfo;
|
|
281
|
+
currency?: string;
|
|
282
|
+
total?: number;
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
/** Response from "anchor_rank_list" sub-endpoint — gifter leaderboard */
|
|
286
|
+
interface AnchorRankListResponse {
|
|
287
|
+
status_code: number;
|
|
288
|
+
data: {
|
|
289
|
+
rank_list: AnchorRankListEntry[];
|
|
290
|
+
/** Room where ranks were accumulated */
|
|
291
|
+
latest_room_id_str?: string;
|
|
292
|
+
/** Rank period start (unix timestamp) */
|
|
293
|
+
rank_time_begin?: number;
|
|
294
|
+
/** Rank period end (unix timestamp) */
|
|
295
|
+
rank_time_end?: number;
|
|
296
|
+
/** Whether to show rank summary */
|
|
297
|
+
show_rank_summary?: boolean;
|
|
298
|
+
/** Default rank type for this anchor */
|
|
299
|
+
default_rank_type?: number;
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/** Entrance tab info from "entrance" sub-endpoint */
|
|
303
|
+
interface EntranceTab {
|
|
304
|
+
title: string;
|
|
305
|
+
rank_type: number;
|
|
306
|
+
list_lynx_type?: number;
|
|
307
|
+
}
|
|
308
|
+
/** Entrance config for a single rank_type */
|
|
309
|
+
interface EntranceInfo {
|
|
310
|
+
rank_type: number;
|
|
311
|
+
/** Whether the anchor appears in this ranking */
|
|
312
|
+
owner_on_rank: boolean;
|
|
313
|
+
/** Anchor's position in this ranking (0-based) */
|
|
314
|
+
owner_rank_idx?: number;
|
|
315
|
+
/** Current score in this ranking */
|
|
316
|
+
current_score?: number;
|
|
317
|
+
/** Countdown in seconds until ranking resets */
|
|
318
|
+
countdown?: number;
|
|
319
|
+
/** Window size in seconds (86400 = daily) */
|
|
320
|
+
window_size?: number;
|
|
321
|
+
/** Unix timestamp when ranking resets */
|
|
322
|
+
reset_time?: number;
|
|
323
|
+
/** Related tab to show when clicking this entrance */
|
|
324
|
+
related_tab_rank_type?: number;
|
|
325
|
+
/** Gap description with points needed to reach a rank */
|
|
326
|
+
affiliated_content?: {
|
|
327
|
+
gap_desc?: {
|
|
328
|
+
default_pattern: string;
|
|
329
|
+
pieces?: Array<{
|
|
330
|
+
string_value: string;
|
|
331
|
+
type: number;
|
|
332
|
+
}>;
|
|
333
|
+
};
|
|
200
334
|
};
|
|
201
|
-
/**
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
335
|
+
/** Class/League info */
|
|
336
|
+
class_info?: {
|
|
337
|
+
class_type: number;
|
|
338
|
+
star_count: number;
|
|
205
339
|
};
|
|
206
|
-
/** Confidence score (0.0–1.0) */
|
|
207
|
-
confidence: number;
|
|
208
340
|
}
|
|
341
|
+
interface EntranceResponse {
|
|
342
|
+
status_code: number;
|
|
343
|
+
data: Array<{
|
|
344
|
+
group_type?: number;
|
|
345
|
+
Priority?: number;
|
|
346
|
+
data?: {
|
|
347
|
+
tabs?: EntranceTab[];
|
|
348
|
+
entrances?: EntranceInfo[];
|
|
349
|
+
};
|
|
350
|
+
}>;
|
|
351
|
+
}
|
|
352
|
+
type RanklistResponse = OnlineAudienceResponse | AnchorRankListResponse | EntranceResponse;
|
|
209
353
|
|
|
210
|
-
|
|
211
|
-
declare class TypedEmitter {
|
|
212
|
-
private _listeners;
|
|
213
|
-
on(event: string, fn: Listener): this;
|
|
214
|
-
once(event: string, fn: Listener): this;
|
|
215
|
-
off(event: string, fn: Listener): this;
|
|
216
|
-
emit(event: string, ...args: any[]): boolean;
|
|
217
|
-
removeAllListeners(event?: string): this;
|
|
218
|
-
}
|
|
219
|
-
declare class TikTokLive extends TypedEmitter {
|
|
354
|
+
declare class TikTokLive extends EventEmitter {
|
|
220
355
|
private ws;
|
|
221
356
|
private heartbeatTimer;
|
|
222
357
|
private reconnectAttempts;
|
|
@@ -224,7 +359,7 @@ declare class TikTokLive extends TypedEmitter {
|
|
|
224
359
|
private _connected;
|
|
225
360
|
private _eventCount;
|
|
226
361
|
private _roomId;
|
|
227
|
-
private
|
|
362
|
+
private _ownerUserId;
|
|
228
363
|
private readonly uniqueId;
|
|
229
364
|
private readonly signServerUrl;
|
|
230
365
|
private readonly apiKey;
|
|
@@ -232,119 +367,173 @@ declare class TikTokLive extends TypedEmitter {
|
|
|
232
367
|
private readonly maxReconnectAttempts;
|
|
233
368
|
private readonly heartbeatInterval;
|
|
234
369
|
private readonly debug;
|
|
235
|
-
private
|
|
236
|
-
private
|
|
370
|
+
private _sessionId?;
|
|
371
|
+
private _ttTargetIdc?;
|
|
237
372
|
constructor(options: TikTokLiveOptions);
|
|
238
373
|
connect(): Promise<void>;
|
|
239
374
|
disconnect(): void;
|
|
240
375
|
get connected(): boolean;
|
|
241
376
|
get eventCount(): number;
|
|
242
377
|
get roomId(): string;
|
|
378
|
+
/** Get the stored session ID (if any) */
|
|
379
|
+
get sessionId(): string | undefined;
|
|
380
|
+
/** Update the session ID at runtime (e.g. after TikTok login) */
|
|
381
|
+
setSession(sessionId: string, ttTargetIdc?: string): void;
|
|
382
|
+
/**
|
|
383
|
+
* Build a cookie header string for authenticated API requests (e.g. ranklist).
|
|
384
|
+
* Returns undefined if no session is set.
|
|
385
|
+
*/
|
|
386
|
+
buildSessionCookieHeader(): string | undefined;
|
|
243
387
|
on<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this;
|
|
244
388
|
once<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this;
|
|
245
389
|
off<K extends keyof TikTokLiveEvents>(event: K, listener: TikTokLiveEvents[K]): this;
|
|
246
390
|
emit<K extends keyof TikTokLiveEvents>(event: K, ...args: Parameters<TikTokLiveEvents[K]>): boolean;
|
|
247
|
-
private handleMessage;
|
|
248
391
|
private handleFrame;
|
|
249
392
|
private startHeartbeat;
|
|
250
393
|
private stopHeartbeat;
|
|
251
394
|
}
|
|
252
395
|
|
|
396
|
+
interface GetRanklistOptions {
|
|
397
|
+
/** API server URL (default: https://api.tik.tools) */
|
|
398
|
+
serverUrl?: string;
|
|
399
|
+
/** API key for authentication */
|
|
400
|
+
apiKey: string;
|
|
401
|
+
/** TikTok username to look up (auto-resolves room_id and anchor_id) */
|
|
402
|
+
uniqueId?: string;
|
|
403
|
+
/** Direct room ID (skip resolution) */
|
|
404
|
+
roomId?: string;
|
|
405
|
+
/** Direct anchor/owner ID (skip resolution) */
|
|
406
|
+
anchorId?: string;
|
|
407
|
+
/**
|
|
408
|
+
* TikTok session cookie string for authentication.
|
|
409
|
+
* Required — ranklist endpoints return 20003 without login.
|
|
410
|
+
* Example: "sessionid=abc123; sid_guard=def456"
|
|
411
|
+
*/
|
|
412
|
+
sessionCookie?: string;
|
|
413
|
+
/**
|
|
414
|
+
* Which ranklist sub-endpoint to call:
|
|
415
|
+
* - "online_audience" (default) — top gifters with scores
|
|
416
|
+
* - "anchor_rank_list" — gifter ranking by rank_type
|
|
417
|
+
* - "entrance" — entrance UI metadata, tabs, gap-to-rank
|
|
418
|
+
*/
|
|
419
|
+
type?: 'online_audience' | 'anchor_rank_list' | 'entrance';
|
|
420
|
+
/**
|
|
421
|
+
* For "anchor_rank_list" type only:
|
|
422
|
+
* - "1" = hourly ranking (default)
|
|
423
|
+
* - "8" = daily ranking
|
|
424
|
+
*/
|
|
425
|
+
rankType?: string;
|
|
426
|
+
}
|
|
253
427
|
/**
|
|
254
|
-
*
|
|
428
|
+
* Fetch ranked user lists from TikTok via the sign server.
|
|
255
429
|
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
430
|
+
* When `sessionCookie` is provided, the server returns a **sign-and-return**
|
|
431
|
+
* response with a signed URL that you must fetch from your own IP
|
|
432
|
+
* (TikTok sessions are IP-bound). Check for `sign_and_return: true` in
|
|
433
|
+
* the response to detect this mode.
|
|
260
434
|
*
|
|
261
|
-
* @
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
*
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* Results are cached for 5 minutes.
|
|
435
|
+
* @example
|
|
436
|
+
* ```ts
|
|
437
|
+
* const data = await getRanklist({
|
|
438
|
+
* apiKey: 'your-key',
|
|
439
|
+
* uniqueId: 'katarina.live',
|
|
440
|
+
* sessionCookie: 'sessionid=abc; sid_guard=def',
|
|
441
|
+
* type: 'online_audience',
|
|
442
|
+
* });
|
|
443
|
+
*
|
|
444
|
+
* if (data.sign_and_return) {
|
|
445
|
+
* // Fetch the signed URL from YOUR IP with your session cookie
|
|
446
|
+
* const resp = await fetch(data.signed_url, {
|
|
447
|
+
* method: data.method,
|
|
448
|
+
* headers: { ...data.headers, Cookie: sessionCookie },
|
|
449
|
+
* ...(data.body ? { body: data.body } : {}),
|
|
450
|
+
* });
|
|
451
|
+
* const tikData = await resp.json();
|
|
452
|
+
* console.log(tikData); // TikTok's raw response
|
|
453
|
+
* } else {
|
|
454
|
+
* console.log(data); // Direct TikTok response (no session)
|
|
455
|
+
* }
|
|
456
|
+
* ```
|
|
284
457
|
*/
|
|
285
|
-
declare function
|
|
286
|
-
|
|
458
|
+
declare function getRanklist(opts: GetRanklistOptions): Promise<RanklistResponse>;
|
|
459
|
+
|
|
460
|
+
interface GetRegionalRanklistOptions {
|
|
461
|
+
/** API server URL (default: https://api.tik.tools) */
|
|
462
|
+
serverUrl?: string;
|
|
463
|
+
/** API key for authentication (Pro or Ultra tier required) */
|
|
464
|
+
apiKey: string;
|
|
465
|
+
/** TikTok username to look up (auto-resolves room_id and anchor_id) */
|
|
466
|
+
uniqueId?: string;
|
|
467
|
+
/** Direct room ID (skip resolution) */
|
|
468
|
+
roomId?: string;
|
|
469
|
+
/** Direct anchor/owner ID (skip resolution) */
|
|
470
|
+
anchorId?: string;
|
|
471
|
+
/**
|
|
472
|
+
* Ranking period:
|
|
473
|
+
* - "1" = Hourly
|
|
474
|
+
* - "8" = Daily (default)
|
|
475
|
+
* - "15" = Popular LIVE
|
|
476
|
+
* - "16" = League
|
|
477
|
+
*/
|
|
478
|
+
rankType?: '1' | '8' | '15' | '16';
|
|
479
|
+
/**
|
|
480
|
+
* Sub-endpoint type:
|
|
481
|
+
* - "list" (default) — ranked users with scores
|
|
482
|
+
* - "entrance" — available ranking tabs/metadata
|
|
483
|
+
*/
|
|
484
|
+
type?: 'list' | 'entrance';
|
|
485
|
+
/** Gap interval filter (default: "0") */
|
|
486
|
+
gapInterval?: string;
|
|
487
|
+
}
|
|
488
|
+
interface RegionalRanklistSignedResponse {
|
|
489
|
+
/** Always 0 on success */
|
|
287
490
|
status_code: number;
|
|
288
|
-
|
|
491
|
+
/** Always "fetch_signed_url" */
|
|
492
|
+
action: string;
|
|
493
|
+
/** The signed TikTok URL to POST */
|
|
289
494
|
signed_url: string;
|
|
495
|
+
/** HTTP method (always POST) */
|
|
496
|
+
method: string;
|
|
497
|
+
/** Required headers for the fetch */
|
|
290
498
|
headers: Record<string, string>;
|
|
499
|
+
/** URL-encoded POST body */
|
|
500
|
+
body: string;
|
|
501
|
+
/** Cookies to include (ttwid etc.) — append your sessionid */
|
|
291
502
|
cookies: string;
|
|
503
|
+
/** Human-readable note */
|
|
504
|
+
note: string;
|
|
292
505
|
}
|
|
293
506
|
/**
|
|
294
|
-
*
|
|
295
|
-
* parsed JSON data from TikTok.
|
|
296
|
-
*/
|
|
297
|
-
declare function fetchSignedUrl(response: SignedUrlResponse): Promise<any>;
|
|
298
|
-
interface CallApiOptions {
|
|
299
|
-
/** API server URL (default: https://api.tik.tools) */
|
|
300
|
-
serverUrl?: string;
|
|
301
|
-
/** API key for authentication */
|
|
302
|
-
apiKey: string;
|
|
303
|
-
/** API endpoint path (e.g. '/webcast/room_video') */
|
|
304
|
-
endpoint: string;
|
|
305
|
-
/** TikTok unique_id to resolve */
|
|
306
|
-
uniqueId: string;
|
|
307
|
-
/** HTTP method (default: POST) */
|
|
308
|
-
method?: 'GET' | 'POST';
|
|
309
|
-
/** Additional body fields for POST requests */
|
|
310
|
-
extraBody?: Record<string, any>;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Call a TikTool API endpoint, handling the full
|
|
314
|
-
* resolve_required → room_id → signed_url → fetch flow automatically.
|
|
507
|
+
* Get a signed URL for fetching regional LIVE leaderboard data.
|
|
315
508
|
*
|
|
316
|
-
*
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Solve a puzzle (slider) CAPTCHA using the TikTool solver.
|
|
509
|
+
* **Two-step pattern**: TikTok sessions are IP-bound, so instead of
|
|
510
|
+
* server-side fetching, this returns a signed URL with headers/body
|
|
511
|
+
* that you POST from your own IP with your session cookie.
|
|
322
512
|
*
|
|
323
|
-
*
|
|
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.
|
|
513
|
+
* Requires **Pro** or **Ultra** API key tier.
|
|
332
514
|
*
|
|
333
|
-
* @
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```ts
|
|
517
|
+
* // Step 1: Get signed URL
|
|
518
|
+
* const signed = await getRegionalRanklist({
|
|
519
|
+
* apiKey: 'your-pro-key',
|
|
520
|
+
* roomId: '7607695933891218198',
|
|
521
|
+
* anchorId: '7444599004337652758',
|
|
522
|
+
* rankType: '8', // Daily
|
|
523
|
+
* });
|
|
342
524
|
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
525
|
+
* // Step 2: Fetch from YOUR IP with YOUR session
|
|
526
|
+
* const resp = await fetch(signed.signed_url, {
|
|
527
|
+
* method: signed.method,
|
|
528
|
+
* headers: { ...signed.headers, Cookie: `sessionid=YOUR_SID; ${signed.cookies}` },
|
|
529
|
+
* body: signed.body,
|
|
530
|
+
* });
|
|
531
|
+
* const { data } = await resp.json();
|
|
532
|
+
* data.rank_view.ranks.forEach((r, i) =>
|
|
533
|
+
* console.log(`${i+1}. ${r.user.nickname} — ${r.score} pts`)
|
|
534
|
+
* );
|
|
535
|
+
* ```
|
|
347
536
|
*/
|
|
348
|
-
declare function
|
|
537
|
+
declare function getRegionalRanklist(opts: GetRegionalRanklistOptions): Promise<RegionalRanklistSignedResponse>;
|
|
349
538
|
|
|
350
|
-
export { type BaseEvent, type BattleArmiesEvent, type BattleEvent, type
|
|
539
|
+
export { type AnchorRankListEntry, type AnchorRankListResponse, type BarrageEvent, type BaseEvent, type BattleArmiesEvent, type BattleEvent, type BattleTaskEvent, type BattleTeam, type BattleTeamUser, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EntranceInfo, type EntranceResponse, type EntranceTab, type EnvelopeEvent, type GetRanklistOptions, type GetRegionalRanklistOptions, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type MemberEvent, type OnlineAudienceEntry, type OnlineAudienceResponse, type QuestionEvent, type RankUpdateEvent, type RanklistResponse, type RanklistSelfInfo, type RanklistUser, type RegionalRanklistSignedResponse, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type SocialEvent, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent, getRanklist, getRegionalRanklist };
|