tiktok-livestream-chat-connector
Advanced tools
Comparing version 0.9.8 to 0.9.9
@@ -110,7 +110,7 @@ "use strict"; | ||
/** | ||
* Create a new instance | ||
* Create a new WebcastPushConnection instance | ||
* @param {string} uniqueId TikTok username (from URL) | ||
* @param {object} [options] Connection options | ||
* @param {boolean} [options[].processInitialData=true] Process the initital data which includes messages of the last minutes | ||
* @param {boolean} [options[].fetchRoomInfoOnConnect=true] Fetch the room info (room state, streamer info, etc.) on connect (will be returned when calling connect()) | ||
* @param {boolean} [options[].fetchRoomInfoOnConnect=true] Fetch the room info (room status, streamer info, etc.) on connect (will be returned when calling connect()) | ||
* @param {boolean} [options[].enableExtendedGiftInfo=false] Enable this option to get extended information on 'gift' events like gift name and cost | ||
@@ -225,53 +225,49 @@ * @param {boolean} [options[].enableWebsocketUpgrade=true] Use WebSocket instead of request polling if TikTok offers it | ||
*/ | ||
connect() { | ||
return new Promise(async (resolve, reject) => { | ||
if (_classPrivateFieldGet(this, _isConnecting)) { | ||
reject(new Error('Already connecting!')); | ||
return; | ||
} | ||
async connect() { | ||
if (_classPrivateFieldGet(this, _isConnecting)) { | ||
throw new Error('Already connecting!'); | ||
} | ||
if (_classPrivateFieldGet(this, _isConnected)) { | ||
reject(new Error('Already connected!')); | ||
return; | ||
} | ||
if (_classPrivateFieldGet(this, _isConnected)) { | ||
throw new Error('Already connected!'); | ||
} | ||
_classPrivateFieldSet(this, _isConnecting, true); | ||
_classPrivateFieldSet(this, _isConnecting, true); | ||
try { | ||
await _classPrivateMethodGet(this, _retrieveRoomId, _retrieveRoomId2).call(this); // Fetch room info if option enabled | ||
try { | ||
await _classPrivateMethodGet(this, _retrieveRoomId, _retrieveRoomId2).call(this); // Fetch room info if option enabled | ||
if (_classPrivateFieldGet(this, _options).fetchRoomInfoOnConnect) { | ||
await _classPrivateMethodGet(this, _fetchRoomInfo, _fetchRoomInfo2).call(this); // Prevent connections to finished rooms | ||
if (_classPrivateFieldGet(this, _options).fetchRoomInfoOnConnect) { | ||
await _classPrivateMethodGet(this, _fetchRoomInfo, _fetchRoomInfo2).call(this); // Prevent connections to finished rooms | ||
if (_classPrivateFieldGet(this, _roomInfo).status === 4) { | ||
throw new Error('LIVE has ended'); | ||
} | ||
} // Fetch all available gift info if option enabled | ||
if (_classPrivateFieldGet(this, _options).enableExtendedGiftInfo) { | ||
await _classPrivateMethodGet(this, _fetchAvailableGifts, _fetchAvailableGifts2).call(this); | ||
if (_classPrivateFieldGet(this, _roomInfo).status === 4) { | ||
throw new Error('LIVE has ended'); | ||
} | ||
} // Fetch all available gift info if option enabled | ||
await _classPrivateMethodGet(this, _fetchRoomData, _fetchRoomData2).call(this, true); | ||
_classPrivateFieldSet(this, _isConnected, true); // Sometimes no upgrade to websocket is offered by TikTok | ||
// In that case we use request polling | ||
if (_classPrivateFieldGet(this, _options).enableExtendedGiftInfo) { | ||
await _classPrivateMethodGet(this, _fetchAvailableGifts, _fetchAvailableGifts2).call(this); | ||
} | ||
await _classPrivateMethodGet(this, _fetchRoomData, _fetchRoomData2).call(this, true); | ||
if (!_classPrivateFieldGet(this, _isWsUpgradeDone)) { | ||
_classPrivateMethodGet(this, _startFetchRoomPolling, _startFetchRoomPolling2).call(this); | ||
} | ||
_classPrivateFieldSet(this, _isConnected, true); // Sometimes no upgrade to websocket is offered by TikTok | ||
// In that case we use request polling | ||
let state = this.getState(); | ||
resolve(state); | ||
this.emit(Events.CONNECTED, state); | ||
} catch (err) { | ||
reject(err); | ||
_classPrivateMethodGet(this, _handleError, _handleError2).call(this, err, 'Error while connecting'); | ||
if (!_classPrivateFieldGet(this, _isWsUpgradeDone)) { | ||
_classPrivateMethodGet(this, _startFetchRoomPolling, _startFetchRoomPolling2).call(this); | ||
} | ||
let state = this.getState(); | ||
this.emit(Events.CONNECTED, state); | ||
return state; | ||
} catch (err) { | ||
_classPrivateMethodGet(this, _handleError, _handleError2).call(this, err, 'Error while connecting'); | ||
throw err; | ||
} finally { | ||
_classPrivateFieldSet(this, _isConnecting, false); | ||
}); | ||
} | ||
} | ||
@@ -315,16 +311,10 @@ /** | ||
getRoomInfo() { | ||
return new Promise(async (resolve, reject) => { | ||
try { | ||
// Retrieve current room_id if not connected | ||
if (!_classPrivateFieldGet(this, _isConnected)) { | ||
await _classPrivateMethodGet(this, _retrieveRoomId, _retrieveRoomId2).call(this); | ||
} | ||
async getRoomInfo() { | ||
// Retrieve current room_id if not connected | ||
if (!_classPrivateFieldGet(this, _isConnected)) { | ||
await _classPrivateMethodGet(this, _retrieveRoomId, _retrieveRoomId2).call(this); | ||
} | ||
await _classPrivateMethodGet(this, _fetchRoomInfo, _fetchRoomInfo2).call(this); | ||
resolve(_classPrivateFieldGet(this, _roomInfo)); | ||
} catch (err) { | ||
reject(err); | ||
} | ||
}); | ||
await _classPrivateMethodGet(this, _fetchRoomInfo, _fetchRoomInfo2).call(this); | ||
return _classPrivateFieldGet(this, _roomInfo); | ||
} | ||
@@ -419,4 +409,5 @@ | ||
await _classPrivateMethodGet(this, _tryUpgradeToWebsocket, _tryUpgradeToWebsocket2).call(this, webcastResponse); | ||
} | ||
} // Skip processing initial data if option disabled | ||
if (isInitial && !_classPrivateFieldGet(this, _options).processInitialData) { | ||
@@ -499,4 +490,4 @@ return; | ||
case 'WebcastGiftMessage': | ||
// Add extended gift info if option enabled | ||
if (Array.isArray(_classPrivateFieldGet(this, _availableGifts)) && simplifiedObj.giftId) { | ||
// Add extended gift info if option enabled | ||
simplifiedObj.extendedGiftInfo = _classPrivateFieldGet(this, _availableGifts).find(x => x.id === simplifiedObj.giftId); | ||
@@ -503,0 +494,0 @@ } |
{ | ||
"name": "tiktok-livestream-chat-connector", | ||
"version": "0.9.8", | ||
"description": "Node.js module to receive live stream chat events like comments and gifts from TikTok LIVE.", | ||
"version": "0.9.9", | ||
"description": "Node.js module to receive live stream events like comments and gifts from TikTok LIVE", | ||
"main": "index.js", | ||
@@ -23,5 +23,11 @@ "engines": { | ||
"live", | ||
"stream", | ||
"livestream", | ||
"chat", | ||
"connector" | ||
"connector", | ||
"api", | ||
"webcast", | ||
"tracker", | ||
"scraper", | ||
"websocket" | ||
], | ||
@@ -28,0 +34,0 @@ "author": "zerodytrash", |
# TikTok-Livestream-Chat-Connector | ||
A Node.js module to receive and decode livestream chat events like comments and gifts in realtime from [TikTok LIVE](https://www.tiktok.com/live) by connecting to TikTok's internal WebCast push service. The package includes a wrapper that connects to the WebCast service using just the username (`uniqueId`). This allows you to connect to your own live chat as well as the live chat of other streamers. No credentials are required. Besides [chat comments](#chat), other events such as [members joining](#member), [gifts](#gift), [viewers](#roomuser), [follows](#social), [shares](#social), [questions](#questionnew) and [likes](#like) can be tracked. | ||
A Node.js module to receive and decode livestream events like comments and gifts in realtime from [TikTok LIVE](https://www.tiktok.com/live) by connecting to TikTok's internal WebCast push service. The package includes a wrapper that connects to the WebCast service using just the username (`uniqueId`). This allows you to connect to your own live chat as well as the live chat of other streamers. No credentials are required. Besides [chat comments](#chat), other events such as [members joining](#member), [gifts](#gift), [viewers](#roomuser), [follows](#social), [shares](#social), [questions](#questionnew) and [likes](#like) can be tracked. | ||
<b>NOTE:</b> This is not an official API. It's a reverse engineering project. The correctness of the data cannot be guaranteed. | ||
**NOTE:** This is not an official API. It's a reverse engineering project. | ||
#### Demo: [https://tiktok-chat.herokuapp.com/](https://tiktok-chat.herokuapp.com/) | ||
### Demo: [https://tiktok-chat.herokuapp.com/](https://tiktok-chat.herokuapp.com/) | ||
@@ -173,7 +173,16 @@ #### Overview | ||
### `gift` | ||
Triggered every time a gift arrives. You will receive additional information via the `extendedGiftInfo` attribute when you enable the [`enableExtendedGiftInfo`](#params-and-options) option | ||
Triggered every time a gift arrives. You will receive additional information via the `extendedGiftInfo` attribute when you enable the [`enableExtendedGiftInfo`](#params-and-options) option. | ||
> **NOTE:** Users have the capability to send gifts in a streak. This increases the `data.gift.repeat_count` value until the user terminates the streak. During this time new gift events are triggered again and again with an increased `data.gift.repeat_count` value. It should be noted that after the end of the streak, another gift event is triggered, which signals the end of the streak via `data.gift.repeat_end`:`1`. This applies only to gifts with `data.gift.gift_type`:`1`. This means that even if the user sends a `gift_type`:`1` gift only once, you will receive the event twice. Once with `repeat_end`:`0` and once with `repeat_end`:`1`. Therefore, the event should be handled as follows: | ||
```javascript | ||
tiktokChatConnection.on('gift', data => { | ||
console.log(`${data.uniqueId} sends gift ${data.giftId}`); | ||
if (data.gift.gift_type === 1 && data.gift.repeat_end === 0) { | ||
// Streak in progress => show only temporary | ||
console.log(`${data.uniqueId} is sending gift ${data.giftId} x${data.gift.repeat_count}`); | ||
} else { | ||
// Streak ended or non-streakable gift => process the gift with final repeat_count | ||
console.log(`${data.uniqueId} has sent gift ${data.giftId} x${data.gift.repeat_count}`); | ||
} | ||
}) | ||
@@ -206,4 +215,5 @@ ``` | ||
is_animated: false, | ||
uri: 'webcast-va/eba3a9bb85c33e017f3648eaf88d7189', | ||
url_list: [] | ||
url_list: [ | ||
// Icon URLs... | ||
] | ||
}, | ||
@@ -213,11 +223,6 @@ id: 5655, | ||
avg_color: '#FFEBEB', | ||
height: 0, | ||
is_animated: false, | ||
open_web_url: '', | ||
open_web_url: '', | ||
uri: 'webcast-va/eba3a9bb85c33e017f3648eaf88d7189', | ||
url_list: [ | ||
// icons... | ||
], | ||
width: 0 | ||
// Image URLs... | ||
] | ||
}, | ||
@@ -244,7 +249,7 @@ is_broadcast_gift: false, | ||
### `like` | ||
Triggered every time a viewer sends likes to the streamer. | ||
Triggered when a viewer sends likes to the streamer. For streams with many viewers, this event is not always triggered by TikTok. | ||
```javascript | ||
tiktokChatConnection.on('like', data => { | ||
console.log(`${data.uniqueId} send likes, total likes: ${data.totalLikeCount}`); | ||
console.log(`${data.uniqueId} sent ${data.likeCount} likes, total likes: ${data.totalLikeCount}`); | ||
}) | ||
@@ -256,3 +261,4 @@ ``` | ||
{ | ||
totalLikeCount: 83033, | ||
likeCount: 5, // likes given by the user (taps on screen) | ||
totalLikeCount: 83033, // likes that this stream has received in total | ||
userId: '6776663624629974121', | ||
@@ -259,0 +265,0 @@ uniqueId: 'zerodytester', |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
45947
347
644