mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 08:49:40 -05:00
Breaking changes:
'Gift': changed from class to enum, so now you can handle
incoming gifts in switch
`Events`
- new:
onGiftComboFinished
- Removed:
onGiftBrodcast
- Rename:
onGiftMessage -> onGift
onRoomPinMessage -> onRoomPin
onRoomMessage -> onRoom
onLinkMessage -> onLink
onBarrageMessage -> onBarrage
onPollMessage -> onPoll
onShopMessage -> onShop
onDetectMessage -> onDetect
`GiftManager`
added:
registerGift
findById
findByName
getGifts
removed:
getActiveGifts
This commit is contained in:
@@ -25,5 +25,5 @@ package io.github.jwdeveloper.tiktok.annotations;
|
||||
|
||||
public enum EventType
|
||||
{
|
||||
Control, Message, Custom, Debug
|
||||
Control, Message, Debug
|
||||
}
|
||||
|
||||
@@ -29,6 +29,6 @@ import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
/**
|
||||
* Triggered when the live stream gets terminated by the host. Will also trigger the TikTokDisconnectedEvent event.
|
||||
*/
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokLiveEndedEvent extends TikTokEvent {
|
||||
}
|
||||
|
||||
@@ -26,6 +26,6 @@ import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokLivePausedEvent extends TikTokEvent {
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import lombok.Getter;
|
||||
* Triggers when a user creates a subscription.
|
||||
*/
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokSubscribeEvent extends TikTokHeaderEvent {
|
||||
private User user;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import io.github.jwdeveloper.tiktok.messages.webcast.WebcastControlMessage;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokUnhandledControlEvent extends TikTokUnhandledEvent<WebcastControlMessage> {
|
||||
|
||||
public TikTokUnhandledControlEvent(WebcastControlMessage data) {
|
||||
|
||||
@@ -29,7 +29,7 @@ import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSocialMessage;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokUnhandledSocialEvent extends TikTokUnhandledEvent<WebcastSocialMessage>
|
||||
{
|
||||
public TikTokUnhandledSocialEvent(WebcastSocialMessage data) {
|
||||
|
||||
@@ -29,12 +29,11 @@ import io.github.jwdeveloper.tiktok.data.models.Gift;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import lombok.Getter;
|
||||
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
@Getter
|
||||
public class TikTokGiftComboFinishedEvent extends TikTokGiftEvent
|
||||
public class TikTokGiftComboEvent extends TikTokGiftEvent
|
||||
{
|
||||
|
||||
public TikTokGiftComboFinishedEvent(Gift gift, WebcastGiftMessage msg) {
|
||||
public TikTokGiftComboEvent(Gift gift, WebcastGiftMessage msg) {
|
||||
super(gift, msg);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Triggered every time a gift arrives.
|
||||
*/
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
|
||||
@@ -31,7 +31,7 @@ import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
@Getter
|
||||
public class TikTokPollEndEvent extends TikTokPollEvent
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ import lombok.Getter;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokPollStartEvent extends TikTokPollEvent {
|
||||
|
||||
private final List<PollOption> options;
|
||||
|
||||
@@ -31,7 +31,7 @@ import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
@Getter
|
||||
public class TikTokPollUpdateEvent extends TikTokPollEvent {
|
||||
private final List<PollOption> options;
|
||||
|
||||
@@ -33,7 +33,7 @@ import lombok.Value;
|
||||
* Triggers when a user follows the streamer. Based on social event.
|
||||
*/
|
||||
@Value
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokFollowEvent extends TikTokHeaderEvent
|
||||
{
|
||||
User user;
|
||||
|
||||
@@ -31,7 +31,7 @@ import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSocialMessage;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokJoinEvent extends TikTokHeaderEvent {
|
||||
private final User user;
|
||||
private final int totalUsers;
|
||||
|
||||
@@ -35,7 +35,7 @@ import lombok.Getter;
|
||||
* Triggered when a viewer sends likes to the streamer. For streams with many viewers, this event is not always triggered by TikTok.
|
||||
*/
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokLikeEvent extends TikTokHeaderEvent
|
||||
{
|
||||
private final User user;
|
||||
|
||||
@@ -33,7 +33,7 @@ import lombok.Getter;
|
||||
* Triggers when a user shares the stream. Based on social event.
|
||||
*/
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Custom)
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokShareEvent extends TikTokHeaderEvent {
|
||||
private final User user;
|
||||
private final int totalShares;
|
||||
|
||||
@@ -34,8 +34,7 @@ import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
public class Picture {
|
||||
@@ -67,21 +66,20 @@ public class Picture {
|
||||
if (isDownloaded()) {
|
||||
return image;
|
||||
}
|
||||
if (link.equalsIgnoreCase("")) {
|
||||
return null;
|
||||
}
|
||||
image = download(link);
|
||||
return image;
|
||||
}
|
||||
|
||||
public Future<Image> downloadImageAsync() {
|
||||
var executor = Executors.newSingleThreadExecutor();
|
||||
var future = executor.submit(this::downloadImage);
|
||||
executor.shutdown();
|
||||
return future;
|
||||
public CompletableFuture<Image> downloadImageAsync() {
|
||||
return CompletableFuture.supplyAsync(this::downloadImage);
|
||||
}
|
||||
|
||||
private BufferedImage download(String urlString) {
|
||||
private BufferedImage download(String urlString)
|
||||
{
|
||||
if(urlString.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var baos = new ByteArrayOutputStream();
|
||||
try (var is = new URL(urlString).openStream()) {
|
||||
var byteChunk = new byte[4096];
|
||||
@@ -105,8 +103,4 @@ public class Picture {
|
||||
public static Picture Empty() {
|
||||
return new Picture("");
|
||||
}
|
||||
|
||||
public static List<Picture> EmptyList() {
|
||||
return new ArrayList<Picture>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,18 +27,22 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Getter
|
||||
public class Text {
|
||||
String key;
|
||||
String pattern;
|
||||
List<TextPiece> textPieces;
|
||||
String value;
|
||||
|
||||
public Text(String key, String pattern, List<TextPiece> textPieces) {
|
||||
this.key = key;
|
||||
this.pattern = pattern;
|
||||
this.textPieces = textPieces;
|
||||
this.value = computeValue();
|
||||
}
|
||||
|
||||
public static Text map(io.github.jwdeveloper.tiktok.messages.data.Text input) {
|
||||
@@ -53,15 +57,31 @@ public class Text {
|
||||
var user = User.map(input.getUserValue().getUser());
|
||||
yield new UserTextPiece(user);
|
||||
}
|
||||
//case 12 -> new GiftTextPiece(input.getStringValue());
|
||||
case 12 -> new GiftTextPiece(input.getGiftValue().getGiftId());
|
||||
default -> new StringTextPiece(input.getStringValue());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private String computeValue() {
|
||||
var regexPattern = Pattern.compile("\\{.*?\\}");
|
||||
var matcher = regexPattern.matcher(pattern);
|
||||
var format = matcher.replaceAll("%s");
|
||||
|
||||
var output = new ArrayList<String>();
|
||||
for (var piece : textPieces) {
|
||||
output.add(piece.getText());
|
||||
}
|
||||
return String.format(format, output.toArray());
|
||||
}
|
||||
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class TextPiece {
|
||||
|
||||
public String getText() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Value
|
||||
@@ -79,13 +99,25 @@ public class Text {
|
||||
public UserTextPiece(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return user.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
public static class GiftTextPiece extends TextPiece {
|
||||
Gift gift;
|
||||
|
||||
public GiftTextPiece(String value) {
|
||||
int giftId;
|
||||
|
||||
public GiftTextPiece(int giftId) {
|
||||
this.giftId = giftId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return giftId + "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ package io.github.jwdeveloper.tiktok.live;
|
||||
import io.github.jwdeveloper.tiktok.listener.ListenersManager;
|
||||
import io.github.jwdeveloper.tiktok.listener.TikTokEventListener;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public interface LiveClient {
|
||||
@@ -34,6 +36,19 @@ public interface LiveClient {
|
||||
*/
|
||||
void connect();
|
||||
|
||||
|
||||
/**
|
||||
* Connects in asynchronous way
|
||||
* When connected Consumer returns instance of LiveClient
|
||||
*/
|
||||
void connectAsync(Consumer<LiveClient> onConnection);
|
||||
|
||||
/**
|
||||
* Connects in asynchronous way
|
||||
*/
|
||||
CompletableFuture<LiveClient> connectAsync();
|
||||
|
||||
|
||||
/**
|
||||
* Disconnects the connection.
|
||||
*/
|
||||
@@ -45,12 +60,6 @@ public interface LiveClient {
|
||||
*/
|
||||
GiftManager getGiftManager();
|
||||
|
||||
/**
|
||||
* Get user manager
|
||||
* @return
|
||||
*/
|
||||
UserManager getUserManager();
|
||||
|
||||
/**
|
||||
* Gets the current room info from TikTok API including streamer info, room status and statistics.
|
||||
*/
|
||||
@@ -58,13 +67,13 @@ public interface LiveClient {
|
||||
|
||||
/**
|
||||
* Manage TikTokEventListener
|
||||
*
|
||||
* @see TikTokEventListener
|
||||
*/
|
||||
ListenersManager getListenersManager();
|
||||
|
||||
/**
|
||||
* Logger
|
||||
* @return
|
||||
*/
|
||||
Logger getLogger();
|
||||
}
|
||||
|
||||
@@ -26,15 +26,17 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LiveRoomMeta {
|
||||
/**
|
||||
* 0 - Unknown
|
||||
* 1 - ?
|
||||
* 2 - Online
|
||||
* 3 - ?
|
||||
* 4 - Offline
|
||||
*/
|
||||
|
||||
private int status;
|
||||
private LiveRoomStatus status;
|
||||
|
||||
private boolean ageRestricted;
|
||||
|
||||
|
||||
|
||||
public enum LiveRoomStatus
|
||||
{
|
||||
HostNotFound,
|
||||
HostOnline,
|
||||
HostOffline
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ package io.github.jwdeveloper.tiktok.live.builder;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.*;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboFinishedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomUserInfoEvent;
|
||||
@@ -37,7 +37,7 @@ import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketRespons
|
||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketUnhandledMessageEvent;
|
||||
|
||||
|
||||
public interface EventBuilder<T> {
|
||||
public interface EventsBuilder<T> {
|
||||
|
||||
T onRoom(EventConsumer<TikTokRoomEvent> event);
|
||||
|
||||
@@ -45,15 +45,13 @@ public interface EventBuilder<T> {
|
||||
|
||||
T onComment(EventConsumer<TikTokCommentEvent> event);
|
||||
|
||||
|
||||
T onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> event);
|
||||
|
||||
T onWebsocketResponse(EventConsumer<TikTokWebsocketResponseEvent> event);
|
||||
|
||||
T onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> event);
|
||||
|
||||
|
||||
T onGiftCombo(EventConsumer<TikTokGiftComboFinishedEvent> event);
|
||||
T onGiftCombo(EventConsumer<TikTokGiftComboEvent> event);
|
||||
|
||||
T onGift(EventConsumer<TikTokGiftEvent> event);
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.live.builder;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
@@ -7,7 +29,7 @@ import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface LiveClientBuilder extends EventBuilder<LiveClientBuilder> {
|
||||
public interface LiveClientBuilder extends EventsBuilder<LiveClientBuilder> {
|
||||
LiveClientBuilder configure(Consumer<ClientSettings> consumer);
|
||||
|
||||
LiveClientBuilder addListener(TikTokEventListener listener);
|
||||
|
||||
@@ -66,7 +66,7 @@ public class JsonUtil {
|
||||
}
|
||||
|
||||
if (fieldAttributes.getName().equals("common_")) {
|
||||
return true;
|
||||
// return true;
|
||||
}
|
||||
if (fieldAttributes.getName().equals("bytes")) {
|
||||
return true;
|
||||
|
||||
@@ -82,7 +82,7 @@ message Text {
|
||||
}
|
||||
|
||||
message TextPieceGift {
|
||||
int64 giftId = 1;
|
||||
int32 giftId = 1;
|
||||
// PatternRef nameRef = 2;
|
||||
// ShowType showType = 3; // Enum
|
||||
int64 colorId = 4;
|
||||
|
||||
@@ -32,13 +32,15 @@ import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokApiService;
|
||||
import io.github.jwdeveloper.tiktok.listener.ListenersManager;
|
||||
import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
|
||||
import io.github.jwdeveloper.tiktok.live.UserManager;
|
||||
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
||||
import io.github.jwdeveloper.tiktok.live.GiftManager;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
||||
import io.github.jwdeveloper.tiktok.websocket.SocketClient;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class TikTokLiveClient implements LiveClient {
|
||||
@@ -70,22 +72,37 @@ public class TikTokLiveClient implements LiveClient {
|
||||
}
|
||||
|
||||
|
||||
public void connectAsync(Consumer<LiveClient> onConnection) {
|
||||
CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
connect();
|
||||
onConnection.accept(this);
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<LiveClient> connectAsync() {
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
connect();
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
try {
|
||||
tryConnect();
|
||||
}
|
||||
catch (TikTokLiveException e)
|
||||
} catch (TikTokLiveException e)
|
||||
{
|
||||
setState(ConnectionState.DISCONNECTED);
|
||||
tikTokEventHandler.publish(this, new TikTokErrorEvent(e));
|
||||
tikTokEventHandler.publish(this, new TikTokDisconnectedEvent());
|
||||
|
||||
if(e instanceof TikTokLiveOfflineHostException && clientSettings.isRetryOnConnectionFailure())
|
||||
{
|
||||
if (e instanceof TikTokLiveOfflineHostException && clientSettings.isRetryOnConnectionFailure()) {
|
||||
try {
|
||||
Thread.sleep(clientSettings.getRetryConnectionTimeout().toMillis());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
catch (Exception ignored){}
|
||||
logger.info("Reconnecting");
|
||||
tikTokEventHandler.publish(this, new TikTokReconnectingEvent());
|
||||
this.connect();
|
||||
@@ -108,27 +125,22 @@ public class TikTokLiveClient implements LiveClient {
|
||||
if (liveRoomInfo.hasConnectionState(ConnectionState.CONNECTING))
|
||||
throw new TikTokLiveException("Already connecting");
|
||||
|
||||
logger.info("Connecting");
|
||||
setState(ConnectionState.CONNECTING);
|
||||
|
||||
|
||||
apiService.updateSessionId();
|
||||
|
||||
if(clientSettings.getRoomId() != null)
|
||||
{
|
||||
if (clientSettings.getRoomId() != null) {
|
||||
liveRoomInfo.setRoomId(clientSettings.getRoomId());
|
||||
logger.info("Using roomID from settings: " + clientSettings.getRoomId());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
var roomId = apiService.fetchRoomId(liveRoomInfo.getHostName());
|
||||
liveRoomInfo.setRoomId(roomId);
|
||||
}
|
||||
|
||||
|
||||
var roomData = apiService.fetchRoomInfo();
|
||||
if (roomData.getStatus() == 0 || roomData.getStatus() == 4) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for HostID could not be found. Is the Host online?");
|
||||
if (roomData.getStatus() != LiveRoomMeta.LiveRoomStatus.HostOnline) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for Host name could not be found. Is the Host online?");
|
||||
}
|
||||
|
||||
var clientData = apiService.fetchClientData();
|
||||
@@ -140,9 +152,9 @@ public class TikTokLiveClient implements LiveClient {
|
||||
public LiveRoomInfo getRoomInfo() {
|
||||
return liveRoomInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenersManager getListenersManager()
|
||||
{
|
||||
public ListenersManager getListenersManager() {
|
||||
return listenersManager;
|
||||
}
|
||||
|
||||
@@ -156,11 +168,6 @@ public class TikTokLiveClient implements LiveClient {
|
||||
return tikTokGiftManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserManager getUserManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void setState(ConnectionState connectionState) {
|
||||
logger.info("TikTokLive client state: " + connectionState.name());
|
||||
|
||||
@@ -22,26 +22,21 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventBuilder;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||
import io.github.jwdeveloper.tiktok.data.events.*;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokConnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboFinishedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomPinEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomUserInfoEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokFollowEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokJoinEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokBarrageEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokShareEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketMessageEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketUnhandledMessageEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketMessageEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
@@ -53,6 +48,7 @@ import io.github.jwdeveloper.tiktok.http.TikTokHttpRequestFactory;
|
||||
import io.github.jwdeveloper.tiktok.listener.TikTokEventListener;
|
||||
import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
|
||||
@@ -64,8 +60,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.*;
|
||||
|
||||
public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
{
|
||||
public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
|
||||
protected final ClientSettings clientSettings;
|
||||
protected final Logger logger;
|
||||
@@ -105,16 +100,21 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
throw new TikTokLiveException("HostName can not be null");
|
||||
}
|
||||
|
||||
if (clientSettings.getHostName().startsWith("@"))
|
||||
{
|
||||
clientSettings.setHostName(clientSettings.getHostName().substring(1));
|
||||
}
|
||||
|
||||
|
||||
var params = clientSettings.getClientParameters();
|
||||
params.put("app_language", clientSettings.getClientLanguage());
|
||||
params.put("webcast_language", clientSettings.getClientLanguage());
|
||||
|
||||
logger.setLevel(clientSettings.getLogLevel());
|
||||
|
||||
var handler = new ConsoleHandler();
|
||||
handler.setFormatter(new Formatter() {
|
||||
@Override
|
||||
public String format(LogRecord record)
|
||||
{
|
||||
public String format(LogRecord record) {
|
||||
var sb = new StringBuilder();
|
||||
sb.append(ConsoleColors.GREEN).append("[").append(record.getLoggerName()).append("] ");
|
||||
sb.append(ConsoleColors.GREEN).append("[").append(record.getLevel()).append("]: ");
|
||||
@@ -126,9 +126,13 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
logger.setUseParentHandlers(false);
|
||||
logger.addHandler(handler);
|
||||
|
||||
logger.setLevel(clientSettings.getLogLevel());
|
||||
|
||||
if (clientSettings.isPrintToConsole() && clientSettings.getLogLevel() == Level.OFF) {
|
||||
logger.setLevel(Level.ALL);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public LiveClient build() {
|
||||
@@ -171,7 +175,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
}
|
||||
|
||||
public CompletableFuture<LiveClient> buildAndConnectAsync() {
|
||||
return CompletableFuture.supplyAsync(this::buildAndConnect);
|
||||
return build().connectAsync();
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandledSocial(
|
||||
@@ -261,8 +265,8 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onGiftCombo(EventConsumer<TikTokGiftComboFinishedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftComboFinishedEvent.class, event);
|
||||
public TikTokLiveClientBuilder onGiftCombo(EventConsumer<TikTokGiftComboEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftComboEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -318,7 +322,6 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onComment(EventConsumer<TikTokCommentEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokCommentEvent.class, event);
|
||||
return this;
|
||||
@@ -328,6 +331,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
tikTokEventHandler.subscribe(TikTokGoalUpdateEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRankUpdate(EventConsumer<TikTokRankUpdateEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRankUpdateEvent.class, event);
|
||||
return this;
|
||||
@@ -349,7 +353,6 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onJoin(EventConsumer<TikTokJoinEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokJoinEvent.class, event);
|
||||
return this;
|
||||
@@ -404,6 +407,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
tikTokEventHandler.subscribe(TikTokWebsocketResponseEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TikTokLiveClientBuilder onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokWebsocketMessageEvent.class, event);
|
||||
|
||||
@@ -26,7 +26,7 @@ import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.*;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokBarrageEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboFinishedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEndEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
|
||||
@@ -142,7 +142,7 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler {
|
||||
}
|
||||
|
||||
if (giftMessage.getRepeatEnd() > 0) {
|
||||
return new TikTokGiftComboFinishedEvent(gift, giftMessage);
|
||||
return new TikTokGiftComboEvent(gift, giftMessage);
|
||||
}
|
||||
|
||||
return new TikTokGiftEvent(gift, giftMessage);
|
||||
|
||||
@@ -30,6 +30,7 @@ import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
import io.github.jwdeveloper.tiktok.mappers.LiveRoomMetaMapper;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
|
||||
import javax.script.ScriptEngineManager;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -116,22 +117,24 @@ public class TikTokApiService {
|
||||
|
||||
|
||||
public LiveRoomMeta fetchRoomInfo() {
|
||||
logger.info("Fetch RoomInfo");
|
||||
logger.info("Fetching RoomInfo");
|
||||
try {
|
||||
var response = tiktokHttpClient.getJObjectFromWebcastAPI("room/info/", clientSettings.getClientParameters());
|
||||
var mapper = new LiveRoomMetaMapper();
|
||||
var liveRoomMeta = mapper.map(response);
|
||||
logger.info("RoomInfo status -> " + liveRoomMeta.getStatus());
|
||||
return liveRoomMeta;
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new TikTokLiveRequestException("Failed to fetch room info from WebCast, see stacktrace for more info.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public WebcastResponse fetchClientData() {
|
||||
logger.info("Fetch ClientData");
|
||||
|
||||
logger.info("Fetching ClientData");
|
||||
try {
|
||||
var response = tiktokHttpClient.getDeserializedMessage("im/fetch/", clientSettings.getClientParameters());
|
||||
var response = tiktokHttpClient.getSigningServerMessage("im/fetch/", clientSettings.getClientParameters());
|
||||
clientSettings.getClientParameters().put("cursor", response.getCursor());
|
||||
clientSettings.getClientParameters().put("internal_ext", response.getInternalExt());
|
||||
return response;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class TikTokHttpClient {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public WebcastResponse getDeserializedMessage(String path, Map<String, Object> parameters) {
|
||||
public WebcastResponse getSigningServerMessage(String path, Map<String, Object> parameters) {
|
||||
var bytes = getSignRequest(Constants.TIKTOK_URL_WEBCAST + path, parameters);
|
||||
try {
|
||||
return WebcastResponse.parseFrom(bytes);
|
||||
|
||||
@@ -25,11 +25,11 @@ package io.github.jwdeveloper.tiktok.listener;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokEventListenerMethodException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -42,7 +42,10 @@ public class TikTokListenersManager implements ListenersManager {
|
||||
|
||||
public TikTokListenersManager(List<TikTokEventListener> listeners, TikTokEventObserver tikTokEventHandler) {
|
||||
this.eventObserver = tikTokEventHandler;
|
||||
this.bindingModels = new ArrayList<>(listeners.stream().map(this::bindToEvents).toList());
|
||||
this.bindingModels = new ArrayList<>(listeners.size());
|
||||
for (var listener : listeners) {
|
||||
addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,9 +25,14 @@ package io.github.jwdeveloper.tiktok.mappers;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
|
||||
public class LiveRoomMetaMapper
|
||||
{
|
||||
|
||||
public class LiveRoomMetaMapper {
|
||||
/**
|
||||
* 0 - Unknown
|
||||
* 1 - ?
|
||||
* 2 - Online
|
||||
* 3 - ?
|
||||
* 4 - Offline
|
||||
*/
|
||||
public LiveRoomMeta map(JsonObject input) {
|
||||
var liveRoomMeta = new LiveRoomMeta();
|
||||
|
||||
@@ -35,14 +40,25 @@ public class LiveRoomMetaMapper
|
||||
return liveRoomMeta;
|
||||
}
|
||||
var data = input.getAsJsonObject("data");
|
||||
|
||||
|
||||
if (data.has("status")) {
|
||||
var status = data.get("status");
|
||||
liveRoomMeta.setStatus(status.getAsInt());
|
||||
var statusId = status.getAsInt();
|
||||
var statusValue = switch (statusId) {
|
||||
case 0 -> LiveRoomMeta.LiveRoomStatus.HostNotFound;
|
||||
case 2 -> LiveRoomMeta.LiveRoomStatus.HostOnline;
|
||||
case 4 -> LiveRoomMeta.LiveRoomStatus.HostOffline;
|
||||
default-> LiveRoomMeta.LiveRoomStatus.HostNotFound;
|
||||
};
|
||||
liveRoomMeta.setStatus(statusValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
liveRoomMeta.setStatus(LiveRoomMeta.LiveRoomStatus.HostNotFound);
|
||||
}
|
||||
|
||||
|
||||
if(data.has("age_restricted"))
|
||||
{
|
||||
if (data.has("age_restricted")) {
|
||||
var element = data.getAsJsonObject("age_restricted");
|
||||
var restricted = element.get("restricted").getAsBoolean();
|
||||
liveRoomMeta.setAgeRestricted(restricted);
|
||||
|
||||
@@ -75,7 +75,7 @@ public class TikTokWebSocketClient implements SocketClient {
|
||||
|
||||
try {
|
||||
if (clientSettings.isHandleExistingEvents()) {
|
||||
logger.info("Handling existing messages");
|
||||
logger.info("Handling existing events");
|
||||
webResponseHandler.handle(tikTokLiveClient, webcastResponse);
|
||||
}
|
||||
var url = getWebSocketUrl(webcastResponse);
|
||||
|
||||
@@ -30,6 +30,7 @@ import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
|
||||
import io.github.jwdeveloper.tiktok.listener.TikTokEventListener;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -42,13 +43,12 @@ public class ListenerExample {
|
||||
*
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
showLogo();
|
||||
CustomListener customListener = new CustomListener();
|
||||
|
||||
TikTokLive.newClient(Main.TEST_TIKTOK_USER)
|
||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
||||
.addListener(customListener)
|
||||
.buildAndConnect();
|
||||
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ListenerExample {
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onError(LiveClient liveClient, TikTokErrorEvent event) {
|
||||
event.getException().printStackTrace();
|
||||
// event.getException().printStackTrace();
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
@@ -99,4 +99,17 @@ public class ListenerExample {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void showLogo()
|
||||
{
|
||||
System.out.println(ConsoleColors.GREEN+"""
|
||||
|
||||
_____ _ _ _____ _ _ _ \s
|
||||
|_ _(_) | _|_ _|__ | | _| | (_)_ _____\s
|
||||
| | | | |/ / | |/ _ \\| |/ / | | \\ \\ / / _ \\
|
||||
| | | | < | | (_) | <| |___| |\\ V / __/
|
||||
|_| |_|_|\\_\\ |_|\\___/|_|\\_\\_____|_| \\_/ \\___|
|
||||
""");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,40 +25,71 @@ package io.github.jwdeveloper.tiktok;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class SimpleExample {
|
||||
public class SimpleExample
|
||||
{
|
||||
public static String TIKTOK_HOSTNAME = "szwagierkaqueen";
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
showLogo();
|
||||
// set tiktok username
|
||||
TikTokLive.newClient(Main.TEST_TIKTOK_USER)
|
||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
||||
.configure(clientSettings ->
|
||||
{
|
||||
clientSettings.setHostName(SimpleExample.TIKTOK_HOSTNAME); // This method is useful in case you want change hostname later
|
||||
clientSettings.setClientLanguage("en"); // Language
|
||||
clientSettings.setTimeout(Duration.ofSeconds(2)); // Connection timeout
|
||||
clientSettings.setLogLevel(Level.ALL); // Log level
|
||||
clientSettings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
clientSettings.setHandleExistingEvents(true); // Invokes all TikTok events that had occurred before connection
|
||||
clientSettings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline
|
||||
clientSettings.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
|
||||
|
||||
// clientSettings.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
|
||||
|
||||
//clientSettings.setRoomId("XXXXXXXXXXXXXXXXX");
|
||||
})
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
switch (event.getGift()) {
|
||||
case ROSE -> print(ConsoleColors.RED, " roses!", "\uD83D\uDC95");
|
||||
case ROSE -> print(ConsoleColors.RED, "Rose!");
|
||||
case GG -> print(ConsoleColors.YELLOW, " GOOD GAME!");
|
||||
case TIKTOK -> print(ConsoleColors.CYAN,"Thanks for TikTok");
|
||||
default -> print(ConsoleColors.GREEN, "[Thanks for gift] ", ConsoleColors.YELLOW, event.getGift().getName(), "X", event.getCombo());
|
||||
default -> print(ConsoleColors.GREEN, "[Thanks for gift] ", ConsoleColors.YELLOW, event.getGift().getName(), "x", event.getCombo());
|
||||
}
|
||||
})
|
||||
.onGiftCombo((liveClient, event) ->
|
||||
{
|
||||
print(ConsoleColors.RED,"GIFT COMBO",event.getGift().getName(),event.getCombo());
|
||||
})
|
||||
.onConnected((client, event) ->
|
||||
{
|
||||
print(ConsoleColors.GREEN, "[Connected]");
|
||||
})
|
||||
.onDisconnected((liveClient, event) ->
|
||||
{
|
||||
print(ConsoleColors.RED,"[Disconnected]");
|
||||
})
|
||||
.onFollow((liveClient, event) ->
|
||||
{
|
||||
print(ConsoleColors.BLUE, "Follow -> ", ConsoleColors.WHITE_BRIGHT, event.getUser().getName());
|
||||
print(ConsoleColors.BLUE, "Follow:", ConsoleColors.WHITE_BRIGHT, event.getUser().getName());
|
||||
})
|
||||
.onJoin((client, event) ->
|
||||
{
|
||||
print(ConsoleColors.WHITE_BRIGHT, "Join ->", ConsoleColors.GREEN, event.getUser().getName());
|
||||
print(ConsoleColors.WHITE, "Join:", ConsoleColors.WHITE_BRIGHT, event.getUser().getName());
|
||||
})
|
||||
.onComment((client, event) ->
|
||||
{
|
||||
print(ConsoleColors.WHITE, event.getUser().getName(), ":", ConsoleColors.WHITE_BRIGHT, event.getText());
|
||||
print(ConsoleColors.GREEN, event.getUser().getName(), ":", ConsoleColors.WHITE_BRIGHT, event.getText());
|
||||
})
|
||||
.onEvent((client, event) ->
|
||||
{
|
||||
@@ -69,7 +100,6 @@ public class SimpleExample {
|
||||
event.getException().printStackTrace();
|
||||
})
|
||||
.buildAndConnectAsync();
|
||||
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
@@ -80,4 +110,17 @@ public class SimpleExample {
|
||||
}
|
||||
System.out.println(sb);
|
||||
}
|
||||
|
||||
private static void showLogo()
|
||||
{
|
||||
System.out.println(ConsoleColors.GREEN+"""
|
||||
|
||||
_____ _ _ _____ _ _ _ \s
|
||||
|_ _(_) | _|_ _|__ | | _| | (_)_ _____\s
|
||||
| | | | |/ / | |/ _ \\| |/ / | | \\ \\ / / _ \\
|
||||
| | | | < | | (_) | <| |___| |\\ V / __/
|
||||
|_| |_|_|\\_\\ |_|\\___/|_|\\_\\_____|_| \\_/ \\___|
|
||||
""");
|
||||
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ConfigurationExample {
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
TikTokLive.newClient(Main.TEST_TIKTOK_USER)
|
||||
.configure(clientSettings ->
|
||||
{
|
||||
clientSettings.setHostName(Main.TEST_TIKTOK_USER); // TikTok hostname
|
||||
clientSettings.setClientLanguage("en"); // Language
|
||||
clientSettings.setTimeout(Duration.ofSeconds(2)); // Connection timeout
|
||||
clientSettings.setLogLevel(Level.ALL); // Log level
|
||||
clientSettings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
clientSettings.setHandleExistingEvents(true); // Invokes all TikTok events that had occurred before connection
|
||||
clientSettings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline
|
||||
clientSettings.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
|
||||
clientSettings.setSessionId("86c3c8bf4b17ebb2d74bb7fa66fd0000");
|
||||
|
||||
//Optional:
|
||||
clientSettings.setRoomId("XXXXXXXXXXXXXXXXX");
|
||||
})
|
||||
.buildAndConnect();
|
||||
|
||||
System.in.read();
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.*;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokConnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomUserInfoEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokFollowEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokJoinEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokShareEvent;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static String TEST_TIKTOK_USER = "bangbetmenygy";
|
||||
|
||||
public static void main(String[] args) throws IOException
|
||||
{
|
||||
showLogo();
|
||||
LiveClient client = TikTokLive.newClient(TEST_TIKTOK_USER)
|
||||
.configure(clientSettings ->
|
||||
{
|
||||
clientSettings.setRetryConnectionTimeout(Duration.ofSeconds(5));
|
||||
clientSettings.setRetryOnConnectionFailure(true);
|
||||
clientSettings.setHandleExistingEvents(true);
|
||||
})
|
||||
.onError((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onConnected(Main::onConnected)
|
||||
.onDisconnected(Main::onDisconnected)
|
||||
.onRoomUserInfo(Main::onRoomUserInfo)
|
||||
.onJoin(Main::onJoin)
|
||||
.onComment(Main::onComment)
|
||||
.onFollow(Main::onFollow)
|
||||
.onShare(Main::onShare)
|
||||
.onSubscribe(Main::onSubscribe)
|
||||
.onLike(Main::onLike)
|
||||
.onGift(Main::onGift)
|
||||
.onEmote(Main::onEmote)
|
||||
.onError((_client, error) ->
|
||||
{
|
||||
error.getException().printStackTrace();
|
||||
})
|
||||
.buildAndConnect();
|
||||
|
||||
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
private static void onConnected(LiveClient tikTokLive, TikTokConnectedEvent e) {
|
||||
print(ConsoleColors.GREEN, "[Connected]");
|
||||
}
|
||||
|
||||
private static void onGift(LiveClient tikTokLive, TikTokGiftEvent e)
|
||||
{
|
||||
switch (e.getGift()) {
|
||||
case ROSE -> print( ConsoleColors.YELLOW,"x", e.getCombo(), " roses!", "\uD83D\uDC95");
|
||||
default -> print(ConsoleColors.YELLOW,"Thanks for gift: ", e.getGift().getName(),"X",e.getCombo());
|
||||
}
|
||||
if(e.getGift().hasDiamondCostRange(1000,10000))
|
||||
{
|
||||
print("Thank you for expensive Gift!");
|
||||
}
|
||||
|
||||
}
|
||||
private static void onDisconnected(LiveClient tikTokLive, TikTokDisconnectedEvent e) {
|
||||
print(ConsoleColors.GREEN, "[Disconnected]");
|
||||
}
|
||||
private static void onRoomUserInfo(LiveClient tikTokLive, TikTokRoomUserInfoEvent e) {
|
||||
print("Viewer count is:", e.getTotalUsers());
|
||||
}
|
||||
|
||||
private static void onJoin(LiveClient tikTokLive, TikTokJoinEvent e) {
|
||||
print(ConsoleColors.GREEN, "Join -> ", ConsoleColors.WHITE_BRIGHT, e.getUser().getName());
|
||||
}
|
||||
|
||||
private static void onComment(LiveClient tikTokLive, TikTokCommentEvent e) {
|
||||
print(ConsoleColors.WHITE, e.getUser().getId(), ":", ConsoleColors.WHITE_BRIGHT, e.getText());
|
||||
}
|
||||
|
||||
private static void onFollow(LiveClient tikTokLive, TikTokFollowEvent e) {
|
||||
print(e.getUser().getId(), "followed!");
|
||||
}
|
||||
|
||||
private static void onShare(LiveClient tikTokLive, TikTokShareEvent e) {
|
||||
print(e.getUser().getId(), "shared!");
|
||||
}
|
||||
|
||||
private static void onSubscribe(LiveClient tikTokLive, TikTokSubscribeEvent e) {
|
||||
print(e.getUser().getId(), "subscribed!");
|
||||
}
|
||||
|
||||
private static void onLike(LiveClient tikTokLive, TikTokLikeEvent e) {
|
||||
|
||||
print(e.getUser().getDisplayName(), "liked!");
|
||||
}
|
||||
private static void onEmote(LiveClient tikTokLive, TikTokEmoteEvent e) {
|
||||
print(e.getUser().getId(), "sent", e.getEmotes().size());
|
||||
}
|
||||
|
||||
private static void showLogo()
|
||||
{
|
||||
System.out.println(ConsoleColors.GREEN+"""
|
||||
|
||||
_____ _ _ _____ _ _ _ \s
|
||||
|_ _(_) | _|_ _|__ | | _| | (_)_ _____\s
|
||||
| | | | |/ / | |/ _ \\| |/ / | | \\ \\ / / _ \\
|
||||
| | | | < | | (_) | <| |___| |\\ V / __/
|
||||
|_| |_|_|\\_\\ |_|\\___/|_|\\_\\_____|_| \\_/ \\___|
|
||||
""");
|
||||
|
||||
}
|
||||
private static void print(Object... messages) {
|
||||
var sb = new StringBuilder();
|
||||
for (var message : messages) {
|
||||
sb.append(message).append(" ");
|
||||
}
|
||||
System.out.println(sb);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -26,6 +26,7 @@ import io.github.jwdeveloper.tiktok.TikTokLive;
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClientBuilder;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.db.TikTokDatabase;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.tables.ExceptionInfoModel;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.tables.TikTokErrorModel;
|
||||
@@ -45,7 +46,7 @@ public class TikTokClientFactory {
|
||||
this.tikTokDatabase = tikTokDatabase;
|
||||
}
|
||||
|
||||
public CompletableFuture<LiveClient> runClientAsync(String tiktokUser, Consumer<TikTokLiveClientBuilder> onBuilder) {
|
||||
public CompletableFuture<LiveClient> runClientAsync(String tiktokUser, Consumer<LiveClientBuilder> onBuilder) {
|
||||
var builder = TikTokLive.newClient(tiktokUser);
|
||||
onBuilder.accept(builder);
|
||||
return builder.onConnected((liveClient, event) ->
|
||||
|
||||
@@ -24,6 +24,7 @@ package io.github.jwdeveloper.tiktok.tools.collector.client;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClientBuilder;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.db.TikTokDatabase;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@@ -35,7 +36,7 @@ public class TikTokMessagessCollectorBuilder {
|
||||
List<String> users;
|
||||
String outputFileName;
|
||||
List<Class<?>> filters;
|
||||
Consumer<TikTokLiveClientBuilder> onBuilder;
|
||||
Consumer<LiveClientBuilder> onBuilder;
|
||||
List<LiveClient> tiktokclients;
|
||||
|
||||
MessageCollector messageCollector;
|
||||
@@ -61,7 +62,7 @@ public class TikTokMessagessCollectorBuilder {
|
||||
}
|
||||
|
||||
|
||||
public TikTokMessagessCollectorBuilder addOnBuilder(Consumer<TikTokLiveClientBuilder> consumer) {
|
||||
public TikTokMessagessCollectorBuilder addOnBuilder(Consumer<LiveClientBuilder> consumer) {
|
||||
onBuilder = consumer;
|
||||
return this;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.webviewer;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.webviewer.handlers.TikTokHandler;
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.webviewer;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.webviewer.handlers;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventsBuilder;
|
||||
import io.github.jwdeveloper.tiktok.utils.FilesUtility;
|
||||
import io.github.jwdeveloper.tiktok.utils.TemplateUtility;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class EventsInfoGenerator {
|
||||
public static void main(String[] args) throws ClassNotFoundException {
|
||||
var res = new EventsInfoGenerator().run();
|
||||
System.out.println(res);
|
||||
}
|
||||
|
||||
|
||||
public String run() {
|
||||
var events = getEventsDtos();
|
||||
var builder = new StringBuilder();
|
||||
for (var entry : events.entrySet()) {
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append(" **" + entry.getKey().name() + "**:").append(System.lineSeparator());
|
||||
for (var dto : entry.getValue()) {
|
||||
var link = getLink(dto);
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append(link);
|
||||
}
|
||||
}
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append("# Examples");
|
||||
builder.append(System.lineSeparator());
|
||||
for (var entry : events.entrySet()) {
|
||||
for (var dto : entry.getValue()) {
|
||||
builder.append("<br>");
|
||||
builder.append(getMethodContent(dto));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public StringBuilder getLink(EventDto dto) {
|
||||
var sb = new StringBuilder();
|
||||
var name = dto.getMethodName().toLowerCase()+"-"+dto.getEventClazz().getSimpleName().toLowerCase();
|
||||
sb.append("- [").append(dto.getMethodName()).append("](#").append(name).append(")");
|
||||
return sb;
|
||||
}
|
||||
|
||||
public String getMethodContent(EventDto dto) {
|
||||
var variables = new HashMap<String, Object>();
|
||||
var doc = getClazzDocumentation(dto.getEventClazz());
|
||||
variables.put("method-name", dto.getMethodName());
|
||||
variables.put("content", doc);
|
||||
variables.put("event-name", dto.getEventClazz().getSimpleName());
|
||||
var temp = """
|
||||
|
||||
|
||||
|
||||
#### {{method-name}} [{{event-name}}](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages.java)
|
||||
|
||||
{{content}}
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.{{method-name}}((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
""";
|
||||
return TemplateUtility.generateTemplate(temp, variables);
|
||||
}
|
||||
|
||||
public String getClazzDocumentation(Class<?> clazz) {
|
||||
var path = clazz.getName();
|
||||
path = path.replace(".", "\\");
|
||||
var fullPath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\API\\src\\main\\java\\" + path + ".java";
|
||||
var content = FilesUtility.loadFileContent(fullPath);
|
||||
var index = content.indexOf(" */");
|
||||
content = content.substring(index+4);
|
||||
|
||||
String pattern = "(?s)\\/\\\\*(.*?)\\*\\/";
|
||||
var r = Pattern.compile(pattern);
|
||||
var m = r.matcher(content);
|
||||
|
||||
|
||||
|
||||
if (!m.find()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
var group = m.group(1);
|
||||
var reuslt = group.replace("*","").replaceAll("\\*", "");
|
||||
return reuslt;
|
||||
}
|
||||
|
||||
public Map<EventType, List<EventDto>> getEventsDtos(){
|
||||
|
||||
var result = new TreeMap<EventType, List<EventDto>>();
|
||||
var baseClazz = EventsBuilder.class;
|
||||
var reflections = new Reflections("io.github.jwdeveloper.tiktok.data.events");
|
||||
var classes = reflections.getSubTypesOf(TikTokEvent.class);
|
||||
var methods = baseClazz.getDeclaredMethods();
|
||||
for (var method : methods) {
|
||||
if (method.getName().equals("onEvent")) {
|
||||
var dto = new EventDto(EventType.Message, "onEvent", TikTokEvent.class);
|
||||
result.computeIfAbsent(EventType.Message, eventType -> new ArrayList<>()).add(dto);
|
||||
continue;
|
||||
}
|
||||
|
||||
var parsedName = method.getName().replaceFirst("on", "");
|
||||
var name = "TikTok" + parsedName + "Event";
|
||||
var optional = classes.stream().filter(e -> e.getSimpleName().equals(name)).findFirst();
|
||||
if (optional.isEmpty()) {
|
||||
System.out.println("Not found!: " + name);
|
||||
continue;
|
||||
}
|
||||
var clazz = optional.get();
|
||||
var annotation = clazz.getAnnotation(EventMeta.class);
|
||||
var dto = new EventDto(annotation.eventType(), method.getName(), clazz);
|
||||
result.computeIfAbsent(dto.eventType, eventType -> new ArrayList<>()).add(dto);
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public static final class EventDto {
|
||||
private EventType eventType;
|
||||
private String methodName;
|
||||
private Class eventClazz;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EventDto{" +
|
||||
"eventType=" + eventType +
|
||||
", methodName='" + methodName + '\'' +
|
||||
", eventClazz=" + eventClazz.getSimpleName() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class EventsListGenerator
|
||||
{
|
||||
|
||||
|
||||
//[a](https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokBarrageMessageEvent.java)
|
||||
//Message Events:
|
||||
//- [member](#member)
|
||||
|
||||
public static String GetEventsList()
|
||||
{
|
||||
var classes = getClasses();
|
||||
var builder = new StringBuilder();
|
||||
for(var entry : classes.entrySet())
|
||||
{
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append(" **"+entry.getKey().name()+"**:").append(System.lineSeparator());
|
||||
|
||||
for(var clazz : entry.getValue())
|
||||
{
|
||||
var name = clazz.getSimpleName();
|
||||
var baseUrl ="https://github.com/jwdeveloper/TikTok-Live-Java/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/"+name+".java";
|
||||
builder.append("- [").append(name).append("](").append(baseUrl).append(")").append(System.lineSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static Map<EventType, List<Class<?>>> getClasses()
|
||||
{
|
||||
Reflections reflections = new Reflections("io.github.jwdeveloper.tiktok.events.messages");
|
||||
var classes = reflections.getSubTypesOf(TikTokEvent.class).stream().toList();
|
||||
Map<EventType, List<Class<?>>> classMap = new HashMap<>();
|
||||
// Group classes by EventType
|
||||
for (Class<?> clazz : classes) {
|
||||
EventType eventType = getEventType(clazz);
|
||||
classMap.computeIfAbsent(eventType, k -> new ArrayList<>()).add(clazz);
|
||||
}
|
||||
return classMap;
|
||||
}
|
||||
|
||||
private static EventType getEventType(Class<?> clazz) {
|
||||
EventMeta annotation = clazz.getAnnotation(EventMeta.class);
|
||||
if (annotation != null) {
|
||||
return annotation.eventType();
|
||||
}
|
||||
return EventType.Custom; // Default value if annotation not present
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
public class FullEventsExampleClass
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
TikTokLive.newClient("username")
|
||||
.onConnected((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onDisconnected((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onError((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onLike((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onJoin((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onFollow((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onShare((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onRoomUserInfo((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onComment((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onLiveEnded((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.onLivePaused((liveClient, event) ->
|
||||
{
|
||||
|
||||
}).onEmote((liveClient, event) ->
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.utils.FilesUtility;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class LiveClientMethodsGenerator
|
||||
{
|
||||
|
||||
|
||||
|
||||
//| Method Name | Description |
|
||||
//| ----------- | ----------- |
|
||||
|
||||
|
||||
public static String generate(String path)
|
||||
{
|
||||
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.append("| Method Name | Description |");
|
||||
sb.append(System.lineSeparator());
|
||||
sb.append("| ----------- | ----------- |");
|
||||
|
||||
var content = FilesUtility.loadFileContent(path);
|
||||
var pattern = "// \\s*(.*?)\\n\\s*(\\w+)\\s*\\(.*?\\)";
|
||||
|
||||
// Create a Pattern object
|
||||
var regex = Pattern.compile(pattern);
|
||||
|
||||
// Create a Matcher object
|
||||
var matcher = regex.matcher(content);
|
||||
|
||||
// Find and print method names and comments
|
||||
while (matcher.find()) {
|
||||
String comment = matcher.group(1);
|
||||
String methodName = matcher.group(2);
|
||||
sb.append(System.lineSeparator());
|
||||
sb.append("| ").append(methodName).append(" | ").append(comment).append(" |");
|
||||
}
|
||||
sb.append(System.lineSeparator());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,20 +43,14 @@ public class ReadmeGenerator
|
||||
|
||||
variables.put("version", getCurrentVersion());
|
||||
|
||||
var exampleCodePath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\TestApplication\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\SimpleExample.java";
|
||||
variables.put("Code-Example", getCodeExample(exampleCodePath));
|
||||
var exampleCodePath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Examples\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\SimpleExample.java";
|
||||
variables.put("code-content", getCodeExample(exampleCodePath));
|
||||
|
||||
variables.put("events-content", new EventsInfoGenerator().run());
|
||||
|
||||
var exampleConfigurationPath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\TestApplication\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\ConfigurationExample.java";
|
||||
variables.put("Configuration-Example", getCodeExample(exampleConfigurationPath));
|
||||
var listenerExamplePath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Examples\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\ListenerExample.java";
|
||||
// variables.put("listener-content", getCodeExample(listenerExamplePath));
|
||||
|
||||
variables.put("Events", EventsListGenerator.GetEventsList());
|
||||
|
||||
var listenerExamplePath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\TestApplication\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\ListenerExample.java";
|
||||
variables.put("Listener-Example", getCodeExample(listenerExamplePath));
|
||||
|
||||
// var liveClientPath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\API\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\live\\LiveClient.java";
|
||||
// variables.put("methods", LiveClientMethodsGenerator.generate(liveClientPath));
|
||||
|
||||
template = TemplateUtility.generateTemplate(template, variables);
|
||||
var outputPath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools-ReadmeGenerator\\src\\main\\resources\\output.md";
|
||||
@@ -72,7 +66,9 @@ public class ReadmeGenerator
|
||||
|
||||
public String getCodeExample(String path)
|
||||
{
|
||||
return FilesUtility.loadFileContent(path);
|
||||
var content = FilesUtility.loadFileContent(path);
|
||||
content = content.substring(content.indexOf("*/")+2);
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,38 +51,20 @@ Do you prefer other programming languages?
|
||||
2. Create your first chat connection
|
||||
|
||||
```java
|
||||
{{Code-Example}}
|
||||
{{code-content}}
|
||||
```
|
||||
## Configuration
|
||||
## Events
|
||||
|
||||
{{events-content}}
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
```java
|
||||
{{Configuration-Example}}
|
||||
```
|
||||
## Listener Example
|
||||
|
||||
```java
|
||||
{{Listener-Example}}
|
||||
{{listener-content}}
|
||||
```
|
||||
|
||||
## Methods
|
||||
A `client (LiveClient)` object contains the following methods.
|
||||
|
||||
|
||||
|
||||
| Method Name | Description |
|
||||
|---------------------| ----------- |
|
||||
| connect | Connects to the live stream. |
|
||||
| disconnect | Disconnects the connection. |
|
||||
| getGiftManager | Gets the meta informations about all gifts. |
|
||||
| getRoomInfo | Gets the current room info from TikTok API including streamer info, room status and statistics. |
|
||||
| getListenersManager | Gets and manage TikTokEventListeners |
|
||||
## Events
|
||||
|
||||
A `TikTokLive` object has the following events
|
||||
|
||||
{{Events}}
|
||||
|
||||
<br><br>
|
||||
|
||||
## Contributing
|
||||
Your improvements are welcome! Feel free to open an <a href="https://github.com/jwdeveloper/TikTok-Live-Java/issues">issue</a> or <a href="https://github.com/jwdeveloper/TikTok-Live-Java/pulls">pull request</a>.
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ApiServiceMock extends TikTokApiService {
|
||||
public LiveRoomMeta fetchRoomInfo()
|
||||
{
|
||||
var meta = new LiveRoomMeta();
|
||||
meta.setStatus(1);
|
||||
meta.setStatus(LiveRoomMeta.LiveRoomStatus.HostOnline);
|
||||
return meta;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,13 +34,6 @@ public class TemplateUtility
|
||||
return template;
|
||||
}
|
||||
|
||||
public static String generateTemplate2(String template, Map<String, Object> values) {
|
||||
for(var entry : values.entrySet())
|
||||
{
|
||||
template = doReplacement2(template,entry.getKey(), entry.getValue().toString());
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
private static String doReplacement(String template, String keyword, String value)
|
||||
{
|
||||
@@ -48,9 +41,5 @@ public class TemplateUtility
|
||||
return template.replaceAll(key, value);
|
||||
}
|
||||
|
||||
private static String doReplacement2(String template, String keyword, String value)
|
||||
{
|
||||
var key = "(\\$)("+keyword+")(\\$)";
|
||||
return template.replaceAll(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user