A Node.js library to receive live stream events such as comments and gifts in realtime from TikTok 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, other events such as Members Joining, Gifts, Subscriptions, Viewers, Follows, Shares, Questions, Likes and Battles can be tracked. You can also send automatic messages into the chat by providing your Session ID.
Do you prefer other programming languages?
NOTE: This is not an official API. It's a reverse engineering project.
NOTE: This JavaScript library is intended for use in Node.js environments. If you want to process or display the data in the browser (client-side), you need to transfer the data from the Node.js environment to the browser. A good approach for this is to use Socket.IO or a different low-latency communication framework. A complete example project can be found here: TikTok-Chat-Reader
UPDATE:
Due to a change on the part of TikTok, versions prior v1.1.7 are no longer functional. If you are using one of these versions, upgrade to the latest version using thenpm i tiktok-live-connector
command.
npm i tiktok-live-connector
const { WebcastPushConnection } = require('tiktok-live-connector');
// Username of someone who is currently live
let tiktokUsername = "officialgeilegisela";
// Create a new wrapper object and pass the username
let tiktokLiveConnection = new WebcastPushConnection(tiktokUsername);
// Connect to the chat (await can be used as well)
tiktokLiveConnection.connect().then(state => {
console.info(`Connected to roomId ${state.roomId}`);
}).catch(err => {
console.error('Failed to connect', err);
})
// Define the events that you want to handle
// In this case we listen to chat messages (comments)
tiktokLiveConnection.on('chat', data => {
console.log(`${data.uniqueId} (userId:${data.userId}) writes: ${data.comment}`);
})
// And here we receive gifts sent to the streamer
tiktokLiveConnection.on('gift', data => {
console.log(`${data.uniqueId} (userId:${data.userId}) sends ${data.giftId}`);
})
// ...and more events described in the documentation below
To create a new WebcastPushConnection
object the following parameters are required.
WebcastPushConnection(uniqueId, [options])
Param Name | Required | Description |
---|---|---|
uniqueId | Yes | The unique username of the broadcaster. You can find this name in the URL. Example: https://www.tiktok.com/@officialgeilegisela/live => officialgeilegisela
|
options | No | Here you can set the following optional connection properties. If you do not specify a value, the default value will be used.processInitialData (default: true ) Define if you want to process the initital data which includes old messages of the last seconds. fetchRoomInfoOnConnect (default: true ) Define if you want to fetch all room information on connect() . If this option is enabled, the connection to offline rooms will be prevented. If enabled, the connect result contains the room info via the roomInfo attribute. You can also manually retrieve the room info (even in an unconnected state) using the getRoomInfo() function.enableExtendedGiftInfo (default: false ) Define if you want to receive extended information about gifts like gift name, cost and images. This information will be provided at the gift event. enableWebsocketUpgrade (default: true ) Define if you want to use a WebSocket connection instead of request polling if TikTok offers it. requestPollingIntervalMs (default: 1000 ) Request polling interval if WebSocket is not used. sessionId (default: null ) Here you can specify the current Session ID of your TikTok account (sessionid cookie value) if you want to send automated chat messages via the sendMessage() function. See ExampleclientParams (default: {} ) Custom client params for Webcast API. requestHeaders (default: {} ) Custom request headers passed to axios. websocketHeaders (default: {} ) Custom websocket headers passed to websocket.client. requestOptions (default: {} ) Custom request options passed to axios. Here you can specify an httpsAgent to use a proxy and a timeout value. See Example. websocketOptions (default: {} ) Custom websocket options passed to websocket.client. Here you can specify an agent to use a proxy and a timeout value. See Example. signProviderOptions (default: {} ) Custom request options for the TikTok signing server. Here you can specify a host , params , and headers . |
Example Options:
let tiktokLiveConnection = new WebcastPushConnection(tiktokUsername, {
processInitialData: false,
enableExtendedGiftInfo: true,
enableWebsocketUpgrade: true,
requestPollingIntervalMs: 2000,
clientParams: {
"app_language": "en-US",
"device_platform": "web"
},
requestHeaders: {
"headerName": "headerValue"
},
websocketHeaders: {
"headerName": "headerValue"
},
requestOptions: {
timeout: 10000
},
websocketOptions: {
timeout: 10000
},
signProviderOptions: {
host: "https://custom-signing-server.com",
params: {
"paramName": "paramValue"
},
headers: {
"headerName": "headerValue"
}
}
});
A WebcastPushConnection
object contains the following methods.
Method Name | Description |
---|---|
connect | Connects to the live stream chat. Returns a Promise which will be resolved when the connection is successfully established. |
disconnect | Disconnects the connection. |
getState | Gets the current connection state including the cached room info (see below). |
getRoomInfo | Gets the current room info from TikTok API including streamer info, room status and statistics. Returns a Promise which will be resolved when the API request is done.Note: You can call this function even if you're not connected. Example |
getAvailableGifts | Gets a list of all available gifts including gift name, image url, diamont cost and a lot of other information. Returns a Promise that will be resolved when all available gifts has been retrieved from the API.Note: You can call this function even if you're not connected. Example |
sendMessage(text, [sessionId])
|
Sends a chat message into the current live room using the provided session cookie (specified in the constructor options or via the second function parameter). Returns a Promise that will be resolved when the chat message has been submitted to the API.WARNING: Use of this function is at your own risk. Spamming messages can lead to the suspension of your TikTok account. Be careful! Example |
A WebcastPushConnection
object has the following events which can be handled via .on(eventName, eventHandler)
Control Events:
Message Events:
Custom Events:
connected
Triggered when the connection is successfully established.
tiktokLiveConnection.on('connected', state => {
console.log('Hurray! Connected!', state);
})
{
isConnected: true,
upgradedToWebsocket: true,
roomId: '7137682087200557829',
roomInfo: {
AnchorABMap: {},
admin_user_ids: [],
anchor_scheduled_time_text: '',
anchor_share_text: '',
anchor_tab_type: 7,
answering_question_content: '',
app_id: 1233,
audio_mute: 0,
auto_cover: 0,
book_end_time: 0,
book_time: 0,
business_live: 0,
challenge_info: '',
client_version: 250701,
comment_has_text_emoji_emote: 0,
comment_name_mode: 0,
commerce_info: {
commerce_permission: 0,
oec_live_enter_room_init_data: '',
use_async_load: false
},
common_label_list: '',
content_tag: '',
cover: {
avg_color: '',
height: 0,
image_type: 0,
is_animated: false,
open_web_url: '',
uri: '720x720/tos-maliva-avt-0068/4e64db7f7c37caf9b2df71df8580a9b0',
url_list: [Array],
width: 0
},
create_time: 1661871149,
deco_list: [],
deprecated10: '',
deprecated11: '',
deprecated12: '',
deprecated13: '',
deprecated14: 0,
deprecated15: 0,
deprecated16: 0,
deprecated17: [],
deprecated18: 0,
deprecated19: '',
deprecated195: false,
deprecated2: '',
deprecated20: 0,
deprecated21: false,
deprecated22: 0,
deprecated23: '',
deprecated24: 0,
deprecated26: '',
deprecated28: '',
deprecated3: {},
deprecated30: '',
deprecated31: false,
deprecated32: '',
deprecated35: 0,
deprecated36: 0,
deprecated39: '',
deprecated4: 0,
deprecated41: 0,
deprecated43: false,
deprecated44: 0,
deprecated5: false,
deprecated6: '',
deprecated7: 0,
deprecated8: '',
deprecated9: '',
disable_preload_stream: false,
drawer_tab_position: '',
effect_info: [],
existed_commerce_goods: false,
fansclub_msg_style: 2,
feed_room_label: {
avg_color: '#F1FFEB',
height: 0,
image_type: 0,
is_animated: false,
open_web_url: '',
uri: 'webcast-sg/2ea90002aca1159b5c67',
url_list: [Array],
width: 0
},
feed_room_labels: [],
filter_msg_rules: [],
finish_reason: 0,
finish_time: 1661878842,
finish_url: '',
finish_url_v2: '',
follow_msg_style: 2,
forum_extra_data: '',
game_tag: [],
gift_msg_style: 2,
gift_poll_vote_enabled: false,
group_source: 0,
has_commerce_goods: false,
have_wishlist: false,
hot_sentence_info: '',
id: 7137682087200558000,
id_str: '7137682087200557829',
indicators: [],
interaction_question_version: 0,
introduction: '',
is_gated_room: false,
is_replay: false,
is_show_user_card_switch: false,
last_ping_time: 1661878842,
layout: 0,
like_count: 0,
link_mic: {
audience_id_list: [],
battle_scores: [],
battle_settings: [Object],
channel_id: 0,
followed_count: 0,
linked_user_list: [],
multi_live_enum: 1,
rival_anchor_id: 0,
show_user_list: []
},
linker_map: {},
linkmic_layout: 0,
live_distribution: [],
live_id: 12,
live_reason: '',
live_room_mode: 0,
live_sub_only: 0,
live_type_audio: false,
live_type_linkmic: false,
live_type_normal: true,
live_type_sandbox: false,
live_type_screenshot: false,
live_type_social_live: false,
live_type_third_party: false,
living_room_attrs: {
admin_flag: 0,
rank: 0,
room_id: 7137682087200558000,
room_id_str: '7137682087200557829',
silence_flag: 0
},
lottery_finish_time: 0,
mosaic_status: 0,
os_type: 1,
owner: {
allow_find_by_contacts: false,
allow_others_download_video: false,
allow_others_download_when_sharing_video: false,
allow_share_show_profile: false,
allow_show_in_gossip: false,
allow_show_my_action: false,
allow_strange_comment: false,
allow_unfollower_comment: false,
allow_use_linkmic: false,
avatar_large: [Object],
avatar_medium: [Object],
avatar_thumb: [Object],
badge_image_list: [],
badge_list: [],
bg_img_url: '',
bio_description: 'HH???تابعوني انستغرامnاذا سقطت سأخذ الجميع معيn?Alin_issa22?' ,
block_status: 0,
border_list: [],
comment_restrict: 0,
commerce_webcast_config_ids: [],
constellation: '',
create_time: 0,
deprecated1: 0,
deprecated12: 0,
deprecated13: 0,
deprecated15: 0,
deprecated16: false,
deprecated17: false,
deprecated18: '',
deprecated19: false,
deprecated2: 0,
deprecated21: 0,
deprecated28: false,
deprecated29: '',
deprecated3: 0,
deprecated4: 0,
deprecated5: '',
deprecated6: 0,
deprecated7: '',
deprecated8: 0,
disable_ichat: 0,
display_id: 'alin.i7',
enable_ichat_img: 0,
exp: 0,
fan_ticket_count: 0,
fold_stranger_chat: false,
follow_info: [Object],
follow_status: 0,
ichat_restrict_type: 0,
id: 6672446849804223000,
id_str: '6672446849804223493',
is_follower: false,
is_following: false,
link_mic_stats: 0,
media_badge_image_list: [],
modify_time: 1661427082,
need_profile_guide: false,
new_real_time_icons: [],
nickname: '?ALIN?',
own_room: [Object],
pay_grade: [Object],
pay_score: 0,
pay_scores: 0,
push_comment_status: false,
push_digg: false,
push_follow: false,
push_friend_action: false,
push_ichat: false,
push_status: false,
push_video_post: false,
push_video_recommend: false,
real_time_icons: [],
sec_uid: 'MS4wLjABAAAAuUKuWAiw0GQO2_zOeyns0YCBRK7ztdoDWAAQ6gPFLBNSdTs-g5BsgScwTD9jWeK_',
secret: 0,
share_qrcode_uri: '',
special_id: '',
status: 1,
ticket_count: 0,
top_fans: [],
top_vip_no: 0,
upcoming_event_list: [],
user_attr: [Object],
user_role: 0,
verified: false,
verified_content: '',
verified_reason: '',
with_car_management_permission: false,
with_commerce_permission: false,
with_fusion_shop_entry: false
},
owner_device_id: 0,
owner_device_id_str: '',
owner_user_id: 6672446849804223000,
owner_user_id_str: '',
pre_enter_time: 0,
preview_flow_tag: 0,
ranklist_audience_type: 0,
relation_tag: '',
replay: true,
room_audit_status: 0,
room_auth: {
Banner: 1,
BroadcastMessage: 0,
Chat: true,
ChatL2: false,
ChatSubOnly: false,
CommercePermission: 0,
CustomizablePoll: 0,
Danmaku: false,
Digg: true,
DonationSticker: 2,
EventPromotion: 0,
Gift: true,
GiftAnchorMt: 1,
GiftPoll: 0,
GoldenEnvelope: 0,
GoldenEnvelopeActivity: 0,
InteractionQuestion: true,
Landscape: 2,
LandscapeChat: 0,
LuckMoney: true,
Pictionary: 0,
Poll: 0,
Promote: false,
PromoteOther: 0,
Props: false,
PublicScreen: 1,
QuickChat: 0,
Rank: 0,
RoomContributor: false,
Share: true,
ShareEffect: 0,
ShoppingRanking: 0,
UserCard: true,
UserCount: 0,
Viewers: false,
deprecated1: false,
deprecated2: 0,
deprecated3: 0,
deprecated4: 0,
deprecated5: 0,
deprecated6: 0,
deprecated7: 0,
deprecated8: 0,
deprecated9: 0,
transaction_history: 1,
use_user_pv: false
},
room_create_ab_param: '',
room_layout: 0,
room_sticker_list: [],
room_tabs: [],
room_tag: 0,
scroll_config: '',
search_id: 0,
share_msg_style: 2,
share_url: 'https://m.tiktok.com/share/live/7137682087200557829/?language=en',
short_title: '',
short_touch_items: [],
social_interaction: { linkmic_scene_linker: {}, multi_live: [Object] },
start_time: 0,
stats: {
deprecated1: 0,
deprecated2: '',
digg_count: 0,
enter_count: 0,
fan_ticket: 0,
follow_count: 686,
gift_uv_count: