tiktok-live-api 1.2.19 → 2.0.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 +93 -65
- package/dist/index.d.mts +275 -16
- package/dist/index.d.ts +275 -16
- package/dist/index.js +172 -20
- package/dist/index.mjs +167 -19
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
2
|
import WebSocket from "ws";
|
|
3
3
|
var WS_BASE = "wss://api.tik.tools";
|
|
4
|
-
var VERSION = "
|
|
4
|
+
var VERSION = "2.0.0";
|
|
5
|
+
var EVENT_ALIASES = {
|
|
6
|
+
roomUserSeq: ["roomUser"],
|
|
7
|
+
question: ["questionNew"],
|
|
8
|
+
battle: ["linkMicBattle"],
|
|
9
|
+
battleArmies: ["linkMicArmies"],
|
|
10
|
+
emoteChat: ["emote"]
|
|
11
|
+
};
|
|
12
|
+
var REVERSE_ALIASES = {};
|
|
13
|
+
for (const [native, aliases] of Object.entries(EVENT_ALIASES)) {
|
|
14
|
+
for (const alias of aliases) {
|
|
15
|
+
REVERSE_ALIASES[alias] = native;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
5
18
|
var TikTokLive = class {
|
|
6
19
|
/**
|
|
7
20
|
* Create a new TikTokLive client.
|
|
@@ -21,8 +34,10 @@ var TikTokLive = class {
|
|
|
21
34
|
this._intentionalClose = false;
|
|
22
35
|
this._reconnectAttempts = 0;
|
|
23
36
|
this._eventCount = 0;
|
|
37
|
+
this._roomId = "";
|
|
38
|
+
this._roomInfo = null;
|
|
24
39
|
this.uniqueId = uniqueId.replace(/^@/, "");
|
|
25
|
-
this.apiKey = options.apiKey || process.env.TIKTOOL_API_KEY || "";
|
|
40
|
+
this.apiKey = options.apiKey || options.signApiKey || process.env.TIKTOOL_API_KEY || "";
|
|
26
41
|
if (!this.apiKey) {
|
|
27
42
|
throw new Error("apiKey is required. Get a free key at https://tik.tools");
|
|
28
43
|
}
|
|
@@ -38,10 +53,17 @@ var TikTokLive = class {
|
|
|
38
53
|
return this._eventCount;
|
|
39
54
|
}
|
|
40
55
|
on(event, handler) {
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
const nativeEvent = REVERSE_ALIASES[event] || event;
|
|
57
|
+
if (!this._handlers.has(nativeEvent)) {
|
|
58
|
+
this._handlers.set(nativeEvent, /* @__PURE__ */ new Set());
|
|
59
|
+
}
|
|
60
|
+
this._handlers.get(nativeEvent).add(handler);
|
|
61
|
+
if (nativeEvent !== event) {
|
|
62
|
+
if (!this._handlers.has(event)) {
|
|
63
|
+
this._handlers.set(event, /* @__PURE__ */ new Set());
|
|
64
|
+
}
|
|
65
|
+
this._handlers.get(event).add(handler);
|
|
43
66
|
}
|
|
44
|
-
this._handlers.get(event).add(handler);
|
|
45
67
|
return this;
|
|
46
68
|
}
|
|
47
69
|
/**
|
|
@@ -51,22 +73,47 @@ var TikTokLive = class {
|
|
|
51
73
|
* @param handler - The handler to remove
|
|
52
74
|
*/
|
|
53
75
|
off(event, handler) {
|
|
54
|
-
|
|
76
|
+
const nativeEvent = REVERSE_ALIASES[event] || event;
|
|
77
|
+
this._handlers.get(nativeEvent)?.delete(handler);
|
|
78
|
+
if (nativeEvent !== event) {
|
|
79
|
+
this._handlers.get(event)?.delete(handler);
|
|
80
|
+
}
|
|
55
81
|
return this;
|
|
56
82
|
}
|
|
57
83
|
_emit(event, data) {
|
|
58
84
|
const handlers = this._handlers.get(event);
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
if (handlers) {
|
|
86
|
+
for (const handler of handlers) {
|
|
87
|
+
try {
|
|
88
|
+
const result = handler(data);
|
|
89
|
+
if (result instanceof Promise) {
|
|
90
|
+
result.catch(
|
|
91
|
+
(err) => console.error(`Error in '${event}' handler:`, err)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
} catch (err) {
|
|
95
|
+
console.error(`Error in '${event}' handler:`, err);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const aliases = EVENT_ALIASES[event];
|
|
100
|
+
if (aliases) {
|
|
101
|
+
for (const alias of aliases) {
|
|
102
|
+
const aliasHandlers = this._handlers.get(alias);
|
|
103
|
+
if (aliasHandlers) {
|
|
104
|
+
for (const handler of aliasHandlers) {
|
|
105
|
+
try {
|
|
106
|
+
const result = handler(data);
|
|
107
|
+
if (result instanceof Promise) {
|
|
108
|
+
result.catch(
|
|
109
|
+
(err) => console.error(`Error in '${alias}' handler:`, err)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.error(`Error in '${alias}' handler:`, err);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
67
116
|
}
|
|
68
|
-
} catch (err) {
|
|
69
|
-
console.error(`Error in '${event}' handler:`, err);
|
|
70
117
|
}
|
|
71
118
|
}
|
|
72
119
|
}
|
|
@@ -91,6 +138,7 @@ var TikTokLive = class {
|
|
|
91
138
|
this._connected = true;
|
|
92
139
|
this._reconnectAttempts = 0;
|
|
93
140
|
this._emit("connected", { uniqueId: this.uniqueId });
|
|
141
|
+
this._emit("websocketConnected", { uniqueId: this.uniqueId });
|
|
94
142
|
resolve();
|
|
95
143
|
});
|
|
96
144
|
this._ws.on("message", (raw) => {
|
|
@@ -99,14 +147,27 @@ var TikTokLive = class {
|
|
|
99
147
|
this._eventCount++;
|
|
100
148
|
const eventType = event.event || "unknown";
|
|
101
149
|
const data = event.data || event;
|
|
150
|
+
if (eventType === "roomInfo") {
|
|
151
|
+
this._roomId = event.roomId || data.roomId || this._roomId;
|
|
152
|
+
this._roomInfo = data;
|
|
153
|
+
}
|
|
102
154
|
this._emit("event", event);
|
|
155
|
+
this._emit("rawData", event);
|
|
156
|
+
this._emit("decodedData", event);
|
|
103
157
|
this._emit(eventType, data);
|
|
158
|
+
if (eventType === "control" && data.action === 3) {
|
|
159
|
+
this._emit("streamEnd", data);
|
|
160
|
+
}
|
|
104
161
|
} catch {
|
|
105
162
|
}
|
|
106
163
|
});
|
|
107
|
-
this._ws.on("close", () => {
|
|
164
|
+
this._ws.on("close", (code, reason) => {
|
|
108
165
|
this._connected = false;
|
|
109
|
-
this._emit("disconnected", {
|
|
166
|
+
this._emit("disconnected", {
|
|
167
|
+
uniqueId: this.uniqueId,
|
|
168
|
+
code,
|
|
169
|
+
reason: reason?.toString()
|
|
170
|
+
});
|
|
110
171
|
this._maybeReconnect();
|
|
111
172
|
});
|
|
112
173
|
this._ws.on("error", (err) => {
|
|
@@ -126,6 +187,23 @@ var TikTokLive = class {
|
|
|
126
187
|
}
|
|
127
188
|
this._connected = false;
|
|
128
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Get current connection state (TTLC-compatible).
|
|
192
|
+
*/
|
|
193
|
+
getState() {
|
|
194
|
+
return {
|
|
195
|
+
isConnected: this._connected,
|
|
196
|
+
roomId: this._roomId,
|
|
197
|
+
roomInfo: this._roomInfo,
|
|
198
|
+
uniqueId: this.uniqueId
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get room info (TTLC-compatible).
|
|
203
|
+
*/
|
|
204
|
+
getRoomInfo() {
|
|
205
|
+
return this._roomInfo;
|
|
206
|
+
}
|
|
129
207
|
async _maybeReconnect() {
|
|
130
208
|
if (this._intentionalClose || !this.autoReconnect || this._reconnectAttempts >= this.maxReconnectAttempts) {
|
|
131
209
|
return;
|
|
@@ -247,7 +325,77 @@ var TikTokCaptions = class {
|
|
|
247
325
|
this._connected = false;
|
|
248
326
|
}
|
|
249
327
|
};
|
|
328
|
+
|
|
329
|
+
// src/compat.ts
|
|
330
|
+
var ControlEvents = {
|
|
331
|
+
CONNECTED: "connected",
|
|
332
|
+
DISCONNECTED: "disconnected",
|
|
333
|
+
ERROR: "error",
|
|
334
|
+
RAWDATA: "rawData",
|
|
335
|
+
DECODEDDATA: "decodedData",
|
|
336
|
+
STREAMEND: "streamEnd",
|
|
337
|
+
WSCONNECTED: "websocketConnected"
|
|
338
|
+
};
|
|
339
|
+
var MessageEvents = {
|
|
340
|
+
CHAT: "chat",
|
|
341
|
+
MEMBER: "member",
|
|
342
|
+
GIFT: "gift",
|
|
343
|
+
ROOMUSER: "roomUser",
|
|
344
|
+
SOCIAL: "social",
|
|
345
|
+
LIKE: "like",
|
|
346
|
+
QUESTIONNEW: "questionNew",
|
|
347
|
+
LINKMICBATTLE: "linkMicBattle",
|
|
348
|
+
LINKMICARMIES: "linkMicArmies",
|
|
349
|
+
LIVEINTRO: "liveIntro",
|
|
350
|
+
EMOTE: "emote",
|
|
351
|
+
ENVELOPE: "envelope",
|
|
352
|
+
SUBSCRIBE: "subscribe",
|
|
353
|
+
BARRAGE: "barrage",
|
|
354
|
+
SUPERFAN: "superFan",
|
|
355
|
+
SUPERFANJOIN: "superFanJoin",
|
|
356
|
+
SUPERFANBOX: "superFanBox",
|
|
357
|
+
ROOMPIN: "roomPin"
|
|
358
|
+
};
|
|
359
|
+
var CustomEvents = {
|
|
360
|
+
FOLLOW: "follow",
|
|
361
|
+
SHARE: "share"
|
|
362
|
+
};
|
|
363
|
+
var WebcastPushConnection = class extends TikTokLive {
|
|
364
|
+
constructor(uniqueId, options = {}) {
|
|
365
|
+
const opts = {
|
|
366
|
+
...options,
|
|
367
|
+
apiKey: options.apiKey || options.signApiKey
|
|
368
|
+
};
|
|
369
|
+
super(uniqueId, opts);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get current connection state — TTLC-compatible shape.
|
|
373
|
+
*
|
|
374
|
+
* Returns the same structure as TikTok-Live-Connector's `getState()`.
|
|
375
|
+
*/
|
|
376
|
+
getState() {
|
|
377
|
+
return {
|
|
378
|
+
isConnected: this._connected,
|
|
379
|
+
upgradedToWebsocket: this._connected,
|
|
380
|
+
roomId: this._roomId,
|
|
381
|
+
roomInfo: this._roomInfo,
|
|
382
|
+
availableGifts: [],
|
|
383
|
+
uniqueId: this.uniqueId
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Get available gifts — TTLC-compatible.
|
|
388
|
+
* Note: Gift info is included in event payloads automatically.
|
|
389
|
+
*/
|
|
390
|
+
getAvailableGifts() {
|
|
391
|
+
return [];
|
|
392
|
+
}
|
|
393
|
+
};
|
|
250
394
|
export {
|
|
395
|
+
ControlEvents,
|
|
396
|
+
CustomEvents,
|
|
397
|
+
MessageEvents,
|
|
251
398
|
TikTokCaptions,
|
|
252
|
-
TikTokLive
|
|
399
|
+
TikTokLive,
|
|
400
|
+
WebcastPushConnection
|
|
253
401
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiktok-live-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Unofficial TikTok LIVE API Client — Real-time chat, gifts, viewers, battles, and AI live captions from any TikTok livestream. Managed WebSocket API with 99.9% uptime.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -85,4 +85,4 @@
|
|
|
85
85
|
"engines": {
|
|
86
86
|
"node": ">=16.0.0"
|
|
87
87
|
}
|
|
88
|
-
}
|
|
88
|
+
}
|