TikTok Live Java

❤️❤️🎁 *Connect to TikTok live in 3 lines* 🎁❤️❤️
# Introduction A Java library inspired by [TikTokLive](https://github.com/isaackogan/TikTokLive) and [TikTokLiveSharp](https://github.com/sebheron/TikTokLiveSharp). Use it 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 library 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. 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. Join the support [discord](https://discord.gg/e2XwPNTBBr) and visit the `#java-support` channel for questions, contributions and ideas. Feel free to make pull requests with missing/new features, fixes, etc Do you prefer other programming languages? - **Node** orginal: [TikTok-Live-Connector](https://github.com/isaackogan/TikTok-Live-Connector) by [@zerodytrash](https://github.com/zerodytrash) - **Python** rewrite: [TikTokLive](https://github.com/isaackogan/TikTokLive) by [@isaackogan](https://github.com/isaackogan) - **Go** rewrite: [GoTikTokLive](https://github.com/Davincible/gotiktoklive) by [@Davincible](https://github.com/Davincible) - **C#** rewrite: [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp) by [@frankvHoof93](https://github.com/frankvHoof93) **NOTE:** This is not an official API. It's a reverse engineering project. #### Overview - [Getting started](#getting-started) - [Events](#events) - [Listeners](#listeners) - [Contributing](#contributing) ## Getting started 1. Install the package via Maven ```xml jitpack.io https://jitpack.io com.github.jwdeveloper.TikTok-Live-Java Client NOT_FOUND compile ``` 2. Create your first chat connection ```java TikTokLive.newClient("bangbetmenygy") .onGift((liveClient, event) -> { String profileName = event.getUser().getProfileName(); String message = switch (event.getGift()) { case ROSE -> "ROSE!"; case GG -> "GOOD GAME"; case TIKTOK -> "Ye"; case CORGI -> "Nice gift"; default -> "Thank you for " + event.getGift().getName(); }; System.out.println(profileName + " sends " + message); }) .onGiftCombo((liveClient, event) -> { String giftName = event.getGift().getName(); int combo = event.getCombo(); String message = switch (event.getComboState()) { case Begin -> "Combo begin! "; case Active -> "Combo Active! "; case Finished -> "Combo Finished! "; }; System.out.println(message + combo + " " + giftName); }) .onJoin((liveClient, event) -> { String profileName = event.getUser().getProfileName(); System.out.println(profileName + "Hello on my stream! "); }) .onConnected((liveClient, event) -> { System.out.println("Connected to live "); }) .onError((liveClient, event) -> { System.out.println("Error! " + event.getException().getMessage()); }) .buildAndConnect(); ``` 3. Configure (optional) ```java TikTokLive.newClient("bangbetmenygy") .configure((settings) -> { settings.setHostName("bangbetmenygy"); // This method is useful in case you want change hostname later settings.setClientLanguage("en"); // Language settings.setTimeout(Duration.ofSeconds(2)); // Connection timeout settings.setLogLevel(Level.ALL); // Log level settings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF settings.setHandleExistingEvents(true); // Invokes all TikTok events that had occurred before connection settings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline settings.setRetryConnectionTimeout(Duration.ofSeconds(1)); // Timeout before next reconnection //Optional: Sometimes not every message from chat are send to TikTokLiveJava to fix this issue you can set sessionId // documentation how to obtain sessionId https://github.com/isaackogan/TikTok-Live-Connector#send-chat-messages settings.setSessionId("86c3c8bf4b17ebb2d74bb7fa66fd0000"); //Optional: //RoomId can be used as an override if you're having issues with HostId. //You can find it in the HTML for the livestream-page settings.setRoomId("XXXXXXXXXXXXXXXXX"); }) .buildAndConnect(); // ``` ## Events **Control**: - [onError](#onerror-tiktokerrorevent) - [onDisconnected](#ondisconnected-tiktokdisconnectedevent) - [onConnected](#onconnected-tiktokconnectedevent) - [onReconnecting](#onreconnecting-tiktokreconnectingevent) **Message**: - [onEvent](#onevent-tiktokevent) - [onSubscribe](#onsubscribe-tiktoksubscribeevent) - [onLiveEnded](#onliveended-tiktokliveendedevent) - [onComment](#oncomment-tiktokcommentevent) - [onLike](#onlike-tiktoklikeevent) - [onRoomUserInfo](#onroomuserinfo-tiktokroomuserinfoevent) - [onUnhandledSocial](#onunhandledsocial-tiktokunhandledsocialevent) - [onEmote](#onemote-tiktokemoteevent) - [onFollow](#onfollow-tiktokfollowevent) - [onJoin](#onjoin-tiktokjoinevent) - [onShare](#onshare-tiktokshareevent) - [onQuestion](#onquestion-tiktokquestionevent) - [onLivePaused](#onlivepaused-tiktoklivepausedevent) - [onGiftCombo](#ongiftcombo-tiktokgiftcomboevent) - [onRoom](#onroom-tiktokroomevent) - [onGift](#ongift-tiktokgiftevent) **Debug**: - [onWebsocketMessage](#onwebsocketmessage-tiktokwebsocketmessageevent) - [onWebsocketUnhandledMessage](#onwebsocketunhandledmessage-tiktokwebsocketunhandledmessageevent) - [onWebsocketResponse](#onwebsocketresponse-tiktokwebsocketresponseevent) # Examples
## onError [TikTokErrorEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) General error event. You should handle this. ```java TikTokLive.newClient("host-name") .onError((liveClient, event) -> { }) .buildAndConnect(); ```
## onDisconnected [TikTokDisconnectedEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered 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. ```java TikTokLive.newClient("host-name") .onDisconnected((liveClient, event) -> { }) .buildAndConnect(); ```
## onConnected [TikTokConnectedEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered when the connection is successfully established. ```java TikTokLive.newClient("host-name") .onConnected((liveClient, event) -> { }) .buildAndConnect(); ```
## onReconnecting [TikTokReconnectingEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) ```java TikTokLive.newClient("host-name") .onReconnecting((liveClient, event) -> { }) .buildAndConnect(); ```
## onEvent [TikTokEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Base class for all events ```java TikTokLive.newClient("host-name") .onEvent((liveClient, event) -> { }) .buildAndConnect(); ```
## onSubscribe [TikTokSubscribeEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggers when a user creates a subscription. ```java TikTokLive.newClient("host-name") .onSubscribe((liveClient, event) -> { }) .buildAndConnect(); ```
## onLiveEnded [TikTokLiveEndedEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered when the live stream gets terminated by the host. Will also trigger the TikTokDisconnectedEvent event. ```java TikTokLive.newClient("host-name") .onLiveEnded((liveClient, event) -> { }) .buildAndConnect(); ```
## onComment [TikTokCommentEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered every time a new chat comment arrives. ```java TikTokLive.newClient("host-name") .onComment((liveClient, event) -> { }) .buildAndConnect(); ```
## onLike [TikTokLikeEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered when a viewer sends likes to the streamer. For streams with many viewers, this event is not always triggered by TikTok. ```java TikTokLive.newClient("host-name") .onLike((liveClient, event) -> { }) .buildAndConnect(); ```
## onRoomUserInfo [TikTokRoomUserInfoEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Only top 5 users in ranking has detailed data rest has only ID ```java TikTokLive.newClient("host-name") .onRoomUserInfo((liveClient, event) -> { }) .buildAndConnect(); ```
## onUnhandledSocial [TikTokUnhandledSocialEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) ```java TikTokLive.newClient("host-name") .onUnhandledSocial((liveClient, event) -> { }) .buildAndConnect(); ```
## onEmote [TikTokEmoteEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered every time a subscriber sends an emote (sticker). ```java TikTokLive.newClient("host-name") .onEmote((liveClient, event) -> { }) .buildAndConnect(); ```
## onFollow [TikTokFollowEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggers when a user follows the streamer. Based on social event. ```java TikTokLive.newClient("host-name") .onFollow((liveClient, event) -> { }) .buildAndConnect(); ```
## onJoin [TikTokJoinEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) ```java TikTokLive.newClient("host-name") .onJoin((liveClient, event) -> { }) .buildAndConnect(); ```
## onShare [TikTokShareEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggers when a user shares the stream. Based on social event. ```java TikTokLive.newClient("host-name") .onShare((liveClient, event) -> { }) .buildAndConnect(); ```
## onQuestion [TikTokQuestionEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered every time someone asks a new question via the question feature. ```java TikTokLive.newClient("host-name") .onQuestion((liveClient, event) -> { }) .buildAndConnect(); ```
## onLivePaused [TikTokLivePausedEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) ```java TikTokLive.newClient("host-name") .onLivePaused((liveClient, event) -> { }) .buildAndConnect(); ```
## onGiftCombo [TikTokGiftComboEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered every time gift is sent @see GiftSendType it has 3 states

Example when user sends gift with combo

>Combo: 1 -> comboState = GiftSendType.Begin

Combo: 4 -> comboState = GiftSendType.Active

Combo: 8 -> comboState = GiftSendType.Active

Combo: 12 -> comboState = GiftSendType.Finsihed

Remember if comboState is Finsihed both TikTokGiftComboEvent and TikTokGiftEvent event gets triggered ```java TikTokLive.newClient("host-name") .onGiftCombo((liveClient, event) -> { }) .buildAndConnect(); ```
## onRoom [TikTokRoomEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) ```java TikTokLive.newClient("host-name") .onRoom((liveClient, event) -> { }) .buildAndConnect(); ```
## onGift [TikTokGiftEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered when user sends gifts that has no combo (most of expensive gifts) or if combo has finished ```java TikTokLive.newClient("host-name") .onGift((liveClient, event) -> { }) .buildAndConnect(); ```
## onWebsocketMessage [TikTokWebsocketMessageEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered every time a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case. ```java TikTokLive.newClient("host-name") .onWebsocketMessage((liveClient, event) -> { }) .buildAndConnect(); ```
## onWebsocketUnhandledMessage [TikTokWebsocketUnhandledMessageEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) Triggered every time a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case. ```java TikTokLive.newClient("host-name") .onWebsocketUnhandledMessage((liveClient, event) -> { }) .buildAndConnect(); ```
## onWebsocketResponse [TikTokWebsocketResponseEvent](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java) ```java TikTokLive.newClient("host-name") .onWebsocketResponse((liveClient, event) -> { }) .buildAndConnect(); ```
## Listeners ```java /** * * Listeners are an alternative way of handling events. * I would to suggest to use then when logic of handing event * is more complex * */ public static void main(String[] args) throws IOException { showLogo(); CustomListener customListener = new CustomListener(); TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME) .addListener(customListener) .buildAndConnect(); System.in.read(); } /** * * Method in TikTokEventListener should meet 4 requirements to be detected * - must have @TikTokEventHandler annotation * - must have 2 parameters * - first parameter must be LiveClient * - second must be class that extending TikTokEvent */ public static class CustomListener implements TikTokEventListener { @TikTokEventHandler public void onLike(LiveClient liveClient, TikTokLikeEvent event) { System.out.println(event.toString()); } @TikTokEventHandler public void onError(LiveClient liveClient, TikTokErrorEvent event) { // event.getException().printStackTrace(); } @TikTokEventHandler public void onComment(LiveClient liveClient, TikTokCommentEvent event) { var userName = event.getUser().getName(); var text = event.getText(); liveClient.getLogger().info(userName + ": " + text); } @TikTokEventHandler public void onGift(LiveClient liveClient, TikTokGiftEvent event) { var message = switch (event.getGift()) { case ROSE -> "Thanks :)"; case APPETIZERS -> ":OO"; case APRIL -> ":D"; case TIKTOK -> ":P"; case CAP -> ":F"; default -> ":I"; }; liveClient.getLogger().info(message); } @TikTokEventHandler public void onAnyEvent(LiveClient liveClient, TikTokEvent event) { liveClient.getLogger().info(event.getClass().getSimpleName()); } } // ``` ## Contributing Your improvements are welcome! Feel free to open an issue or pull request.