-
-
Notifications
You must be signed in to change notification settings - Fork 33
Creating custom Events and message mapping
If you manage your own event and you think it will add value to TikTokJava
community
I really encourge you to contribute and merge your code to library :)
Nomencrature
-
Message
is packet of data send by Tiktok in protocol buffer format, for exampleWebcastGiftMessage
-
Event
is object created by TikTokLiveJava, for exampleTikTokGiftEvent
First step is to understand incoming data from TikTok. It is send as bytes that are later parsed to protocol buffer classes.
Library use TikTokLiveJava/API/src/main/proto/webcast.proto file that defines Messages
structure, and generate java classes
All incoming messages from TikTok have Webcast
prefix, For example WebcastGiftMessage
Remeber that webcast.proto file is not always up to data with TikTok so you might not found some messages
Run this code and wait unitl your desire message will be display. For example If we want to know what is the message name when someone sends chat message, just
- Run this code
- Open TikTok in browser, sends message to chat
- Look at the program console what message name was displayd
- you should see
Current message is WebcastChatMessage
TikTokLive.newClient("test")
.onWebsocketResponse((liveClient, event) ->
{
var messages =event.getResponse().getMessagesList();
for(var message: messages)
{
var name = message.getMethod();
System.out.printLine("Current message is "+name);
}
}).buildAndConnect();
Now we know that message name is WebcastChatMessage
and we want to map it to our new event
To doing so we can use onMapping
method that provides mappings utilitis
In the best scenario protocol buffer class is already generated for our message
so we can use mapper.webcastObjectToEvent()
- That takes class of message as first parameter
- Lambda function with message object as input and event object as output
TikTokLive.newClient("test")
.onMapping(mapper ->
{
mapper.forMessage(WebcastChatMessage.class)
.onMapping((inputBytes, messageName, mapperHelper) ->
{
System.out.println("onMapping mapping: " + messageName);
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastChatMessage.class);
var language = chatMessage.getContentLanguage();
var userName = chatMessage.getUser().getNickname();
var content= chatMessage.getContent();
var event = new CustomChatEvent(language, userName, content);
return MappingResult.of(message, event);
})
}).buildAndConnect();
What if you really want to listen for WebcastBottomMessage
message but is not defined in proto
file?
You can use mapper.bytesToEvent()
that takes as input bytes of selected message
then with
ProtocolUtils.getProtocolBufferStructure(bytes);
you can create structer of message
and display it to console so you will see how does it looks like
mapper.forMessage("WebcastMemberMessage")
.onBeforeMapping((inputBytes, messageName, mapperHelper) ->
{
if (mapperHelper.isMessageHasProtoClass(messageName)) {
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, messageName);
// System.out.println(mapperHelper.toJson(messageObject));
} else {
var structure = mapperHelper.bytesToProtoBufferStructure(inputBytes);
// System.out.println(structure.toJson());
}
return inputBytes;
});
Lets create custom event, it need to extends TikTokEvent
@Data
public class CustomChatEvent extends TikTokEvent {
private final String langauge;
private final String userName;
private final String message;
public CustomChatEvent(String language, String userName, String message) {
this.langauge = language;
this.userName = userName;
this.message = message;
}
}
Use .onCustomEvent
in order to register your event to library and its handler
and make onMapping
that will returns your event object for some tiktok message
public static void main(String[] args) {
TikTokLive.newClient("test")
.onEvent(CustomChatEvent.class, (liveClient, event) ->
{
System.out.println("hello world!");
})
.onMapping(mapper ->
{
mapper.forMessage("WebcastMemberMessage")
.onMapping((inputBytes, messageName, mapperHelper) ->
{
System.out.println("onMapping mapping: " + messageName);
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastChatMessage.class);
var language = message.getContentLanguage();
var userName = message.getUser().getNickname();
var content = message.getContent();
var event = new CustomChatEvent(language, userName, content);
return MappingResult.of(message, event);
})
}).buildAndConnect();
}