UNPKG

@qixils/tiktok-live-connector

Version:

Node.js module to receive live stream chat events like comments and gifts from TikTok LIVE

108 lines (80 loc) 3.39 kB
"use strict"; function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); } function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; } const { EventEmitter } = require('node:events'); const Config = require('./webcastConfig.js'); const WebSocketClient = require('websocket').client; const { deserializeWebsocketMessage, serializeMessage } = require('./webcastProtobuf.js'); var _handleEvents = /*#__PURE__*/new WeakSet(); var _handleMessage = /*#__PURE__*/new WeakSet(); var _sendPing = /*#__PURE__*/new WeakSet(); var _sendAck = /*#__PURE__*/new WeakSet(); class WebcastWebsocket extends EventEmitter { constructor(wsUrl, cookieJar, clientParams, wsParams, customHeaders, websocketOptions) { super(); _classPrivateMethodInitSpec(this, _sendAck); _classPrivateMethodInitSpec(this, _sendPing); _classPrivateMethodInitSpec(this, _handleMessage); _classPrivateMethodInitSpec(this, _handleEvents); this.client = new WebSocketClient(); this.pingInterval = null; this.connection = null; this.wsParams = { ...clientParams, ...wsParams }; this.wsUrlWithParams = `${wsUrl}?${new URLSearchParams(this.wsParams)}`; this.wsHeaders = { Cookie: cookieJar.getCookieString(), ...(customHeaders || {}) }; _classPrivateMethodGet(this, _handleEvents, _handleEvents2).call(this); this.client.connect(this.wsUrlWithParams, 'echo-protocol', Config.TIKTOK_URL_WEBCAST, this.wsHeaders, websocketOptions); } } function _handleEvents2() { this.client.on('connect', wsConnection => this.emit('connect', wsConnection)); this.client.on('connectFailed', err => this.emit('connectFailed', err)); this.on('connect', wsConnection => { this.connection = wsConnection; this.pingInterval = setInterval(() => _classPrivateMethodGet(this, _sendPing, _sendPing2).call(this), 10000); wsConnection.on('message', message => { if (message.type === 'binary') { _classPrivateMethodGet(this, _handleMessage, _handleMessage2).call(this, message); } }); wsConnection.on('close', () => { clearInterval(this.pingInterval); }); }); } async function _handleMessage2(message) { try { let decodedContainer = await deserializeWebsocketMessage(message.binaryData); if (decodedContainer.id > 0) { _classPrivateMethodGet(this, _sendAck, _sendAck2).call(this, decodedContainer.id); } // Emit 'WebcastResponse' from ws message container if decoding success if (typeof decodedContainer.webcastResponse === 'object') { this.emit('webcastResponse', decodedContainer.webcastResponse); } } catch (err) { this.emit('messageDecodingFailed', err); } } function _sendPing2() { // Send static connection alive ping this.connection.sendBytes(Buffer.from('3A026862', 'hex')); } function _sendAck2(id) { let ackMsg = serializeMessage('WebcastWebsocketAck', { type: 'ack', id }); this.connection.sendBytes(Buffer.from(ackMsg)); } module.exports = WebcastWebsocket;