mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 08:49:40 -05:00
Changes:
- New event `onSuccessResponseMapping` triggered when Webcast.Message was successfully mapped to TikTokEvent - New Project Tools-collector: Tool generates instance of SqlLite database and collect to it both to events and exceptions occurred while TikTokLive client was running
This commit is contained in:
81
.gitignore
vendored
81
.gitignore
vendored
@@ -1,3 +1,82 @@
|
||||
# Project exclude paths
|
||||
/API/target/
|
||||
/Client/target/
|
||||
/Client/target/
|
||||
*.db
|
||||
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
@@ -1,8 +1,6 @@
|
||||
package io.github.jwdeveloper.tiktok.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.messages.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
|
||||
public interface TikTokEventBuilder<T> {
|
||||
@@ -89,6 +87,9 @@ public interface TikTokEventBuilder<T> {
|
||||
T onUnhandledControl(TikTokEventConsumer<TikTokUnhandledControlEvent> event);
|
||||
|
||||
T onEvent(TikTokEventConsumer<TikTokEvent> event);
|
||||
|
||||
T onSuccessResponseMapping(TikTokEventConsumer<TikTokSuccessResponseMappingEvent> event);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,13 +21,18 @@ public class TikTokLiveMessageException extends TikTokLiveException {
|
||||
this.webcastResponse = webcastResponse;
|
||||
}
|
||||
|
||||
public void messageToBase64()
|
||||
public String messageName()
|
||||
{
|
||||
var decoded = Base64.getEncoder().encodeToString(webcastMessage.getBinary().toByteArray());
|
||||
return webcastMessage.getType();
|
||||
}
|
||||
|
||||
public void webcastResponseToBase64()
|
||||
public String messageToBase64()
|
||||
{
|
||||
var decoded = Base64.getEncoder().encodeToString(webcastResponse.toByteArray());
|
||||
return Base64.getEncoder().encodeToString(webcastMessage.getBinary().toByteArray());
|
||||
}
|
||||
|
||||
public String webcastResponseToBase64()
|
||||
{
|
||||
return Base64.getEncoder().encodeToString(webcastResponse.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,6 +317,12 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
|
||||
tikTokEventHandler.subscribe(TikTokEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TikTokLiveClientBuilder onSuccessResponseMapping(TikTokEventConsumer<TikTokSuccessResponseMappingEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokSuccessResponseMappingEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokSuccessResponseMappingEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokUnhandledEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokMessageMappingException;
|
||||
@@ -69,6 +70,7 @@ public abstract class TikTokMessageHandler {
|
||||
}
|
||||
var handler = handlers.get(message.getType());
|
||||
var tiktokEvent = handler.handle(message);
|
||||
tikTokEventHandler.publish(client, new TikTokSuccessResponseMappingEvent(tiktokEvent, message));
|
||||
tikTokEventHandler.publish(client, tiktokEvent);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler {
|
||||
public void init() {
|
||||
|
||||
//ConnectionEvents events
|
||||
register(WebcastControlMessage.class, TikTokRoomMessageEvent.class);
|
||||
register(SystemMessage.class, this::handleWebcastControlMessage);
|
||||
register(WebcastControlMessage.class, this::handleWebcastControlMessage);
|
||||
register(SystemMessage.class,TikTokRoomMessageEvent.class);
|
||||
|
||||
|
||||
//Room status events
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.io.IOException;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static String TEST_TIKTOK_USER = "kitovskyyy";
|
||||
public static String TEST_TIKTOK_USER = "polonezgarage";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
var client = TikTokLive.newClient(TEST_TIKTOK_USER)
|
||||
|
||||
50
Tools-EventsCollector/pom.xml
Normal file
50
Tools-EventsCollector/pom.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>0.0.14-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>Tools-EventsCollector</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.34.0</version> <!-- Use the latest version available -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jdbi</groupId>
|
||||
<artifactId>jdbi3-core</artifactId>
|
||||
<version>3.23.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jdbi</groupId>
|
||||
<artifactId>jdbi3-sqlobject</artifactId>
|
||||
<version>3.23.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.32</version> <!-- Use the latest version available -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<artifactId>Client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,65 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokLive;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
||||
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;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.tables.TikTokMessageModel;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws SQLException {
|
||||
var tiktokUser = "mr_cios";
|
||||
var db = new TikTokDatabase("test");
|
||||
db.init();
|
||||
TikTokLive.newClient(tiktokUser)
|
||||
.onWebcastResponseDebug((liveClient, event) ->
|
||||
{
|
||||
var eventName = event.getEvent().getClass().getSimpleName();
|
||||
var binary = Base64.getEncoder().encodeToString(event.getMessage().getBinary().toByteArray());
|
||||
var model = TikTokMessageModel.builder()
|
||||
.type("message")
|
||||
.hostName(tiktokUser)
|
||||
.eventName(eventName)
|
||||
.eventContent(binary)
|
||||
.build();
|
||||
|
||||
db.insertMessage(model);
|
||||
System.out.println("EVENT: " + eventName);
|
||||
})
|
||||
.onError((liveClient, event) ->
|
||||
{
|
||||
var exception = event.getException();
|
||||
var exceptionContent = ExceptionInfoModel.getStackTraceAsString(exception);
|
||||
var builder = TikTokErrorModel.builder();
|
||||
if (exception instanceof TikTokLiveMessageException ex) {
|
||||
builder.hostName(tiktokUser)
|
||||
.errorName(ex.messageName())
|
||||
.errorType("error-message")
|
||||
.exceptionContent(exceptionContent)
|
||||
.message(ex.messageToBase64())
|
||||
.response(ex.webcastResponseToBase64());
|
||||
} else {
|
||||
builder.hostName(tiktokUser)
|
||||
.errorName(exception.getClass().getSimpleName())
|
||||
.errorType("error-system")
|
||||
.exceptionContent(exceptionContent)
|
||||
.message("")
|
||||
.response("");
|
||||
}
|
||||
|
||||
var error = builder.build();
|
||||
db.insertError(error);
|
||||
System.out.println("ERROR: "+error.getErrorName());
|
||||
exception.printStackTrace();
|
||||
|
||||
})
|
||||
.buildAndRun();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector.db;
|
||||
|
||||
public class SqlConsts
|
||||
{
|
||||
public static String CREATE_MESSAGES_TABLE = """
|
||||
CREATE TABLE IF NOT EXISTS TikTokMessageModel (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
hostName TEXT,
|
||||
type TEXT,
|
||||
eventName TEXT,
|
||||
eventContent TEXT,
|
||||
createdAt TEXT
|
||||
);
|
||||
""";
|
||||
|
||||
public static String CREATE_ERROR_TABLE = """
|
||||
CREATE TABLE IF NOT EXISTS TikTokErrorModel (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
hostName VARCHAR(255),
|
||||
errorName VARCHAR(255),
|
||||
errorType VARCHAR(255),
|
||||
exceptionContent TEXT,
|
||||
message TEXT,
|
||||
response TEXT,
|
||||
createdAt DATETIME
|
||||
);
|
||||
""";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector.db;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.tables.TikTokErrorModel;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.tables.TikTokMessageModel;
|
||||
import org.jdbi.v3.core.Jdbi;
|
||||
import org.jdbi.v3.sqlobject.SqlObjectPlugin;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class TikTokDatabase
|
||||
{
|
||||
private final String database;
|
||||
private TikTokMessageModelDAO messagesTable;
|
||||
private TikTokErrorModelDAO errorTable;
|
||||
|
||||
public TikTokDatabase(String database) {
|
||||
this.database =database;
|
||||
}
|
||||
|
||||
public void init() throws SQLException {
|
||||
var jdbcUrl ="jdbc:sqlite:"+database+".db";
|
||||
var connection = DriverManager.getConnection(jdbcUrl);
|
||||
Jdbi jdbi = Jdbi.create(jdbcUrl)
|
||||
.installPlugin(new SqlObjectPlugin());
|
||||
jdbi.useHandle(handle -> {
|
||||
handle.execute(SqlConsts.CREATE_MESSAGES_TABLE);
|
||||
handle.execute(SqlConsts.CREATE_ERROR_TABLE);
|
||||
});
|
||||
messagesTable = jdbi.onDemand(TikTokMessageModelDAO.class);
|
||||
errorTable = jdbi.onDemand(TikTokErrorModelDAO.class);
|
||||
}
|
||||
|
||||
public void insertMessage(TikTokMessageModel message)
|
||||
{
|
||||
var dateFormat = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss.SSS");
|
||||
message.setCreatedAt(dateFormat.format(new Date()));
|
||||
messagesTable.insertTikTokMessage(message);
|
||||
}
|
||||
|
||||
public void insertError(TikTokErrorModel message)
|
||||
{
|
||||
var dateFormat = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss.SSS");
|
||||
message.setCreatedAt(dateFormat.format(new Date()));
|
||||
errorTable.insertTikTokMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector.db;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.tables.TikTokErrorModel;
|
||||
|
||||
import org.jdbi.v3.sqlobject.customizer.BindBean;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
|
||||
|
||||
public interface TikTokErrorModelDAO
|
||||
{
|
||||
@SqlUpdate("INSERT INTO TikTokErrorModel (hostName, errorName, errorType, exceptionContent, message, response, createdAt) " +
|
||||
"VALUES (:hostName, :errorName, :errorType, :exceptionContent, :message, :response, :createdAt)")
|
||||
void insertTikTokMessage(@BindBean TikTokErrorModel message);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector.db;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.tables.TikTokMessageModel;
|
||||
import org.jdbi.v3.sqlobject.customizer.BindBean;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
|
||||
|
||||
public interface TikTokMessageModelDAO
|
||||
{
|
||||
@SqlUpdate("INSERT INTO TikTokMessageModel (hostName, eventName,type, eventContent, createdAt) " +
|
||||
"VALUES (:hostName, :eventName, :type, :eventContent, :createdAt)")
|
||||
void insertTikTokMessage(@BindBean TikTokMessageModel message);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector.tables;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
public class ExceptionInfoModel
|
||||
{
|
||||
private String message;
|
||||
private String stackTrace;
|
||||
|
||||
public ExceptionInfoModel(Throwable throwable) {
|
||||
this.message = throwable.getMessage();
|
||||
this.stackTrace = getStackTraceAsString(throwable);
|
||||
}
|
||||
|
||||
public static String getStackTraceAsString(Throwable throwable) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
throwable.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
// Getters for message and stackTrace
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getStackTrace() {
|
||||
return stackTrace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector.tables;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class TikTokErrorModel
|
||||
{
|
||||
private Integer id;
|
||||
|
||||
private String hostName;
|
||||
|
||||
private String errorName;
|
||||
|
||||
private String errorType;
|
||||
|
||||
private String exceptionContent;
|
||||
|
||||
private String message;
|
||||
|
||||
private String response;
|
||||
|
||||
private String createdAt;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.github.jwdeveloper.tiktok.tools.collector.tables;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class TikTokMessageModel
|
||||
{
|
||||
private Integer id;
|
||||
|
||||
private String hostName;
|
||||
|
||||
private String eventName;
|
||||
|
||||
private String type;
|
||||
|
||||
private String eventContent;
|
||||
|
||||
private String createdAt;
|
||||
}
|
||||
Reference in New Issue
Block a user