@tiktool/live 2.7.1 → 2.9.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/dist/index.d.mts CHANGED
@@ -74,6 +74,24 @@ interface BattleEvent extends BaseEvent {
74
74
  battleDuration: number;
75
75
  teams: BattleTeam[];
76
76
  }
77
+ interface BattleContributor {
78
+ /** TikTok userId of the gifter */
79
+ userId: string;
80
+ /** Diamond score this gifter contributed to the host's team */
81
+ score: number;
82
+ /** Display nickname (may be empty if not set on the account) */
83
+ nickname: string;
84
+ }
85
+ interface BattleHost {
86
+ /** TikTok userId of the host on this PK side */
87
+ hostUserId: string;
88
+ /** Total diamonds for this host's team */
89
+ teamTotalScore: number;
90
+ /** Side index (0 = left side, 1 = right side, …) */
91
+ teamIdx: number;
92
+ /** Per-gifter breakdown, sorted MVP first (highest score → lowest). */
93
+ contributors: BattleContributor[];
94
+ }
77
95
  interface BattleArmiesEvent extends BaseEvent {
78
96
  type: 'battleArmies';
79
97
  battleId: string;
@@ -87,6 +105,58 @@ interface BattleArmiesEvent extends BaseEvent {
87
105
  timeLeftSeconds: number;
88
106
  /** Battle end timestamp in milliseconds (battleStartMs + duration*1000). Use for clock-independent timer: Math.max(0, (endTimeMs - Date.now()) / 1000) */
89
107
  endTimeMs: number;
108
+ /** Stable match ID across multi-round PK (from top-level field 2). */
109
+ matchId?: string;
110
+ /** Per-round session ID (from top-level field 4). */
111
+ sessionId?: string;
112
+ /** TikTok server-side clock at frame emit (ms epoch). */
113
+ serverTsMs?: number;
114
+ /** Hex string tag used by TikTok for per-session matching (~34 chars). */
115
+ sessionTag?: string;
116
+ /** Total battle duration in seconds (from f18.f3). Alias for battleDurationSeconds. */
117
+ durationSec?: number;
118
+ /** Seconds remaining computed using TikTok server clock (no VPS drift). */
119
+ secsRemaining?: number;
120
+ /**
121
+ * Multi-guest host breakdown — one entry per host on a PK side.
122
+ * Each entry includes per-gifter contributors sorted MVP first.
123
+ */
124
+ hosts?: BattleHost[];
125
+ }
126
+ /**
127
+ * Battle Item Card event — booster multipliers (x2/x3), gloves, mist, thunder,
128
+ * extra-time, match-guide, etc. Emitted on `battleItemCard`.
129
+ */
130
+ interface BattleItemCardEvent extends BaseEvent {
131
+ type: 'battleItemCard';
132
+ battleId: string;
133
+ /** 2=gloves/crit, 3=mist, 4=match_guide, 10=x2?, 11=x3, … */
134
+ cardType: number;
135
+ /** 'gloves' | 'mist' | 'booster_x2' | 'booster_x3' | 'match_guide' | 'thunder' | 'extra_time' | raw resource key */
136
+ effect: string;
137
+ /** Raw TikTok resource key (e.g. 'pm_mt_boost_crit_name'). */
138
+ effectKey: string;
139
+ /** 2 or 3 for booster_x2/x3, otherwise 0. */
140
+ multiplier: number;
141
+ senderUserId: string;
142
+ senderNickname: string;
143
+ senderUniqueId: string;
144
+ /** First CDN URL for sender's avatar (best-resolution). */
145
+ senderAvatarUrl: string;
146
+ /** Unix seconds when the buff activated. */
147
+ activatedAtSec: number;
148
+ /** Total active duration in seconds. */
149
+ durationSec: number;
150
+ /** Unix seconds when the buff ends. */
151
+ endsAtSec: number;
152
+ /** Comment template, e.g. "{0:user} sent 1 magic mist". */
153
+ commentTemplate: string;
154
+ /** Full TikTok CDN URL for the card art (webp/jpeg). */
155
+ iconUrl: string;
156
+ /** Short identifier e.g. 'card_mist_v3' / 'card_crit_v3' / 'top3_buffer'. */
157
+ iconKey: string;
158
+ /** Hex e.g. '#BCD9E0' (mist blue), '#E0D4BC' (gloves tan). */
159
+ accentColor: string;
90
160
  }
91
161
  interface SubscribeEvent extends BaseEvent {
92
162
  type: 'subscribe';
@@ -140,7 +210,7 @@ interface UnknownEvent extends BaseEvent {
140
210
  type: 'unknown';
141
211
  method: string;
142
212
  }
143
- type LiveEvent = ChatEvent | MemberEvent | LikeEvent | GiftEvent | SocialEvent | RoomUserSeqEvent | BattleEvent | BattleArmiesEvent | SubscribeEvent | EmoteChatEvent | EnvelopeEvent | QuestionEvent | ControlEvent | RoomEvent | LiveIntroEvent | RankUpdateEvent | LinkMicEvent | UnknownEvent;
213
+ type LiveEvent = ChatEvent | MemberEvent | LikeEvent | GiftEvent | SocialEvent | RoomUserSeqEvent | BattleEvent | BattleArmiesEvent | BattleItemCardEvent | SubscribeEvent | EmoteChatEvent | EnvelopeEvent | QuestionEvent | ControlEvent | RoomEvent | LiveIntroEvent | RankUpdateEvent | LinkMicEvent | UnknownEvent;
144
214
  interface TikTokLiveEvents {
145
215
  connected: () => void;
146
216
  disconnected: (code: number, reason: string) => void;
@@ -154,6 +224,7 @@ interface TikTokLiveEvents {
154
224
  roomUserSeq: (event: RoomUserSeqEvent) => void;
155
225
  battle: (event: BattleEvent) => void;
156
226
  battleArmies: (event: BattleArmiesEvent) => void;
227
+ battleItemCard: (event: BattleItemCardEvent) => void;
157
228
  subscribe: (event: SubscribeEvent) => void;
158
229
  emoteChat: (event: EmoteChatEvent) => void;
159
230
  envelope: (event: EnvelopeEvent) => void;
@@ -208,6 +279,18 @@ interface TikTokLiveOptions {
208
279
  roomId?: string;
209
280
  /** Pre-resolved ttwid session cookie — skips direct TikTok page fetch when provided with roomId */
210
281
  sessionId?: string;
282
+ /**
283
+ * Optional HTTP/HTTPS proxy URL. When set, the SDK's outbound WebSocket
284
+ * (and HTTP requests) tunnel through this proxy instead of your container's
285
+ * IP. Required when running 50+ concurrent direct connections to avoid
286
+ * TikTok's per-IP rate limiting (manifests as code=1006 abnormal closes).
287
+ *
288
+ * Format: `http://user:pass@host:port` or `http://host:port`.
289
+ *
290
+ * Example (Webshare residential):
291
+ * proxy: 'http://USER:PASS@p.webshare.io:80'
292
+ */
293
+ proxy?: string;
211
294
  }
212
295
 
213
296
  declare class TikTokLive extends EventEmitter {
@@ -231,12 +314,18 @@ declare class TikTokLive extends EventEmitter {
231
314
  private readonly debug;
232
315
  private readonly _presetRoomId;
233
316
  private readonly _presetSessionId;
317
+ private readonly proxyUrl;
234
318
  constructor(options: TikTokLiveOptions);
319
+ /**
320
+ * Build an HttpsProxyAgent when `proxy` option is set, else undefined.
321
+ * Lazy-required so users without proxy don't pay the dependency cost.
322
+ */
323
+ private getProxyAgent;
235
324
  connect(): Promise<void>;
236
325
  disconnect(): void;
237
326
  /**
238
327
  * Fully destroy the client, releasing all resources and listeners.
239
- * After calling destroy(), the instance cannot be reused — create a new one.
328
+ * After calling destroy(), the instance cannot be reused — create a new one.
240
329
  */
241
330
  destroy(): void;
242
331
  get connected(): boolean;
@@ -246,7 +335,7 @@ declare class TikTokLive extends EventEmitter {
246
335
  /**
247
336
  * Get live stream video URLs for a TikTok user.
248
337
  * Returns FLV & HLS URLs segmented by quality (FULL_HD1, HD1, SD1, SD2).
249
- * This is a standalone method — no WebSocket connection required.
338
+ * This is a standalone method — no WebSocket connection required.
250
339
  *
251
340
  * @example
252
341
  * ```ts
@@ -280,4 +369,4 @@ declare class TikTokLive extends EventEmitter {
280
369
  private stopHeartbeat;
281
370
  }
282
371
 
283
- export { type BaseEvent, type BattleArmiesEvent, type BattleEvent, type BattleTeam, type BattleTeamUser, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type MemberEvent, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type SocialEvent, type StreamInfo, type StreamQuality, type StreamUrls, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent };
372
+ export { type BaseEvent, type BattleArmiesEvent, type BattleContributor, type BattleEvent, type BattleHost, type BattleItemCardEvent, type BattleTeam, type BattleTeamUser, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type MemberEvent, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type SocialEvent, type StreamInfo, type StreamQuality, type StreamUrls, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent };
package/dist/index.d.ts CHANGED
@@ -74,6 +74,24 @@ interface BattleEvent extends BaseEvent {
74
74
  battleDuration: number;
75
75
  teams: BattleTeam[];
76
76
  }
77
+ interface BattleContributor {
78
+ /** TikTok userId of the gifter */
79
+ userId: string;
80
+ /** Diamond score this gifter contributed to the host's team */
81
+ score: number;
82
+ /** Display nickname (may be empty if not set on the account) */
83
+ nickname: string;
84
+ }
85
+ interface BattleHost {
86
+ /** TikTok userId of the host on this PK side */
87
+ hostUserId: string;
88
+ /** Total diamonds for this host's team */
89
+ teamTotalScore: number;
90
+ /** Side index (0 = left side, 1 = right side, …) */
91
+ teamIdx: number;
92
+ /** Per-gifter breakdown, sorted MVP first (highest score → lowest). */
93
+ contributors: BattleContributor[];
94
+ }
77
95
  interface BattleArmiesEvent extends BaseEvent {
78
96
  type: 'battleArmies';
79
97
  battleId: string;
@@ -87,6 +105,58 @@ interface BattleArmiesEvent extends BaseEvent {
87
105
  timeLeftSeconds: number;
88
106
  /** Battle end timestamp in milliseconds (battleStartMs + duration*1000). Use for clock-independent timer: Math.max(0, (endTimeMs - Date.now()) / 1000) */
89
107
  endTimeMs: number;
108
+ /** Stable match ID across multi-round PK (from top-level field 2). */
109
+ matchId?: string;
110
+ /** Per-round session ID (from top-level field 4). */
111
+ sessionId?: string;
112
+ /** TikTok server-side clock at frame emit (ms epoch). */
113
+ serverTsMs?: number;
114
+ /** Hex string tag used by TikTok for per-session matching (~34 chars). */
115
+ sessionTag?: string;
116
+ /** Total battle duration in seconds (from f18.f3). Alias for battleDurationSeconds. */
117
+ durationSec?: number;
118
+ /** Seconds remaining computed using TikTok server clock (no VPS drift). */
119
+ secsRemaining?: number;
120
+ /**
121
+ * Multi-guest host breakdown — one entry per host on a PK side.
122
+ * Each entry includes per-gifter contributors sorted MVP first.
123
+ */
124
+ hosts?: BattleHost[];
125
+ }
126
+ /**
127
+ * Battle Item Card event — booster multipliers (x2/x3), gloves, mist, thunder,
128
+ * extra-time, match-guide, etc. Emitted on `battleItemCard`.
129
+ */
130
+ interface BattleItemCardEvent extends BaseEvent {
131
+ type: 'battleItemCard';
132
+ battleId: string;
133
+ /** 2=gloves/crit, 3=mist, 4=match_guide, 10=x2?, 11=x3, … */
134
+ cardType: number;
135
+ /** 'gloves' | 'mist' | 'booster_x2' | 'booster_x3' | 'match_guide' | 'thunder' | 'extra_time' | raw resource key */
136
+ effect: string;
137
+ /** Raw TikTok resource key (e.g. 'pm_mt_boost_crit_name'). */
138
+ effectKey: string;
139
+ /** 2 or 3 for booster_x2/x3, otherwise 0. */
140
+ multiplier: number;
141
+ senderUserId: string;
142
+ senderNickname: string;
143
+ senderUniqueId: string;
144
+ /** First CDN URL for sender's avatar (best-resolution). */
145
+ senderAvatarUrl: string;
146
+ /** Unix seconds when the buff activated. */
147
+ activatedAtSec: number;
148
+ /** Total active duration in seconds. */
149
+ durationSec: number;
150
+ /** Unix seconds when the buff ends. */
151
+ endsAtSec: number;
152
+ /** Comment template, e.g. "{0:user} sent 1 magic mist". */
153
+ commentTemplate: string;
154
+ /** Full TikTok CDN URL for the card art (webp/jpeg). */
155
+ iconUrl: string;
156
+ /** Short identifier e.g. 'card_mist_v3' / 'card_crit_v3' / 'top3_buffer'. */
157
+ iconKey: string;
158
+ /** Hex e.g. '#BCD9E0' (mist blue), '#E0D4BC' (gloves tan). */
159
+ accentColor: string;
90
160
  }
91
161
  interface SubscribeEvent extends BaseEvent {
92
162
  type: 'subscribe';
@@ -140,7 +210,7 @@ interface UnknownEvent extends BaseEvent {
140
210
  type: 'unknown';
141
211
  method: string;
142
212
  }
143
- type LiveEvent = ChatEvent | MemberEvent | LikeEvent | GiftEvent | SocialEvent | RoomUserSeqEvent | BattleEvent | BattleArmiesEvent | SubscribeEvent | EmoteChatEvent | EnvelopeEvent | QuestionEvent | ControlEvent | RoomEvent | LiveIntroEvent | RankUpdateEvent | LinkMicEvent | UnknownEvent;
213
+ type LiveEvent = ChatEvent | MemberEvent | LikeEvent | GiftEvent | SocialEvent | RoomUserSeqEvent | BattleEvent | BattleArmiesEvent | BattleItemCardEvent | SubscribeEvent | EmoteChatEvent | EnvelopeEvent | QuestionEvent | ControlEvent | RoomEvent | LiveIntroEvent | RankUpdateEvent | LinkMicEvent | UnknownEvent;
144
214
  interface TikTokLiveEvents {
145
215
  connected: () => void;
146
216
  disconnected: (code: number, reason: string) => void;
@@ -154,6 +224,7 @@ interface TikTokLiveEvents {
154
224
  roomUserSeq: (event: RoomUserSeqEvent) => void;
155
225
  battle: (event: BattleEvent) => void;
156
226
  battleArmies: (event: BattleArmiesEvent) => void;
227
+ battleItemCard: (event: BattleItemCardEvent) => void;
157
228
  subscribe: (event: SubscribeEvent) => void;
158
229
  emoteChat: (event: EmoteChatEvent) => void;
159
230
  envelope: (event: EnvelopeEvent) => void;
@@ -208,6 +279,18 @@ interface TikTokLiveOptions {
208
279
  roomId?: string;
209
280
  /** Pre-resolved ttwid session cookie — skips direct TikTok page fetch when provided with roomId */
210
281
  sessionId?: string;
282
+ /**
283
+ * Optional HTTP/HTTPS proxy URL. When set, the SDK's outbound WebSocket
284
+ * (and HTTP requests) tunnel through this proxy instead of your container's
285
+ * IP. Required when running 50+ concurrent direct connections to avoid
286
+ * TikTok's per-IP rate limiting (manifests as code=1006 abnormal closes).
287
+ *
288
+ * Format: `http://user:pass@host:port` or `http://host:port`.
289
+ *
290
+ * Example (Webshare residential):
291
+ * proxy: 'http://USER:PASS@p.webshare.io:80'
292
+ */
293
+ proxy?: string;
211
294
  }
212
295
 
213
296
  declare class TikTokLive extends EventEmitter {
@@ -231,12 +314,18 @@ declare class TikTokLive extends EventEmitter {
231
314
  private readonly debug;
232
315
  private readonly _presetRoomId;
233
316
  private readonly _presetSessionId;
317
+ private readonly proxyUrl;
234
318
  constructor(options: TikTokLiveOptions);
319
+ /**
320
+ * Build an HttpsProxyAgent when `proxy` option is set, else undefined.
321
+ * Lazy-required so users without proxy don't pay the dependency cost.
322
+ */
323
+ private getProxyAgent;
235
324
  connect(): Promise<void>;
236
325
  disconnect(): void;
237
326
  /**
238
327
  * Fully destroy the client, releasing all resources and listeners.
239
- * After calling destroy(), the instance cannot be reused — create a new one.
328
+ * After calling destroy(), the instance cannot be reused — create a new one.
240
329
  */
241
330
  destroy(): void;
242
331
  get connected(): boolean;
@@ -246,7 +335,7 @@ declare class TikTokLive extends EventEmitter {
246
335
  /**
247
336
  * Get live stream video URLs for a TikTok user.
248
337
  * Returns FLV & HLS URLs segmented by quality (FULL_HD1, HD1, SD1, SD2).
249
- * This is a standalone method — no WebSocket connection required.
338
+ * This is a standalone method — no WebSocket connection required.
250
339
  *
251
340
  * @example
252
341
  * ```ts
@@ -280,4 +369,4 @@ declare class TikTokLive extends EventEmitter {
280
369
  private stopHeartbeat;
281
370
  }
282
371
 
283
- export { type BaseEvent, type BattleArmiesEvent, type BattleEvent, type BattleTeam, type BattleTeamUser, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type MemberEvent, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type SocialEvent, type StreamInfo, type StreamQuality, type StreamUrls, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent };
372
+ export { type BaseEvent, type BattleArmiesEvent, type BattleContributor, type BattleEvent, type BattleHost, type BattleItemCardEvent, type BattleTeam, type BattleTeamUser, type ChatEvent, type ControlEvent, type EmoteChatEvent, type EnvelopeEvent, type GiftEvent, type LikeEvent, type LinkMicEvent, type LiveEvent, type LiveIntroEvent, type MemberEvent, type QuestionEvent, type RankUpdateEvent, type RoomEvent, type RoomInfo, type RoomUserSeqEvent, type SocialEvent, type StreamInfo, type StreamQuality, type StreamUrls, type SubscribeEvent, TikTokLive, type TikTokLiveEvents, type TikTokLiveOptions, type TikTokUser, type UnknownEvent };