{"id":13615005,"url":"https://github.com/zerodytrash/TikTok-Live-Connector","last_synced_at":"2025-04-13T20:32:40.352Z","repository":{"id":39667733,"uuid":"455400811","full_name":"zerodytrash/TikTok-Live-Connector","owner":"zerodytrash","description":"Node.js library to receive live stream events (comments, gifts, etc.) in realtime from TikTok LIVE.","archived":false,"fork":false,"pushed_at":"2025-03-16T03:32:03.000Z","size":299,"stargazers_count":1519,"open_issues_count":127,"forks_count":320,"subscribers_count":43,"default_branch":"main","last_synced_at":"2025-04-10T19:06:00.442Z","etag":null,"topics":["api","api-wrapper","bot","broadcast","chat","chat-reader","connector","hacktoberfest","javascript","live","livestream","nodejs","package","scraper","stream","tiktok","tiktok-api","tiktok-live","webcast","websocket"],"latest_commit_sha":null,"homepage":"https://discord.gg/2c6kX6g3Pa","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zerodytrash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"zerodytrash","ko_fi":"zerody","patreon":"zerody","custom":"https://www.buymeacoffee.com/zerody"}},"created_at":"2022-02-04T02:41:27.000Z","updated_at":"2025-04-10T17:39:11.000Z","dependencies_parsed_at":"2023-09-27T06:49:44.196Z","dependency_job_id":"7897f3b6-690a-4810-8f81-40bafaabe275","html_url":"https://github.com/zerodytrash/TikTok-Live-Connector","commit_stats":{"total_commits":153,"total_committers":10,"mean_commits":15.3,"dds":0.08496732026143794,"last_synced_commit":"3277f0707dd4702650e682eed0bcd06b936de7e3"},"previous_names":["zerodytrash/tiktok-livestream-chat-connector"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodytrash%2FTikTok-Live-Connector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodytrash%2FTikTok-Live-Connector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodytrash%2FTikTok-Live-Connector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodytrash%2FTikTok-Live-Connector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zerodytrash","download_url":"https://codeload.github.com/zerodytrash/TikTok-Live-Connector/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248777913,"owners_count":21160058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","api-wrapper","bot","broadcast","chat","chat-reader","connector","hacktoberfest","javascript","live","livestream","nodejs","package","scraper","stream","tiktok","tiktok-api","tiktok-live","webcast","websocket"],"created_at":"2024-08-01T20:01:08.088Z","updated_at":"2025-04-13T20:32:40.313Z","avatar_url":"https://github.com/zerodytrash.png","language":"JavaScript","funding_links":["https://github.com/sponsors/zerodytrash","https://ko-fi.com/zerody","https://patreon.com/zerody","https://www.buymeacoffee.com/zerody"],"categories":["TypeScript"],"sub_categories":[],"readme":"# TikTok-Live-Connector\nA Node.js library to receive live stream events such as 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), [Subscriptions](#subscribe), [Viewers](#roomuser), [Follows](#social), [Shares](#social), [Questions](#questionnew), [Likes](#like) and [Battles](#linkmicbattle) can be tracked. You can also send [automatic messages](#send-chat-messages) into the chat by providing your Session ID.\n\n### Example Project: [https://tiktok-chat-reader.zerody.one/](https://tiktok-chat-reader.zerody.one/)\n\nDo you prefer other programming languages?\n- **Python** rewrite: [TikTokLive](https://github.com/isaackogan/TikTokLive) by [@isaackogan](https://github.com/isaackogan)\n- **Java** rewrite: [TikTokLiveJava](https://github.com/jwdeveloper/TikTokLiveJava) by [@jwdeveloper](https://github.com/jwdeveloper)\n- **C#** rewrite: [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp) by [@frankvHoof93](https://github.com/frankvHoof93)\n- **Go** rewrite: [GoTikTokLive](https://github.com/Davincible/gotiktoklive) by [@Davincible](https://github.com/Davincible)\n\n**NOTE:** This is not an official API. It's a reverse engineering project.\n\n**NOTE:** This JavaScript library is intended for use in [Node.js](https://nodejs.org/) 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](https://socket.io/) or a different low-latency communication framework. A complete example project can be found here: [TikTok-Chat-Reader](https://github.com/zerodytrash/TikTok-Chat-Reader)\n\n\u003e **UPDATE**:\u003cbr\u003eDue 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 the `npm i tiktok-live-connector` command.\n\n#### Overview\n- [Getting started](#getting-started)\n- [Params and options](#params-and-options)\n- [Methods](#methods)\n- [Events](#events)\n- [Examples](#examples)\n- [Contributing](#contributing)\n\n## Getting started\n\n1. Install the package via NPM\n```\nnpm i tiktok-live-connector\n```\n\n2. Create your first chat connection\n\n```javascript\nconst { WebcastPushConnection } = require('tiktok-live-connector');\n\n// Username of someone who is currently live\nlet tiktokUsername = \"officialgeilegisela\";\n\n// Create a new wrapper object and pass the username\nlet tiktokLiveConnection = new WebcastPushConnection(tiktokUsername);\n\n// Connect to the chat (await can be used as well)\ntiktokLiveConnection.connect().then(state =\u003e {\n    console.info(`Connected to roomId ${state.roomId}`);\n}).catch(err =\u003e {\n    console.error('Failed to connect', err);\n})\n\n// Define the events that you want to handle\n// In this case we listen to chat messages (comments)\ntiktokLiveConnection.on('chat', data =\u003e {\n    console.log(`${data.uniqueId} (userId:${data.userId}) writes: ${data.comment}`);\n})\n\n// And here we receive gifts sent to the streamer\ntiktokLiveConnection.on('gift', data =\u003e {\n    console.log(`${data.uniqueId} (userId:${data.userId}) sends ${data.giftId}`);\n})\n\n// ...and more events described in the documentation below\n```\n\n## Params and options\n\nTo create a new `WebcastPushConnection` object the following parameters are required.\n\n`WebcastPushConnection(uniqueId, [options])`\n\n| Param Name | Required | Description |\n| ---------- | -------- | ----------- |\n| uniqueId   | Yes | The unique username of the broadcaster. You can find this name in the URL.\u003cbr\u003eExample: `https://www.tiktok.com/@officialgeilegisela/live` =\u003e `officialgeilegisela` |\n| options  | No | Here you can set the following optional connection properties. If you do not specify a value, the default value will be used.\u003cbr\u003e\u003cbr\u003e`processInitialData` (default: `true`) \u003cbr\u003e Define if you want to process the initital data which includes old messages of the last seconds.\u003cbr\u003e\u003cbr\u003e`fetchRoomInfoOnConnect` (default: `true`) \u003cbr\u003e Define if you want to fetch all room information on [`connect()`](#methods). 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()`](#methods) function.\u003cbr\u003e\u003cbr\u003e`enableExtendedGiftInfo` (default: `false`) \u003cbr\u003e 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](#gift). \u003cbr\u003e\u003cbr\u003e`enableWebsocketUpgrade` (default: `true`) \u003cbr\u003e Define if you want to use a WebSocket connection instead of request polling if TikTok offers it. \u003cbr\u003e\u003cbr\u003e`requestPollingIntervalMs` (default: `1000`) \u003cbr\u003e Request polling interval if WebSocket is not used.\u003cbr\u003e\u003cbr\u003e`sessionId` (default: `null`) \u003cbr\u003e 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()`](#methods) function. See [Example](#send-chat-messages)\u003cbr\u003e\u003cbr\u003e`clientParams` (default: `{}`) \u003cbr\u003e Custom client params for Webcast API.\u003cbr\u003e\u003cbr\u003e`requestHeaders` (default: `{}`) \u003cbr\u003e Custom request headers passed to [axios](https://github.com/axios/axios).\u003cbr\u003e\u003cbr\u003e`websocketHeaders` (default: `{}`) \u003cbr\u003e Custom websocket headers passed to [websocket.client](https://github.com/theturtle32/WebSocket-Node). \u003cbr\u003e\u003cbr\u003e`requestOptions` (default: `{}`) \u003cbr\u003e Custom request options passed to [axios](https://github.com/axios/axios). Here you can specify an `httpsAgent` to use a proxy and a `timeout` value. See [Example](#connect-via-proxy). \u003cbr\u003e\u003cbr\u003e`websocketOptions` (default: `{}`) \u003cbr\u003e Custom websocket options passed to [websocket.client](https://github.com/theturtle32/WebSocket-Node). Here you can specify an `agent` to use a proxy and a `timeout` value. See [Example](#connect-via-proxy). \u003cbr\u003e\u003cbr\u003e`signProviderOptions` (default: `{}`) \u003cbr\u003e Custom request options for the TikTok signing server. Here you can specify a `host`, `params`, and `headers`. |\n\nExample Options:\n```javascript\nlet tiktokLiveConnection = new WebcastPushConnection(tiktokUsername, {\n    processInitialData: false,\n    enableExtendedGiftInfo: true,\n    enableWebsocketUpgrade: true,\n    requestPollingIntervalMs: 2000,\n    clientParams: {\n        \"app_language\": \"en-US\",\n        \"device_platform\": \"web\"\n    },\n    requestHeaders: {\n        \"headerName\": \"headerValue\"\n    },\n    websocketHeaders: {\n        \"headerName\": \"headerValue\"\n    },\n    requestOptions: {\n        timeout: 10000\n    },\n    websocketOptions: {\n        timeout: 10000\n    },\n    signProviderOptions: {\n        host: \"https://custom-signing-server.com\",\n        params: {\n            \"paramName\": \"paramValue\"\n        },\n        headers: {\n            \"headerName\": \"headerValue\"\n        }\n    }\n});\n```\n\n## Methods\nA `WebcastPushConnection` object contains the following methods.\n\n| Method Name | Description |\n| ----------- | ----------- |\n| connect     | Connects to the live stream chat.\u003cbr\u003eReturns a `Promise` which will be resolved when the connection is successfully established. |\n| disconnect  | Disconnects the connection. |\n| getState    | Gets the current connection state including the cached room info (see below). |\n| getRoomInfo | Gets the current room info from TikTok API including streamer info, room status and statistics.\u003cbr\u003eReturns a `Promise` which will be resolved when the API request is done.\u003cbr\u003e*\u003cb\u003eNote: \u003c/b\u003eYou can call this function even if you're not connected.*\u003cbr\u003e[Example](#retrieve-room-info) |\n| getAvailableGifts | Gets a list of all available gifts including gift name, image url, diamont cost and a lot of other information.\u003cbr\u003eReturns a `Promise` that will be resolved when all available gifts has been retrieved from the API.\u003cbr\u003e*\u003cb\u003eNote: \u003c/b\u003eYou can call this function even if you're not connected.*\u003cbr\u003e[Example](#retrieve-available-gifts) |\n| sendMessage\u003cbr\u003e`(text, [sessionId])` | Sends a chat message into the current live room using the provided session cookie (specified in the [constructor options](#params-and-options) or via the second function parameter).\u003cbr\u003eReturns a `Promise` that will be resolved when the chat message has been submitted to the API.\u003cbr\u003e\u003cbr\u003e\u003cb\u003eWARNING: Use of this function is at your own risk. Spamming messages can lead to the suspension of your TikTok account. Be careful!\u003c/b\u003e\u003cbr\u003e[Example](#send-chat-messages)|\n\n## Events\n\nA `WebcastPushConnection` object has the following events which can be handled via `.on(eventName, eventHandler)`\n\nControl Events:\n- [connected](#connected)\n- [disconnected](#disconnected)\n- [streamEnd](#streamend)\n- [rawData](#rawdata)\n- [websocketConnected](#websocketconnected)\n- [error](#error)\n\nMessage Events:\n- [member](#member)\n- [chat](#chat)\n- [gift](#gift)\n- [roomUser](#roomuser)\n- [like](#like)\n- [social](#social)\n- [emote](#emote)\n- [envelope](#envelope)\n- [questionNew](#questionnew)\n- [linkMicBattle](#linkmicbattle)\n- [linkMicArmies](#linkmicarmies)\n- [liveIntro](#liveintro)\n- [subscribe](#subscribe)\n\nCustom Events:\n- [follow](#follow)\n- [share](#share)\n\n\u003cbr\u003e\u003cbr\u003e\n\n### Control Events\n\n### `connected`\nTriggered when the connection is successfully established.\n\n```javascript\ntiktokLiveConnection.on('connected', state =\u003e {\n    console.log('Hurray! Connected!', state);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n  isConnected: true,\n  upgradedToWebsocket: true,\n  roomId: '7137682087200557829',        \n  roomInfo: {\n    AnchorABMap: {},\n    admin_user_ids: [],\n    anchor_scheduled_time_text: '',     \n    anchor_share_text: '',\n    anchor_tab_type: 7,\n    answering_question_content: '',     \n    app_id: 1233,\n    audio_mute: 0,\n    auto_cover: 0,\n    book_end_time: 0,\n    book_time: 0,\n    business_live: 0,\n    challenge_info: '',\n    client_version: 250701,\n    comment_has_text_emoji_emote: 0,    \n    comment_name_mode: 0,\n    commerce_info: {\n      commerce_permission: 0,\n      oec_live_enter_room_init_data: '',\n      use_async_load: false\n    },\n    common_label_list: '',\n    content_tag: '',\n    cover: {\n      avg_color: '',\n      height: 0,\n      image_type: 0,\n      is_animated: false,\n      open_web_url: '',\n      uri: '720x720/tos-maliva-avt-0068/4e64db7f7c37caf9b2df71df8580a9b0',\n      url_list: [Array],\n      width: 0\n    },\n    create_time: 1661871149,\n    deco_list: [],\n    deprecated10: '',\n    deprecated11: '',\n    deprecated12: '',\n    deprecated13: '',\n    deprecated14: 0,\n    deprecated15: 0,\n    deprecated16: 0,\n    deprecated17: [],\n    deprecated18: 0,\n    deprecated19: '',\n    deprecated195: false,\n    deprecated2: '',\n    deprecated20: 0,\n    deprecated21: false,\n    deprecated22: 0,\n    deprecated23: '',\n    deprecated24: 0,\n    deprecated26: '',\n    deprecated28: '',\n    deprecated3: {},\n    deprecated30: '',\n    deprecated31: false,\n    deprecated32: '',\n    deprecated35: 0,\n    deprecated36: 0,\n    deprecated39: '',\n    deprecated4: 0,\n    deprecated41: 0,\n    deprecated43: false,\n    deprecated44: 0,\n    deprecated5: false,\n    deprecated6: '',\n    deprecated7: 0,\n    deprecated8: '',\n    deprecated9: '',\n    disable_preload_stream: false,\n    drawer_tab_position: '',\n    effect_info: [],\n    existed_commerce_goods: false,\n    fansclub_msg_style: 2,\n    feed_room_label: {\n      avg_color: '#F1FFEB',\n      height: 0,\n      image_type: 0,\n      is_animated: false,\n      open_web_url: '',\n      uri: 'webcast-sg/2ea90002aca1159b5c67',\n      url_list: [Array],\n      width: 0\n    },\n    feed_room_labels: [],\n    filter_msg_rules: [],\n    finish_reason: 0,\n    finish_time: 1661878842,\n    finish_url: '',\n    finish_url_v2: '',\n    follow_msg_style: 2,\n    forum_extra_data: '',\n    game_tag: [],\n    gift_msg_style: 2,\n    gift_poll_vote_enabled: false,\n    group_source: 0,\n    has_commerce_goods: false,\n    have_wishlist: false,\n    hot_sentence_info: '',\n    id: 7137682087200558000,\n    id_str: '7137682087200557829',\n    indicators: [],\n    interaction_question_version: 0,\n    introduction: '',\n    is_gated_room: false,\n    is_replay: false,\n    is_show_user_card_switch: false,\n    last_ping_time: 1661878842,\n    layout: 0,\n    like_count: 0,\n    link_mic: {\n      audience_id_list: [],\n      battle_scores: [],\n      battle_settings: [Object],\n      channel_id: 0,\n      followed_count: 0,\n      linked_user_list: [],\n      multi_live_enum: 1,\n      rival_anchor_id: 0,\n      show_user_list: []\n    },\n    linker_map: {},\n    linkmic_layout: 0,\n    live_distribution: [],\n    live_id: 12,\n    live_reason: '',\n    live_room_mode: 0,\n    live_sub_only: 0,\n    live_type_audio: false,\n    live_type_linkmic: false,\n    live_type_normal: true,\n    live_type_sandbox: false,\n    live_type_screenshot: false,\n    live_type_social_live: false,\n    live_type_third_party: false,\n    living_room_attrs: {\n      admin_flag: 0,\n      rank: 0,\n      room_id: 7137682087200558000,\n      room_id_str: '7137682087200557829',\n      silence_flag: 0\n    },\n    lottery_finish_time: 0,\n    mosaic_status: 0,\n    os_type: 1,\n    owner: {\n      allow_find_by_contacts: false,\n      allow_others_download_video: false,\n      allow_others_download_when_sharing_video: false,\n      allow_share_show_profile: false,\n      allow_show_in_gossip: false,\n      allow_show_my_action: false,\n      allow_strange_comment: false,\n      allow_unfollower_comment: false,\n      allow_use_linkmic: false,\n      avatar_large: [Object],\n      avatar_medium: [Object],\n      avatar_thumb: [Object],\n      badge_image_list: [],\n      badge_list: [],\n      bg_img_url: '',\n      bio_description: 'HH📍🇩🇪تابعوني انستغرام\\nاذا سقطت سأخذ الجميع معي\\n👻Alin_issa22👻'  ,\n      block_status: 0,\n      border_list: [],\n      comment_restrict: 0,\n      commerce_webcast_config_ids: [],\n      constellation: '',\n      create_time: 0,\n      deprecated1: 0,\n      deprecated12: 0,\n      deprecated13: 0,\n      deprecated15: 0,\n      deprecated16: false,\n      deprecated17: false,\n      deprecated18: '',\n      deprecated19: false,\n      deprecated2: 0,\n      deprecated21: 0,\n      deprecated28: false,\n      deprecated29: '',\n      deprecated3: 0,\n      deprecated4: 0,\n      deprecated5: '',\n      deprecated6: 0,\n      deprecated7: '',\n      deprecated8: 0,\n      disable_ichat: 0,\n      display_id: 'alin.i7',\n      enable_ichat_img: 0,\n      exp: 0,\n      fan_ticket_count: 0,\n      fold_stranger_chat: false,\n      follow_info: [Object],\n      follow_status: 0,\n      ichat_restrict_type: 0,\n      id: 6672446849804223000,\n      id_str: '6672446849804223493',\n      is_follower: false,\n      is_following: false,\n      link_mic_stats: 0,\n      media_badge_image_list: [],\n      modify_time: 1661427082,\n      need_profile_guide: false,\n      new_real_time_icons: [],\n      nickname: '🦋ALIN🦋',\n      own_room: [Object],\n      pay_grade: [Object],\n      pay_score: 0,\n      pay_scores: 0,\n      push_comment_status: false,\n      push_digg: false,\n      push_follow: false,\n      push_friend_action: false,\n      push_ichat: false,\n      push_status: false,\n      push_video_post: false,\n      push_video_recommend: false,\n      real_time_icons: [],\n      sec_uid: 'MS4wLjABAAAAuUKuWAiw0GQO2_zOeyns0YCBRK7ztdoDWAAQ6gPFLBNSdTs-g5BsgScwTD9jWeK_',\n      secret: 0,\n      share_qrcode_uri: '',\n      special_id: '',\n      status: 1,\n      ticket_count: 0,\n      top_fans: [],\n      top_vip_no: 0,\n      upcoming_event_list: [],\n      user_attr: [Object],\n      user_role: 0,\n      verified: false,\n      verified_content: '',\n      verified_reason: '',\n      with_car_management_permission: false,\n      with_commerce_permission: false,\n      with_fusion_shop_entry: false\n    },\n    owner_device_id: 0,\n    owner_device_id_str: '',\n    owner_user_id: 6672446849804223000,\n    owner_user_id_str: '',\n    pre_enter_time: 0,\n    preview_flow_tag: 0,\n    ranklist_audience_type: 0,\n    relation_tag: '',\n    replay: true,\n    room_audit_status: 0,\n    room_auth: {\n      Banner: 1,\n      BroadcastMessage: 0,\n      Chat: true,\n      ChatL2: false,\n      ChatSubOnly: false,\n      CommercePermission: 0,\n      CustomizablePoll: 0,\n      Danmaku: false,\n      Digg: true,\n      DonationSticker: 2,\n      EventPromotion: 0,\n      Gift: true,\n      GiftAnchorMt: 1,\n      GiftPoll: 0,\n      GoldenEnvelope: 0,\n      GoldenEnvelopeActivity: 0,\n      InteractionQuestion: true,\n      Landscape: 2,\n      LandscapeChat: 0,\n      LuckMoney: true,\n      Pictionary: 0,\n      Poll: 0,\n      Promote: false,\n      PromoteOther: 0,\n      Props: false,\n      PublicScreen: 1,\n      QuickChat: 0,\n      Rank: 0,\n      RoomContributor: false,\n      Share: true,\n      ShareEffect: 0,\n      ShoppingRanking: 0,\n      UserCard: true,\n      UserCount: 0,\n      Viewers: false,\n      deprecated1: false,\n      deprecated2: 0,\n      deprecated3: 0,\n      deprecated4: 0,\n      deprecated5: 0,\n      deprecated6: 0,\n      deprecated7: 0,\n      deprecated8: 0,\n      deprecated9: 0,\n      transaction_history: 1,\n      use_user_pv: false\n    },\n    room_create_ab_param: '',\n    room_layout: 0,\n    room_sticker_list: [],\n    room_tabs: [],\n    room_tag: 0,\n    scroll_config: '',\n    search_id: 0,\n    share_msg_style: 2,\n    share_url: 'https://m.tiktok.com/share/live/7137682087200557829/?language=en',\n    short_title: '',\n    short_touch_items: [],\n    social_interaction: { linkmic_scene_linker: {}, multi_live: [Object] },\n    start_time: 0,\n    stats: {\n      deprecated1: 0,\n      deprecated2: '',\n      digg_count: 0,\n      enter_count: 0,\n      fan_ticket: 0,\n      follow_count: 686,\n      gift_uv_count: 0,\n      id: 7137682087200558000,\n      id_str: '7137682087200557829',\n      like_count: 0,\n      replay_fan_ticket: 0,\n      replay_viewers: 64076,\n      share_count: 0,\n      total_user: 104582,\n      total_user_desp: '',\n      user_count_composition: [Object],\n      watermelon: 0\n    },\n    status: 2,\n    sticker_list: [],\n    stream_id: 2993830046178738000,\n    stream_id_str: '2993830046178738249',\n    stream_status: 0,\n    stream_url: {\n      candidate_resolution: [Array],\n      complete_push_urls: [],\n      default_resolution: 'ORIGION',\n      extra: [Object],\n      flv_pull_url: [Object],\n      flv_pull_url_params: [Object],\n      hls_pull_url: 'https://pull-hls-f16-va01.tiktokcdn.com/stage/stream-2993830046178738249_or4/index.m3u8',\n      hls_pull_url_map: {},\n      hls_pull_url_params: '{\"VCodec\":\"h264\"}',\n      id: 2993830046178738000,\n      id_str: '2993830046178738249',\n      live_core_sdk_data: [Object],\n      provider: 0,\n      push_urls: [],\n      resolution_name: [Object],\n      rtmp_pull_url: 'https://pull-f5-va01.tiktokcdn.com/stage/stream-2993830046178738249_or4.flv',\n      rtmp_pull_url_params: '{\"VCodec\":\"h264\"}',\n      rtmp_push_url: '',\n      rtmp_push_url_params: '',\n      stream_control_type: 0\n    },\n    stream_url_filtered_info: { is_gated_room: false, is_paid_event: false },\n    title: 'انا جيت😍 🥰' ,\n    top_fans: [ [Object], [Object], [Object] ],\n    use_filter: false,\n    user_count: 1136,\n    user_share_text: '',\n    video_feed_tag: '',\n    webcast_comment_tcs: 0,\n    webcast_sdk_version: 0,\n    with_draw_something: false,\n    with_ktv: false,\n    with_linkmic: true\n  },\n  availableGifts: [] // Filled if `enableExtendedGiftInfo` set\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cbr\u003e\n\n### `disconnected`\nTriggered when the connection gets disconnected. In that case you can call `connect()` again to have a reconnect logic. Note that you should wait a little bit before attempting a reconnect to to avoid being rate-limited.\n\n```javascript\ntiktokLiveConnection.on('disconnected', () =\u003e {\n    console.log('Disconnected :(');\n})\n```\n\u003cbr\u003e\n\n### `streamEnd`\nTriggered when the live stream gets terminated by the host. Will also trigger the [`disconnected`](#disconnected) event.\n\n```javascript\ntiktokLiveConnection.on('streamEnd', (actionId) =\u003e {\n    if (actionId === 3) {\n        console.log('Stream ended by user');\n    }\n    if (actionId === 4) {\n        console.log('Stream ended by platform moderator (ban)');\n    }\n})\n```\n\u003cbr\u003e\n\n### `rawData`\nTriggered every time a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case with \u003ca href=\"https://www.npmjs.com/package/protobufjs\"\u003eprotobufjs\u003c/a\u003e.\n\n```javascript\ntiktokLiveConnection.on('rawData', (messageTypeName, binary) =\u003e {\n    console.log(messageTypeName, binary);\n})\n```\n\u003cbr\u003e\n\n### `websocketConnected`\nWill be triggered as soon as a websocket connection is established. The websocket client object is passed.\n\n```javascript\ntiktokLiveConnection.on('websocketConnected', websocketClient =\u003e {\n    console.log(\"Websocket:\", websocketClient.connection);\n})\n```\n\u003cbr\u003e\n\n### `error`\nGeneral error event. You should handle this.\n\n```javascript\ntiktokLiveConnection.on('error', err =\u003e {\n    console.error('Error!', err);\n})\n```\n\u003cbr\u003e\n\n\n### Message Events\n\n### `member`\nTriggered every time a new viewer joins the live stream.\n\n```javascript\ntiktokLiveConnection.on('member', data =\u003e {\n    console.log(`${data.uniqueId} joins the stream!`);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    actionId: 1,\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...webp\",\n    followRole: 0, // 0 = none; 1 = follower; 2 = friends\n    userBadges: [\n        {\n            type: \"pm_mt_moderator_im\",\n            name: \"Moderator\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/rankl...image\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/....~...image\"\n        }\n    ],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 2139,\n        followerCount: 853,\n        followStatus: 0,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137750885996120859\",\n    createTime: \"1661887134195\",\n    displayType: \"live_room_enter_toast\",\n    label: \"{0:user} joined\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cbr\u003e\n\n### `chat`\nTriggered every time a new chat comment arrives.\n\n```javascript\ntiktokLiveConnection.on('chat', data =\u003e {\n    console.log(`${data.uniqueId} writes: ${data.comment}`);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    comment: \"How are you?\",\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n    followRole: 0, // 0 = none; 1 = follower; 2 = friends\n    userBadges: [\n        {\n            // Moderator badge\n            type: \"pm_mt_moderator_im\",\n            name: \"Moderator\"\n        },\n        {\n            // Top Gifter badge\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/rankl...image\"\n        },\n        {\n            // Subscriber Badge\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/....~...image\"\n        }\n    ],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 10000,\n        followerCount: 606,\n        followStatus: 0,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137750790064065286\",\n    createTime: \"1661887134718\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `gift`\nTriggered every time a gift arrives. You will receive additional information via the `extendedGiftInfo` attribute when you enable the [`enableExtendedGiftInfo`](#params-and-options) option. \n\n\u003e **NOTE:** Users have the capability to send gifts in a streak. This increases the `repeatCount` value until the user terminates the streak. During this time new gift events are triggered again and again with an increased `repeatCount` 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 `repeatEnd`:`true`. This applies only to gifts with `giftType`:`1`. This means that even if the user sends a `giftType`:`1` gift only once, you will receive the event twice. Once with `repeatEnd`:`false` and once with `repeatEnd`:`true`. Therefore, the event should be handled as follows:\n\n\n```javascript\ntiktokLiveConnection.on('gift', data =\u003e {\n    if (data.giftType === 1 \u0026\u0026 !data.repeatEnd) {\n        // Streak in progress =\u003e show only temporary\n        console.log(`${data.uniqueId} is sending gift ${data.giftName} x${data.repeatCount}`);\n    } else {\n        // Streak ended or non-streakable gift =\u003e process the gift with final repeat_count\n        console.log(`${data.uniqueId} has sent gift ${data.giftName} x${data.repeatCount}`);\n    }\n})\n```\n\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    // Gift Details\n    giftId: 5953,\n    repeatCount: 1,\n    repeatEnd: true,\n    groupId: \"1661887131074\",\n    monitorExtra: {\n        anchor_id: 7087613897129494000,\n        from_idc: \"maliva\",\n        from_user_id: 7044640112358049000,\n        gift_id: 5953,\n        gift_type: 1,\n        log_id: \"20220830191849010192055159174B7670\",\n        msg_id: 7137749190944230000,\n        repeat_count: 1,\n        repeat_end: 1,\n        room_id: 7137728632142843000,\n        send_gift_profit_core_start_ms: 0,\n        send_gift_send_message_success_ms: 1661887134397,\n        to_user_id: 7087613897129494000\n    },\n    // Sender Details\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n    followRole: 0, // 0 = none; 1 = follower; 2 = friends\n    userBadges: [],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 360,\n        followerCount: 740,\n        followStatus: 0,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137749190944230150\",\n    createTime: \"1661887134397\",\n    displayType: \"webcast_aweme_gift_send_message\",\n    label: \"{0:user} sent {1:gift} {2:string}\",\n    gift: {\n        gift_id: 5953,\n        repeat_count: 1,\n        repeat_end: 1,\n        gift_type: 1\n    },\n    describe: \"Sent Nevalyashka doll\",\n    giftType: 1,\n    diamondCount: 25,\n    giftName: \"Nevalyashka doll\",\n    giftPictureUrl: \"https://p19-webcast.tiktokcdn.com/img/maliva/webca...png\",\n    timestamp: 1661887134397,\n    extendedGiftInfo: {\n        // This will be filled when you enable the `enableExtendedGiftInfo` option\n    },\n\n    // Receiver Details (can also be a guest broadcaster)\n    receiverUserId: \"7087613897129493510\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `roomUser`\nTriggered every time a statistic message arrives. This message currently contains the viewer count and a top gifter list.\n\n```javascript\ntiktokLiveConnection.on('roomUser', data =\u003e {\n    console.log(`Viewer Count: ${data.viewerCount}`);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    topViewers: [\n        {\n            user: {\n                userId: \"6822565897317303297\",\n                secUid: \"MS4wLjABAAAALIKFhzvmiCws6B6KWfRgWr5MbyGVPXevakvnP8xc7VLkWtcqNeEe9coyRA74KNxm\",\n                uniqueId: \"linmjh\",\n                nickname: \"gì z má ( ^ㆍㅅㆍ^)\",\n                profilePictureUrl: \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n                followRole: 0,\n                userBadges: [],\n                userDetails: {\n                    createTime: \"1588502711\",\n                    bioDescription: \"\",\n                    profilePictureUrls: [\n                        \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n                        \"https://p9-sign-sg.tiktokcdn.com/aweme/100x100/tos...webp\",\n                        \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...jpeg\"\n                    ]\n                },\n                followInfo: {\n                    followingCount: 781,\n                    followerCount: 51,\n                    followStatus: 0,\n                    pushStatus: 0\n                },\n                isModerator: false,\n                isNewGifter: false,\n                isSubscriber: false,\n                topGifterRank: null\n            },\n            coinCount: 0\n        },\n        {\n            user: {\n                userId: \"6828542044454863874\",\n                secUid: \"MS4wLjABAAAAxP4NgzG7uJz1tcB8o3JN8PxHWej20NJWCHP1IG1PZ0OmQLB6SVORRSoX0Ool4dwj\",\n                uniqueId: \"xuanthainguyen0\",\n                nickname: \"Xuan Thai Nguyen\",\n                profilePictureUrl: \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/ti...webp\",\n                followRole: 0,\n                userBadges: [],\n                userDetails: {\n                    createTime: \"1593865836\",\n                    bioDescription: \"\",\n                    profilePictureUrls: [\n                        \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/ti...webp\",\n                        \"https://p9-sign-sg.tiktokcdn.com/aweme/100x100/tik...webp\",\n                        \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/ti...jpeg\"\n                    ]\n                },\n                followInfo: {\n                    followingCount: 6,\n                    followerCount: 6,\n                    followStatus: 0,\n                    pushStatus: 0\n                },\n                isModerator: false,\n                isNewGifter: false,\n                isSubscriber: false,\n                topGifterRank: null\n            },\n            coinCount: 0\n        },\n        {\n            user: {\n                userId: \"7014684709204624385\",\n                secUid: \"MS4wLjABAAAAnVMJ9MXN5HqjnpyEwgEhjv97Pc_ixtG4Iwnnagbrd99WhEATfhZLW6McX-uErTp9\",\n                uniqueId: \"dyip0c3sbo2t\",\n                nickname: \"Huu Trân572\",\n                profilePictureUrl: \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/ti...webp\",\n                followRole: 0,\n                userBadges: [],\n                userDetails: {\n                    createTime: \"1640318249\",\n                    bioDescription: \"\",\n                    profilePictureUrls: [\n                        \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/ti...webp\",\n                        \"https://p9-sign-sg.tiktokcdn.com/aweme/100x100/tik...webp\",\n                        \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/ti...jpeg\"\n                    ]\n                },\n                followInfo: {\n                    followingCount: 35,\n                    followerCount: 21,\n                    followStatus: 0,\n                    pushStatus: 0\n                },\n                isModerator: false,\n                isNewGifter: false,\n                isSubscriber: false,\n                topGifterRank: null\n            },\n            coinCount: 0\n        },\n        {\n            user: {\n                userId: \"7133413217468187675\",\n                secUid: \"MS4wLjABAAAA2u64n6KnroBOMQo4pR9bLv0twyCIy0X-wd7S__WR4d2VObktWAfs_ck08pjD4hIV\",\n                uniqueId: \"uservay64gw9d5\",\n                nickname: \"uservay64gw9d5\",\n                profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...webp\",\n                followRole: 0,\n                userBadges: [],\n                userDetails: {\n                    createTime: \"1660877330\",\n                    bioDescription: \"\",\n                    profilePictureUrls: [\n                        \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...webp\",\n                        \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...jpeg\"\n                    ]\n                },\n                followInfo: {\n                    followingCount: 2,\n                    followerCount: 0,\n                    followStatus: 0,\n                    pushStatus: 0\n                },\n                isModerator: false,\n                isNewGifter: false,\n                isSubscriber: false,\n                topGifterRank: null\n            },\n            coinCount: 0\n        },\n        {\n            user: {\n                userId: \"6800374961430791170\",\n                secUid: \"MS4wLjABAAAAF3tD_kSi9qas_10I5I5YUIBfXKd0KlKvKTKACzfXS1Wwp04e03xJCTswwzCMRgEu\",\n                uniqueId: \"hungtran0293\",\n                nickname: \"Trần Hùng\",\n                profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...webp\",\n                followRole: 0,\n                userBadges: [],\n                userDetails: {\n                    createTime: \"1585370455\",\n                    bioDescription: \"\",\n                    profilePictureUrls: [\n                        \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...webp\",\n                        \"https://p16-sign-va.tiktokcdn.com/tos-useast2a-avt...jpeg\"\n                    ]\n                },\n                followInfo: {\n                    followingCount: 1735,\n                    followerCount: 313,\n                    followStatus: 0,\n                    pushStatus: 0\n                },\n                isModerator: false,\n                isNewGifter: false,\n                isSubscriber: false,\n                topGifterRank: null\n            },\n            coinCount: 0\n        }\n    ],\n    viewerCount: 630\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cbr\u003e\n\n### `like`\nTriggered when a viewer sends likes to the streamer. For streams with many viewers, this event is not always triggered by TikTok.\n\n```javascript\ntiktokLiveConnection.on('like', data =\u003e {\n    console.log(`${data.uniqueId} sent ${data.likeCount} likes, total likes: ${data.totalLikeCount}`);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    likeCount: 6, // likes given by the user (taps on screen)\n    totalLikeCount: 21349, // likes that this stream has received in total (from all users)\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n    followRole: 0, // 0 = none; 1 = follower; 2 = friends,\n    userBadges: [\n        {\n            type: \"pm_mt_moderator_im\",\n            name: \"Moderator\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/rankl...image\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/....~...image\"\n        }\n    ],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p19-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 617,\n        followerCount: 112,\n        followStatus: 1,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137750883651619630\",\n    createTime: \"1661887134554\",\n    displayType: \"pm_mt_msg_viewer\",\n    label: \"{0:user} liked the LIVE\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `social`\nTriggered every time someone shares the stream or follows the host.\n\n```javascript\ntiktokLiveConnection.on('social', data =\u003e {\n    console.log('social event data:', data);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n    followRole: 1,\n    userBadges: [],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p19-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 277,\n        followerCount: 96,\n        followStatus: 1,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137750889884076842\",\n    createTime: \"1661887134629\",\n    displayType: \"pm_main_follow_message_viewer_2\", // or pm_mt_guidance_share\n    label: \"{0:user} followed the host\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `emote`\nTriggered every time a subscriber sends an emote (sticker).\n\n```javascript\ntiktokLiveConnection.on('emote', data =\u003e {\n    console.log('emote received', data);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n    followRole: 0, // 0 = none; 1 = follower; 2 = friends,\n    userBadges: [],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-00...webp\",\n            \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n            \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 14,\n        followerCount: 6,\n        followStatus: 1,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: true,\n    topGifterRank: null,\n    emoteId: \"7121025198379731714\",\n    emoteImageUrl: \"https://p19-webcast.tiktokcdn.com/webcast-sg/61964...image\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `envelope`\nTriggered every time someone sends a treasure chest.\n\n```javascript\ntiktokLiveConnection.on('envelope', data =\u003e {\n    console.log('envelope received', data);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-webcast.tiktokcdn.com/img/alisg/webcas...png\",\n    followRole: 0, // 0 = none; 1 = follower; 2 = friends\n    userBadges: [],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-webcast.tiktokcdn.com/img/alisg/webcas...png\",\n            \"https://p19-webcast.tiktokcdn.com/img/alisg/webcas...png\"\n        ]\n    },\n    followInfo: {\n        followingCount: 828,\n        followerCount: 1353,\n        followStatus: 0,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    coins: 20,\n    canOpen: 20,\n    timestamp: 1661887422\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `questionNew`\nTriggered every time someone asks a new question via the question feature.\n\n```javascript\ntiktokLiveConnection.on('questionNew', data =\u003e {\n    console.log(`${data.uniqueId} asks ${data.questionText}`);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    questionText: \"Do you know why TikTok has such a complicated API?\",\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n    followRole: 0, // 0 = none; 1 = follower; 2 = friends\n    userBadges: [],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 982,\n        followerCount: 175,\n        followStatus: 0,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `linkMicBattle`\nTriggered every time a battle starts.\n\n```javascript\ntiktokLiveConnection.on('linkMicBattle', (data) =\u003e {\n    console.log(`New Battle: ${data.battleUsers[0].uniqueId} VS ${data.battleUsers[1].uniqueId}`);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    battleUsers: [\n        {\n            userId: \"6901252963970515973\", // Host\n            uniqueId: \"growsa_fluffynation\",\n            nickname: \"GrowSA_FluffyNation\",\n            profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            userBadges: [],\n            userDetails: {\n                profilePictureUrls: [\n                    \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n                    \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...jpeg\"\n                ]\n            },\n            isModerator: false,\n            isNewGifter: false,\n            isSubscriber: false,\n            topGifterRank: null\n        },\n        {\n            userId: \"262781145296064512\", // Guest\n            uniqueId: \"real_martinpinkysmith\",\n            nickname: \"Martin Pinky Smith\",\n            profilePictureUrl: \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n            userBadges: [],\n            userDetails: {\n                profilePictureUrls: [\n                    \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n                    \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...jpeg\"\n                ]\n            },\n            isModerator: false,\n            isNewGifter: false,\n            isSubscriber: false,\n            topGifterRank: null\n        }\n    ]\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `linkMicArmies`\nTriggered every time a battle participant receives points. Contains the current status of the battle and the army that suported the group.\n\n```javascript\ntiktokLiveConnection.on('linkMicArmies', (data) =\u003e {\n    console.log('linkMicArmies', data);\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    battleStatus: 1,\n    battleArmies: [\n        {\n            hostUserId: \"6842213780475085829\",\n            points: 0,\n            participants: []\n        },\n        {\n            hostUserId: \"6722878711857579013\",\n            points: 33,\n            participants: [\n                {\n                    userId: \"7122168301669204994\",\n                    secUid: \"\",\n                    nickname: \"🦋\",\n                    profilePictureUrl: null,\n                    userBadges: [],\n                    userDetails: {\n                        createTime: \"0\",\n                        bioDescription: \"\"\n                    },\n                    isModerator: false,\n                    isNewGifter: false,\n                    isSubscriber: false,\n                    topGifterRank: null\n                },\n                {\n                    userId: \"7112729060212966406\",\n                    secUid: \"\",\n                    nickname: \"ealkaabi44\",\n                    profilePictureUrl: null,\n                    userBadges: [],\n                    userDetails: {\n                        createTime: \"0\",\n                        bioDescription: \"\"\n                    },\n                    isModerator: false,\n                    isNewGifter: false,\n                    isSubscriber: false,\n                    topGifterRank: null\n                },\n                {\n                    userId: \"7006435669158708229\",\n                    secUid: \"\",\n                    nickname: \"worood🦁 🌹🌹🌹🌹\",\n                    profilePictureUrl: null,\n                    userBadges: [],\n                    userDetails: {\n                        createTime: \"0\",\n                        bioDescription: \"\"\n                    },\n                    isModerator: false,\n                    isNewGifter: false,\n                    isSubscriber: false,\n                    topGifterRank: null\n                }\n            ]\n        }\n    ]\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\u003cbr\u003e\n\n### `liveIntro`\nTriggered when a live intro message appears.\n\n```javascript\ntiktokLiveConnection.on('liveIntro', (msg) =\u003e {\n    console.log(msg);\n})\n```\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    id: \"1658723381\",\n    description: \"welcome to my broadcast!\",\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n    followRole: 0,\n    userBadges: [\n        {\n            type: \"pm_mt_moderator_im\",\n            name: \"Moderator\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/rankl...image\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/....~...image\"\n        }\n    ],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p77-sign-va.tiktokcdn.com/tos-maliva-avt-0...webp\",\n            \"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 886,\n        followerCount: 57141,\n        followStatus: 0,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cbr\u003e\n\n### `subscribe`\nTriggers when a user creates a subscription.\n\n```javascript\ntiktokLiveConnection.on('subscribe', (data) =\u003e {\n    console.log(data.uniqueId, \"subscribed!\");\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    subMonth: 1,\n    oldSubscribeStatus: 2,\n    subscribingStatus: 1,\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n    followRole: 0,\n    userBadges: [],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...webp\",\n            \"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/to...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 23,\n        followerCount: 43,\n        followStatus: 0,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137745705032043266\",\n    createTime: \"1661885986187\",\n    displayType: \"pm_mt_subinfo_user\",\n    label: \"{0:user} just subscribed to the host\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cbr\u003e\n\n### Custom Events\nThese events are based on message events.\n\u003cbr\u003e\n\n### `follow`\nTriggers when a user follows the streamer. Based on `social` event.\n\n```javascript\ntiktokLiveConnection.on('follow', (data) =\u003e {\n    console.log(data.uniqueId, \"followed!\");\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n    followRole: 1,\n    userBadges: [\n        {\n            type: \"pm_mt_moderator_im\",\n            name: \"Moderator\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/rankl...image\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/....~...image\"\n        }\n    ],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p19-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 277,\n        followerCount: 96,\n        followStatus: 1,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137750889884076842\",\n    createTime: \"1661887134629\",\n    displayType: \"pm_main_follow_message_viewer_2\",\n    label: \"{0:user} followed the host\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cbr\u003e\n\n### `share`\nTriggers when a user shares the stream. Based on `social` event.\n\n```javascript\ntiktokLiveConnection.on('share', (data) =\u003e {\n    console.log(data.uniqueId, \"shared the stream!\");\n})\n```\n\n\u003cdetails\u003e\u003csummary\u003e⚡ Show Data Structure\u003c/summary\u003e\u003cp\u003e\n\n```javascript\n{\n    userId: \"6813181309701719620\",\n    secUid: \"\u003credacted\u003e\",\n    uniqueId: \"zerodytester\",\n    nickname: \"Zerody Tester\",\n    profilePictureUrl: \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n    followRole: 1,\n    userBadges: [\n        {\n            type: \"pm_mt_moderator_im\",\n            name: \"Moderator\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/rankl...image\"\n        },\n        {\n            type: \"image\",\n            displayType: 1,\n            url: \"https://p19-webcast.tiktokcdn.com/webcast-va/....~...image\"\n        }\n    ],\n    userDetails: {\n        createTime: \"0\",\n        bioDescription: \"\",\n        profilePictureUrls: [\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p19-sign.tiktokcdn-us.com/tos-useast5-avt-...webp\",\n            \"https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-...jpeg\"\n        ]\n    },\n    followInfo: {\n        followingCount: 277,\n        followerCount: 96,\n        followStatus: 1,\n        pushStatus: 0\n    },\n    isModerator: false,\n    isNewGifter: false,\n    isSubscriber: false,\n    topGifterRank: null,\n    msgId: \"7137750889884076842\",\n    createTime: \"1661887134629\",\n    displayType: \"pm_mt_guidance_share\",\n    label: \"{0:user} shared the live\"\n}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cbr\u003e\n\n## Examples\n### Retrieve Room Info\n````javascript\nlet tiktokLiveConnection = new WebcastPushConnection('@username');\n\ntiktokLiveConnection.getRoomInfo().then(roomInfo =\u003e {\n    console.log(roomInfo);\n    console.log(`Stream started timestamp: ${roomInfo.create_time}, Streamer bio: ${roomInfo.owner.bio_description}`);\n    console.log(`HLS URL: ${roomInfo.stream_url.hls_pull_url}`); // Can be played or recorded with e.g. VLC\n}).catch(err =\u003e {\n    console.error(err);\n})\n````\n\n### Retrieve Available Gifts\n````javascript\nlet tiktokLiveConnection = new WebcastPushConnection('@username');\n\ntiktokLiveConnection.getAvailableGifts().then(giftList =\u003e {\n    console.log(giftList);\n    giftList.forEach(gift =\u003e {\n        console.log(`id: ${gift.id}, name: ${gift.name}, cost: ${gift.diamond_count}`)\n    });\n}).catch(err =\u003e {\n    console.error(err);\n})\n````\n\n### Send Chat Messages\n\u003e Due to the increased signature requirements by TikTok, sending chat messages is currently not possible.\n\nYou can send chat messages via the [`sendMessage()`](#methods) function to automatically respond to chat commands for example. For this you need to provide your Session ID. \n\nTo get the Session ID from your account, open TikTok in your web browser and make sure you are logged in, then press F12 to open the developer tools. Switch to the **Application** tab and select **Cookies** on the left side. Then take the value of the cookie with the name **`sessionid`**.\n\n\u003cb\u003eWARNING: Use of this function is at your own risk. Spamming messages can lead to the suspension of your TikTok account. Be careful!\u003c/b\u003e\n\n````javascript\nlet tiktokLiveConnection = new WebcastPushConnection('@username', {\n    sessionId: 'f7fbba3a57e48dd1ecd0b7b72cb27e6f' // Replace this with the Session ID of your TikTok account\n});\n\ntiktokLiveConnection.connect().catch(err =\u003e console.log(err));\n\ntiktokLiveConnection.on('chat', data =\u003e {\n    if (data.comment.toLowerCase() === '!dice') {\n        let diceResult = Math.ceil(Math.random() * 6);\n        tiktokLiveConnection.sendMessage(`@${data.uniqueId} you rolled a ${diceResult}`).catch(err =\u003e console.error(err));\n    }\n})\n````\n\n### Connect via Proxy\n[proxy-agent](https://www.npmjs.com/package/proxy-agent) supports `http`, `https`, `socks4` and `socks5` proxies:\n````\nnpm i proxy-agent\n````\nYou can specify if you want to use a proxy for https requests, websockets or both:\n````javascript\nconst { WebcastPushConnection } = require('tiktok-live-connector');\nconst ProxyAgent = require('proxy-agent');\n\nlet tiktokLiveConnection = new WebcastPushConnection('@username', {\n    requestOptions: {\n        httpsAgent: new ProxyAgent('https://username:password@host:port'),\n        timeout: 10000 // 10 seconds\n    },\n    websocketOptions: {\n        agent: new ProxyAgent('https://username:password@host:port'),\n        timeout: 10000 // 10 seconds\n    }\n});\n\n// Connect as usual\n````\n\n\n## Contributing\nYour improvements are welcome! Feel free to open an \u003ca href=\"https://github.com/zerodytrash/TikTok-Live-Connector/issues\"\u003eissue\u003c/a\u003e or \u003ca href=\"https://github.com/zerodytrash/TikTok-Live-Connector/pulls\"\u003epull request\u003c/a\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerodytrash%2FTikTok-Live-Connector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzerodytrash%2FTikTok-Live-Connector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerodytrash%2FTikTok-Live-Connector/lists"}