mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 16:59:39 -05:00
Due to convention, interfaces should not have TikTok name inside, but they should have prefix Live instead
- rename TikTokMapper to LiveMapper - rename TikTokLiveMapperHelper to LiveMapperHelper Create interface: LiveEventsHandler for TikTokLiveEventHandler LiveMessagesHandler for TikTokLiveMessageHandler
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.time.Duration;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CodeExample {
|
||||
public static void main(String[] args) {
|
||||
TikTokLive.newClient("mrBeast")
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
System.out.println("Thank you for Money!");
|
||||
})
|
||||
.buildAndConnect();
|
||||
}
|
||||
|
||||
|
||||
public static void codeExample() {
|
||||
// <code>
|
||||
TikTokLive.newClient("bangbetmenygy")
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
String message = switch (event.getGift().getName())
|
||||
{
|
||||
case "Rose" -> "ROSE!";
|
||||
case "Good game" -> "GOOD GAME";
|
||||
case "Ye" -> "Ye";
|
||||
case "Nice gift" -> "Nice gift";
|
||||
default -> "Thank you for " + event.getGift().getName();
|
||||
};
|
||||
System.out.println(event.getUser().getProfileName() + " sends " + message);
|
||||
})
|
||||
.onGiftCombo((liveClient, event) ->
|
||||
{
|
||||
System.out.println(event.getComboState()+ " " + event.getCombo() + " " + event.getGift().getName());
|
||||
})
|
||||
.onRoomInfo((liveClient, event) ->
|
||||
{
|
||||
var roomInfo = event.getRoomInfo();
|
||||
System.out.println("Room Id: "+roomInfo.getRoomId());
|
||||
System.out.println("Likes: "+roomInfo.getLikesCount());
|
||||
System.out.println("Viewers: "+roomInfo.getViewersCount());
|
||||
})
|
||||
.onJoin((liveClient, event) ->
|
||||
{
|
||||
System.out.println(event.getUser().getProfileName() + "Hello on my stream! ");
|
||||
})
|
||||
.onConnected((liveClient, event) ->
|
||||
{
|
||||
System.out.println("Connected to live ");
|
||||
})
|
||||
.onError((liveClient, event) ->
|
||||
{
|
||||
System.out.println("Error! " + event.getException().getMessage());
|
||||
})
|
||||
.buildAndConnect();
|
||||
// </code>
|
||||
}
|
||||
|
||||
public static void configExample() {
|
||||
// <code>
|
||||
TikTokLive.newClient("bangbetmenygy")
|
||||
.configure((settings) ->
|
||||
{
|
||||
settings.setHostName("bangbetmenygy"); // This method is useful in case you want change hostname later
|
||||
settings.setClientLanguage("en"); // Language
|
||||
settings.setLogLevel(Level.ALL); // Log level
|
||||
settings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
settings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline
|
||||
settings.setRetryConnectionTimeout(Duration.ofSeconds(1)); // Timeout before next reconnection
|
||||
|
||||
//Optional: Sometimes not every message from chat are send to TikTokLiveJava to fix this issue you can set sessionId
|
||||
// documentation how to obtain sessionId https://github.com/isaackogan/TikTok-Live-Connector#send-chat-messages
|
||||
settings.setSessionId("86c3c8bf4b17ebb2d74bb7fa66fd0000");
|
||||
|
||||
//Optional:
|
||||
//RoomId can be used as an override if you're having issues with HostId.
|
||||
//You can find it in the HTML for the livestream-page
|
||||
settings.setRoomId("XXXXXXXXXXXXXXXXX");
|
||||
|
||||
//Optional:
|
||||
//API Key for increased limit to signing server
|
||||
settings.setApiKey("XXXXXXXXXXXXXXXXX");
|
||||
})
|
||||
.buildAndConnect();
|
||||
// </code>
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.util.HashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CodeExamplesGenerator {
|
||||
public static void main(String[] args) {
|
||||
var result = new CodeExamplesGenerator().run();
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
public String run() {
|
||||
|
||||
var content = FilesUtility.loadFileContent("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools-ReadmeGenerator\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\CodeExample.java");
|
||||
var p = "<code>(.*?)</code>";
|
||||
var r = Pattern.compile(p, Pattern.DOTALL);
|
||||
var m = r.matcher(content);
|
||||
|
||||
|
||||
var pattern = """
|
||||
```java
|
||||
{{code}}
|
||||
```
|
||||
3. Configure (optional)
|
||||
|
||||
```java
|
||||
{{config}}
|
||||
```
|
||||
""";
|
||||
|
||||
|
||||
var values = new HashMap<String, Object>();
|
||||
m.find();
|
||||
var code = m.group(0)
|
||||
.replace("<code>", "")
|
||||
.replace("// </code>", "")
|
||||
.replaceAll("(?m)^ {8}", "");
|
||||
values.put("code", code);
|
||||
|
||||
m.find();
|
||||
values.put("config", m.group(1));
|
||||
var result = TemplateUtility.generateTemplate(pattern, values);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.descrabble.api.DescriptionDecorator;
|
||||
import io.github.jwdeveloper.descrabble.api.elements.Element;
|
||||
import io.github.jwdeveloper.descrabble.api.elements.ElementFactory;
|
||||
|
||||
public class EventsDecorator implements DescriptionDecorator {
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void decorate(Element root, ElementFactory factory)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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 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 baseUrl = "https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/";
|
||||
baseUrl += dto.getEventClazz().getPackageName().replace(".","/");
|
||||
baseUrl += "/"+dto.getEventClazz().getSimpleName()+".java";
|
||||
variables.put("event-file-url",baseUrl);
|
||||
var temp = """
|
||||
|
||||
|
||||
## {{method-name}} [{{event-name}}]({{event-file-url}})
|
||||
|
||||
{{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() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
|
||||
/*
|
||||
* 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.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class FilesUtility
|
||||
{
|
||||
public static List<Path> getFiles(String input) {
|
||||
Path path = Paths.get(input);
|
||||
try (Stream<Path> paths = Files.list(path)) {
|
||||
return paths.filter(Files::isRegularFile).toList();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
public static String getFileFromResource(Class clazz, String path)
|
||||
{
|
||||
try {
|
||||
var stream =clazz.getClassLoader().getResourceAsStream(path);
|
||||
var bytes= stream.readAllBytes();
|
||||
stream.close();
|
||||
return new String(bytes);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
public static List<Path> getFileContent(String input) {
|
||||
Path path = Paths.get(input);
|
||||
try (Stream<Path> paths = Files.list(path)) {
|
||||
return paths.filter(Files::isRegularFile).toList();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveFile(String path, String content)
|
||||
{
|
||||
Path filePath = Paths.get(path);
|
||||
try {
|
||||
// Write the content to the file
|
||||
Files.write(filePath, content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean pathExists(String path) {
|
||||
var directory = new File(path);
|
||||
return directory.exists();
|
||||
}
|
||||
|
||||
public static File ensurePath(String path) {
|
||||
var directory = new File(path);
|
||||
if (directory.exists()) {
|
||||
return directory;
|
||||
}
|
||||
directory.mkdirs();
|
||||
return directory;
|
||||
}
|
||||
|
||||
public static void ensureFile(String paths) {
|
||||
var file = new File(paths);
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String loadFileContent(String path) {
|
||||
ensureFile(path);
|
||||
Path pathh = Paths.get(path);
|
||||
try {
|
||||
return new String(Files.readAllBytes(pathh));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.util.regex.Pattern;
|
||||
|
||||
public class ListenerExampleGenerator
|
||||
{
|
||||
public static void main(String[] arg)
|
||||
{
|
||||
var result = new ListenerExampleGenerator();
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
|
||||
public String run()
|
||||
{
|
||||
var content = FilesUtility.loadFileContent("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Examples\\src\\main\\java\\io\\github\\jwdeveloper\\tiktok\\ListenerExample.java");
|
||||
var p = "<code>(.*?)</code>";
|
||||
var r = Pattern.compile(p, Pattern.DOTALL);
|
||||
var m = r.matcher(content);
|
||||
m.find();
|
||||
return m.group(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.descrabble.api.DescriptionGenerator;
|
||||
import io.github.jwdeveloper.descrabble.framework.Descrabble;
|
||||
import io.github.jwdeveloper.descrabble.plugin.github.DescrabbleGithub;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Main
|
||||
{
|
||||
public static void main(String[] args) throws IOException {
|
||||
var version = System.getenv("VERSION");
|
||||
if (version == null || version.equals("")) {
|
||||
version = "[Replace with current version]";
|
||||
}
|
||||
|
||||
var inputStream = Main.class.getResourceAsStream("/readme-template.html");
|
||||
var targetFile = new File("temp.file");
|
||||
FileUtils.copyInputStreamToFile(inputStream, targetFile);
|
||||
|
||||
var output = System.getProperty("user.dir");
|
||||
|
||||
|
||||
DescriptionGenerator generator = Descrabble.create()
|
||||
.withTemplate(targetFile)
|
||||
.withVariable("version", version)
|
||||
.withDecorator(new EventsDecorator())
|
||||
.withPlugin(DescrabbleGithub.plugin("README.md"))
|
||||
.build();
|
||||
|
||||
|
||||
generator.generate(output);
|
||||
targetFile.delete();
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Resources;
|
||||
import com.hubspot.jinjava.Jinjava;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class Main2 {
|
||||
public static void main(String[] args) throws IOException {
|
||||
var version = System.getenv("VERSION");
|
||||
if (version == null || version.equals("")) {
|
||||
version = "[Replace with current version]";
|
||||
}
|
||||
|
||||
var template = Resources.toString(Resources.getResource("my-template.html"), Charsets.UTF_8);
|
||||
|
||||
var jinjava = new Jinjava();
|
||||
var context = new HashMap<String, Object>();
|
||||
context.put("version", version);
|
||||
|
||||
var renderedTemplate = jinjava.render(template, context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.util.HashMap;
|
||||
|
||||
public class ReadmeGenerator {
|
||||
public static void main(String[] args) {
|
||||
var generator = new ReadmeGenerator();
|
||||
generator.generate();
|
||||
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
var template = FilesUtility.getFileFromResource(ReadmeGenerator.class, "template.md");
|
||||
var variables = new HashMap<String, Object>();
|
||||
|
||||
variables.put("version", getCurrentVersion());
|
||||
variables.put("code-content", new CodeExamplesGenerator().run());
|
||||
variables.put("events-content", new EventsInfoGenerator().run());
|
||||
variables.put("listener-content",new ListenerExampleGenerator().run());
|
||||
|
||||
template = TemplateUtility.generateTemplate(template, variables);
|
||||
var outputPath = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools-ReadmeGenerator\\src\\main\\resources\\output.md";
|
||||
FilesUtility.saveFile(outputPath, template);
|
||||
}
|
||||
|
||||
public String getCurrentVersion() {
|
||||
var version = System.getenv("version");
|
||||
;
|
||||
|
||||
return version == null ? "NOT_FOUND" : version;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
/*
|
||||
* 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.util.Map;
|
||||
|
||||
public class TemplateUtility {
|
||||
public static String generateTemplate(String template, Map<String, Object> values) {
|
||||
for (var entry : values.entrySet()) {
|
||||
template = doReplacement(template, entry.getKey(), entry.getValue().toString());
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
private static String doReplacement(String template, String keyword, String value) {
|
||||
var key = "(\\{\\{)" + keyword + "(}})";
|
||||
return template.replaceAll(key, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
1
tools-readme/src/main/resources/logo.svg
Normal file
1
tools-readme/src/main/resources/logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 241 KiB |
732
tools-readme/src/main/resources/output.md
Normal file
732
tools-readme/src/main/resources/output.md
Normal file
@@ -0,0 +1,732 @@
|
||||
<div align="center" >
|
||||
<a target="blank" >
|
||||
<img src="https://raw.githubusercontent.com/jwdeveloper/TikTokLiveJava/develop-1_0_0/Tools-ReadmeGenerator/src/main/resources/logo.svg" width="15%" >
|
||||
</img>
|
||||
</a>
|
||||
</div>
|
||||
<div align="center" >
|
||||
<h1>TikTok Live Java</h1>
|
||||
|
||||
❤️❤️🎁 *Connect to TikTok live in 3 lines* 🎁❤️❤️
|
||||
|
||||
<div align="center" >
|
||||
<a href="https://jitpack.io/#jwdeveloper/TikTok-Live-Java" target="blank" >
|
||||
<img src="https://jitpack.io/v/jwdeveloper/TikTok-Live-Java.svg" width="20%" >
|
||||
</img>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="https://discord.gg/e2XwPNTBBr" target="blank" >
|
||||
<img src="https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white" >
|
||||
</img>
|
||||
</a>
|
||||
|
||||
<a target="blank" >
|
||||
<img src="https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=openjdk&logoColor=white" >
|
||||
</img>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
# Introduction
|
||||
A Java library inspired by [TikTokLive](https://github.com/isaackogan/TikTokLive) and [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp). Use it to receive live stream events such as comments and gifts in realtime from [TikTok LIVE](https://www.tiktok.com/live) by connecting to TikTok's internal WebCast push service.
|
||||
The library includes a wrapper that connects to the WebCast service using just the username (`uniqueId`). This allows you to connect to your own live chat as well as the live chat of other streamers.
|
||||
No credentials are required. Events such as [Members Joining](#member), [Gifts](#gift), [Subscriptions](#subscribe), [Viewers](#roomuser), [Follows](#social), [Shares](#social), [Questions](#questionnew), [Likes](#like) and [Battles](#linkmicbattle) can be tracked.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://www.youtube.com/watch?v=eerWGgUKc6c" align="right" target="blank"><img src="https://img.youtube.com/vi/eerWGgUKc6c/hqdefault.jpg" alt="IMAGE ALT TEXT" width="38%" align="right"></a>
|
||||
</div>
|
||||
|
||||
Join the support [discord](https://discord.gg/e2XwPNTBBr) and visit the `#java-support` channel for questions, contributions and ideas. Feel free to make pull requests with missing/new features, fixes, etc
|
||||
|
||||
Do you prefer other programming languages?
|
||||
- **Node** orginal: [TikTok-Live-Connector](https://github.com/isaackogan/TikTok-Live-Connector) by [@zerodytrash](https://github.com/zerodytrash)
|
||||
- **Python** rewrite: [TikTokLive](https://github.com/isaackogan/TikTokLive) by [@isaackogan](https://github.com/isaackogan)
|
||||
- **Go** rewrite: [GoTikTokLive](https://github.com/Davincible/gotiktoklive) by [@Davincible](https://github.com/Davincible)
|
||||
- **C#** rewrite: [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp) by [@frankvHoof93](https://github.com/frankvHoof93)
|
||||
|
||||
**NOTE:** This is not an official API. It's a reverse engineering project.
|
||||
|
||||
#### Overview
|
||||
- [Getting started](#getting-started)
|
||||
- [Events](#events)
|
||||
- [Listeners](#listeners)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Install the package via Maven
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
||||
<artifactId>Client</artifactId>
|
||||
<version>NOT_FOUND</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
2. Create your first chat connection
|
||||
|
||||
```java
|
||||
|
||||
TikTokLive.newClient("bangbetmenygy")
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
String message = switch (event.getGift()) {
|
||||
case ROSE -> "ROSE!";
|
||||
case GG -> "GOOD GAME";
|
||||
case TIKTOK -> "Ye";
|
||||
case CORGI -> "Nice gift";
|
||||
default -> "Thank you for " + event.getGift().getName();
|
||||
};
|
||||
System.out.println(event.getUser().getProfileName() + " sends " + message);
|
||||
})
|
||||
.onGiftCombo((liveClient, event) ->
|
||||
{
|
||||
System.out.println(event.getComboState()+ " " + event.getCombo() + " " + event.getGift().getName());
|
||||
})
|
||||
.onRoomInfo((liveClient, event) ->
|
||||
{
|
||||
var roomInfo = event.getRoomInfo();
|
||||
System.out.println("Room Id: "+roomInfo.getRoomId());
|
||||
System.out.println("Likes: "+roomInfo.getLikesCount());
|
||||
System.out.println("Viewers: "+roomInfo.getViewersCount());
|
||||
})
|
||||
.onJoin((liveClient, event) ->
|
||||
{
|
||||
System.out.println(event.getUser().getProfileName() + "Hello on my stream! ");
|
||||
})
|
||||
.onConnected((liveClient, event) ->
|
||||
{
|
||||
System.out.println("Connected to live ");
|
||||
})
|
||||
.onError((liveClient, event) ->
|
||||
{
|
||||
System.out.println("Error! " + event.getException().getMessage());
|
||||
})
|
||||
.buildAndConnect();
|
||||
|
||||
```
|
||||
3. Configure (optional)
|
||||
|
||||
```java
|
||||
|
||||
TikTokLive.newClient("bangbetmenygy")
|
||||
.configure((settings) ->
|
||||
{
|
||||
settings.setHostName("bangbetmenygy"); // This method is useful in case you want change hostname later
|
||||
settings.setClientLanguage("en"); // Language
|
||||
settings.setLogLevel(Level.ALL); // Log level
|
||||
settings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
settings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline
|
||||
settings.setRetryConnectionTimeout(Duration.ofSeconds(1)); // Timeout before next reconnection
|
||||
|
||||
//Optional: Sometimes not every message from chat are send to TikTokLiveJava to fix this issue you can set sessionId
|
||||
// documentation how to obtain sessionId https://github.com/isaackogan/TikTok-Live-Connector#send-chat-messages
|
||||
settings.setSessionId("86c3c8bf4b17ebb2d74bb7fa66fd0000");
|
||||
|
||||
//Optional:
|
||||
//RoomId can be used as an override if you're having issues with HostId.
|
||||
//You can find it in the HTML for the livestream-page
|
||||
settings.setRoomId("XXXXXXXXXXXXXXXXX");
|
||||
})
|
||||
.buildAndConnect();
|
||||
//
|
||||
```
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
|
||||
|
||||
**Control**:
|
||||
|
||||
- [onReconnecting](#onreconnecting-tiktokreconnectingevent)
|
||||
- [onError](#onerror-tiktokerrorevent)
|
||||
- [onConnected](#onconnected-tiktokconnectedevent)
|
||||
- [onDisconnected](#ondisconnected-tiktokdisconnectedevent)
|
||||
|
||||
**Message**:
|
||||
|
||||
- [onEvent](#onevent-tiktokevent)
|
||||
- [onEvent](#onevent-tiktokevent)
|
||||
- [onComment](#oncomment-tiktokcommentevent)
|
||||
- [onRoomInfo](#onroominfo-tiktokroominfoevent)
|
||||
- [onGift](#ongift-tiktokgiftevent)
|
||||
- [onSubscribe](#onsubscribe-tiktoksubscribeevent)
|
||||
- [onFollow](#onfollow-tiktokfollowevent)
|
||||
- [onGiftCombo](#ongiftcombo-tiktokgiftcomboevent)
|
||||
- [onLiveEnded](#onliveended-tiktokliveendedevent)
|
||||
- [onQuestion](#onquestion-tiktokquestionevent)
|
||||
- [onShare](#onshare-tiktokshareevent)
|
||||
- [onLiveUnpaused](#onliveunpaused-tiktokliveunpausedevent)
|
||||
- [onEmote](#onemote-tiktokemoteevent)
|
||||
- [onJoin](#onjoin-tiktokjoinevent)
|
||||
- [onLike](#onlike-tiktoklikeevent)
|
||||
- [onLivePaused](#onlivepaused-tiktoklivepausedevent)
|
||||
|
||||
**Debug**:
|
||||
|
||||
- [onWebsocketResponse](#onwebsocketresponse-tiktokwebsocketresponseevent)
|
||||
- [onWebsocketUnhandledMessage](#onwebsocketunhandledmessage-tiktokwebsocketunhandledmessageevent)
|
||||
- [onHttpResponse](#onhttpresponse-tiktokhttpresponseevent)
|
||||
- [onWebsocketMessage](#onwebsocketmessage-tiktokwebsocketmessageevent)
|
||||
# Examples
|
||||
<br>
|
||||
|
||||
## onReconnecting [TikTokReconnectingEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokReconnectingEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onReconnecting((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onError [TikTokErrorEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokErrorEvent.java)
|
||||
|
||||
|
||||
General error event. You should handle this.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onError((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onConnected [TikTokConnectedEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokConnectedEvent.java)
|
||||
|
||||
|
||||
Triggered when the connection is successfully established.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onConnected((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onDisconnected [TikTokDisconnectedEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokDisconnectedEvent.java)
|
||||
|
||||
|
||||
Triggered when the connection gets disconnected. In that case you can call connect() again to have a reconnect logic.
|
||||
Note that you should wait a little bit before attempting a reconnect to to avoid being rate-limited.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onDisconnected((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onEvent [TikTokEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/common/TikTokEvent.java)
|
||||
|
||||
|
||||
Base class for all events
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onEvent((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onEvent [TikTokEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/common/TikTokEvent.java)
|
||||
|
||||
|
||||
Base class for all events
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onEvent((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onComment [TikTokCommentEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokCommentEvent.java)
|
||||
|
||||
|
||||
Triggered every time a new chat comment arrives.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onComment((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onRoomInfo [TikTokRoomInfoEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/room/TikTokRoomInfoEvent.java)
|
||||
|
||||
|
||||
Triggered when LiveRoomInfo got updated such as likes, viewers, ranking ....
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onRoomInfo((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onGift [TikTokGiftEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftEvent.java)
|
||||
|
||||
|
||||
Triggered when user sends gifts that has
|
||||
no combo (most of expensive gifts)
|
||||
or if combo has finished
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onSubscribe [TikTokSubscribeEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokSubscribeEvent.java)
|
||||
|
||||
|
||||
Triggers when a user creates a subscription.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onSubscribe((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onFollow [TikTokFollowEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/social/TikTokFollowEvent.java)
|
||||
|
||||
|
||||
Triggers when a user follows the streamer. Based on social event.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onFollow((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onGiftCombo [TikTokGiftComboEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftComboEvent.java)
|
||||
|
||||
|
||||
Triggered every time gift is sent
|
||||
|
||||
@see GiftSendType it has 3 states
|
||||
|
||||
<p>Example when user sends gift with combo</p>
|
||||
<p>>Combo: 1 -> comboState = GiftSendType.Begin</p>
|
||||
<p>Combo: 4 -> comboState = GiftSendType.Active</p>
|
||||
<p>Combo: 8 -> comboState = GiftSendType.Active</p>
|
||||
<p>Combo: 12 -> comboState = GiftSendType.Finished</p>
|
||||
<p>
|
||||
Remember if comboState is Finished both TikTokGiftComboEvent and TikTokGiftEvent event gets triggered
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onGiftCombo((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onLiveEnded [TikTokLiveEndedEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokLiveEndedEvent.java)
|
||||
|
||||
|
||||
Triggered when the live stream gets terminated by the host. Will also trigger the TikTokDisconnectedEvent event.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onLiveEnded((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onQuestion [TikTokQuestionEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokQuestionEvent.java)
|
||||
|
||||
|
||||
Triggered every time someone asks a new question via the question feature.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onQuestion((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onShare [TikTokShareEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/social/TikTokShareEvent.java)
|
||||
|
||||
|
||||
Triggers when a user shares the stream. Based on social event.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onShare((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onLiveUnpaused [TikTokLiveUnpausedEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokLiveUnpausedEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onLiveUnpaused((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onEmote [TikTokEmoteEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokEmoteEvent.java)
|
||||
|
||||
|
||||
Triggered every time a subscriber sends an emote (sticker).
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onEmote((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onJoin [TikTokJoinEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/social/TikTokJoinEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onJoin((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onLike [TikTokLikeEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/social/TikTokLikeEvent.java)
|
||||
|
||||
|
||||
Triggered when a viewer sends likes to the streamer. For streams with many viewers, this event is not always triggered by TikTok.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onLike((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onLivePaused [TikTokLivePausedEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokLivePausedEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onLivePaused((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onWebsocketResponse [TikTokWebsocketResponseEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/websocket/TikTokWebsocketResponseEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onWebsocketUnhandledMessage [TikTokWebsocketUnhandledMessageEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/websocket/TikTokWebsocketUnhandledMessageEvent.java)
|
||||
|
||||
|
||||
Triggered every time a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onWebsocketUnhandledMessage((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onHttpResponse [TikTokHttpResponseEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/http/TikTokHttpResponseEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onHttpResponse((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## onWebsocketMessage [TikTokWebsocketMessageEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/websocket/TikTokWebsocketMessageEvent.java)
|
||||
|
||||
|
||||
Triggered every time TikTok sends data. Data incoming as protobuf message.
|
||||
You can deserialize the binary object depending on the use case.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onWebsocketMessage((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{for item of data }}
|
||||
|
||||
{{if item is 2}}
|
||||
|
||||
my name is {{item.name}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
<br>
|
||||
|
||||
## Listeners
|
||||
|
||||
```java
|
||||
|
||||
/**
|
||||
*
|
||||
* Listeners are an alternative way of handling events.
|
||||
* I would to suggest to use then when logic of handing event
|
||||
* is more complex
|
||||
*
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
showLogo();
|
||||
CustomListener customListener = new CustomListener();
|
||||
|
||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
||||
.addListener(customListener)
|
||||
.buildAndConnect();
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method in TikTokEventListener should meet 4 requirements to be detected
|
||||
* - must have @TikTokEventObserver annotation
|
||||
* - must have 2 parameters
|
||||
* - first parameter must be LiveClient
|
||||
* - second must be class that extending TikTokEvent
|
||||
*/
|
||||
|
||||
public static class CustomListener implements TikTokEventListener {
|
||||
|
||||
@TikTokEventObserver
|
||||
public void onLike(LiveClient liveClient, TikTokLikeEvent event) {
|
||||
System.out.println(event.toString());
|
||||
}
|
||||
|
||||
@TikTokEventObserver
|
||||
public void onError(LiveClient liveClient, TikTokErrorEvent event) {
|
||||
// event.getException().printStackTrace();
|
||||
}
|
||||
|
||||
@TikTokEventObserver
|
||||
public void onComment(LiveClient liveClient, TikTokCommentEvent event) {
|
||||
var userName = event.getUser().getName();
|
||||
var text = event.getText();
|
||||
liveClient.getLogger().info(userName + ": " + text);
|
||||
}
|
||||
|
||||
@TikTokEventObserver
|
||||
public void onGift(LiveClient liveClient, TikTokGiftEvent event) {
|
||||
var message = switch (event.getGift()) {
|
||||
case ROSE -> "Thanks :)";
|
||||
case APPETIZERS -> ":OO";
|
||||
case APRIL -> ":D";
|
||||
case TIKTOK -> ":P";
|
||||
case CAP -> ":F";
|
||||
default -> ":I";
|
||||
};
|
||||
liveClient.getLogger().info(message);
|
||||
}
|
||||
|
||||
@TikTokEventObserver
|
||||
public void onAnyEvent(LiveClient liveClient, TikTokEvent event) {
|
||||
liveClient.getLogger().info(event.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
```
|
||||
|
||||
|
||||
## 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>.
|
||||
70
tools-readme/src/main/resources/readme-template.html
Normal file
70
tools-readme/src/main/resources/readme-template.html
Normal file
@@ -0,0 +1,70 @@
|
||||
<container>
|
||||
<image width="15%"
|
||||
image="https://raw.githubusercontent.com/jwdeveloper/DepenDance/master/Tools-Readme/src/main/resources/logo.svg">
|
||||
</image>
|
||||
</container>
|
||||
|
||||
<container>
|
||||
<title>TikTok Live Java</title>
|
||||
<br>
|
||||
<i align="center">*❤️❤️🎁 *Connect to TikTok live in 3 lines* 🎁❤️❤️*</i>
|
||||
<br>
|
||||
<container>
|
||||
<image width="20%" image="https://jitpack.io/v/jwdeveloper/DepenDance.svg"
|
||||
open="https://jitpack.io/#jwdeveloper/DepenDance"></image>
|
||||
<image image="https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white"
|
||||
open="https://discord.gg/2hu6fPPeF7"></image>
|
||||
<image image="https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=openjdk&logoColor=white"></image>
|
||||
</container>
|
||||
</container>
|
||||
|
||||
<text>
|
||||
A Java library inspired by [TikTokLive](https://github.com/isaackogan/TikTokLive) and [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp). Use it to receive live stream events such as comments and gifts in realtime from [TikTok LIVE](https://www.tiktok.com/live) by connecting to TikTok's internal WebCast push service.
|
||||
The library includes a wrapper that connects to the WebCast service using just the username (`uniqueId`). This allows you to connect to your own live chat as well as the live chat of other streamers.
|
||||
No credentials are required. Events such as [Members Joining](#member), [Gifts](#gift), [Subscriptions](#subscribe), [Viewers](#roomuser), [Follows](#social), [Shares](#social), [Questions](#questionnew), [Likes](#like) and [Battles](#linkmicbattle) can be tracked.
|
||||
</text>
|
||||
|
||||
<br>
|
||||
<code language="xml">
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependency>
|
||||
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
||||
<artifactId>Client</artifactId>
|
||||
<version>{{version}}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</code>
|
||||
<br>
|
||||
|
||||
|
||||
<text>Lightweight dependency injection container that is both small and performance efficient</text>
|
||||
|
||||
<title>Features</title>
|
||||
<br>
|
||||
<text>- [x] Injecting object via constructor</text>
|
||||
<br>
|
||||
<text>- [x] Method object providers</text>
|
||||
<br>
|
||||
<text>- [x] Class Scanner to avoid manual registration [Scanner](#autoscan)</text>
|
||||
<br>
|
||||
<text>- [x] You need to get [List of objects](#lists) in the constructor, no problem</text>
|
||||
<br>
|
||||
<text>- [x] Create [object instance](#object-instances) by yourself and register it to container!</text>
|
||||
<br>
|
||||
<text>- [x] Object lifetimes [SINGLETON, TRANSIENT] [see](#basic)</text>
|
||||
<br>
|
||||
<text>- [x] [Generic types](#generic-types)</text>
|
||||
<br>
|
||||
<text>- [x] [Many constructors](#manyconstructors)</text>
|
||||
<br>
|
||||
<text>- [x] Highly customizable, adjust container with build in [events](#events) system</text>
|
||||
<br>
|
||||
|
||||
<title>Tutorial</title>
|
||||
|
||||
|
||||
107
tools-readme/src/main/resources/template.md
Normal file
107
tools-readme/src/main/resources/template.md
Normal file
@@ -0,0 +1,107 @@
|
||||
<div align="center" >
|
||||
<a target="blank" >
|
||||
<img src="https://raw.githubusercontent.com/jwdeveloper/TikTokLiveJava/develop-1_0_0/Tools-ReadmeGenerator/src/main/resources/logo.svg" width="15%" >
|
||||
</img>
|
||||
</a>
|
||||
</div>
|
||||
<div align="center" >
|
||||
<h1>TikTok Live Java</h1>
|
||||
|
||||
❤️❤️🎁 *Connect to TikTok live in 3 lines* 🎁❤️❤️
|
||||
|
||||
<div align="center" >
|
||||
<a href="https://jitpack.io/#jwdeveloper/TikTok-Live-Java" target="blank" >
|
||||
<img src="https://jitpack.io/v/jwdeveloper/TikTok-Live-Java.svg" width="20%" >
|
||||
</img>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="https://discord.gg/e2XwPNTBBr" target="blank" >
|
||||
<img src="https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white" >
|
||||
</img>
|
||||
</a>
|
||||
|
||||
<a target="blank" >
|
||||
<img src="https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=openjdk&logoColor=white" >
|
||||
</img>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
# Introduction
|
||||
A Java library inspired by [TikTokLive](https://github.com/isaackogan/TikTokLive) and [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp). Use it to receive live stream events such as comments and gifts in realtime from [TikTok LIVE](https://www.tiktok.com/live) by connecting to TikTok's internal WebCast push service.
|
||||
The library includes a wrapper that connects to the WebCast service using just the username (`uniqueId`). This allows you to connect to your own live chat as well as the live chat of other streamers.
|
||||
No credentials are required. Events such as [Members Joining](#member), [Gifts](#gift), [Subscriptions](#subscribe), [Viewers](#roomuser), [Follows](#social), [Shares](#social), [Questions](#questionnew), [Likes](#like) and [Battles](#linkmicbattle) can be tracked.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://www.youtube.com/watch?v=eerWGgUKc6c" align="right" target="blank"><img src="https://img.youtube.com/vi/eerWGgUKc6c/hqdefault.jpg" alt="IMAGE ALT TEXT" width="38%" align="right"></a>
|
||||
</div>
|
||||
|
||||
Join the support [discord](https://discord.gg/e2XwPNTBBr) and visit the `#java-support` channel for questions, contributions and ideas. Feel free to make pull requests with missing/new features, fixes, etc
|
||||
|
||||
Do you prefer other programming languages?
|
||||
- **Node** orginal: [TikTok-Live-Connector](https://github.com/isaackogan/TikTok-Live-Connector) by [@zerodytrash](https://github.com/zerodytrash)
|
||||
- **Python** rewrite: [TikTokLive](https://github.com/isaackogan/TikTokLive) by [@isaackogan](https://github.com/isaackogan)
|
||||
- **Go** rewrite: [GoTikTokLive](https://github.com/Davincible/gotiktoklive) by [@Davincible](https://github.com/Davincible)
|
||||
- **C#** rewrite: [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp) by [@frankvHoof93](https://github.com/frankvHoof93)
|
||||
|
||||
**NOTE:** This is not an official API. It's a reverse engineering project.
|
||||
|
||||
#### Overview
|
||||
- [Getting started](#getting-started)
|
||||
- [Events](#events)
|
||||
- [Listeners](#listeners)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Install the package via Maven
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
||||
<artifactId>Client</artifactId>
|
||||
<version>{{version}}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
2. Create your first chat connection
|
||||
|
||||
{{code-content}}
|
||||
|
||||
## Events
|
||||
|
||||
|
||||
@{events-content}
|
||||
|
||||
{{for item of data}}
|
||||
|
||||
{{if item is 2}}
|
||||
|
||||
my name is {{item.name}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
<br>
|
||||
|
||||
## Listeners
|
||||
|
||||
```java
|
||||
{{listener-content}}
|
||||
```
|
||||
|
||||
## 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>.
|
||||
Reference in New Issue
Block a user