@tiktool/live 1.2.0 → 1.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/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +210 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +210 -62
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -56,6 +56,7 @@ interface BattleTeamUser {
|
|
|
56
56
|
}
|
|
57
57
|
interface BattleTeam {
|
|
58
58
|
hostUserId: string;
|
|
59
|
+
hostUser?: TikTokUser;
|
|
59
60
|
score: number;
|
|
60
61
|
users: BattleTeamUser[];
|
|
61
62
|
}
|
|
@@ -69,6 +70,7 @@ interface BattleEvent extends BaseEvent {
|
|
|
69
70
|
interface BattleArmiesEvent extends BaseEvent {
|
|
70
71
|
type: 'battleArmies';
|
|
71
72
|
battleId: string;
|
|
73
|
+
status: number;
|
|
72
74
|
teams: BattleTeam[];
|
|
73
75
|
}
|
|
74
76
|
interface SubscribeEvent extends BaseEvent {
|
|
@@ -173,6 +175,7 @@ declare class TikTokLive extends EventEmitter {
|
|
|
173
175
|
private _connected;
|
|
174
176
|
private _eventCount;
|
|
175
177
|
private _roomId;
|
|
178
|
+
private _battleHosts;
|
|
176
179
|
private readonly uniqueId;
|
|
177
180
|
private readonly signServerUrl;
|
|
178
181
|
private readonly apiKey;
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ interface BattleTeamUser {
|
|
|
56
56
|
}
|
|
57
57
|
interface BattleTeam {
|
|
58
58
|
hostUserId: string;
|
|
59
|
+
hostUser?: TikTokUser;
|
|
59
60
|
score: number;
|
|
60
61
|
users: BattleTeamUser[];
|
|
61
62
|
}
|
|
@@ -69,6 +70,7 @@ interface BattleEvent extends BaseEvent {
|
|
|
69
70
|
interface BattleArmiesEvent extends BaseEvent {
|
|
70
71
|
type: 'battleArmies';
|
|
71
72
|
battleId: string;
|
|
73
|
+
status: number;
|
|
72
74
|
teams: BattleTeam[];
|
|
73
75
|
}
|
|
74
76
|
interface SubscribeEvent extends BaseEvent {
|
|
@@ -173,6 +175,7 @@ declare class TikTokLive extends EventEmitter {
|
|
|
173
175
|
private _connected;
|
|
174
176
|
private _eventCount;
|
|
175
177
|
private _roomId;
|
|
178
|
+
private _battleHosts;
|
|
176
179
|
private readonly uniqueId;
|
|
177
180
|
private readonly signServerUrl;
|
|
178
181
|
private readonly apiKey;
|
package/dist/index.js
CHANGED
|
@@ -159,80 +159,147 @@ function buildAck(id) {
|
|
|
159
159
|
function parseUser(data) {
|
|
160
160
|
const f = decodeProto(data);
|
|
161
161
|
const id = String(getInt(f, 1) || getStr(f, 1));
|
|
162
|
-
const nickname = getStr(f, 3) || getStr(f,
|
|
163
|
-
const uniqueId = getStr(f, 38) || getStr(f, 4) || getStr(f, 2);
|
|
162
|
+
const nickname = getStr(f, 3) || getStr(f, 2);
|
|
163
|
+
const uniqueId = getStr(f, 38) || getStr(f, 4) || getStr(f, 2) || "";
|
|
164
164
|
let profilePicture;
|
|
165
|
-
const avatarBuf = getBytes(f, 9);
|
|
165
|
+
const avatarBuf = getBytes(f, 9) || getBytes(f, 3);
|
|
166
166
|
if (avatarBuf) {
|
|
167
167
|
try {
|
|
168
168
|
const avatarFields = decodeProto(avatarBuf);
|
|
169
|
-
const
|
|
170
|
-
if (
|
|
169
|
+
const urlBufs = getAllBytes(avatarFields, 1);
|
|
170
|
+
if (urlBufs.length > 0) profilePicture = urlBufs[0].toString("utf-8");
|
|
171
171
|
} catch {
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
-
|
|
174
|
+
const badges = [];
|
|
175
|
+
const badgeBuf = getBytes(f, 64);
|
|
176
|
+
if (badgeBuf) {
|
|
177
|
+
try {
|
|
178
|
+
const badgeFields = decodeProto(badgeBuf);
|
|
179
|
+
const badgeItems = getAllBytes(badgeFields, 21);
|
|
180
|
+
for (const bi of badgeItems) {
|
|
181
|
+
const bf = decodeProto(bi);
|
|
182
|
+
const name = getStr(bf, 3) || getStr(bf, 2);
|
|
183
|
+
if (name) badges.push(name);
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
id,
|
|
190
|
+
nickname,
|
|
191
|
+
uniqueId: uniqueId || nickname || id,
|
|
192
|
+
profilePicture,
|
|
193
|
+
badges: badges.length > 0 ? badges : void 0
|
|
194
|
+
};
|
|
175
195
|
}
|
|
176
|
-
function
|
|
177
|
-
const
|
|
178
|
-
const hostUserId = String(getInt(
|
|
179
|
-
|
|
196
|
+
function parseBattleTeamFromArmies(itemBuf) {
|
|
197
|
+
const f = decodeProto(itemBuf);
|
|
198
|
+
const hostUserId = String(getInt(f, 1));
|
|
199
|
+
let teamScore = 0;
|
|
180
200
|
const users = [];
|
|
181
|
-
const
|
|
182
|
-
for (const
|
|
201
|
+
const groups = getAllBytes(f, 2);
|
|
202
|
+
for (const gb of groups) {
|
|
183
203
|
try {
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
|
|
204
|
+
const gf = decodeProto(gb);
|
|
205
|
+
const points = getInt(gf, 2);
|
|
206
|
+
teamScore += points;
|
|
207
|
+
const userBufs = getAllBytes(gf, 1);
|
|
208
|
+
for (const ub of userBufs) {
|
|
209
|
+
try {
|
|
210
|
+
const user = parseUser(ub);
|
|
211
|
+
users.push({ user, score: points });
|
|
212
|
+
} catch {
|
|
213
|
+
}
|
|
214
|
+
}
|
|
189
215
|
} catch {
|
|
190
216
|
}
|
|
191
217
|
}
|
|
192
|
-
return { hostUserId, score, users };
|
|
218
|
+
return { hostUserId, score: teamScore, users };
|
|
193
219
|
}
|
|
194
220
|
function parseWebcastMessage(method, payload) {
|
|
195
221
|
const f = decodeProto(payload);
|
|
196
|
-
const base = { timestamp: Date.now(), msgId:
|
|
222
|
+
const base = { timestamp: Date.now(), msgId: "" };
|
|
223
|
+
const typeBuf = getBytes(f, 1);
|
|
224
|
+
if (typeBuf) {
|
|
225
|
+
try {
|
|
226
|
+
const tf = decodeProto(typeBuf);
|
|
227
|
+
const ts = getInt(tf, 4);
|
|
228
|
+
if (ts) base.timestamp = ts;
|
|
229
|
+
} catch {
|
|
230
|
+
}
|
|
231
|
+
}
|
|
197
232
|
switch (method) {
|
|
233
|
+
// Proto: WebcastChatMessage { MessageType type=1, User user=2, string comment=3 }
|
|
198
234
|
case "WebcastChatMessage": {
|
|
199
235
|
const userBuf = getBytes(f, 2);
|
|
200
236
|
const user = userBuf ? parseUser(userBuf) : { id: "0", nickname: "", uniqueId: "" };
|
|
201
237
|
return { ...base, type: "chat", user, comment: getStr(f, 3) };
|
|
202
238
|
}
|
|
239
|
+
// Proto: WebcastMemberMessage { User user=2, WebcastMessageEvent event=1 }
|
|
203
240
|
case "WebcastMemberMessage": {
|
|
204
241
|
const userBuf = getBytes(f, 2);
|
|
205
242
|
const user = userBuf ? parseUser(userBuf) : { id: "0", nickname: "", uniqueId: "" };
|
|
206
|
-
|
|
243
|
+
let action = 1;
|
|
244
|
+
const eventBuf = getBytes(f, 1);
|
|
245
|
+
if (eventBuf) {
|
|
246
|
+
const ef = decodeProto(eventBuf);
|
|
247
|
+
const detailBuf = getBytes(ef, 8);
|
|
248
|
+
if (detailBuf) {
|
|
249
|
+
const df = decodeProto(detailBuf);
|
|
250
|
+
const label = getStr(df, 2);
|
|
251
|
+
if (label.includes("followed")) action = 2;
|
|
252
|
+
else if (label.includes("share")) action = 3;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return { ...base, type: "member", user, action };
|
|
207
256
|
}
|
|
257
|
+
// Proto: WebcastLikeMessage { User user=5, WebcastMessageEvent event=1, int32 likeCount=2, int32 totalLikeCount=3 }
|
|
208
258
|
case "WebcastLikeMessage": {
|
|
209
259
|
const userBuf = getBytes(f, 5);
|
|
210
260
|
const user = userBuf ? parseUser(userBuf) : { id: "0", nickname: "", uniqueId: "" };
|
|
211
|
-
return {
|
|
261
|
+
return {
|
|
262
|
+
...base,
|
|
263
|
+
type: "like",
|
|
264
|
+
user,
|
|
265
|
+
likeCount: getInt(f, 2),
|
|
266
|
+
totalLikes: getInt(f, 3)
|
|
267
|
+
};
|
|
212
268
|
}
|
|
269
|
+
// Proto: WebcastGiftMessage {
|
|
270
|
+
// User user=7, int32 giftId=2, int32 repeatCount=5, int32 repeatEnd=9,
|
|
271
|
+
// GiftDetails giftDetails=15, GiftExtra giftExtra=23
|
|
272
|
+
// }
|
|
273
|
+
// GiftDetails { GiftImage giftImage=1, string giftName=16, string describe=2,
|
|
274
|
+
// int32 giftType=11, int32 diamondCount=12 }
|
|
275
|
+
// GiftExtra { uint64 timestamp=6, uint64 toUserId=8 }
|
|
213
276
|
case "WebcastGiftMessage": {
|
|
214
277
|
const userBuf = getBytes(f, 7);
|
|
215
278
|
const user = userBuf ? parseUser(userBuf) : { id: "0", nickname: "", uniqueId: "" };
|
|
216
|
-
const giftId = getInt(f,
|
|
279
|
+
const giftId = getInt(f, 2);
|
|
217
280
|
const repeatCount = getInt(f, 5);
|
|
218
281
|
const repeatEnd = getInt(f, 9) === 1;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const gf3 = decodeProto(giftBuf3);
|
|
232
|
-
if (!giftName) giftName = getStr(gf3, 2);
|
|
233
|
-
if (!diamondCount) diamondCount = getInt(gf3, 5);
|
|
282
|
+
let giftName = "", diamondCount = 0, giftType = 0;
|
|
283
|
+
let giftImageUrl = "";
|
|
284
|
+
const detailsBuf = getBytes(f, 15);
|
|
285
|
+
if (detailsBuf) {
|
|
286
|
+
const df = decodeProto(detailsBuf);
|
|
287
|
+
giftName = getStr(df, 16) || getStr(df, 2);
|
|
288
|
+
diamondCount = getInt(df, 12);
|
|
289
|
+
giftType = getInt(df, 11);
|
|
290
|
+
const imgBuf = getBytes(df, 1);
|
|
291
|
+
if (imgBuf) {
|
|
292
|
+
const imgf = decodeProto(imgBuf);
|
|
293
|
+
giftImageUrl = getStr(imgf, 1);
|
|
234
294
|
}
|
|
235
295
|
}
|
|
296
|
+
let toUserId = "";
|
|
297
|
+
const extraBuf = getBytes(f, 23);
|
|
298
|
+
if (extraBuf) {
|
|
299
|
+
const ef = decodeProto(extraBuf);
|
|
300
|
+
toUserId = String(getInt(ef, 8));
|
|
301
|
+
}
|
|
302
|
+
const groupId = toUserId || getStr(f, 11);
|
|
236
303
|
return {
|
|
237
304
|
...base,
|
|
238
305
|
type: "gift",
|
|
@@ -247,46 +314,93 @@ function parseWebcastMessage(method, payload) {
|
|
|
247
314
|
groupId
|
|
248
315
|
};
|
|
249
316
|
}
|
|
317
|
+
// Proto: WebcastSocialMessage { User user=2, WebcastMessageEvent event=1 }
|
|
250
318
|
case "WebcastSocialMessage": {
|
|
251
319
|
const userBuf = getBytes(f, 2);
|
|
252
320
|
const user = userBuf ? parseUser(userBuf) : { id: "0", nickname: "", uniqueId: "" };
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
321
|
+
let action = "follow";
|
|
322
|
+
const eventBuf = getBytes(f, 1);
|
|
323
|
+
if (eventBuf) {
|
|
324
|
+
const ef = decodeProto(eventBuf);
|
|
325
|
+
const detailBuf = getBytes(ef, 8);
|
|
326
|
+
if (detailBuf) {
|
|
327
|
+
const df = decodeProto(detailBuf);
|
|
328
|
+
const label = getStr(df, 2);
|
|
329
|
+
if (label.includes("share")) action = "share";
|
|
330
|
+
else if (label.includes("follow")) action = "follow";
|
|
331
|
+
const displayType = getStr(df, 1);
|
|
332
|
+
if (displayType === "pm_mt_msg_viewer_share") action = "share";
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return { ...base, type: "social", user, action };
|
|
256
336
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
337
|
+
// Proto: WebcastRoomUserSeqMessage { int32 viewerCount=3 }
|
|
338
|
+
case "WebcastRoomUserSeqMessage": {
|
|
339
|
+
const viewerCount = getInt(f, 3) || getInt(f, 2);
|
|
340
|
+
const totalViewers = getInt(f, 1) || viewerCount;
|
|
341
|
+
return { ...base, type: "roomUserSeq", totalViewers, viewerCount };
|
|
342
|
+
}
|
|
343
|
+
// Proto: WebcastLinkMicBattle { repeated WebcastLinkMicBattleItems battleUsers=10 }
|
|
344
|
+
// battleUsers → { battleGroup=2 → { LinkUser user=1 } }
|
|
264
345
|
case "WebcastLinkMicBattle": {
|
|
265
|
-
const battleId = String(getInt(f, 1) ||
|
|
266
|
-
const status = getInt(f, 2);
|
|
346
|
+
const battleId = String(getInt(f, 1) || "");
|
|
347
|
+
const status = getInt(f, 2) || 1;
|
|
267
348
|
const battleDuration = getInt(f, 3);
|
|
268
349
|
const teams = [];
|
|
269
|
-
const
|
|
270
|
-
for (const
|
|
350
|
+
const battleUserBufs = getAllBytes(f, 10);
|
|
351
|
+
for (const bub of battleUserBufs) {
|
|
271
352
|
try {
|
|
272
|
-
|
|
353
|
+
const bf = decodeProto(bub);
|
|
354
|
+
const groupBuf = getBytes(bf, 2);
|
|
355
|
+
if (groupBuf) {
|
|
356
|
+
const gf = decodeProto(groupBuf);
|
|
357
|
+
const linkUserBuf = getBytes(gf, 1);
|
|
358
|
+
if (linkUserBuf) {
|
|
359
|
+
const user = parseUser(linkUserBuf);
|
|
360
|
+
teams.push({
|
|
361
|
+
hostUserId: user.id,
|
|
362
|
+
score: 0,
|
|
363
|
+
users: [{ user, score: 0 }]
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
273
367
|
} catch {
|
|
274
368
|
}
|
|
275
369
|
}
|
|
370
|
+
if (teams.length === 0) {
|
|
371
|
+
const teamBufs7 = getAllBytes(f, 7);
|
|
372
|
+
for (const tb of teamBufs7) {
|
|
373
|
+
try {
|
|
374
|
+
teams.push(parseBattleTeamFromArmies(tb));
|
|
375
|
+
} catch {
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
276
379
|
return { ...base, type: "battle", battleId, status, battleDuration, teams };
|
|
277
380
|
}
|
|
381
|
+
// Proto: WebcastLinkMicArmies { repeated battleItems=3, int32 battleStatus=7 }
|
|
382
|
+
// battleItems → { hostUserId=1, repeated battleGroups=2 }
|
|
383
|
+
// battleGroups → { repeated users=1, int32 points=2 }
|
|
278
384
|
case "WebcastLinkMicArmies": {
|
|
279
|
-
const battleId = String(getInt(f, 1) ||
|
|
385
|
+
const battleId = String(getInt(f, 1) || "");
|
|
386
|
+
const battleStatus = getInt(f, 7);
|
|
280
387
|
const teams = [];
|
|
281
|
-
const
|
|
282
|
-
for (const
|
|
388
|
+
const itemBufs = getAllBytes(f, 3);
|
|
389
|
+
for (const ib of itemBufs) {
|
|
283
390
|
try {
|
|
284
|
-
teams.push(
|
|
391
|
+
teams.push(parseBattleTeamFromArmies(ib));
|
|
285
392
|
} catch {
|
|
286
393
|
}
|
|
287
394
|
}
|
|
288
|
-
return {
|
|
395
|
+
return {
|
|
396
|
+
...base,
|
|
397
|
+
type: "battleArmies",
|
|
398
|
+
battleId,
|
|
399
|
+
teams,
|
|
400
|
+
status: battleStatus
|
|
401
|
+
};
|
|
289
402
|
}
|
|
403
|
+
// Proto: WebcastSubNotifyMessage { User user=2, ... subMonth=3 }
|
|
290
404
|
case "WebcastSubNotifyMessage": {
|
|
291
405
|
const userBuf = getBytes(f, 2);
|
|
292
406
|
const user = userBuf ? parseUser(userBuf) : { id: "0", nickname: "", uniqueId: "" };
|
|
@@ -312,10 +426,18 @@ function parseWebcastMessage(method, payload) {
|
|
|
312
426
|
const envelopeId = String(getInt(f, 1) || getStr(f, 1));
|
|
313
427
|
return { ...base, type: "envelope", envelopeId, diamondCount: getInt(f, 3) };
|
|
314
428
|
}
|
|
429
|
+
// Proto: WebcastQuestionNewMessage { MessageType type=1, QuestionDetails questionDetails=2 }
|
|
430
|
+
// QuestionDetails { string questionText=2, User user=5 }
|
|
315
431
|
case "WebcastQuestionNewMessage": {
|
|
316
|
-
|
|
317
|
-
const
|
|
318
|
-
|
|
432
|
+
let questionText = "", user = { id: "0", nickname: "", uniqueId: "" };
|
|
433
|
+
const detailBuf = getBytes(f, 2);
|
|
434
|
+
if (detailBuf) {
|
|
435
|
+
const df = decodeProto(detailBuf);
|
|
436
|
+
questionText = getStr(df, 2);
|
|
437
|
+
const userBuf = getBytes(df, 5);
|
|
438
|
+
if (userBuf) user = parseUser(userBuf);
|
|
439
|
+
}
|
|
440
|
+
return { ...base, type: "question", user, questionText };
|
|
319
441
|
}
|
|
320
442
|
case "WebcastRankUpdateMessage":
|
|
321
443
|
case "WebcastHourlyRankMessage": {
|
|
@@ -335,14 +457,17 @@ function parseWebcastMessage(method, payload) {
|
|
|
335
457
|
}
|
|
336
458
|
return { ...base, type: "rankUpdate", rankType, rankList };
|
|
337
459
|
}
|
|
460
|
+
// Proto: WebcastControlMessage { int32 action=2 }
|
|
338
461
|
case "WebcastControlMessage":
|
|
339
462
|
return { ...base, type: "control", action: getInt(f, 2) || getInt(f, 1) };
|
|
340
463
|
case "WebcastRoomMessage":
|
|
341
464
|
case "RoomMessage":
|
|
342
465
|
return { ...base, type: "room", status: getInt(f, 2) };
|
|
466
|
+
// Proto: WebcastLiveIntroMessage { uint64 id=2, string description=4, User user=5 }
|
|
343
467
|
case "WebcastLiveIntroMessage": {
|
|
344
|
-
const roomId = String(getInt(f,
|
|
345
|
-
|
|
468
|
+
const roomId = String(getInt(f, 2));
|
|
469
|
+
const title = getStr(f, 4) || getStr(f, 2);
|
|
470
|
+
return { ...base, type: "liveIntro", roomId, title };
|
|
346
471
|
}
|
|
347
472
|
case "WebcastLinkMicMethod":
|
|
348
473
|
case "WebcastLinkmicBattleTaskMessage": {
|
|
@@ -418,6 +543,8 @@ var TikTokLive = class extends import_events.EventEmitter {
|
|
|
418
543
|
_connected = false;
|
|
419
544
|
_eventCount = 0;
|
|
420
545
|
_roomId = "";
|
|
546
|
+
// Cache host identities from battle events for enriching battleArmies
|
|
547
|
+
_battleHosts = /* @__PURE__ */ new Map();
|
|
421
548
|
uniqueId;
|
|
422
549
|
signServerUrl;
|
|
423
550
|
apiKey;
|
|
@@ -615,6 +742,27 @@ var TikTokLive = class extends import_events.EventEmitter {
|
|
|
615
742
|
const events = parseWebcastResponse(inner);
|
|
616
743
|
for (const evt of events) {
|
|
617
744
|
this._eventCount++;
|
|
745
|
+
if (evt.type === "battle") {
|
|
746
|
+
for (const team of evt.teams) {
|
|
747
|
+
const host = team.users.find((u) => u.user.id === team.hostUserId);
|
|
748
|
+
if (host) {
|
|
749
|
+
this._battleHosts.set(team.hostUserId, host.user);
|
|
750
|
+
team.hostUser = host.user;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
if (evt.type === "battleArmies") {
|
|
755
|
+
for (const team of evt.teams) {
|
|
756
|
+
const host = team.users.find((u) => u.user.id === team.hostUserId);
|
|
757
|
+
if (host) {
|
|
758
|
+
team.hostUser = host.user;
|
|
759
|
+
this._battleHosts.set(team.hostUserId, host.user);
|
|
760
|
+
} else {
|
|
761
|
+
const cached = this._battleHosts.get(team.hostUserId);
|
|
762
|
+
if (cached) team.hostUser = cached;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
618
766
|
this.emit("event", evt);
|
|
619
767
|
this.emit(evt.type, evt);
|
|
620
768
|
}
|