mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 16:59:39 -05:00
Compare commits
13 Commits
1.0.4-Rele
...
develop-1-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3832db111e | ||
|
|
46d5f15d3f | ||
|
|
e3e0d8a88e | ||
|
|
e0136d0f3b | ||
|
|
dd5ccbfb7f | ||
|
|
110a4fab4c | ||
|
|
69a2a6a338 | ||
|
|
530551763c | ||
|
|
ca1827853a | ||
|
|
ea8c740faa | ||
|
|
1977cbe8dc | ||
|
|
c3a48c4d70 | ||
|
|
2c51844fd9 |
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>API</artifactId>
|
||||
|
||||
@@ -52,11 +52,6 @@ public class ClientSettings {
|
||||
*/
|
||||
private Duration retryConnectionTimeout;
|
||||
|
||||
/**
|
||||
* Whether to handle Events received from Room when Connecting
|
||||
*/
|
||||
private boolean handleExistingEvents;
|
||||
|
||||
/**
|
||||
* Whether to print Logs to Console
|
||||
*/
|
||||
|
||||
@@ -57,7 +57,6 @@ public class Constants {
|
||||
var clientSettings = new ClientSettings();
|
||||
clientSettings.setTimeout(Duration.ofSeconds(DEFAULT_TIMEOUT));
|
||||
clientSettings.setClientLanguage("en-US");
|
||||
clientSettings.setHandleExistingEvents(true);
|
||||
clientSettings.setRetryOnConnectionFailure(false);
|
||||
clientSettings.setRetryConnectionTimeout(Duration.ofSeconds(1));
|
||||
clientSettings.setPrintToConsole(false);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.data.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Value;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MessageMetaData
|
||||
{
|
||||
private Duration handlingTime;
|
||||
}
|
||||
@@ -20,41 +20,24 @@
|
||||
* 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.utils;
|
||||
package io.github.jwdeveloper.tiktok.data.dto;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
public class CancelationToken
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class TikTokUserInfo
|
||||
{
|
||||
private boolean isCanceled =false;
|
||||
UserStatus userStatus;
|
||||
|
||||
public void cancel()
|
||||
String roomId;
|
||||
|
||||
public enum UserStatus
|
||||
{
|
||||
isCanceled =true;
|
||||
}
|
||||
|
||||
public boolean isCancel()
|
||||
{
|
||||
|
||||
return isCanceled;
|
||||
}
|
||||
|
||||
public void throwIfCancel()
|
||||
{
|
||||
if(!isCanceled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw new TikTokLiveException("Token requested cancelation");
|
||||
}
|
||||
|
||||
public boolean isNotCancel()
|
||||
{
|
||||
return !isCancel();
|
||||
}
|
||||
|
||||
public static CancelationToken create()
|
||||
{
|
||||
return new CancelationToken();
|
||||
NotFound,
|
||||
Offline,
|
||||
LivePaused,
|
||||
Live
|
||||
}
|
||||
}
|
||||
@@ -20,48 +20,24 @@
|
||||
* 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.data.events.room;
|
||||
package io.github.jwdeveloper.tiktok.data.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.UserAttribute;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.RoomMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLiveIntroMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastRoomMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSystemMessage;
|
||||
import lombok.Getter;
|
||||
import lombok.Data;
|
||||
|
||||
@Getter
|
||||
|
||||
@Data
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokRoomEvent extends TikTokHeaderEvent
|
||||
{
|
||||
private User hostUser;
|
||||
private String hostLanguage;
|
||||
private final String welcomeMessage;
|
||||
public class CustomEvent extends TikTokHeaderEvent {
|
||||
private final User user;
|
||||
private final String title;
|
||||
|
||||
public TikTokRoomEvent(WebcastRoomMessage msg) {
|
||||
super(msg.getCommon());
|
||||
welcomeMessage = msg.getContent();
|
||||
public CustomEvent(User user, String title) {
|
||||
this.user = user;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public TikTokRoomEvent(RoomMessage msg) {
|
||||
super(msg.getCommon());
|
||||
welcomeMessage = msg.getContent();
|
||||
}
|
||||
|
||||
public TikTokRoomEvent(WebcastSystemMessage msg) {
|
||||
super(msg.getCommon());
|
||||
welcomeMessage = msg.getMessage();
|
||||
}
|
||||
|
||||
public TikTokRoomEvent(WebcastLiveIntroMessage msg) {
|
||||
super(msg.getCommon());
|
||||
hostUser = User.map(msg.getHost());
|
||||
hostUser.addAttribute(UserAttribute.LiveHost);
|
||||
welcomeMessage = msg.getContent();
|
||||
hostLanguage = msg.getLanguage();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,18 +34,10 @@ import java.util.List;
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokLinkEvent extends TikTokHeaderEvent {
|
||||
private final String token;
|
||||
|
||||
private User user;
|
||||
|
||||
private final List<User> otherUsers;
|
||||
|
||||
public TikTokLinkEvent(WebcastLinkMessage msg) {
|
||||
super(msg.getCommon());
|
||||
token = msg.getToken();
|
||||
if (msg.getUser().getUser().hasUser()) {
|
||||
user = new User(msg.getUser().getUser().getUser());
|
||||
}
|
||||
otherUsers = msg.getUser().getOtherUsersList().stream().map(e -> new User(e.getUser())).toList();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.data.events;
|
||||
|
||||
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.Message)
|
||||
public class TikTokLiveUnpausedEvent extends TikTokEvent {
|
||||
}
|
||||
@@ -26,7 +26,9 @@ import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.UserAttribute;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastMemberMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSubNotifyMessage;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
@@ -34,16 +36,20 @@ import lombok.Getter;
|
||||
*/
|
||||
@Getter
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokSubscribeEvent extends TikTokHeaderEvent {
|
||||
private User user;
|
||||
public class TikTokSubscribeEvent extends TikTokHeaderEvent
|
||||
{
|
||||
private final User user;
|
||||
|
||||
public TikTokSubscribeEvent(WebcastMemberMessage msg) {
|
||||
super(msg.getCommon());
|
||||
|
||||
if(msg.hasUser())
|
||||
{
|
||||
user = new User(msg.getUser());
|
||||
public TikTokSubscribeEvent(WebcastMemberMessage msg) {
|
||||
super(msg.getCommon());
|
||||
user = User.map(msg.getUser());
|
||||
user.addAttribute(UserAttribute.Subscriber);
|
||||
}
|
||||
|
||||
public TikTokSubscribeEvent(WebcastSubNotifyMessage msg) {
|
||||
super(msg.getCommon());
|
||||
user = User.map(msg.getUser());
|
||||
user.addAttribute(UserAttribute.Subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,32 +24,19 @@ package io.github.jwdeveloper.tiktok.data.events.room;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.RankingUser;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastRoomUserSeqMessage;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Triggered when LiveRoomInfo got updated such as likes, viewers, ranking ....
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@EventMeta(eventType = EventType.Message)
|
||||
public class TikTokRoomUserInfoEvent extends TikTokHeaderEvent {
|
||||
private final int totalUsers;
|
||||
|
||||
/**
|
||||
* Only top 5 users in ranking has detailed data
|
||||
* rest has only ID
|
||||
*/
|
||||
private final List<RankingUser> usersRanking;
|
||||
public TikTokRoomUserInfoEvent(WebcastRoomUserSeqMessage msg) {
|
||||
super(msg.getCommon());
|
||||
totalUsers = msg.getTotalUser();
|
||||
usersRanking = msg.getRanksListList().stream().map(RankingUser::new)
|
||||
.sorted((ru1, ru2) -> Integer.compare(ru2.getScore(), ru1.getScore()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public class TikTokRoomInfoEvent extends TikTokEvent
|
||||
{
|
||||
LiveRoomInfo roomInfo;
|
||||
}
|
||||
@@ -24,7 +24,9 @@ package io.github.jwdeveloper.tiktok.data.events.websocket;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||
import io.github.jwdeveloper.tiktok.data.dto.MessageMetaData;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@@ -34,22 +36,32 @@ import java.time.Duration;
|
||||
|
||||
|
||||
/**
|
||||
* Triggered every time a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case.
|
||||
* Triggered every time TikTok sends data. Data incoming as protobuf message.
|
||||
* You can deserialize the binary object depending on the use case.
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@EventMeta(eventType = EventType.Debug)
|
||||
public class TikTokWebsocketMessageEvent extends TikTokEvent
|
||||
{
|
||||
private TikTokEvent event;
|
||||
public class TikTokWebsocketMessageEvent extends TikTokEvent {
|
||||
|
||||
/*
|
||||
* Original message that is coming from TikTok
|
||||
* message.method - Name of message type, for example "WebcastGiftMessage"
|
||||
* message.payload - Bytes array that contains actual data of message.
|
||||
* Example of parsing, WebcastGiftMessage giftMessage = WebcastGiftMessage.parseFrom(message.getPayload());
|
||||
*/
|
||||
private WebcastResponse.Message message;
|
||||
|
||||
private MetaData metaData;
|
||||
/*
|
||||
* TikTokLiveJava event that was created from TikTok message data
|
||||
* Example: TikTokGiftEvent
|
||||
*/
|
||||
private TikTokEvent event;
|
||||
|
||||
/*
|
||||
* Metadata information about mapping message to event, such as time and stuff
|
||||
*/
|
||||
private MessageMetaData metaData;
|
||||
|
||||
|
||||
@Value
|
||||
public static class MetaData
|
||||
{
|
||||
Duration handlingTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,9 @@ public class TikTokWebsocketUnhandledMessageEvent extends TikTokUnhandledEvent<W
|
||||
public TikTokWebsocketUnhandledMessageEvent(WebcastResponse.Message data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
public WebcastResponse.Message getMessage()
|
||||
{
|
||||
return this.getData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.data.models.chest;
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
// This enum is generated
|
||||
package io.github.jwdeveloper.tiktok.data.models.gifts;
|
||||
|
||||
@@ -33,6 +55,8 @@ public enum Gift {
|
||||
|
||||
PANTHER_PAWS_8358(8358, "Panther Paws", 199, "https://storage.streamdps.com/iblock/a25/a25d2409e1d851566987913c9fb9860f/6aeb9164cf39e2602933d28dbd106119.webp"),
|
||||
|
||||
GOLDEN_PARTY(9499, "Golden Party", 3000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/a00450f3e3aa1f01b62774950e5729c3.png~tplv-obj.jpg"),
|
||||
|
||||
SHOOTING_STARS(5753, "Shooting Stars", 1580, "https://storage.streamdps.com/iblock/b36/b36bb8c332ade25b2e591cd3ed164a99/a06c10f4dc562c24f4f5b6812b9fa01f.png"),
|
||||
|
||||
LION(6369, "Lion", 29999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/4fb89af2082a290b37d704e20f4fe729~tplv-obj.jpg"),
|
||||
@@ -47,6 +71,8 @@ public enum Gift {
|
||||
|
||||
MAKE_UP_BOX(6033, "Make-up Box", 1999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/a29aa87203ec09c699e3dafa1944b23e~tplv-obj.jpg"),
|
||||
|
||||
PLAY_SAMBA(5793, "Play Samba", 99, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/fd3d6cc127464bacded6ed009074ae2f~tplv-obj.png"),
|
||||
|
||||
LITTLE_CROWN(6097, "Little Crown", 99, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/cf3db11b94a975417043b53401d0afe1~tplv-obj.jpg"),
|
||||
|
||||
RUBY_RED(8434, "Ruby red", 88, "https://storage.streamdps.com/iblock/405/405fcf52a1de3d14ab9834c1f30cc330/0deed9ee2c79ba6bf2005b0ce667bf60.webp"),
|
||||
@@ -155,6 +181,8 @@ public enum Gift {
|
||||
|
||||
COWBOY_HAT(8842, "Cowboy Hat", 199, "https://storage.streamdps.com/iblock/5f3/5f3df5eccbc82f458fdacd0f82d13e40/40980853c80e3da0e902a1db49ea9798.webp"),
|
||||
|
||||
FESTA_JUNINA_S_HAT(8638, "Festa Junina's Hat", 199, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/61b32ccce11b289b3c1db7438dfb4450~tplv-obj.png"),
|
||||
|
||||
SPORTS_CAR(6089, "Sports Car", 7000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/e7ce188da898772f18aaffe49a7bd7db~tplv-obj.jpg"),
|
||||
|
||||
ICE_TEA(5464, "Ice Tea", 1, "https://storage.streamdps.com/iblock/531/5313a4ca89a7c7588a88898c8f1e9053/dab85392562772099474a050c251d340.png"),
|
||||
@@ -199,6 +227,8 @@ public enum Gift {
|
||||
|
||||
GIFT_BOX_6835(6835, "Gift Box", 3999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/3646c259f8ce6f79c762ad00ce51dda0~tplv-obj.jpg"),
|
||||
|
||||
FISHING_GEAR(5956, "Fishing Gear", 199, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/1b2353958374f585e25b2f2344c6d0ad~tplv-obj.png"),
|
||||
|
||||
ARCADE_GAME(5876, "Arcade Game", 1200, "https://storage.streamdps.com/iblock/d5a/d5aaa3c8ef3d271c2f93709c3ff51e67/721d870d5a5d9d82d726ff5a9ba3aa5e.png"),
|
||||
|
||||
ARCADE_GAME_7041(7041, "Arcade Game", 1200, "https://storage.streamdps.com/iblock/fd0/fd0785612b024900444a0a69083400ff/3181d6af50b05dd65a7ba75902bb5b94.webp"),
|
||||
@@ -217,6 +247,10 @@ public enum Gift {
|
||||
|
||||
GAMEPAD(6052, "Gamepad", 10, "https://storage.streamdps.com/iblock/711/711b578c104edcf1639ff4e2e7779660/6cbb6613fbbd40dac6dfd8857b05545a.png"),
|
||||
|
||||
LIVE_FEST_CLAPPERS(9333, "LIVE Fest Clappers", 100, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/63e85e00169ec5be3bfa90bb004cda5e.png~tplv-obj.png"),
|
||||
|
||||
RAINBOW(8616, "Rainbow", 1, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5fb7267489192fc77c4c8b647c124680~tplv-obj.png"),
|
||||
|
||||
ORANGE_JUICE(5778, "Orange Juice", 1, "https://storage.streamdps.com/iblock/3d6/3d635024d8744f8648306d56a5c4f62f/be0f5f006bd2350e904b23b607e4f06b.png"),
|
||||
|
||||
GERRY_THE_GIRAFFE(6842, "Gerry the Giraffe", 1000, "https://storage.streamdps.com/iblock/792/792ef3f53d86b5cb066d5c0bb5b00a87/91aa5cf7f51a533841bea8617419c54d.webp"),
|
||||
@@ -289,7 +323,9 @@ public enum Gift {
|
||||
|
||||
SAKURA_TRAIN(6244, "Sakura Train", 3999, "https://storage.streamdps.com/iblock/a8e/a8e50d5c5d0eaa42bd71dbeca3b1b95a/204910c857958e7e9efd0178d30a2fbe.png"),
|
||||
|
||||
AUTUMN_LEAVES(6967, "Autumn Leaves", 500, "https://storage.streamdps.com/iblock/f04/f042339687e8abaa2fc0e1976d9b11f4/251a0624bc3a23ba39d75467868dcbf8.webp"),
|
||||
AUTUMN_LEAVES(5890, "Autumn leaves", 500, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/30adcaf443df63e3bfd2751ad251f87d~tplv-obj.png"),
|
||||
|
||||
FRANGIPANI(5992, "Frangipani", 1, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7464fad59650123fe0989e426618847d~tplv-obj.png"),
|
||||
|
||||
SKI_GOGGLES(7781, "Ski Goggles", 199, "https://storage.streamdps.com/iblock/f42/f42cbce436db4e60adbf85641a768a12/fa9a4cea3c23829cf6f0725fea8d3c1a.webp"),
|
||||
|
||||
@@ -329,6 +365,8 @@ public enum Gift {
|
||||
|
||||
RABBIT(6348, "Rabbit", 1999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/61b42d630091b661e82fc8ed400b1de2~tplv-obj.jpg"),
|
||||
|
||||
ASMR(6240, "ASMR", 10, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/748e74c8309e08dbc5b03e03f28a0ea0~tplv-obj.png"),
|
||||
|
||||
ROSE(5655, "Rose", 1, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/eba3a9bb85c33e017f3648eaf88d7189~tplv-obj.jpg"),
|
||||
|
||||
TRENDING_FIGURE(9138, "Trending Figure", 999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/df7b556ccf369bf9a42fe83ec8a77acf.png~tplv-obj.jpg"),
|
||||
@@ -349,6 +387,8 @@ public enum Gift {
|
||||
|
||||
FLAME_HEART(9087, "Flame heart", 1, "https://storage.streamdps.com/iblock/10d/10df10624cdeebe8ff5e0e89e8c8e960/28b8da2878a420f8465cbbc1ec1e6b58.webp"),
|
||||
|
||||
FAIRY_BREAD(5823, "Fairy Bread", 1, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a42f9ac9cd6b26da03818ff65ac919f1~tplv-obj.png"),
|
||||
|
||||
TIKTOK_SHUTTLE(6751, "TikTok Shuttle", 20000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/8ef48feba8dd293a75ae9d4376fb17c9~tplv-obj.jpg"),
|
||||
|
||||
MAGGIE(7911, "Maggie", 15000, "https://storage.streamdps.com/iblock/a12/a12a1b23f1f6a19d728de84e1f43e21d/ff288346e9855a9bb6deb4450491028f.webp"),
|
||||
@@ -361,10 +401,14 @@ public enum Gift {
|
||||
|
||||
GAMER_CYBER_MASK(7895, "Gamer Cyber Mask", 399, "https://storage.streamdps.com/iblock/383/383652cc1fd3cae9402eeae3a8f5ee1e/df8a16397bb0ed28c0e522b4cfb26500.webp"),
|
||||
|
||||
HAPPY_FATHER_S_DAY(8712, "Happy Father's Day", 1, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/193eba78ded4d388a0b5a7ae95943796~tplv-obj.png"),
|
||||
|
||||
KO(7542, "KO", 20, "https://storage.streamdps.com/iblock/e5e/e5efb63a21695a08d9647508aca3c95e/cffda8af4cc1a9f4a66eb01b11f4db85.webp"),
|
||||
|
||||
KO_7655(7655, "KO", 20, "https://storage.streamdps.com/iblock/aa6/aa613e765fe5c42519bd83d2d4705118/7db90e1f83b8c87c74dfdc8ee88440cb.webp"),
|
||||
|
||||
MAGIC_FOREST(9135, "Magic Forest", 6000, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/63a758dbef9788f690e97cd65dbbb8d2~tplv-obj.png"),
|
||||
|
||||
LEON_AND_LILI(8916, "Leon and Lili", 9699, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/6958244f3eeb69ce754f735b5833a4aa.png~tplv-obj.jpg"),
|
||||
|
||||
MAGIC_STAGE(6263, "Magic Stage", 2599, "https://storage.streamdps.com/iblock/399/399df717aefef9de9259e8256221076f/dfa2835c35b2177701ee65139bdfc59a.png"),
|
||||
@@ -383,6 +427,8 @@ public enum Gift {
|
||||
|
||||
PAIMON_SURPRISE(8299, "Paimon Surprise", 1299, "https://storage.streamdps.com/iblock/ffc/ffc784ca54363f5d1d0c195419a3c19b/27096967caade6f066ce748bf5327244.webp"),
|
||||
|
||||
GOOD_EVENING(8267, "Good Evening", 399, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/0015a756ff783f37a2cf3b5d634b3cd6~tplv-obj.png"),
|
||||
|
||||
HI_MAY(6471, "Hi May", 88, "https://storage.streamdps.com/iblock/970/970b0a868ce24c4b7b7059a904fa7b00/622d597d3cec282d6d2c8129fedd5075.png"),
|
||||
|
||||
WEDDING(6286, "Wedding", 1400, "https://storage.streamdps.com/iblock/7be/7beeb7f1098cf5f784739a0be38a06f8/0678483823c912e4dea96fa19a2f0d86.png"),
|
||||
@@ -405,6 +451,8 @@ public enum Gift {
|
||||
|
||||
MUSIC_NOTE(5915, "Music Note", 169, "https://storage.streamdps.com/iblock/cc1/cc17f136f458a86943d7fd503c0a34b4/c56797b8b830d159f31fe5ca5527f586.png"),
|
||||
|
||||
FLOWER_SHOW(5831, "Flower Show", 500, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b6266323ef3ea0d313cbab6911ff8c46~tplv-obj.png"),
|
||||
|
||||
MAXWELL(8189, "Maxwell", 10, "https://storage.streamdps.com/iblock/82b/82b7041dcdd8fcc1842c0dd7b5a63099/73736d5ec979ad00f4b771397d9b998b.webp"),
|
||||
|
||||
LOVE_DROP(8277, "Love Drop", 1800, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/1ea684b3104abb725491a509022f7c02~tplv-obj.jpg"),
|
||||
@@ -413,6 +461,8 @@ public enum Gift {
|
||||
|
||||
YACHT(6103, "Yacht", 9888, "https://storage.streamdps.com/iblock/b6c/b6c9d3c6df6733cc85149897764d2c6b/023d358a3d7a7a330ed006eb07117582.png"),
|
||||
|
||||
YACHT_9501(9501, "Yacht", 20000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/e69e2626f6ff43d1c1f2b8ae5ea42514.png~tplv-obj.jpg"),
|
||||
|
||||
WINDOW_BASKET(8648, "Window basket", 500, "https://storage.streamdps.com/iblock/a8d/a8d0c44c86385d4cd02ad2d840dcb148/8bbdca8666946a2e7172b3eaeed02303.webp"),
|
||||
|
||||
SWAN(5897, "Swan", 699, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/97a26919dbf6afe262c97e22a83f4bf1~tplv-obj.jpg"),
|
||||
@@ -427,6 +477,8 @@ public enum Gift {
|
||||
|
||||
SCORPIO_STAR_SIGN(7159, "Scorpio Star Sign", 9999, "https://storage.streamdps.com/iblock/c91/c91f3a3685b5c54d9e96d5f9443c4fda/50c48574ff60f328b7a50b80cd9aa4b8.webp"),
|
||||
|
||||
SOCCER_BALL(5852, "Soccer Ball", 39, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e1932db6aea81bbddc4e7dc0229ac155~tplv-obj.png"),
|
||||
|
||||
GAME_CONTROLLER(6467, "Game Controller", 100, "https://storage.streamdps.com/iblock/603/6032c1b0d5c2c07abe04956b3cdd45cd/d75d75a7e81f96f39d2ffd574063924f.png"),
|
||||
|
||||
GAME_CONTROLLER_6960(6960, "Game Controller", 100, "https://storage.streamdps.com/iblock/030/030f63329d68d21c5faacab88006a17f/fbb8dd78b47184321d93e3ae5a1f2cca.webp"),
|
||||
@@ -435,6 +487,8 @@ public enum Gift {
|
||||
|
||||
HANGING_LIGHTS(5937, "Hanging Lights", 199, "https://storage.streamdps.com/iblock/e03/e03da22fa8c302dbf1d9439c65380549/6d9f912b5a9253f91c01ed58e3ccbe47.png"),
|
||||
|
||||
FOOTY(5893, "Footy", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/94f8ac5c7b6f90aba713b44ddac40bf1~tplv-obj.png"),
|
||||
|
||||
BATIK_CLOTHES(5461, "Batik Clothes", 1000, "https://storage.streamdps.com/iblock/46d/46d0f497391a934d27d9b993f444d8b2/121af719b172eed61d8a75c1b1341c9d.png"),
|
||||
|
||||
DANCING_QUEENS(9240, "Dancing queens", 20000, "https://storage.streamdps.com/iblock/c79/c793af446369ecef5238e73312c84ccd/464a76f3e6eaee9afc771f45a4bba9df.webp"),
|
||||
@@ -481,20 +535,30 @@ public enum Gift {
|
||||
|
||||
FOUNTAIN(8887, "Fountain", 1200, "https://storage.streamdps.com/iblock/07d/07d678346c7eb588bc3cbddf343ab791/8f8f50f5350e4b1c0b151aff333e43a4.webp"),
|
||||
|
||||
KOALA(5822, "Koala", 10, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/22c8fa54da366c111f7bb915d4429e2d~tplv-obj.png"),
|
||||
|
||||
GARLAND_HEADPIECE(6437, "Garland Headpiece", 199, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/bdbdd8aeb2b69c173a3ef666e63310f3~tplv-obj.jpg"),
|
||||
|
||||
AEROBIC_HEADBAND(9255, "Aerobic headband", 99, "https://storage.streamdps.com/iblock/3d9/3d98c2fbc96922da37a9d22881bb06b9/0a99af132ab8e3fe9806d2412abc6bf0.webp"),
|
||||
|
||||
MOUNTAINS(9516, "Mountains", 12000, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/51a7d74bcb4a6417be59f0ffc0b77e96.png~tplv-obj.png"),
|
||||
|
||||
FULL_MOON(7222, "Full moon", 299, "https://storage.streamdps.com/iblock/e64/e64dd135280596ce7f1aebbdc3e33a80/494b818b6a4217f1807255ca148c7b2d.webp"),
|
||||
|
||||
CHEEMS_DOG(6486, "Cheems Dog", 199, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/d2c9e50efa3b9ff1ed31c96440a9d3a1~tplv-obj.png"),
|
||||
|
||||
CAT_PAWS(6046, "Cat Paws", 1, "https://storage.streamdps.com/iblock/c04/c04061e18b637df6759417bfe5418c9c/89bc2c5278f4a3c28acebdd10f6bc089.webp"),
|
||||
|
||||
WAVING_HAND(5959, "Waving Hand", 7, "https://storage.streamdps.com/iblock/6da/6da44060164719c3bcb171fb06d6d0d4/a80d1fa6879b0970246f41c444dca47c.webp"),
|
||||
|
||||
FRUITS_HAT_(6744, "Fruits Hat ", 199, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2316b31fc5259cc29f281d88fbca0568~tplv-obj.png"),
|
||||
|
||||
BUBBLES(5850, "Bubbles", 500, "https://storage.streamdps.com/iblock/4b1/4b1a012395fd18f6ed835539089dd3c3/98688050698f0180bdd46018a4e98ec1.png"),
|
||||
|
||||
SILVER_SPORTS_CAR(8433, "Silver sports car", 5000, "https://storage.streamdps.com/iblock/132/132eb0981780e3e268f844106037b277/a1afff85fc6c53482fccbea21709d36b.webp"),
|
||||
|
||||
LIGHTNING_STORM(9515, "Lightning Storm", 6000, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/6f673fbb0ae6860e2b1e254538c958ba.png~tplv-obj.png"),
|
||||
|
||||
RACCOON(8448, "Raccoon", 15, "https://storage.streamdps.com/iblock/539/5396582d174489f32525f871cb3087f8/041896a3554f3d4b8c86f486bc81b125.webp"),
|
||||
|
||||
HEART_ME(7934, "Heart Me", 1, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/d56945782445b0b8c8658ed44f894c7b~tplv-obj.jpg"),
|
||||
@@ -503,6 +567,8 @@ public enum Gift {
|
||||
|
||||
TIKTOK_TROPHY(7357, "TikTok Trophy", 699, "https://storage.streamdps.com/iblock/7f6/7f6d5df92bf4b5b559567b9a870d485f/1811197db0860ff395435d51d35598ef.webp"),
|
||||
|
||||
LOVE_BOMB(6050, "Love Bomb", 299, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a1c1b14f5e9f7be5d76fa4928f574f1~tplv-obj.png"),
|
||||
|
||||
TENNIS(6169, "Tennis", 1, "https://storage.streamdps.com/iblock/f20/f20121609887f7ff35952c1bc52529e2/9ff66229b1f81d21b15444ba2b53db98.png"),
|
||||
|
||||
NECKLACE(5662, "Necklace", 400, "https://storage.streamdps.com/iblock/a40/a40013bbd1e38e11c0772f8b605c6c25/567d58bd02385de4af1523980cb03a85.png"),
|
||||
@@ -515,6 +581,8 @@ public enum Gift {
|
||||
|
||||
BIRTHDAY_CAKE_9097(9097, "Birthday Cake", 1, "https://storage.streamdps.com/iblock/5b9/5b9eca4a99e965cb25183681a07a5276/c28f7e9c4a8e42460225ff2d12300ae7.webp"),
|
||||
|
||||
BANANA_LEAF_VESSEL(5991, "Banana leaf vessel", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8e635863e20cfa3651bd8a5b762ae72d~tplv-obj.png"),
|
||||
|
||||
ICE_LOLLY(6545, "Ice Lolly", 10, "https://storage.streamdps.com/iblock/93d/93dda2498d64aa0a29d444103a7804dd/92fd7397fffbaa8755cb233815964bbf.png"),
|
||||
|
||||
CONFETTI(5585, "Confetti", 100, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/cb4e11b3834e149f08e1cdcc93870b26~tplv-obj.jpg"),
|
||||
@@ -547,6 +615,8 @@ public enum Gift {
|
||||
|
||||
CELEBRATION_TIME(6790, "Celebration Time", 6999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/e73e786041d8218d8e9dbbc150855f1b~tplv-obj.jpg"),
|
||||
|
||||
EXCLUSIVE_YACHT(9524, "Exclusive Yacht", 20000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/da8c85d5ae09ebf320216202e8fa015d.png~tplv-obj.jpg"),
|
||||
|
||||
MONTY(7742, "Monty", 1, "https://storage.streamdps.com/iblock/c70/c70e3a9404b18068056d04d5394d739a/4e0e55d9d10a7747b7caf462cd87b4b3.webp"),
|
||||
|
||||
PYRAMIDS(8416, "Pyramids", 15000, "https://storage.streamdps.com/iblock/988/988ffe82e8f3b235bd91dac1e31e708d/ad0365d14ba0480e5d6d60f6eb798608.webp"),
|
||||
@@ -585,16 +655,22 @@ public enum Gift {
|
||||
|
||||
SWING(5899, "Swing", 399, "https://storage.streamdps.com/iblock/8a1/8a16a7c5d463793c8c3ab5aa407a87d8/dee86ec9c8e98ebcc58e2e3c09b93d10.png"),
|
||||
|
||||
STORMS_AT_SEA(9514, "Storms at sea", 2200, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/4918fbbdf220873dd8cae4c94d1ae037.png~tplv-obj.png"),
|
||||
|
||||
SUPERHERO_FIGHT(8814, "Superhero fight", 30000, "https://storage.streamdps.com/iblock/d6b/d6b1c955153c8f8c5048d6c8f0d1b418/97d04b889e64328e9ab07224f6072b5f.webp"),
|
||||
|
||||
COOKIE(6883, "Cookie", 5, "https://storage.streamdps.com/iblock/fd2/fd20c8c619b1d43efb9f2fe1923c48a7/45c056f74c9f214dc55d464eab43b224.webp"),
|
||||
|
||||
DOG_BONE(8108, "Dog Bone", 10, "https://storage.streamdps.com/iblock/8ba/8badf8e0a5bcbf8d98ed6c4fc0e16c69/b0a8a8020986eb564713c042d23f83b2.webp"),
|
||||
|
||||
RUSSIAN_CREPES(5547, "Russian Crepes", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8525a07c6bf16a74eee66e9ad119b3b8.png~tplv-obj.png"),
|
||||
|
||||
FLYING_JETS(7482, "Flying Jets", 5000, "https://storage.streamdps.com/iblock/5a4/5a4f3c7adc31f60326e3adf1a3a20bf9/bc96de02ceba4b91c1f9c996293974b4.webp"),
|
||||
|
||||
FLYING_JETS_7720(7720, "Flying Jets", 5000, "https://storage.streamdps.com/iblock/738/73887ee5dc4a63709a10a2e3eff67b7c/1588215b603e2495582288471573cd57.webp"),
|
||||
|
||||
FLYING_JETS_9500(9500, "Flying Jets", 5000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1d067d13988e8754ed6adbebd89b9ee8.png~tplv-obj.jpg"),
|
||||
|
||||
INDOOR_FAN(6565, "Indoor Fan", 199, "https://storage.streamdps.com/iblock/499/499dc6bf36be95e90398a56d18bfeebe/231f634c0c86d034f193477f208f66ca.webp"),
|
||||
|
||||
MIC(5650, "Mic", 5, "https://storage.streamdps.com/iblock/1db/1dbec91a90cdeca9f7fb1ea7280ad5cd/cae0a287f4d2e8d0e1558dcbb4aa3b2f.png"),
|
||||
@@ -621,12 +697,16 @@ public enum Gift {
|
||||
|
||||
ROMANTIC_CARRIAGE(5627, "Romantic Carriage", 6000, "https://storage.streamdps.com/iblock/681/68132980826d9ddb208928c54a798f7f/e4f143cb38a0687729539972b2132ac1.png"),
|
||||
|
||||
AMAZING(5983, "Amazing", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/18256fd3f4402601dd07c83adae3e9a2~tplv-obj.png"),
|
||||
|
||||
BRIDAL_VEIL(5902, "Bridal Veil", 299, "https://storage.streamdps.com/iblock/ac0/ac0cbd1870dd92251f6ef620acb652e5/fe8eca664be736231b8e8e2cc2237a15.png"),
|
||||
|
||||
TULIP_BOX(5325, "Tulip Box", 200, "https://storage.streamdps.com/iblock/d44/d4471e5deb9cb5831f846ca4c9df9c5d/7d1236ecd67b3e655c3dfd72673a423d.png"),
|
||||
|
||||
SQUIRREL(7213, "Squirrel", 1, "https://storage.streamdps.com/iblock/5c3/5c37dce1eab0d67386329f3a2920a874/38104bd52d316ea76464433b3b07dea7.webp"),
|
||||
|
||||
CHOC_CHIP_COOKIE(6416, "Choc Chip Cookie", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7dd2731de2e644301a329d3eb437b427~tplv-obj.png"),
|
||||
|
||||
METEOR_SHOWER(6563, "Meteor Shower", 3000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/71883933511237f7eaa1bf8cd12ed575~tplv-obj.jpg"),
|
||||
|
||||
CAKE(5720, "Cake", 20, "https://storage.streamdps.com/iblock/edb/edbe349c5a4be01ec1fbf2225d0f48dc/4169ef7f0263177384205df6663451c8.png"),
|
||||
@@ -669,6 +749,10 @@ public enum Gift {
|
||||
|
||||
CHOCOLATE(5860, "Chocolate", 1, "https://storage.streamdps.com/iblock/522/52287f41673e2fd836c83ec78e95f08a/77307666e41e09e54052fd321c2906c4.png"),
|
||||
|
||||
RIO_DE_JANEIRO(7218, "Rio de Janeiro", 9999, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/34c0eb43c3d50e8ab64408171ebbe733~tplv-obj.png"),
|
||||
|
||||
BLOOMING_RIBBONS(9498, "Blooming Ribbons", 1000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/f76750ab58ee30fc022c9e4e11d25c9d.png~tplv-obj.jpg"),
|
||||
|
||||
CORNFLOWER(8186, "Cornflower", 5, "https://storage.streamdps.com/iblock/025/025c50c390f6a12148a69728284c7298/36b50fe529db9d7db028b0774842e103.webp"),
|
||||
|
||||
ASMR_TIME_(6990, "ASMR Time ", 10, "https://storage.streamdps.com/iblock/49d/49dccba4525df92ed17678cc6ea47e95/b2c8c52d5294bb531d7d87a4c3ff97fe.webp"),
|
||||
@@ -747,8 +831,12 @@ public enum Gift {
|
||||
|
||||
HI_MARCH(7977, "Hi March", 88, "https://storage.streamdps.com/iblock/e22/e2266686271c7a90ff04517f248c6f73/0459d679c01a5bfa5a4be1d61ec81ec8.webp"),
|
||||
|
||||
FANTASTIC(6813, "Fantastic", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a1b2204b06aa19d45a0338e9f0099ea7~tplv-obj.png"),
|
||||
|
||||
HEDGEHOG(6868, "Hedgehog", 299, "https://storage.streamdps.com/iblock/841/841e924150793d6961df0a1c89cc67ca/5886839b7de0b1289303081f9af380f8.webp"),
|
||||
|
||||
LIVE_FEST(9334, "LIVE Fest", 1, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1e98afffef90ed4b2cc9c9ebb88e3608.png~tplv-obj.png"),
|
||||
|
||||
I_LOVE_TR(7139, "I LOVE TR", 1, "https://storage.streamdps.com/iblock/84d/84d68e92c471e7da792aa98d856c824c/7728ac60043efb9c96e2ce0f77dbef31.webp"),
|
||||
|
||||
SHIBA_INU(5482, "Shiba Inu", 222, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/ddbcee02f5b86b803b0ec34357cd82ec.png~tplv-obj.jpg"),
|
||||
@@ -779,6 +867,8 @@ public enum Gift {
|
||||
|
||||
RHYTHMIC_BEAR(9468, "Rhythmic Bear", 2999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/16eacf541e4bd6816e88139d079519f5.png~tplv-obj.jpg"),
|
||||
|
||||
CRYSTAL_BALL(6428, "Crystal Ball", 1700, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7e4f9a99b7003ae05186f5324aae9fbf~tplv-obj.png"),
|
||||
|
||||
PHOENIX(7319, "Phoenix", 25999, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/ef248375c4167d70c1642731c732c982~tplv-obj.jpg"),
|
||||
|
||||
BOUQUET_FLOWER(5780, "Bouquet Flower", 30, "https://storage.streamdps.com/iblock/ceb/cebb5d5f7004d6ccf9336ae20281be88/5061b1767c2325fe6704eb08d97c5cb8.png"),
|
||||
@@ -799,6 +889,8 @@ public enum Gift {
|
||||
|
||||
FRUITS_HAT(7091, "Fruits Hat", 199, "https://storage.streamdps.com/iblock/404/404cc4794702cc6feb93bf4517bc0762/05846cb2d9548cf2f0573159110ecb64.webp"),
|
||||
|
||||
SPINNING_TOP(6483, "Spinning Top", 10, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/6cde70e04a6b40a9879f7b99ff191808~tplv-obj.png"),
|
||||
|
||||
MISHKA_BEAR(5486, "Mishka Bear", 100, "https://storage.streamdps.com/iblock/880/8809f52dbf40e0d670067f8c223d7c04/c603798bc6cd2bdc5a032ddbeb55e258.png"),
|
||||
|
||||
MISHKA_BEAR_5566(5566, "Mishka Bear", 100, "https://storage.streamdps.com/iblock/010/010ccc7a5d5e21231b46cea3223d5b1f/aa9c15ca87e4df8dad9be22164978fc2.png"),
|
||||
@@ -827,8 +919,12 @@ public enum Gift {
|
||||
|
||||
BIG_LOVE(7224, "Big Love", 5, "https://storage.streamdps.com/iblock/9d7/9d791fea266e119ffd938095526a1b55/1923108683e8c0aba3b78e1d0e8137cf.webp"),
|
||||
|
||||
TGIF(6592, "TGIF", 1, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2734231d880b5cd20149f4cc8c760279~tplv-obj.png"),
|
||||
|
||||
GOLDEN_GAMEPAD(6582, "Golden Gamepad", 30, "https://storage.streamdps.com/iblock/e85/e85940610dd45adc8733b51106c60712/ca839e1139ca0b94070c1e38093e95ec.png"),
|
||||
|
||||
COCONUT_TREE(5794, "Coconut Tree", 199, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/eb0923dbab5251f4c2e0496b11b55c4f~tplv-obj.png"),
|
||||
|
||||
SUMMER_BAND(6555, "Summer Band", 3999, "https://storage.streamdps.com/iblock/43b/43b88814d979720d80a6e17258ab3bd8/b1abf3d90ae212317d6ae339ed5f5be7.png"),
|
||||
|
||||
GORILLA(8602, "Gorilla", 30000, "https://storage.streamdps.com/iblock/1e2/1e29b9d1a0263f1487498dc556cdcbc1/bec227242f8c9b258855071aa050ac17.webp"),
|
||||
@@ -845,12 +941,16 @@ public enum Gift {
|
||||
|
||||
COOPER_SKATES_HOME(6865, "Cooper Skates Home", 599, "https://storage.streamdps.com/iblock/041/04184b09ec8e7bf137d33cf57ce4eec9/3c2e360b023b9980e54e9d9a394883b9.webp"),
|
||||
|
||||
EXCLUSIVE_JET(9523, "Exclusive Jet", 5000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1cc167a00aa4d5dfe48018afb38c3daa.png~tplv-obj.jpg"),
|
||||
|
||||
BIRTHDAY_PARTY(6787, "Birthday Party", 6999, "https://storage.streamdps.com/iblock/135/135b2ac0877de059f56e510b0ac70d08/07285ba7471fb98743bfe308d0b58ce2.webp"),
|
||||
|
||||
BIRTHDAY_PARTY_9095(9095, "Birthday Party", 6999, "https://storage.streamdps.com/iblock/d0d/d0d1164a9ed81239b70cb25b93927023/d0dba293643c67dc33c1f4dda04e5b50.webp"),
|
||||
|
||||
TEASING(6390, "Teasing", 401, "https://storage.streamdps.com/iblock/e14/e14c9b35975f1da5b8a5e3f116dae2bb/9f8cea9b65620e8376e44802c25ddf27.png"),
|
||||
|
||||
CRICKET(6006, "Cricket", 99, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/408d55c0526ada808be7db3e22c02a56~tplv-obj.png"),
|
||||
|
||||
FOAMY_DRINK(6740, "Foamy Drink", 100, "https://storage.streamdps.com/iblock/cc8/cc8133c73d5ca2cb5fde306f5b4e2a11/fb273956755fe6fbf7263023a9c36ebe.webp"),
|
||||
|
||||
CAPYBARA(8217, "Capybara", 30, "https://storage.streamdps.com/iblock/e94/e944534be54186446d7c38563c772029/553d899c4bd4be31e7b051bb36e842f8.webp"),
|
||||
@@ -897,6 +997,8 @@ public enum Gift {
|
||||
|
||||
GRAPES(7234, "Grapes", 1, "https://storage.streamdps.com/iblock/442/442580106ac8748b79ef450eb25b5981/df624c619c48b583adee184bca134c80.webp"),
|
||||
|
||||
LLAMA_GREETINGS(6531, "Llama Greetings", 299, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a6b95ce6350f5f4bdff6880ac6993789~tplv-obj.png"),
|
||||
|
||||
SAM_THE_WHALE(8391, "Sam the Whale", 30000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/f48a1887eb88238738996bb997b31c0f.png~tplv-obj.jpg"),
|
||||
|
||||
DIAMOND_TREE(7963, "Diamond Tree", 1088, "https://storage.streamdps.com/iblock/47a/47afc3c8563cacbff2ce13f2310a2fc4/84761a2a3e0431bda3bf3d2cc9d02b3f.webp"),
|
||||
@@ -913,10 +1015,14 @@ public enum Gift {
|
||||
|
||||
BIRD_WHISPERER(8344, "Bird Whisperer", 5000, "https://storage.streamdps.com/iblock/079/079bf5895816fb04293d01375eaf23a5/672128ca0f65deb0e75e2a9a690a79f0.webp"),
|
||||
|
||||
GOOD_NIGHT(8268, "Good Night", 399, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b7b55087141bd5f965eb31a99a5f157b~tplv-obj.png"),
|
||||
|
||||
ALIEN_PEACE_SIGN(7831, "Alien Peace Sign", 1, "https://storage.streamdps.com/iblock/5f7/5f7b29f5c7a4ca3a4dbbe8dc0e195459/cd83433a0f1697a0b66a891cbd7cf1af.webp"),
|
||||
|
||||
THE_MAGIC_LAMP(7161, "The Magic Lamp", 1000, "https://storage.streamdps.com/iblock/e0d/e0d45fccd69220f321531383d97f51fc/4296cc4b886f31bb5b2cf106ebf640ab.webp"),
|
||||
|
||||
TACO_(6113, "Taco ", 9, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/43d06db8c962623dbed6ecf70fb89ca8~tplv-obj.png"),
|
||||
|
||||
TIARA(8496, "Tiara", 299, "https://storage.streamdps.com/iblock/1b1/1b1ee7b697bae41ee2cbf834d1f1099e/303eec791a710c2417bb5075529681d9.webp"),
|
||||
|
||||
COFFEE(5333, "Coffee", 1, "https://storage.streamdps.com/iblock/920/920b64634d946a2238950c353c16df81/0fe22d9bdee1bd6d9d77f66bcd8cf45a.png"),
|
||||
@@ -953,8 +1059,12 @@ public enum Gift {
|
||||
|
||||
OWL(5885, "Owl", 500, "https://storage.streamdps.com/iblock/e87/e87fc92de64aa711c6ce23ed3b2214c2/338e115665b1c9f75108b50a43adb95b.png"),
|
||||
|
||||
TOP_HOST(6194, "Top Host", 199, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5947dc37282c417b411c61f20ee7d6d4~tplv-obj.png"),
|
||||
|
||||
TIKTOK_CROWN(8873, "TikTok Crown", 299, "https://storage.streamdps.com/iblock/a79/a790613bdf2e83725d0519bbf289529d/83bb670c15ab91b9192c50300f4c8054.webp"),
|
||||
|
||||
LOVED(6705, "Loved", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a41781b0a29ba3c409c5dd83eed07f8~tplv-obj.png"),
|
||||
|
||||
ON_FIRE(6840, "On Fire", 200, "https://storage.streamdps.com/iblock/cba/cba95075d6b63b84fbc52abb9d1d8208/d93ecc0b966bf972f01e77339a68e124.webp"),
|
||||
|
||||
ON_FIRE_6958(6958, "On Fire", 200, "https://storage.streamdps.com/iblock/4ec/4ec314b4ee7dff4e92a8e1e75100dddf/19c9b5d8b5f24b1465632a31e55edca1.webp"),
|
||||
@@ -1037,6 +1147,8 @@ public enum Gift {
|
||||
|
||||
NACHOS(7088, "Nachos", 9, "https://storage.streamdps.com/iblock/ff1/ff16cd1c796189ed8fcfdb019eb224ef/1ae8b0b05294c56b99197256fcaa3fd4.webp"),
|
||||
|
||||
SNAG(6411, "Snag", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/aa2d9b162c766a7fdf71fcead6d7bbcd~tplv-obj.png"),
|
||||
|
||||
APPETIZERS(6106, "Appetizers", 19, "https://storage.streamdps.com/iblock/76b/76b94aaced493a2448cf655b5468feaf/8c1bea41ec9fb547f0a0eb46d658a1c8.png"),
|
||||
|
||||
LOVE_LETTER(7932, "Love Letter", 1, "https://storage.streamdps.com/iblock/a40/a40cb58d5e8c07fa3e46a9acb4e34f6f/477507a1b14df0a22ef895c6214f3789.webp"),
|
||||
@@ -1047,8 +1159,12 @@ public enum Gift {
|
||||
|
||||
BUMPER_CARS(5996, "Bumper Cars", 1288, "https://storage.streamdps.com/iblock/53b/53b569311552b729d1b347268370e576/8f236deca90a65e7046f7576d69976af.png"),
|
||||
|
||||
CAMPFIRE(5843, "Campfire", 388, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e280eb1b7fe92b4efe612d98064d5a2d~tplv-obj.png"),
|
||||
|
||||
CAKE_SLICE(6784, "Cake Slice", 1, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/f681afb4be36d8a321eac741d387f1e2~tplv-obj.jpg"),
|
||||
|
||||
EXCLUSIVE_SPARK(9522, "Exclusive Spark", 1000, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/f0bda1eb6856e2feea9cfcb6c575c8a0.png~tplv-obj.jpg"),
|
||||
|
||||
CROCODILE(8740, "Crocodile", 10, "https://storage.streamdps.com/iblock/4e2/4e2d9df24c472158b8ed93546fc73b16/75722a173b75d601e0a80a679902529f.webp"),
|
||||
|
||||
LOVE_YOU_6671(6671, "Love You", 199, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/134e51c00f46e01976399883ca4e4798~tplv-obj.jpg"),
|
||||
@@ -1063,8 +1179,12 @@ public enum Gift {
|
||||
|
||||
DIAMOND_CROWN_5604(5604, "Diamond Crown", 1499, "https://storage.streamdps.com/iblock/3b5/3b56c2352a02829ac4445094a3f76b51/738ad17c91919a940ee2001f9f262a95.png"),
|
||||
|
||||
COCONUT_DRINK(8225, "Coconut Drink", 5, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/ce27ad017f987240dc447e65ae866f4f~tplv-obj.png"),
|
||||
|
||||
M4_TROPHY(7544, "M4 Trophy", 450, "https://storage.streamdps.com/iblock/f40/f40a34a8e59806907deaa4f74df3462d/8deac28cb21517228bcd354645a987ea.webp"),
|
||||
|
||||
FLOWER(6034, "Flower", 299, "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/9c20971eeb28b6b4ba37e57df3983da0~tplv-obj.png"),
|
||||
|
||||
PERFUME(5658, "Perfume", 20, "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/20b8f61246c7b6032777bb81bf4ee055~tplv-obj.jpg"),
|
||||
|
||||
KISS_YOUR_HEART(6661, "Kiss your Heart", 99, "https://storage.streamdps.com/iblock/13d/13d940df83e04a30523ca88c080ee8d8/213f06af314da4637a9ae8fc25bfaea3.webp"),
|
||||
|
||||
@@ -45,6 +45,8 @@ public class User {
|
||||
@Getter(AccessLevel.NONE)
|
||||
private Set<UserAttribute> attributes;
|
||||
|
||||
|
||||
|
||||
public List<UserAttribute> getAttributes() {
|
||||
return attributes.stream().toList();
|
||||
}
|
||||
@@ -107,6 +109,23 @@ public class User {
|
||||
this.attributes = new HashSet<>();
|
||||
}
|
||||
|
||||
public User(Long id,
|
||||
String name,
|
||||
String profileName,
|
||||
Picture picture,
|
||||
long following,
|
||||
long followers,
|
||||
List<Badge> badges) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.profileName = profileName;
|
||||
this.picture = picture;
|
||||
this.following = following;
|
||||
this.followers = followers;
|
||||
this.badges = badges;
|
||||
this.attributes = new HashSet<>();
|
||||
}
|
||||
|
||||
public User(Long userId,
|
||||
String nickName) {
|
||||
this.id = userId;
|
||||
|
||||
@@ -26,15 +26,20 @@ package io.github.jwdeveloper.tiktok.exceptions;
|
||||
/**
|
||||
* Happens when incoming data from TikTok can not be mapped to TikTokEvent's
|
||||
*/
|
||||
public class TikTokMessageMappingException extends TikTokLiveException
|
||||
{
|
||||
public TikTokMessageMappingException(Class<?> inputClazz, Class<?> outputClass, Throwable throwable)
|
||||
{
|
||||
super("Unable to handle mapping from class: " + inputClazz.getSimpleName() + " to class " + outputClass.getSimpleName(),throwable);
|
||||
public class TikTokMessageMappingException extends TikTokLiveException {
|
||||
public TikTokMessageMappingException(Class<?> inputClazz, Class<?> outputClass, Throwable throwable) {
|
||||
super("Unable to handle mapping from class: " + inputClazz.getSimpleName() + " to class " + outputClass.getSimpleName(), throwable);
|
||||
}
|
||||
|
||||
public TikTokMessageMappingException(Class<?> inputClazz, Class<?> outputClass, String message)
|
||||
{
|
||||
super("Unable to handle mapping from class: " + inputClazz.getSimpleName() + " to class " + outputClass.getSimpleName()+": "+message);
|
||||
public TikTokMessageMappingException(Class<?> inputClazz, Class<?> outputClass, String message) {
|
||||
super("Unable to handle mapping from class: " + inputClazz.getSimpleName() + " to class " + outputClass.getSimpleName() + ": " + message);
|
||||
}
|
||||
|
||||
public TikTokMessageMappingException(Class<?> inputClazz, String message, Throwable throwable) {
|
||||
super("Unable to handle mapping from class: " + inputClazz.getSimpleName() + ": " + message, throwable);
|
||||
}
|
||||
|
||||
public TikTokMessageMappingException(String message, Throwable throwable) {
|
||||
super( message, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,14 +22,31 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.live;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.models.RankingUser;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LiveRoomInfo
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return get current count of viewers of live
|
||||
*/
|
||||
int getViewersCount();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return get total current count of viewers since beginning of live
|
||||
*/
|
||||
int getTotalViewersCount();
|
||||
int getLikesCount();
|
||||
boolean isAgeRestricted();
|
||||
String getRoomId();
|
||||
String getHostName();
|
||||
String getTitle();
|
||||
User getHostUser();
|
||||
List<RankingUser> getUsersRanking();
|
||||
ConnectionState getConnectionState();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.live;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@@ -29,6 +30,11 @@ public class LiveRoomMeta {
|
||||
|
||||
private LiveRoomStatus status;
|
||||
private boolean ageRestricted;
|
||||
private String titie;
|
||||
private int likeCount;
|
||||
private int totalViewers;
|
||||
private int viewers;
|
||||
private User host;
|
||||
|
||||
public enum LiveRoomStatus
|
||||
{
|
||||
|
||||
@@ -24,11 +24,9 @@ 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.envelop.TikTokChestEvent;
|
||||
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;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomInfoEvent;
|
||||
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;
|
||||
@@ -40,9 +38,14 @@ import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketUnhandl
|
||||
|
||||
public interface EventsBuilder<T> {
|
||||
|
||||
T onRoom(EventConsumer<TikTokRoomEvent> event);
|
||||
/**
|
||||
* Method used to register own custom events
|
||||
* @param eventClazz event class
|
||||
* @param event action
|
||||
*/
|
||||
<E extends TikTokEvent> T onCustomEvent(Class<E> eventClazz, EventConsumer<E> event);
|
||||
|
||||
T onRoomUserInfo(EventConsumer<TikTokRoomUserInfoEvent> event);
|
||||
T onRoomInfo(EventConsumer<TikTokRoomInfoEvent> event);
|
||||
|
||||
T onComment(EventConsumer<TikTokCommentEvent> event);
|
||||
|
||||
@@ -53,9 +56,8 @@ public interface EventsBuilder<T> {
|
||||
T onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> event);
|
||||
|
||||
|
||||
|
||||
|
||||
T onGiftCombo(EventConsumer<TikTokGiftComboEvent> event);
|
||||
|
||||
T onGift(EventConsumer<TikTokGiftEvent> event);
|
||||
|
||||
T onQuestion(EventConsumer<TikTokQuestionEvent> event);
|
||||
@@ -71,12 +73,13 @@ public interface EventsBuilder<T> {
|
||||
T onJoin(EventConsumer<TikTokJoinEvent> event);
|
||||
|
||||
T onShare(EventConsumer<TikTokShareEvent> event);
|
||||
T onUnhandledSocial(EventConsumer<TikTokUnhandledSocialEvent> event);
|
||||
|
||||
// T onChest(EventConsumer<TikTokChestEvent> event);
|
||||
// T onChest(EventConsumer<TikTokChestEvent> event);
|
||||
|
||||
T onLivePaused(EventConsumer<TikTokLivePausedEvent> event);
|
||||
|
||||
T onLiveUnpaused(EventConsumer<TikTokLiveUnpausedEvent> event);
|
||||
|
||||
T onLiveEnded(EventConsumer<TikTokLiveEndedEvent> event);
|
||||
|
||||
T onConnected(EventConsumer<TikTokConnectedEvent> event);
|
||||
@@ -86,11 +89,10 @@ public interface EventsBuilder<T> {
|
||||
T onDisconnected(EventConsumer<TikTokDisconnectedEvent> event);
|
||||
|
||||
T onError(EventConsumer<TikTokErrorEvent> event);
|
||||
|
||||
T onEvent(EventConsumer<TikTokEvent> event);
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO Figure out how those events works
|
||||
//T onLinkMicFanTicket(TikTokEventConsumer<TikTokLinkMicFanTicketEvent> event);
|
||||
|
||||
|
||||
@@ -23,20 +23,60 @@
|
||||
package io.github.jwdeveloper.tiktok.live.builder;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.listener.TikTokEventListener;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.mappers.TikTokMapper;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface LiveClientBuilder extends EventsBuilder<LiveClientBuilder> {
|
||||
LiveClientBuilder configure(Consumer<ClientSettings> consumer);
|
||||
|
||||
/**
|
||||
* This method is triggered after default mappings are registered
|
||||
* It could be used to OVERRIDE behaviour of mappings and implement custom behaviour
|
||||
*
|
||||
* Be aware if for example you override WebcastGiftEvent, onGiftEvent() will not be working
|
||||
*
|
||||
* @param onCustomMappings lambda method
|
||||
* @return
|
||||
*/
|
||||
LiveClientBuilder onMapping(Consumer<TikTokMapper> onCustomMappings);
|
||||
|
||||
|
||||
/**
|
||||
* Configuration of client settings
|
||||
* @see ClientSettings
|
||||
* @param onConfigure
|
||||
* @return
|
||||
*/
|
||||
LiveClientBuilder configure(Consumer<ClientSettings> onConfigure);
|
||||
|
||||
/**
|
||||
* @see TikTokEventListener
|
||||
* Adding events listener class, its fancy way to register events without using lamda method
|
||||
* but actual method in class that implements TikTokEventListener
|
||||
* @return
|
||||
*/
|
||||
LiveClientBuilder addListener(TikTokEventListener listener);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return LiveClient object
|
||||
*/
|
||||
LiveClient build();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return LiveClient object and connects to TikTok live
|
||||
*/
|
||||
LiveClient buildAndConnect();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return LiveClient object and connects to TikTok live asynchronously
|
||||
*/
|
||||
CompletableFuture<LiveClient> buildAndConnectAsync();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package io.github.jwdeveloper.tiktok.mappers;
|
||||
|
||||
import com.google.protobuf.GeneratedMessageV3;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface TikTokMapper {
|
||||
|
||||
|
||||
/**
|
||||
* Triggered when `sourceClass` is mapped,
|
||||
* input is bytes that are coming from TikTok in `sourceClass` packet
|
||||
* output is TikTok event we want to create
|
||||
* <p>
|
||||
* bytesToEvent(WebcastGiftMessage.class, bytes ->
|
||||
* {
|
||||
* var giftMessage = WebcastGiftMessage.parseFrom(bytes);
|
||||
* var giftName = giftMessage.getGift().getName();
|
||||
* return new TikTokEvent(Gift.ROSE, giftMessage);
|
||||
* })
|
||||
*
|
||||
* @param sourceClass protocol buffer webcast class
|
||||
* @param onMapping lambda function that is triggered on mapping. takes as input ProtocolBuffer object and as output TikTokEvent
|
||||
*/
|
||||
void bytesToEvent(Class<? extends GeneratedMessageV3> sourceClass, Function<byte[], TikTokEvent> onMapping);
|
||||
|
||||
void bytesToEvents(Class<? extends GeneratedMessageV3> sourceClass, Function<byte[], List<TikTokEvent>> onMapping);
|
||||
|
||||
|
||||
/**
|
||||
* In case you found some TikTok message that has not Webcast class use this method
|
||||
*
|
||||
* @param messageName Name of TikTok data event
|
||||
* @param onMapping lambda function that is triggered on mapping. takes as input ProtocolBuffer object and as output TikTokEvent
|
||||
*/
|
||||
void bytesToEvent(String messageName, Function<byte[], TikTokEvent> onMapping);
|
||||
|
||||
void bytesToEvents(String messageName, Function<byte[], List<TikTokEvent>> onMapping);
|
||||
|
||||
|
||||
/**
|
||||
* This method can be used to override default mapping for
|
||||
* certain TikTok incoming data message. For this example
|
||||
* we are overriding WebcastGiftMessage and retuning CustomGiftEvent
|
||||
* instead of TikTokGiftEvent
|
||||
* <p>
|
||||
* webcastObjectToEvent(WebcastGiftMessage.class, webcastGiftMessage ->
|
||||
* {
|
||||
* var giftName = webcastGiftMessage.getGift().getName();
|
||||
* var user = webcastGiftMessage.getUser().getNickname();
|
||||
* return new CustomGiftEvent(giftName, user);
|
||||
* })
|
||||
*
|
||||
* @param sourceClass ProtocolBuffer class that represent incoming custom data, hint class should starts with Webcast prefix
|
||||
* @param onMapping lambda function that is triggered on mapping. takes as input ProtocolBuffer object and as output TikTokEvent
|
||||
*/
|
||||
<T extends GeneratedMessageV3> void webcastObjectToEvent(Class<T> sourceClass, Function<T, TikTokEvent> onMapping);
|
||||
|
||||
<T extends GeneratedMessageV3> void webcastObjectToEvents(Class<T> sourceClass, Function<T, List<TikTokEvent>> onMapping);
|
||||
|
||||
/**
|
||||
* Triggered when `sourceClass` is mapped,
|
||||
* looking for constructor in `outputClass` with one parameter that is of type `sourceClass`
|
||||
* and created instance of object from this constructor
|
||||
*
|
||||
* @param sourceClass protocol buffer webcast class
|
||||
* @param outputClass TikTok event class
|
||||
*/
|
||||
void webcastObjectToConstructor(Class<? extends GeneratedMessageV3> sourceClass, Class<? extends TikTokEvent> outputClass);
|
||||
|
||||
}
|
||||
@@ -25,8 +25,10 @@ package io.github.jwdeveloper.tiktok.utils;
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.github.jwdeveloper.tiktok.data.dto.MessageMetaData;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class JsonUtil {
|
||||
@@ -34,13 +36,25 @@ public class JsonUtil {
|
||||
return new GsonBuilder()
|
||||
.addSerializationExclusionStrategy(new ExclusionStrategy() {
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
|
||||
public boolean shouldSkipField(FieldAttributes fieldAttributes)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> aClass) {
|
||||
return aClass.equals(Image.class);
|
||||
public boolean shouldSkipClass(Class<?> aClass)
|
||||
{
|
||||
if(aClass.equals(Image.class))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(aClass.equals(MessageMetaData.class))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.disableHtmlEscaping()
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package io.github.jwdeveloper.tiktok.utils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class ProtoBufferFileGenerator {
|
||||
|
||||
|
||||
public static String generate(ProtoBufferObject protoBuffObj, String name) {
|
||||
|
||||
var sb = new StringBuilder();
|
||||
var offset = 2;
|
||||
sb.append("message ").append(name).append(" { \n");
|
||||
|
||||
var objects = new TreeMap<String, ProtoBufferObject>();
|
||||
var objectCounter = 0;
|
||||
for (var entry : protoBuffObj.getFields().entrySet()) {
|
||||
var index = entry.getKey();
|
||||
var field = entry.getValue();
|
||||
var fieldName = field.type.toLowerCase() + "Value";
|
||||
var value = field.value;
|
||||
if (field.value instanceof ProtoBufferObject object) {
|
||||
fieldName += objectCounter;
|
||||
value = "";
|
||||
objects.put(fieldName,object);
|
||||
objectCounter++;
|
||||
|
||||
}
|
||||
for (var i = 0; i < offset; i++) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(field.type).append(" ").append(fieldName)
|
||||
.append(" ")
|
||||
.append("=")
|
||||
.append(" ")
|
||||
.append(index)
|
||||
.append(";")
|
||||
.append(" //")
|
||||
.append(value)
|
||||
.append("\n");
|
||||
}
|
||||
sb.append(" \n");
|
||||
for(var object : objects.entrySet())
|
||||
{
|
||||
var structure = generate(object.getValue(),object.getKey());
|
||||
sb.append(structure);
|
||||
}
|
||||
|
||||
|
||||
sb.append(" \n");
|
||||
sb.append("} \n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.github.jwdeveloper.tiktok.utils;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class ProtoBufferJsonGenerator {
|
||||
public static JsonObject genratejson(ProtoBufferObject protoBuffObj) {
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
for (var entry : protoBuffObj.getFields().entrySet()) {
|
||||
var fieldName = entry.getKey() + "_" + entry.getValue().type;
|
||||
if (entry.getValue().value instanceof ProtoBufferObject protoObj)
|
||||
{
|
||||
JsonObject childJson = genratejson(protoObj);
|
||||
jsonObject.add(fieldName, childJson);
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = entry.getValue().value.toString();
|
||||
jsonObject.addProperty(fieldName, value);
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public static String generate(ProtoBufferObject protoBufferObject) {
|
||||
var json = genratejson(protoBufferObject);
|
||||
var gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
return gson.toJson(json);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package io.github.jwdeveloper.tiktok.utils;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class ProtoBufferObject {
|
||||
@Getter
|
||||
private final Map<Integer, ProtoBufferField> fields;
|
||||
|
||||
public ProtoBufferObject() {
|
||||
this.fields = new TreeMap<>();
|
||||
}
|
||||
|
||||
public void addField(int index, String type, Object value) {
|
||||
fields.put(index, new ProtoBufferField(type, value));
|
||||
}
|
||||
|
||||
public void addField(int index, ProtoBufferField value) {
|
||||
fields.put(index, value);
|
||||
}
|
||||
|
||||
|
||||
public String toProtoFile()
|
||||
{
|
||||
return ProtoBufferFileGenerator.generate(this,"UnknownMessage");
|
||||
}
|
||||
|
||||
public String toJson()
|
||||
{
|
||||
return ProtoBufferJsonGenerator.generate(this);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(0, true);
|
||||
}
|
||||
|
||||
public String toString(int offset ,boolean nested) {
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.append("\n");
|
||||
for (var entry : fields.entrySet()) {
|
||||
var index = entry.getKey();
|
||||
var field = entry.getValue();
|
||||
|
||||
for(var i =0;i<offset;i++)
|
||||
{
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(index).append(" ")
|
||||
.append(field.type).append(" ");
|
||||
|
||||
var value = field.value;
|
||||
if (value instanceof ProtoBufferObject child) {
|
||||
sb.append(child.toString(offset+2,nested));
|
||||
} else {
|
||||
sb.append(entry.getValue().value);
|
||||
}
|
||||
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
public class ProtoBufferField {
|
||||
public String type;
|
||||
|
||||
public Object value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package io.github.jwdeveloper.tiktok.utils;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.UnknownFieldSet;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
public class ProtocolUtils {
|
||||
public static String toBase64(byte[] bytes) {
|
||||
|
||||
return Base64.getEncoder().encodeToString(bytes);
|
||||
}
|
||||
|
||||
public static String toBase64(WebcastResponse.Message bytes) {
|
||||
return Base64.getEncoder().encodeToString(bytes.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
public static byte[] fromBase64(String base64) {
|
||||
|
||||
return Base64.getDecoder().decode(base64);
|
||||
}
|
||||
|
||||
public static ProtoBufferObject getProtocolBufferStructure(byte[] bytes) {
|
||||
|
||||
try {
|
||||
var files = UnknownFieldSet.parseFrom(bytes);
|
||||
var protoBufferObject = new ProtoBufferObject();
|
||||
createStructure(files, protoBufferObject);
|
||||
return protoBufferObject;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createStructure(UnknownFieldSet unknownFieldSet, ProtoBufferObject root) throws InvalidProtocolBufferException {
|
||||
for (var entry : unknownFieldSet.asMap().entrySet()) {
|
||||
var objectValue = entry.getValue();
|
||||
var type = "undefind";
|
||||
Object value = null;
|
||||
var index = entry.getKey();
|
||||
if (!objectValue.getLengthDelimitedList().isEmpty()) {
|
||||
var nestedObject = new ProtoBufferObject();
|
||||
for (var str : objectValue.getLengthDelimitedList()) {
|
||||
try {
|
||||
var nestedFieldsSet = UnknownFieldSet.parseFrom(str);
|
||||
createStructure(nestedFieldsSet, nestedObject);
|
||||
} catch (Exception e)
|
||||
{
|
||||
type = "string";
|
||||
value = str.toStringUtf8();
|
||||
}
|
||||
}
|
||||
if (value != null) {
|
||||
root.addField(index, "string", value);
|
||||
} else {
|
||||
root.addField(index, "object", nestedObject);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!objectValue.getFixed32List().isEmpty()) {
|
||||
type = "Fixed32List";
|
||||
value = objectValue.getFixed32List();
|
||||
}
|
||||
|
||||
if (!objectValue.getFixed64List().isEmpty()) {
|
||||
type = "Fixed64List";
|
||||
value = objectValue.getFixed64List();
|
||||
}
|
||||
|
||||
if (!objectValue.getGroupList().isEmpty()) {
|
||||
type = "getGroupList";
|
||||
value = objectValue.getGroupList();
|
||||
}
|
||||
|
||||
if (!objectValue.getVarintList().isEmpty()) {
|
||||
type = "int";
|
||||
value = objectValue.getVarintList().get(0);
|
||||
}
|
||||
|
||||
root.addField(index, type, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static WebcastResponse.Message fromBase64ToMessage(String base64) throws InvalidProtocolBufferException {
|
||||
var bytes = fromBase64(base64);
|
||||
return WebcastResponse.Message.parseFrom(bytes);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -974,3 +974,159 @@ message FanTicketRoomNoticeContent {
|
||||
int64 EventTime = 4;
|
||||
string FanTicketIconUrl = 5;
|
||||
}
|
||||
|
||||
message LinkerAcceptNoticeContent {
|
||||
int64 FromUserId = 1;
|
||||
int64 FromRoomId = 2;
|
||||
int64 ToUserId = 3;
|
||||
}
|
||||
|
||||
message LinkerCancelContent {
|
||||
int64 FromUserId = 1;
|
||||
int64 ToUserId = 2;
|
||||
int64 CancelType = 3;
|
||||
int64 ActionId = 4;
|
||||
}
|
||||
|
||||
message LinkerCloseContent {
|
||||
|
||||
}
|
||||
|
||||
message LinkerCreateContent {
|
||||
int64 OwnerId = 1;
|
||||
int64 OwnerRoomId = 2;
|
||||
int64 LinkType = 3;
|
||||
}
|
||||
|
||||
message LinkerEnterContent {
|
||||
repeated User LinkedUsersList = 1;
|
||||
//LinkmicMultiLiveEnum AnchorMultiLiveEnum = 2;
|
||||
// Data.LinkmicUserSettingInfo AnchorSettingInfo = 3;
|
||||
}
|
||||
|
||||
message LinkerInviteContent {
|
||||
int64 FromUserId = 1;
|
||||
int64 FromRoomId = 2;
|
||||
string ToRtcExtInfo = 3;
|
||||
bool RtcJoinChannel = 4;
|
||||
int64 Vendor = 5;
|
||||
string SecFromUserId = 6;
|
||||
string ToLinkmicIdStr = 7;
|
||||
User FromUser = 8;
|
||||
int64 RequiredMicIdx = 9;
|
||||
map<int64, string> RtcExtInfoMap = 10;
|
||||
//Data.LinkmicMultiLiveEnum AnchorMultiLiveEnum = 11;
|
||||
//Data.LinkmicUserSettingInfo AnchorSettingInfo = 12;
|
||||
string InviterLinkmicIdStr = 13;
|
||||
// InviteTopHostInfo FromTopHostInfo = 16;
|
||||
int64 ActionId = 17;
|
||||
// repeated LinkmicUserInfo LinkedUsersList = 18;
|
||||
// Data.PerceptionDialogInfo Dialog = 19;
|
||||
// Data.PunishEventInfo PunishInfo = 20;
|
||||
int32 FromRoomAgeRestricted = 21;
|
||||
// Data.Tag FromTag = 22;
|
||||
// repeated Data.CohostABTestSetting AbTestSettingList = 23;
|
||||
// Data.LinkerInviteMessageExtra LinkerInviteMsgExtra = 101;
|
||||
}
|
||||
|
||||
message LinkerKickOutContent {
|
||||
int64 FromUserId = 1;
|
||||
//LinkMic.KickoutReason KickoutReason = 2;
|
||||
}
|
||||
|
||||
message LinkerLeaveContent {
|
||||
int64 UserId = 1;
|
||||
string LinkmicIdStr = 2;
|
||||
int64 SendLeaveUid = 3;
|
||||
int64 LeaveReason = 4;
|
||||
}
|
||||
|
||||
message LinkerLinkedListChangeContent {
|
||||
repeated User LinkedUsersList = 1;
|
||||
}
|
||||
|
||||
message LinkerListChangeContent {
|
||||
repeated User LinkedUsersList = 1;
|
||||
repeated User AppliedUsersList = 2;
|
||||
repeated User ConnectingUsersList = 3;
|
||||
}
|
||||
|
||||
message LinkerMediaChangeContent {
|
||||
// MicIdxOperation Op = 1;
|
||||
int64 ToUserId = 2;
|
||||
int64 AnchorId = 3;
|
||||
int64 RoomId = 4;
|
||||
// LinkerSceneType ChangeScene = 5;
|
||||
}
|
||||
|
||||
message LinkerMicIdxUpdateContent {
|
||||
LinkerMicIdxUpdateInfo MicIdxUpdateInfo = 1;
|
||||
}
|
||||
|
||||
message LinkerMicIdxUpdateInfo {
|
||||
// MicIdxOperation Op = 1;
|
||||
int64 UserId = 2;
|
||||
int64 MicIdx = 3;
|
||||
}
|
||||
|
||||
message LinkerMuteContent {
|
||||
int64 UserId = 1;
|
||||
// Data.MuteStatus Status = 2;
|
||||
}
|
||||
|
||||
message LinkerRandomMatchContent {
|
||||
User User = 1;
|
||||
int64 RoomId = 2;
|
||||
int64 InviteType = 3;
|
||||
string MatchId = 4;
|
||||
int64 InnerChannelId = 5;
|
||||
}
|
||||
|
||||
message LinkerReplyContent {
|
||||
int64 FromUserId = 1;
|
||||
int64 FromRoomId = 2;
|
||||
// LinkmicInfo FromUserLinkmicInfo = 3;
|
||||
int64 ToUserId = 4;
|
||||
// LinkmicInfo ToUserLinkmicInfo = 5;
|
||||
int64 LinkType = 6;
|
||||
int64 ReplyStatus = 7;
|
||||
LinkerSetting LinkerSetting = 8;
|
||||
User FromUser = 9;
|
||||
User ToUser = 10;
|
||||
map<int64, string> RtcExtInfoMap = 11;
|
||||
LinkerMicIdxUpdateInfo InviteeMicIdxUpdateInfo = 12;
|
||||
map<int64, int64> ApplierMicIdxInfoMap = 13;
|
||||
// Data.LinkmicMultiLiveEnum AnchorMultiLiveEnum = 14;
|
||||
// Data.LinkmicUserSettingInfo AnchorSettingInfo = 15;
|
||||
int64 ActionId = 16;
|
||||
// repeated LinkmicUserInfo LinkedUsersList = 17;
|
||||
int64 SourceType = 18;
|
||||
}
|
||||
|
||||
message LinkerSetting {
|
||||
int64 MaxMemberLimit = 1;
|
||||
int64 LinkType = 2;
|
||||
int64 Scene = 3;
|
||||
int64 OwnerUserId = 4;
|
||||
int64 OwnerRoomId = 5;
|
||||
int64 Vendor = 6;
|
||||
}
|
||||
|
||||
message LinkerSysKickOutContent {
|
||||
int64 UserId = 1;
|
||||
string LinkmicIdStr = 2;
|
||||
}
|
||||
|
||||
message LinkerUpdateUserContent {
|
||||
int64 FromUserId = 1;
|
||||
int64 ToUserId = 2;
|
||||
map<string, string> UpdateInfoMap = 3;
|
||||
}
|
||||
|
||||
message LinkerUpdateUserSettingContent {
|
||||
// Data.LinkmicUserSettingInfo UpdateUserSettingInfo = 1;
|
||||
}
|
||||
|
||||
message LinkerWaitingListChangeContent {
|
||||
|
||||
}
|
||||
@@ -68,6 +68,7 @@ enum MemberMessageAction {
|
||||
enum ControlAction {
|
||||
ControlActionUNKNOWN = 0;
|
||||
STREAM_PAUSED = 1; // Stream Paused by Host
|
||||
STREAM_UNPAUSED = 2;
|
||||
STREAM_ENDED = 3; // Stream Ended by Host
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,8 @@ message WebcastCaptionMessage {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Comment sent by User
|
||||
//@WebcastChatMessage
|
||||
message WebcastChatMessage {
|
||||
@@ -608,7 +610,7 @@ message WebcastUnauthorizedMemberMessage {
|
||||
string nickName = 4;
|
||||
Text enterText = 5;
|
||||
}
|
||||
|
||||
S
|
||||
//@WebcastMsgDetectMessage
|
||||
message WebcastMsgDetectMessage {
|
||||
Common common = 1;
|
||||
@@ -681,29 +683,33 @@ message WebcastSystemMessage {
|
||||
//@WebcastLinkMessage
|
||||
message WebcastLinkMessage {
|
||||
Common common = 1;
|
||||
uint32 data1 = 2;
|
||||
uint64 data2 = 3;
|
||||
uint32 data3 = 4;
|
||||
LinkMessageData data = 18;
|
||||
LinkMessageUserContainer user = 20;
|
||||
string token = 200;
|
||||
|
||||
message LinkMessageData {
|
||||
DataContainer data = 1; // index 1 is an Id
|
||||
}
|
||||
|
||||
message LinkMessageUserContainer {
|
||||
LinkMessageUser user = 1;
|
||||
repeated LinkMessageUser otherUsers = 2;
|
||||
|
||||
message LinkMessageUser {
|
||||
User user = 1;
|
||||
uint64 timeStamp = 2;
|
||||
uint32 data1 = 4;
|
||||
string idString = 5;
|
||||
uint32 data2 = 7;
|
||||
}
|
||||
}
|
||||
int64 MessageType = 2;
|
||||
int64 LinkerId = 3;
|
||||
int64 Scene = 4;
|
||||
LinkerInviteContent InviteContent = 5;
|
||||
LinkerReplyContent ReplyContent = 6;
|
||||
LinkerCreateContent CreateContent = 7;
|
||||
LinkerCloseContent CloseContent = 8;
|
||||
LinkerEnterContent EnterContent = 9;
|
||||
LinkerLeaveContent LeaveContent = 10;
|
||||
LinkerCancelContent CancelContent = 11;
|
||||
LinkerKickOutContent KickOutContent = 12;
|
||||
LinkerLinkedListChangeContent LinkedListChangeContent = 13;
|
||||
LinkerUpdateUserContent UpdateUserContent = 14;
|
||||
LinkerWaitingListChangeContent WaitingListChangeContent = 15;
|
||||
LinkerMuteContent MuteContent = 16;
|
||||
LinkerRandomMatchContent RandomMatchContent = 17;
|
||||
LinkerUpdateUserSettingContent UpdateUserSettingContent = 18;
|
||||
LinkerMicIdxUpdateContent MicIdxUpdateContent = 19;
|
||||
LinkerListChangeContent ListChangeContent = 20;
|
||||
// CohostListChangeContent CohostListChangeContent = 21;
|
||||
LinkerMediaChangeContent MediaChangeContent = 22;
|
||||
LinkerAcceptNoticeContent ReplyAcceptNoticeContent = 23;
|
||||
LinkerSysKickOutContent SysKickOutContent = 101;
|
||||
// LinkmicUserToastContent UserToastContent = 102;
|
||||
string Extra = 200;
|
||||
int64 ExpireTimestamp = 201;
|
||||
string TransferExtra = 202;
|
||||
}
|
||||
|
||||
//@WebcastLinkLayerMessage
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ package io.github.jwdeveloper.tiktok;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokReconnectingEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomInfoEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveOfflineHostException;
|
||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;
|
||||
@@ -92,8 +93,7 @@ public class TikTokLiveClient implements LiveClient {
|
||||
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());
|
||||
@@ -108,6 +108,10 @@ public class TikTokLiveClient implements LiveClient {
|
||||
this.connect();
|
||||
}
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
logger.info("Unhandled exception report this bug to github https://github.com/jwdeveloper/TikTokLiveJava/issues");
|
||||
this.disconnect();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +131,7 @@ public class TikTokLiveClient implements LiveClient {
|
||||
|
||||
setState(ConnectionState.CONNECTING);
|
||||
|
||||
|
||||
apiService.updateSessionId();
|
||||
|
||||
if (clientSettings.getRoomId() != null) {
|
||||
@@ -138,14 +143,24 @@ public class TikTokLiveClient implements LiveClient {
|
||||
}
|
||||
|
||||
|
||||
var roomData = apiService.fetchRoomInfo();
|
||||
if (roomData.getStatus() != LiveRoomMeta.LiveRoomStatus.HostOnline) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for Host name could not be found. Is the Host online?");
|
||||
var liveRoomMeta = apiService.fetchRoomInfo();
|
||||
if (liveRoomMeta.getStatus() == LiveRoomMeta.LiveRoomStatus.HostNotFound) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for Host name could not be found.");
|
||||
}
|
||||
if (liveRoomMeta.getStatus() == LiveRoomMeta.LiveRoomStatus.HostOffline) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for not be found, is the Host offline?");
|
||||
}
|
||||
|
||||
liveRoomInfo.setTitle(liveRoomMeta.getTitie());
|
||||
liveRoomInfo.setViewersCount(liveRoomMeta.getViewers());
|
||||
liveRoomInfo.setTotalViewersCount(liveRoomMeta.getTotalViewers());
|
||||
liveRoomInfo.setAgeRestricted(liveRoomMeta.isAgeRestricted());
|
||||
liveRoomInfo.setHost(liveRoomMeta.getHost());
|
||||
|
||||
var clientData = apiService.fetchClientData();
|
||||
webSocketClient.start(clientData, this);
|
||||
setState(ConnectionState.CONNECTED);
|
||||
tikTokEventHandler.publish(this, new TikTokRoomInfoEvent(liveRoomInfo));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,9 +28,8 @@ import io.github.jwdeveloper.tiktok.data.events.envelop.TikTokChestEvent;
|
||||
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.TikTokRoomInfoEvent;
|
||||
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;
|
||||
@@ -41,8 +40,14 @@ import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketUnhandl
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import io.github.jwdeveloper.tiktok.handlers.events.TikTokGiftEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandler;
|
||||
import io.github.jwdeveloper.tiktok.live.GiftManager;
|
||||
import io.github.jwdeveloper.tiktok.mappers.TikTokLiveMapper;
|
||||
import io.github.jwdeveloper.tiktok.mappers.TikTokMapper;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokCommonEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokGiftEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokRoomInfoEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokSocialMediaEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokApiService;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokCookieJar;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokHttpClient;
|
||||
@@ -53,6 +58,7 @@ 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.mappers.TikTokGenericEventMapper;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
|
||||
|
||||
@@ -66,9 +72,11 @@ import java.util.logging.*;
|
||||
public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
|
||||
protected final ClientSettings clientSettings;
|
||||
|
||||
protected final Logger logger;
|
||||
protected final TikTokEventObserver tikTokEventHandler;
|
||||
protected final List<TikTokEventListener> listeners;
|
||||
protected Consumer<TikTokMapper> onCustomMappings;
|
||||
|
||||
public TikTokLiveClientBuilder(String userName) {
|
||||
this.tikTokEventHandler = new TikTokEventObserver();
|
||||
@@ -76,10 +84,18 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
this.clientSettings.setHostName(userName);
|
||||
this.logger = Logger.getLogger(TikTokLive.class.getSimpleName() + " " + userName);
|
||||
this.listeners = new ArrayList<>();
|
||||
this.onCustomMappings = (e) -> {
|
||||
};
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder configure(Consumer<ClientSettings> consumer) {
|
||||
consumer.accept(clientSettings);
|
||||
|
||||
public LiveClientBuilder onMapping(Consumer<TikTokMapper> onCustomMappings) {
|
||||
this.onCustomMappings = onCustomMappings;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder configure(Consumer<ClientSettings> onConfigure) {
|
||||
onConfigure.accept(clientSettings);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -103,8 +119,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
throw new TikTokLiveException("HostName can not be null");
|
||||
}
|
||||
|
||||
if (clientSettings.getHostName().startsWith("@"))
|
||||
{
|
||||
if (clientSettings.getHostName().startsWith("@")) {
|
||||
clientSettings.setHostName(clientSettings.getHostName().substring(1));
|
||||
}
|
||||
|
||||
@@ -131,12 +146,9 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
|
||||
logger.setLevel(clientSettings.getLogLevel());
|
||||
|
||||
if (clientSettings.isPrintToConsole() && clientSettings.getLogLevel() == Level.OFF) {
|
||||
logger.setLevel(Level.ALL);
|
||||
if (!clientSettings.isPrintToConsole()) {
|
||||
logger.setLevel(Level.OFF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public LiveClient build() {
|
||||
@@ -151,19 +163,14 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
var apiClient = new TikTokHttpClient(cookieJar, requestFactory);
|
||||
var apiService = new TikTokApiService(apiClient, logger, clientSettings);
|
||||
var giftManager = new TikTokGiftManager(logger);
|
||||
var eventMapper = new TikTokGenericEventMapper();
|
||||
var giftHandler = new TikTokGiftEventHandler(giftManager);
|
||||
var eventsMapper = createMapper(giftManager, tiktokRoomInfo);
|
||||
var messageHandler = new TikTokMessageHandler(tikTokEventHandler, eventsMapper);
|
||||
|
||||
var webResponseHandler = new TikTokMessageHandlerRegistration(tikTokEventHandler,
|
||||
tiktokRoomInfo,
|
||||
eventMapper,
|
||||
giftHandler
|
||||
);
|
||||
|
||||
var webSocketClient = new TikTokWebSocketClient(logger,
|
||||
cookieJar,
|
||||
clientSettings,
|
||||
webResponseHandler,
|
||||
messageHandler,
|
||||
tikTokEventHandler);
|
||||
|
||||
return new TikTokLiveClient(tiktokRoomInfo,
|
||||
@@ -176,6 +183,64 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
logger);
|
||||
}
|
||||
|
||||
public TikTokLiveMapper createMapper(GiftManager giftManager, TikTokRoomInfo roomInfo) {
|
||||
var eventMapper = new TikTokGenericEventMapper();
|
||||
var mapper = new TikTokLiveMapper(eventMapper);
|
||||
|
||||
//ConnectionEvents events
|
||||
var commonHandler = new TikTokCommonEventHandler();
|
||||
var giftHandler = new TikTokGiftEventHandler(giftManager);
|
||||
var roomInfoHandler = new TikTokRoomInfoEventHandler(roomInfo);
|
||||
var socialHandler = new TikTokSocialMediaEventHandler(roomInfo);
|
||||
|
||||
mapper.bytesToEvent(WebcastControlMessage.class, commonHandler::handleWebcastControlMessage);
|
||||
|
||||
//Room status events
|
||||
mapper.bytesToEvent(WebcastLiveIntroMessage.class, roomInfoHandler::handleIntro);
|
||||
mapper.bytesToEvent(WebcastRoomUserSeqMessage.class, roomInfoHandler::handleUserRanking);
|
||||
|
||||
mapper.webcastObjectToConstructor(WebcastCaptionMessage.class, TikTokCaptionEvent.class);
|
||||
|
||||
//User Interactions events
|
||||
mapper.webcastObjectToConstructor(WebcastChatMessage.class, TikTokCommentEvent.class);
|
||||
mapper.bytesToEvents(WebcastLikeMessage.class, roomInfoHandler::handleLike);
|
||||
mapper.bytesToEvents(WebcastGiftMessage.class, giftHandler::handleGift);
|
||||
mapper.bytesToEvent(WebcastSocialMessage.class, socialHandler::handle);
|
||||
mapper.bytesToEvents(WebcastMemberMessage.class, roomInfoHandler::handleMemberMessage);
|
||||
|
||||
//Host Interaction events
|
||||
mapper.bytesToEvent(WebcastPollMessage.class, commonHandler::handlePollEvent);
|
||||
mapper.bytesToEvent(WebcastRoomPinMessage.class, commonHandler::handlePinMessage);
|
||||
mapper.webcastObjectToConstructor(WebcastGoalUpdateMessage.class, TikTokGoalUpdateEvent.class);
|
||||
|
||||
//LinkMic events
|
||||
mapper.webcastObjectToConstructor(WebcastLinkMicBattle.class, TikTokLinkMicBattleEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastLinkMicArmies.class, TikTokLinkMicArmiesEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
|
||||
|
||||
//Rank events
|
||||
mapper.webcastObjectToConstructor(WebcastRankTextMessage.class, TikTokRankTextEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastRankUpdateMessage.class, TikTokRankUpdateEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastHourlyRankMessage.class, TikTokRankUpdateEvent.class);
|
||||
|
||||
//Others events
|
||||
mapper.webcastObjectToConstructor(WebcastInRoomBannerMessage.class, TikTokInRoomBannerEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastMsgDetectMessage.class, TikTokDetectEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastBarrageMessage.class, TikTokBarrageEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastUnauthorizedMemberMessage.class, TikTokUnauthorizedMemberEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastOecLiveShoppingMessage.class, TikTokShopEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastImDeleteMessage.class, TikTokIMDeleteEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastQuestionNewMessage.class, TikTokQuestionEvent.class);
|
||||
mapper.bytesToEvents(WebcastEnvelopeMessage.class, commonHandler::handleEnvelop);
|
||||
mapper.webcastObjectToConstructor(WebcastSubNotifyMessage.class, TikTokSubscribeEvent.class);
|
||||
mapper.webcastObjectToConstructor(WebcastEmoteChatMessage.class, TikTokEmoteEvent.class);
|
||||
|
||||
onCustomMappings.accept(mapper);
|
||||
return mapper;
|
||||
}
|
||||
|
||||
|
||||
public LiveClient buildAndConnect() {
|
||||
var client = build();
|
||||
client.connect();
|
||||
@@ -186,18 +251,20 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
return build().connectAsync();
|
||||
}
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandledSocial(
|
||||
EventConsumer<TikTokUnhandledSocialEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledSocialEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// @Override
|
||||
public LiveClientBuilder onChest(EventConsumer<TikTokChestEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokChestEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onLinkMicFanTicket(
|
||||
EventConsumer<TikTokLinkMicFanTicketEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicFanTicketEvent.class, event);
|
||||
@@ -247,16 +314,31 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRoom(EventConsumer<TikTokRoomEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomEvent.class, event);
|
||||
@Override
|
||||
public <E extends TikTokEvent> LiveClientBuilder onCustomEvent(Class<E> eventClazz, EventConsumer<E> event) {
|
||||
tikTokEventHandler.subscribe(eventClazz, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public LiveClientBuilder onRoomInfo(EventConsumer<TikTokRoomInfoEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomInfoEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onLivePaused(EventConsumer<TikTokLivePausedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLivePausedEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveClientBuilder onLiveUnpaused(EventConsumer<TikTokLiveUnpausedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLiveUnpausedEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLike(EventConsumer<TikTokLikeEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLikeEvent.class, event);
|
||||
return this;
|
||||
@@ -329,13 +411,6 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRoomUserInfo(
|
||||
EventConsumer<TikTokRoomUserInfoEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomUserInfoEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onComment(EventConsumer<TikTokCommentEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokCommentEvent.class, event);
|
||||
return this;
|
||||
|
||||
@@ -23,34 +23,51 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||
import io.github.jwdeveloper.tiktok.messages.data.User;
|
||||
import io.github.jwdeveloper.tiktok.data.models.RankingUser;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class TikTokRoomInfo implements LiveRoomInfo
|
||||
{
|
||||
public class TikTokRoomInfo implements LiveRoomInfo {
|
||||
private String roomId;
|
||||
|
||||
private int likesCount;
|
||||
|
||||
private int viewersCount;
|
||||
|
||||
private int totalViewersCount;
|
||||
|
||||
private boolean ageRestricted;
|
||||
|
||||
private User host;
|
||||
|
||||
private Picture picture;
|
||||
|
||||
private String description;
|
||||
private List<RankingUser> usersRanking = new LinkedList<>();
|
||||
|
||||
private String hostName;
|
||||
|
||||
private String title;
|
||||
|
||||
private String language = "en";
|
||||
|
||||
private ConnectionState connectionState = ConnectionState.DISCONNECTED;
|
||||
|
||||
public boolean hasConnectionState(ConnectionState state)
|
||||
{
|
||||
public boolean hasConnectionState(ConnectionState state) {
|
||||
return connectionState == state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getHostUser() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateRanking(List<RankingUser> rankingUsers) {
|
||||
usersRanking.clear();
|
||||
usersRanking.addAll(rankingUsers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,47 +23,30 @@
|
||||
package io.github.jwdeveloper.tiktok.handlers;
|
||||
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.dto.MessageMetaData;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
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.exceptions.TikTokLiveMessageException;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.mappers.TikTokGenericEventMapper;
|
||||
import io.github.jwdeveloper.tiktok.mappers.TikTokLiveMapper;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
import io.github.jwdeveloper.tiktok.utils.Stopwatch;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
public abstract class TikTokMessageHandler {
|
||||
public class TikTokMessageHandler {
|
||||
|
||||
private final Map<String, io.github.jwdeveloper.tiktok.handler.TikTokMessageHandler> handlers;
|
||||
private final TikTokEventObserver tikTokEventHandler;
|
||||
protected final TikTokGenericEventMapper mapper;
|
||||
private final TikTokLiveMapper mapper;
|
||||
|
||||
public TikTokMessageHandler(TikTokEventObserver tikTokEventHandler, TikTokGenericEventMapper mapper) {
|
||||
handlers = new HashMap<>();
|
||||
public TikTokMessageHandler(TikTokEventObserver tikTokEventHandler, TikTokLiveMapper mapper) {
|
||||
this.tikTokEventHandler = tikTokEventHandler;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public void registerMapping(Class<?> clazz, Function<byte[], TikTokEvent> func) {
|
||||
handlers.put(clazz.getSimpleName(), messagePayload -> List.of(func.apply(messagePayload)));
|
||||
}
|
||||
|
||||
public void registerMappings(Class<?> clazz, Function<byte[], List<TikTokEvent>> func) {
|
||||
handlers.put(clazz.getSimpleName(), func::apply);
|
||||
}
|
||||
|
||||
public void registerMapping(Class<?> input, Class<?> output) {
|
||||
registerMapping(input, (e) -> mapper.mapToEvent(input, output, e));
|
||||
}
|
||||
|
||||
public void handle(LiveClient client, WebcastResponse webcastResponse) {
|
||||
tikTokEventHandler.publish(client, new TikTokWebsocketResponseEvent(webcastResponse));
|
||||
@@ -79,19 +62,18 @@ public abstract class TikTokMessageHandler {
|
||||
|
||||
public void handleSingleMessage(LiveClient client, WebcastResponse.Message message) throws Exception {
|
||||
var messageClassName = message.getMethod();
|
||||
if (!handlers.containsKey(messageClassName)) {
|
||||
if (!mapper.isRegistered(messageClassName)) {
|
||||
tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(message));
|
||||
return;
|
||||
}
|
||||
var handler = handlers.get(messageClassName);
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.start();
|
||||
var events = handler.handle(message.getPayload().toByteArray());
|
||||
var events = mapper.handleMapping(messageClassName, message.getPayload().toByteArray());
|
||||
var handlingTimeInMs = stopwatch.stop();
|
||||
var metadata = new TikTokWebsocketMessageEvent.MetaData(Duration.ofNanos(handlingTimeInMs));
|
||||
var metadata = new MessageMetaData(Duration.ofNanos(handlingTimeInMs));
|
||||
|
||||
for (var event : events) {
|
||||
tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(event, message, metadata));
|
||||
tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(message, event, metadata));
|
||||
tikTokEventHandler.publish(client, event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,210 +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.handlers;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.data.events.*;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.envelop.TikTokChestEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEndEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollStartEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollUpdateEvent;
|
||||
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.social.TikTokShareEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.Text;
|
||||
import io.github.jwdeveloper.tiktok.data.models.chest.Chest;
|
||||
import io.github.jwdeveloper.tiktok.handlers.events.TikTokGiftEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.mappers.TikTokGenericEventMapper;
|
||||
import io.github.jwdeveloper.tiktok.messages.enums.EnvelopeDisplay;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
||||
import io.github.jwdeveloper.tiktok.models.SocialTypes;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TikTokMessageHandlerRegistration extends TikTokMessageHandler {
|
||||
|
||||
private final TikTokRoomInfo roomInfo;
|
||||
private final TikTokGiftEventHandler giftHandler;
|
||||
private final Pattern socialMediaPattern = Pattern.compile("pm_mt_guidance_viewer_([0-9]+)_share");
|
||||
|
||||
public TikTokMessageHandlerRegistration(TikTokEventObserver tikTokEventHandler,
|
||||
TikTokRoomInfo roomInfo,
|
||||
TikTokGenericEventMapper genericTikTokEventMapper,
|
||||
TikTokGiftEventHandler tikTokGiftEventHandler) {
|
||||
super(tikTokEventHandler, genericTikTokEventMapper);
|
||||
this.giftHandler = tikTokGiftEventHandler;
|
||||
this.roomInfo = roomInfo;
|
||||
init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
//ConnectionEvents events
|
||||
registerMapping(WebcastControlMessage.class, this::handleWebcastControlMessage);
|
||||
registerMapping(WebcastSystemMessage.class, TikTokRoomEvent.class);
|
||||
|
||||
|
||||
//Room status events
|
||||
registerMapping(WebcastLiveIntroMessage.class, TikTokRoomEvent.class);
|
||||
registerMapping(WebcastRoomUserSeqMessage.class, this::handleRoomUserSeqMessage);
|
||||
registerMapping(RoomMessage.class, TikTokRoomEvent.class);
|
||||
registerMapping(WebcastRoomMessage.class, TikTokRoomEvent.class);
|
||||
registerMapping(WebcastCaptionMessage.class, TikTokCaptionEvent.class);
|
||||
|
||||
//User Interactions events
|
||||
registerMapping(WebcastChatMessage.class, TikTokCommentEvent.class);
|
||||
registerMapping(WebcastLikeMessage.class, this::handleLike);
|
||||
registerMappings(WebcastGiftMessage.class, giftHandler::handleGift);
|
||||
registerMapping(WebcastSocialMessage.class, this::handleSocialMedia);
|
||||
registerMapping(WebcastMemberMessage.class, this::handleMemberMessage);
|
||||
|
||||
//Host Interaction events
|
||||
registerMapping(WebcastPollMessage.class, this::handlePollEvent);
|
||||
registerMapping(WebcastRoomPinMessage.class, this::handlePinMessage);
|
||||
registerMapping(WebcastGoalUpdateMessage.class, TikTokGoalUpdateEvent.class);
|
||||
|
||||
//LinkMic events
|
||||
registerMapping(WebcastLinkMicBattle.class, TikTokLinkMicBattleEvent.class);
|
||||
registerMapping(WebcastLinkMicArmies.class, TikTokLinkMicArmiesEvent.class);
|
||||
registerMapping(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
|
||||
registerMapping(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
|
||||
|
||||
//Rank events
|
||||
registerMapping(WebcastRankTextMessage.class, TikTokRankTextEvent.class);
|
||||
registerMapping(WebcastRankUpdateMessage.class, TikTokRankUpdateEvent.class);
|
||||
registerMapping(WebcastHourlyRankMessage.class, TikTokRankUpdateEvent.class);
|
||||
|
||||
//Others events
|
||||
registerMapping(WebcastInRoomBannerMessage.class, TikTokInRoomBannerEvent.class);
|
||||
registerMapping(WebcastMsgDetectMessage.class, TikTokDetectEvent.class);
|
||||
registerMapping(WebcastBarrageMessage.class, TikTokBarrageEvent.class);
|
||||
registerMapping(WebcastUnauthorizedMemberMessage.class, TikTokUnauthorizedMemberEvent.class);
|
||||
registerMapping(WebcastOecLiveShoppingMessage.class, TikTokShopEvent.class);
|
||||
registerMapping(WebcastImDeleteMessage.class, TikTokIMDeleteEvent.class);
|
||||
registerMapping(WebcastQuestionNewMessage.class, TikTokQuestionEvent.class);
|
||||
registerMappings(WebcastEnvelopeMessage.class, this::handleEnvelop);
|
||||
registerMapping(WebcastSubNotifyMessage.class, TikTokSubNotifyEvent.class);
|
||||
registerMapping(WebcastEmoteChatMessage.class, TikTokEmoteEvent.class);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
private TikTokEvent handleWebcastControlMessage(byte[] msg) {
|
||||
var message = WebcastControlMessage.parseFrom(msg);
|
||||
return switch (message.getAction()) {
|
||||
case STREAM_PAUSED -> new TikTokLivePausedEvent();
|
||||
case STREAM_ENDED -> new TikTokLiveEndedEvent();
|
||||
default -> new TikTokUnhandledControlEvent(message);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
private TikTokEvent handleSocialMedia(byte[] msg) {
|
||||
var message = WebcastSocialMessage.parseFrom(msg);
|
||||
|
||||
var socialType = Text.map(message.getCommon().getDisplayText()).getKey();
|
||||
var matcher = socialMediaPattern.matcher(socialType);
|
||||
|
||||
if (matcher.find()) {
|
||||
var value = matcher.group(1);
|
||||
var number = Integer.parseInt(value);
|
||||
return new TikTokShareEvent(message, number);
|
||||
}
|
||||
|
||||
return switch (socialType) {
|
||||
case SocialTypes.LikeType -> new TikTokLikeEvent(message, roomInfo.getLikesCount());
|
||||
case SocialTypes.FollowType -> new TikTokFollowEvent(message);
|
||||
case SocialTypes.ShareType -> new TikTokShareEvent(message);
|
||||
case SocialTypes.JoinType -> new TikTokJoinEvent(message, roomInfo.getViewersCount());
|
||||
default -> new TikTokUnhandledSocialEvent(message);
|
||||
};
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private TikTokEvent handleMemberMessage(byte[] msg) {
|
||||
var message = WebcastMemberMessage.parseFrom(msg);
|
||||
roomInfo.setViewersCount(message.getMemberCount());
|
||||
return switch (message.getAction()) {
|
||||
case JOINED -> new TikTokJoinEvent(message);
|
||||
case SUBSCRIBED -> new TikTokSubscribeEvent(message);
|
||||
default -> new TikTokUnhandledMemberEvent(message);
|
||||
};
|
||||
}
|
||||
|
||||
private TikTokEvent handleRoomUserSeqMessage(byte[] msg) {
|
||||
var event = (TikTokRoomUserInfoEvent) mapper.mapToEvent(WebcastRoomUserSeqMessage.class, TikTokRoomUserInfoEvent.class, msg);
|
||||
roomInfo.setViewersCount(event.getTotalUsers());
|
||||
return event;
|
||||
}
|
||||
|
||||
private TikTokEvent handleLike(byte[] msg) {
|
||||
var event = (TikTokLikeEvent) mapper.mapToEvent(WebcastLikeMessage.class, TikTokLikeEvent.class, msg);
|
||||
roomInfo.setLikesCount(event.getTotalLikes());
|
||||
return event;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private TikTokEvent handlePinMessage(byte[] msg) {
|
||||
var pinMessage = WebcastRoomPinMessage.parseFrom(msg);
|
||||
var chatMessage = WebcastChatMessage.parseFrom(pinMessage.getPinnedMessage());
|
||||
var chatEvent = new TikTokCommentEvent(chatMessage);
|
||||
return new TikTokRoomPinEvent(pinMessage, chatEvent);
|
||||
}
|
||||
|
||||
//TODO Probably not working
|
||||
@SneakyThrows
|
||||
private TikTokEvent handlePollEvent(byte[] msg) {
|
||||
var poolMessage = WebcastPollMessage.parseFrom(msg);
|
||||
return switch (poolMessage.getMessageType()) {
|
||||
case 0 -> new TikTokPollStartEvent(poolMessage);
|
||||
case 1 -> new TikTokPollEndEvent(poolMessage);
|
||||
case 2 -> new TikTokPollUpdateEvent(poolMessage);
|
||||
default -> new TikTokPollEvent(poolMessage);
|
||||
};
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private List<TikTokEvent> handleEnvelop(byte[] data) {
|
||||
var msg = WebcastEnvelopeMessage.parseFrom(data);
|
||||
if (msg.getDisplay() != EnvelopeDisplay.EnvelopeDisplayNew) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var totalDiamonds = msg.getEnvelopeInfo().getDiamondCount();
|
||||
var totalUsers = msg.getEnvelopeInfo().getPeopleCount();
|
||||
var chest = new Chest(totalDiamonds, totalUsers);
|
||||
|
||||
return List.of(new TikTokChestEvent(chest, msg));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package io.github.jwdeveloper.tiktok.handlers.events;
|
||||
|
||||
public class TikTokChestEventHandler {
|
||||
}
|
||||
@@ -22,8 +22,11 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.http;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.data.dto.TikTokUserInfo;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveOfflineHostException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
@@ -57,62 +60,50 @@ public class TikTokApiService {
|
||||
}
|
||||
|
||||
public String fetchRoomId(String userName) {
|
||||
var roomId = fetchRoomIdFromTiktokApi(userName);
|
||||
clientSettings.getClientParameters().put("room_id", roomId);
|
||||
logger.info("RoomID -> " + roomId);
|
||||
return roomId;
|
||||
var userInfo = fetchUserInfoFromTikTokApi(userName);
|
||||
clientSettings.getClientParameters().put("room_id", userInfo.getRoomId());
|
||||
logger.info("RoomID -> " + userInfo.getRoomId());
|
||||
return userInfo.getRoomId();
|
||||
}
|
||||
|
||||
private String fetchRoomIdFromTikTokPage(String userName)
|
||||
{
|
||||
/* var roomId = RequestChain.<String>create()
|
||||
.then(() -> fetchRoomIdFromTikTokPage(userName))
|
||||
.then(() -> fetchRoomIdFromTiktokApi(userName))
|
||||
.run();*/
|
||||
logger.info("Fetching room ID");
|
||||
String html;
|
||||
try {
|
||||
html = tiktokHttpClient.getLivestreamPage(userName);
|
||||
} catch (Exception e) {
|
||||
throw new TikTokLiveRequestException("Failed to fetch room id from WebCast, see stacktrace for more info.", e);
|
||||
}
|
||||
|
||||
var firstPattern = Pattern.compile("room_id=([0-9]*)");
|
||||
var firstMatcher = firstPattern.matcher(html);
|
||||
var id = "";
|
||||
|
||||
if (firstMatcher.find()) {
|
||||
id = firstMatcher.group(1);
|
||||
} else {
|
||||
var secondPattern = Pattern.compile("\"roomId\":\"([0-9]*)\"");
|
||||
var secondMatcher = secondPattern.matcher(html);
|
||||
|
||||
if (secondMatcher.find()) {
|
||||
id = secondMatcher.group(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (id.isEmpty()) {
|
||||
throw new TikTokLiveOfflineHostException("Unable to fetch room ID, live host could be offline or name is misspelled");
|
||||
}
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private String fetchRoomIdFromTiktokApi(String userName) {
|
||||
public TikTokUserInfo fetchUserInfoFromTikTokApi(String userName) {
|
||||
|
||||
var params = new HashMap<>(clientSettings.getClientParameters());
|
||||
params.put("uniqueId", userName);
|
||||
params.put("sourceType", 54);
|
||||
var roomData = tiktokHttpClient.getJsonFromTikTokApi("api-live/user/room/", params);
|
||||
JsonObject roomData = null;
|
||||
try {
|
||||
roomData = tiktokHttpClient.getJsonFromTikTokApi("api-live/user/room/", params);
|
||||
} catch (Exception e) {
|
||||
|
||||
|
||||
throw new TikTokLiveRequestException("Failed to fetch pre connection room information, it happens when TikTok temporary blocks you. Try to connect again in few minutes");
|
||||
}
|
||||
|
||||
var message = roomData.get("message").getAsString();
|
||||
|
||||
if (message.equals("params_error")) {
|
||||
throw new TikTokLiveRequestException("fetchRoomIdFromTiktokApi -> Unable to fetch roomID, contact with developer");
|
||||
}
|
||||
if (message.equals("user_not_found")) {
|
||||
return new TikTokUserInfo(TikTokUserInfo.UserStatus.NotFound, "");
|
||||
}
|
||||
//live -> status 2
|
||||
//live paused -> 3
|
||||
//not live -> status 4
|
||||
var data = roomData.getAsJsonObject("data");
|
||||
var user =data.getAsJsonObject("user");
|
||||
var user = data.getAsJsonObject("user");
|
||||
var roomId = user.get("roomId").getAsString();
|
||||
var status = user.get("status").getAsInt();
|
||||
|
||||
var statusEnum = switch (status) {
|
||||
case 2 -> TikTokUserInfo.UserStatus.Live;
|
||||
case 3 -> TikTokUserInfo.UserStatus.LivePaused;
|
||||
case 4 -> TikTokUserInfo.UserStatus.Offline;
|
||||
default -> TikTokUserInfo.UserStatus.NotFound;
|
||||
};
|
||||
|
||||
return roomId;
|
||||
return new TikTokUserInfo(statusEnum, roomId);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,12 +111,18 @@ public class TikTokApiService {
|
||||
logger.info("Fetching RoomInfo");
|
||||
try {
|
||||
var response = tiktokHttpClient.getJsonFromWebcastApi("room/info/", clientSettings.getClientParameters());
|
||||
if (!response.has("data")) {
|
||||
var gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
var json = gson.toJson(response);
|
||||
throw new TikTokLiveRequestException("room info response does not contains data field: \n"+ json);
|
||||
}
|
||||
|
||||
var mapper = new LiveRoomMetaMapper();
|
||||
var liveRoomMeta = mapper.map(response);
|
||||
logger.info("RoomInfo status -> " + liveRoomMeta.getStatus());
|
||||
return liveRoomMeta;
|
||||
} catch (Exception e) {
|
||||
throw new TikTokLiveRequestException("Failed to fetch room info from WebCast, see stacktrace for more info.", e);
|
||||
throw new TikTokLiveRequestException("Failed to fetch room info from WebCast server, see stacktrace for more info.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +135,7 @@ public class TikTokApiService {
|
||||
clientSettings.getClientParameters().put("internal_ext", response.getInternalExt());
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
throw new TikTokLiveRequestException("Failed to fetch client data", e);
|
||||
throw new TikTokLiveRequestException("Failed to fetch live websocket connection data", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,37 @@
|
||||
/*
|
||||
* 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.http;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.Constants;
|
||||
import io.github.jwdeveloper.tiktok.data.dto.TikTokUserInfo;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TikTokDataChecker
|
||||
{
|
||||
public class TikTokDataChecker {
|
||||
|
||||
public CompletableFuture<Boolean> isOnlineAsync(String hostName) {
|
||||
return CompletableFuture.supplyAsync(() -> isOnline(hostName));
|
||||
@@ -17,63 +42,24 @@ public class TikTokDataChecker
|
||||
}
|
||||
|
||||
public boolean isOnline(String hostName) {
|
||||
var factory = new TikTokHttpRequestFactory(new TikTokCookieJar());
|
||||
var url = getLiveUrl(hostName);
|
||||
try {
|
||||
var response = factory.get(url);
|
||||
var titleContent = extractTitleContent(response);
|
||||
return isTitleLiveOnline(titleContent);
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new TikTokLiveRequestException("Unable to make check live online request",e);
|
||||
}
|
||||
var data = getApiService().fetchUserInfoFromTikTokApi(hostName);
|
||||
return data.getUserStatus() == TikTokUserInfo.UserStatus.Live ||
|
||||
data.getUserStatus() == TikTokUserInfo.UserStatus.LivePaused;
|
||||
}
|
||||
|
||||
public boolean isHostNameValid(String hostName) {
|
||||
var factory = new TikTokHttpRequestFactory(new TikTokCookieJar());
|
||||
var url = getProfileUrl(hostName);
|
||||
try {
|
||||
var response = factory.get(url);
|
||||
var titleContent = extractTitleContent(response);
|
||||
return isTitleHostNameValid(titleContent, hostName);
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new TikTokLiveRequestException("Unable to make check host name valid request",e);
|
||||
}
|
||||
var data = getApiService().fetchUserInfoFromTikTokApi(hostName);
|
||||
return data.getUserStatus() != TikTokUserInfo.UserStatus.NotFound;
|
||||
}
|
||||
|
||||
private boolean isTitleLiveOnline(String title) {
|
||||
return title.contains("is LIVE");
|
||||
public TikTokApiService getApiService() {
|
||||
var jar = new TikTokCookieJar();
|
||||
var factory = new TikTokHttpRequestFactory(jar);
|
||||
var client = new TikTokHttpClient(jar, factory);
|
||||
var settings = new ClientSettings();
|
||||
settings.setClientParameters(Constants.DefaultClientParams());
|
||||
var apiService = new TikTokApiService(client, Logger.getGlobal(), settings);
|
||||
return apiService;
|
||||
}
|
||||
|
||||
private boolean isTitleHostNameValid(String title, String hostName)
|
||||
{
|
||||
return title.contains(hostName);
|
||||
}
|
||||
|
||||
private String extractTitleContent(String html) {
|
||||
var regex = "<title\\b[^>]*>(.*?)<\\/title>";
|
||||
var pattern = Pattern.compile(regex);
|
||||
var matcher = pattern.matcher(html);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getLiveUrl(String hostName) {
|
||||
var sb = new StringBuilder();
|
||||
sb.append("https://www.tiktok.com/@");
|
||||
sb.append(hostName);
|
||||
sb.append("/live");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String getProfileUrl(String hostName) {
|
||||
var sb = new StringBuilder();
|
||||
sb.append("https://www.tiktok.com/@");
|
||||
sb.append(hostName);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ public class TikTokHttpClient {
|
||||
|
||||
public JsonObject getJsonFromWebcastApi(String path, Map<String, Object> parameters) {
|
||||
var get = getRequest(Constants.TIKTOK_URL_WEBCAST + path, parameters);
|
||||
|
||||
var json = JsonParser.parseString(get);
|
||||
var jsonObject = json.getAsJsonObject();
|
||||
return jsonObject;
|
||||
|
||||
@@ -22,9 +22,15 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.mappers;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.UserAttribute;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class LiveRoomMetaMapper {
|
||||
/**
|
||||
* 0 - Unknown
|
||||
@@ -46,15 +52,12 @@ public class LiveRoomMetaMapper {
|
||||
var status = data.get("status");
|
||||
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;
|
||||
default -> LiveRoomMeta.LiveRoomStatus.HostNotFound;
|
||||
};
|
||||
liveRoomMeta.setStatus(statusValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
liveRoomMeta.setStatus(LiveRoomMeta.LiveRoomStatus.HostNotFound);
|
||||
}
|
||||
|
||||
@@ -63,6 +66,61 @@ public class LiveRoomMetaMapper {
|
||||
var restricted = element.get("restricted").getAsBoolean();
|
||||
liveRoomMeta.setAgeRestricted(restricted);
|
||||
}
|
||||
|
||||
if (data.has("title")) {
|
||||
var element = data.get("title");
|
||||
var title = element.getAsString();
|
||||
liveRoomMeta.setTitie(title);
|
||||
}
|
||||
|
||||
if (data.has("stats")) {
|
||||
var statsElement = data.getAsJsonObject("stats");
|
||||
var likeElement = statsElement.get("like_count");
|
||||
var likes = likeElement.getAsInt();
|
||||
|
||||
var titalUsersElement = statsElement.get("total_user");
|
||||
var totalUsers = titalUsersElement.getAsInt();
|
||||
|
||||
|
||||
liveRoomMeta.setLikeCount(likes);
|
||||
liveRoomMeta.setTotalViewers(totalUsers);
|
||||
}
|
||||
|
||||
if(data.has("user_count"))
|
||||
{
|
||||
var element = data.get("user_count");
|
||||
var viewers = element.getAsInt();
|
||||
liveRoomMeta.setViewers(viewers);
|
||||
}
|
||||
|
||||
if(data.has("owner"))
|
||||
{
|
||||
var element = data.getAsJsonObject("owner");
|
||||
var user = getUser(element);
|
||||
liveRoomMeta.setHost(user);
|
||||
}
|
||||
|
||||
return liveRoomMeta;
|
||||
}
|
||||
|
||||
public User getUser(JsonObject jsonElement)
|
||||
{
|
||||
var id = jsonElement.get("id").getAsLong();
|
||||
var name = jsonElement.get("display_id").getAsString();
|
||||
var profileName = jsonElement.get("nickname").getAsString();
|
||||
|
||||
|
||||
var followElement =jsonElement.getAsJsonObject("follow_info");
|
||||
var followers = followElement.get("follower_count").getAsInt();
|
||||
var followingCount = followElement.get("following_count").getAsInt();
|
||||
|
||||
|
||||
var pictureElement =jsonElement.getAsJsonObject("avatar_large");
|
||||
var link = pictureElement.getAsJsonArray("url_list").get(1).getAsString();
|
||||
var picture = new Picture(link);
|
||||
|
||||
var user = new User(id,name,profileName,picture,followers,followingCount,new ArrayList<>());
|
||||
user.addAttribute(UserAttribute.LiveHost);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class TikTokGenericEventMapper {
|
||||
}
|
||||
}
|
||||
|
||||
private Method getParsingMethod(Class<?> input) throws NoSuchMethodException {
|
||||
public Method getParsingMethod(Class<?> input) throws NoSuchMethodException {
|
||||
if (methodCache.containsKey(input)) {
|
||||
return methodCache.get(input);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package io.github.jwdeveloper.tiktok.mappers;
|
||||
|
||||
import com.google.protobuf.GeneratedMessageV3;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokMessageMappingException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TikTokLiveMapper implements TikTokMapper {
|
||||
private final Map<String, Function<byte[], List<TikTokEvent>>> mappers;
|
||||
private final TikTokGenericEventMapper genericMapper;
|
||||
|
||||
public TikTokLiveMapper(TikTokGenericEventMapper genericMapper) {
|
||||
this.mappers = new HashMap<>();
|
||||
this.genericMapper = genericMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bytesToEvent(String messageName, Function<byte[], TikTokEvent> onMapping) {
|
||||
mappers.put(messageName, messagePayload -> List.of(onMapping.apply(messagePayload)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bytesToEvents(String messageName, Function<byte[], List<TikTokEvent>> onMapping) {
|
||||
mappers.put(messageName, onMapping::apply);
|
||||
}
|
||||
|
||||
public void bytesToEvent(Class<? extends GeneratedMessageV3> clazz, Function<byte[], TikTokEvent> onMapping) {
|
||||
mappers.put(clazz.getSimpleName(), messagePayload -> List.of(onMapping.apply(messagePayload)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void bytesToEvents(Class<? extends GeneratedMessageV3> clazz, Function<byte[], List<TikTokEvent>> onMapping) {
|
||||
mappers.put(clazz.getSimpleName(), onMapping::apply);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void webcastObjectToConstructor(Class<? extends GeneratedMessageV3> sourceClass, Class<? extends TikTokEvent> outputClass) {
|
||||
bytesToEvent(sourceClass, (e) -> genericMapper.mapToEvent(sourceClass, outputClass, e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GeneratedMessageV3> void webcastObjectToEvent(Class<T> source, Function<T, TikTokEvent> onMapping) {
|
||||
bytesToEvent(source, (bytes) ->
|
||||
{
|
||||
try {
|
||||
var parsingMethod = genericMapper.getParsingMethod(source);
|
||||
var sourceObject = parsingMethod.invoke(null, bytes);
|
||||
var event = onMapping.apply((T) sourceObject);
|
||||
return event;
|
||||
} catch (Exception e) {
|
||||
throw new TikTokMessageMappingException(source, "can't find parsing method", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GeneratedMessageV3> void webcastObjectToEvents(Class<T> source, Function<T, List<TikTokEvent>> onMapping) {
|
||||
bytesToEvents(source, (bytes) ->
|
||||
{
|
||||
try {
|
||||
var parsingMethod = genericMapper.getParsingMethod(source);
|
||||
var sourceObject = parsingMethod.invoke(null, bytes);
|
||||
var event = onMapping.apply((T) sourceObject);
|
||||
return event;
|
||||
} catch (Exception e) {
|
||||
throw new TikTokMessageMappingException(source, "can't find parsing method", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isRegistered(String input) {
|
||||
return mappers.containsKey(input);
|
||||
}
|
||||
|
||||
public List<TikTokEvent> handleMapping(String input, byte[] bytes) {
|
||||
if (!isRegistered(input)) {
|
||||
return List.of();
|
||||
}
|
||||
var mapper = mappers.get(input);
|
||||
var events = mapper.apply(bytes);
|
||||
return events;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.mappers.events;
|
||||
|
||||
public class TikTokChestEventHandler {
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package io.github.jwdeveloper.tiktok.mappers.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.*;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.envelop.TikTokChestEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEndEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollStartEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollUpdateEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomPinEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.chest.Chest;
|
||||
import io.github.jwdeveloper.tiktok.messages.enums.EnvelopeDisplay;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class TikTokCommonEventHandler
|
||||
{
|
||||
|
||||
@SneakyThrows
|
||||
public TikTokEvent handleWebcastControlMessage(byte[] msg) {
|
||||
var message = WebcastControlMessage.parseFrom(msg);
|
||||
return switch (message.getAction()) {
|
||||
case STREAM_PAUSED -> new TikTokLivePausedEvent();
|
||||
case STREAM_ENDED -> new TikTokLiveEndedEvent();
|
||||
case STREAM_UNPAUSED -> new TikTokLiveUnpausedEvent();
|
||||
default -> new TikTokUnhandledControlEvent(message);
|
||||
};
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public TikTokEvent handlePinMessage(byte[] msg) {
|
||||
var pinMessage = WebcastRoomPinMessage.parseFrom(msg);
|
||||
var chatMessage = WebcastChatMessage.parseFrom(pinMessage.getPinnedMessage());
|
||||
var chatEvent = new TikTokCommentEvent(chatMessage);
|
||||
return new TikTokRoomPinEvent(pinMessage, chatEvent);
|
||||
}
|
||||
|
||||
//TODO Probably not working
|
||||
@SneakyThrows
|
||||
public TikTokEvent handlePollEvent(byte[] msg) {
|
||||
var poolMessage = WebcastPollMessage.parseFrom(msg);
|
||||
return switch (poolMessage.getMessageType()) {
|
||||
case 0 -> new TikTokPollStartEvent(poolMessage);
|
||||
case 1 -> new TikTokPollEndEvent(poolMessage);
|
||||
case 2 -> new TikTokPollUpdateEvent(poolMessage);
|
||||
default -> new TikTokPollEvent(poolMessage);
|
||||
};
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public List<TikTokEvent> handleEnvelop(byte[] data) {
|
||||
var msg = WebcastEnvelopeMessage.parseFrom(data);
|
||||
if (msg.getDisplay() != EnvelopeDisplay.EnvelopeDisplayNew) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var totalDiamonds = msg.getEnvelopeInfo().getDiamondCount();
|
||||
var totalUsers = msg.getEnvelopeInfo().getPeopleCount();
|
||||
var chest = new Chest(totalDiamonds, totalUsers);
|
||||
|
||||
return List.of(new TikTokChestEvent(chest, msg));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
* 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.handlers.events;
|
||||
package io.github.jwdeveloper.tiktok.mappers.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||
@@ -53,12 +53,19 @@ public class TikTokGiftEventHandler {
|
||||
return handleGift(currentMessage);
|
||||
}
|
||||
|
||||
public List<TikTokEvent> handleGift(WebcastGiftMessage currentMessage)
|
||||
{
|
||||
public List<TikTokEvent> handleGift(WebcastGiftMessage currentMessage) {
|
||||
var userId = currentMessage.getUser().getId();
|
||||
var currentType = GiftSendType.fromNumber(currentMessage.getSendType());
|
||||
var containsPreviousMessage = giftsMessages.containsKey(userId);
|
||||
|
||||
|
||||
//If gift is not streakable just return onGift event
|
||||
if (currentMessage.getGift().getType() != 1) {
|
||||
var comboEvent = getGiftComboEvent(currentMessage, GiftSendType.Finished);
|
||||
var giftEvent = getGiftEvent(currentMessage);
|
||||
return List.of(comboEvent, giftEvent);
|
||||
}
|
||||
|
||||
if (!containsPreviousMessage) {
|
||||
if (currentType == GiftSendType.Finished) {
|
||||
return List.of(getGiftEvent(currentMessage));
|
||||
@@ -89,7 +96,6 @@ public class TikTokGiftEventHandler {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private TikTokGiftEvent getGiftEvent(WebcastGiftMessage message) {
|
||||
var gift = getGiftObject(message);
|
||||
return new TikTokGiftEvent(gift, message);
|
||||
@@ -100,15 +106,13 @@ public class TikTokGiftEventHandler {
|
||||
return new TikTokGiftComboEvent(gift, message, state);
|
||||
}
|
||||
|
||||
private Gift getGiftObject(WebcastGiftMessage giftMessage)
|
||||
{
|
||||
private Gift getGiftObject(WebcastGiftMessage giftMessage) {
|
||||
var giftId = (int) giftMessage.getGiftId();
|
||||
var gift = giftManager.findById(giftId);
|
||||
if (gift == Gift.UNDEFINED) {
|
||||
gift = giftManager.findByName(giftMessage.getGift().getName());
|
||||
}
|
||||
if (gift == Gift.UNDEFINED)
|
||||
{
|
||||
if (gift == Gift.UNDEFINED) {
|
||||
gift = giftManager.registerGift(
|
||||
giftId,
|
||||
giftMessage.getGift().getName(),
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.mappers.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokUnhandledMemberEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomInfoEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokJoinEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.RankingUser;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLikeMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLiveIntroMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastMemberMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastRoomUserSeqMessage;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TikTokRoomInfoEventHandler {
|
||||
private final TikTokRoomInfo roomInfo;
|
||||
|
||||
public TikTokRoomInfoEventHandler(TikTokRoomInfo roomInfo) {
|
||||
this.roomInfo = roomInfo;
|
||||
}
|
||||
|
||||
public TikTokEvent handleRoomInfo(Consumer<TikTokRoomInfo> consumer) {
|
||||
consumer.accept(roomInfo);
|
||||
return new TikTokRoomInfoEvent(roomInfo);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public TikTokEvent handleUserRanking(byte[] msg) {
|
||||
var message = WebcastRoomUserSeqMessage.parseFrom(msg);
|
||||
var totalUsers = message.getTotalUser();
|
||||
var userRanking = message.getRanksListList().stream().map(RankingUser::new)
|
||||
.sorted((ru1, ru2) -> Integer.compare(ru2.getScore(), ru1.getScore()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return handleRoomInfo(tikTokRoomInfo ->
|
||||
{
|
||||
tikTokRoomInfo.setTotalViewersCount(totalUsers);
|
||||
tikTokRoomInfo.updateRanking(userRanking);
|
||||
});
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public TikTokEvent handleIntro(byte[] msg) {
|
||||
var message = WebcastLiveIntroMessage.parseFrom(msg);
|
||||
var hostUser = User.map(message.getHost());
|
||||
var language = message.getLanguage();
|
||||
|
||||
return handleRoomInfo(tikTokRoomInfo ->
|
||||
{
|
||||
if(tikTokRoomInfo.getHost() == null)
|
||||
{
|
||||
tikTokRoomInfo.setHost(hostUser);
|
||||
}
|
||||
tikTokRoomInfo.setLanguage(language);
|
||||
});
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public List<TikTokEvent> handleMemberMessage(byte[] msg) {
|
||||
var message = WebcastMemberMessage.parseFrom(msg);
|
||||
|
||||
var event = switch (message.getAction()) {
|
||||
case JOINED -> new TikTokJoinEvent(message);
|
||||
case SUBSCRIBED -> new TikTokSubscribeEvent(message);
|
||||
default -> new TikTokUnhandledMemberEvent(message);
|
||||
};
|
||||
|
||||
var roomInfoEvent = this.handleRoomInfo(tikTokRoomInfo ->
|
||||
{
|
||||
tikTokRoomInfo.setViewersCount(message.getMemberCount());
|
||||
});
|
||||
|
||||
return List.of(event, roomInfoEvent);
|
||||
}
|
||||
@SneakyThrows
|
||||
public List<TikTokEvent> handleLike(byte[] msg)
|
||||
{
|
||||
var message = WebcastLikeMessage.parseFrom(msg);
|
||||
var event = new TikTokLikeEvent(message);
|
||||
var roomInfoEvent = this.handleRoomInfo(tikTokRoomInfo ->
|
||||
{
|
||||
tikTokRoomInfo.setLikesCount(event.getTotalLikes());
|
||||
});
|
||||
return List.of(event, roomInfoEvent);
|
||||
}
|
||||
}
|
||||
@@ -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.mappers.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokUnhandledSocialEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
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.data.models.Text;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSocialMessage;
|
||||
import io.github.jwdeveloper.tiktok.models.SocialTypes;
|
||||
import lombok.SneakyThrows;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TikTokSocialMediaEventHandler
|
||||
{
|
||||
private final TikTokRoomInfo roomInfo;
|
||||
private final Pattern socialMediaPattern = Pattern.compile("pm_mt_guidance_viewer_([0-9]+)_share");
|
||||
|
||||
public TikTokSocialMediaEventHandler(TikTokRoomInfo roomInfo) {
|
||||
this.roomInfo = roomInfo;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public TikTokEvent handle(byte[] msg)
|
||||
{
|
||||
var message = WebcastSocialMessage.parseFrom(msg);
|
||||
|
||||
var socialType = Text.map(message.getCommon().getDisplayText()).getKey();
|
||||
var matcher = socialMediaPattern.matcher(socialType);
|
||||
|
||||
if (matcher.find()) {
|
||||
var value = matcher.group(1);
|
||||
var number = Integer.parseInt(value);
|
||||
return new TikTokShareEvent(message, number);
|
||||
}
|
||||
|
||||
return switch (socialType) {
|
||||
case SocialTypes.LikeType -> new TikTokLikeEvent(message, roomInfo.getLikesCount());
|
||||
case SocialTypes.FollowType -> new TikTokFollowEvent(message);
|
||||
case SocialTypes.ShareType -> new TikTokShareEvent(message);
|
||||
case SocialTypes.JoinType -> new TikTokJoinEvent(message, roomInfo.getViewersCount());
|
||||
default -> new TikTokUnhandledSocialEvent(message);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -24,11 +24,9 @@ package io.github.jwdeveloper.tiktok.websocket;
|
||||
|
||||
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.Constants;
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandler;
|
||||
import io.github.jwdeveloper.tiktok.http.HttpUtils;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokCookieJar;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
@@ -44,7 +42,7 @@ public class TikTokWebSocketClient implements SocketClient {
|
||||
private final Logger logger;
|
||||
private final ClientSettings clientSettings;
|
||||
private final TikTokCookieJar tikTokCookieJar;
|
||||
private final TikTokMessageHandlerRegistration webResponseHandler;
|
||||
private final TikTokMessageHandler messageHandler;
|
||||
private final TikTokEventObserver tikTokEventHandler;
|
||||
private WebSocketClient webSocketClient;
|
||||
private TikTokWebSocketPingingTask pingingTask;
|
||||
@@ -53,12 +51,12 @@ public class TikTokWebSocketClient implements SocketClient {
|
||||
public TikTokWebSocketClient(Logger logger,
|
||||
TikTokCookieJar tikTokCookieJar,
|
||||
ClientSettings clientSettings,
|
||||
TikTokMessageHandlerRegistration webResponseHandler,
|
||||
TikTokMessageHandler messageHandler,
|
||||
TikTokEventObserver tikTokEventHandler) {
|
||||
this.logger = logger;
|
||||
this.tikTokCookieJar = tikTokCookieJar;
|
||||
this.clientSettings = clientSettings;
|
||||
this.webResponseHandler = webResponseHandler;
|
||||
this.messageHandler = messageHandler;
|
||||
this.tikTokEventHandler = tikTokEventHandler;
|
||||
isConnected = false;
|
||||
}
|
||||
@@ -74,10 +72,7 @@ public class TikTokWebSocketClient implements SocketClient {
|
||||
}
|
||||
|
||||
try {
|
||||
if (clientSettings.isHandleExistingEvents()) {
|
||||
logger.info("Handling existing events");
|
||||
webResponseHandler.handle(tikTokLiveClient, webcastResponse);
|
||||
}
|
||||
messageHandler.handle(tikTokLiveClient, webcastResponse);
|
||||
var url = getWebSocketUrl(webcastResponse);
|
||||
webSocketClient = startWebSocket(url, tikTokLiveClient);
|
||||
webSocketClient.connect();
|
||||
@@ -85,7 +80,8 @@ public class TikTokWebSocketClient implements SocketClient {
|
||||
pingingTask = new TikTokWebSocketPingingTask();
|
||||
pingingTask.run(webSocketClient);
|
||||
isConnected = true;
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e)
|
||||
{
|
||||
isConnected = false;
|
||||
throw new TikTokLiveException("Failed to connect to the websocket", e);
|
||||
}
|
||||
@@ -109,7 +105,7 @@ public class TikTokWebSocketClient implements SocketClient {
|
||||
return new TikTokWebSocketListener(url,
|
||||
headers,
|
||||
3000,
|
||||
webResponseHandler,
|
||||
messageHandler,
|
||||
tikTokEventHandler,
|
||||
liveClient);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandler;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastPushFrame;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
@@ -44,33 +44,22 @@ import java.util.Optional;
|
||||
|
||||
public class TikTokWebSocketListener extends WebSocketClient {
|
||||
|
||||
private final TikTokMessageHandlerRegistration webResponseHandler;
|
||||
private final TikTokMessageHandler messageHandler;
|
||||
private final TikTokEventObserver tikTokEventHandler;
|
||||
private final LiveClient tikTokLiveClient;
|
||||
|
||||
public TikTokWebSocketListener(URI serverUri,
|
||||
Map<String, String> httpHeaders,
|
||||
int connectTimeout,
|
||||
TikTokMessageHandlerRegistration webResponseHandler,
|
||||
TikTokMessageHandler messageHandler,
|
||||
TikTokEventObserver tikTokEventHandler,
|
||||
LiveClient tikTokLiveClient) {
|
||||
super(serverUri, new Draft_6455(), httpHeaders,connectTimeout);
|
||||
this.webResponseHandler = webResponseHandler;
|
||||
this.messageHandler = messageHandler;
|
||||
this.tikTokEventHandler = tikTokEventHandler;
|
||||
this.tikTokLiveClient = tikTokLiveClient;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake serverHandshake) {
|
||||
tikTokEventHandler.publish(tikTokLiveClient,new TikTokConnectedEvent());
|
||||
if(isNotClosing())
|
||||
{
|
||||
sendPing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMessage(ByteBuffer bytes)
|
||||
{
|
||||
@@ -85,6 +74,19 @@ public class TikTokWebSocketListener extends WebSocketClient {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake serverHandshake) {
|
||||
tikTokEventHandler.publish(tikTokLiveClient,new TikTokConnectedEvent());
|
||||
if(isNotClosing())
|
||||
{
|
||||
sendPing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onClose(int i, String s, boolean b) {
|
||||
tikTokEventHandler.publish(tikTokLiveClient,new TikTokDisconnectedEvent());
|
||||
@@ -114,7 +116,7 @@ public class TikTokWebSocketListener extends WebSocketClient {
|
||||
// sendAckId(webResponse.getFetchInterval());
|
||||
}
|
||||
|
||||
webResponseHandler.handle(tikTokLiveClient, webResponse);
|
||||
messageHandler.handle(tikTokLiveClient, webResponse);
|
||||
}
|
||||
|
||||
private Optional<WebcastPushFrame> getWebcastWebsocketMessage(byte[] buffer) {
|
||||
|
||||
@@ -69,4 +69,7 @@ public class TikTokGiftManagerTest {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -22,9 +22,12 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.handlers.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||
import io.github.jwdeveloper.tiktok.data.models.gifts.GiftSendType;
|
||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokGiftEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.messages.data.GiftStruct;
|
||||
import io.github.jwdeveloper.tiktok.messages.data.Image;
|
||||
import io.github.jwdeveloper.tiktok.messages.data.User;
|
||||
@@ -52,7 +55,20 @@ class TikTokGiftEventHandlerTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleGifts() {
|
||||
var message = getGiftMessage("example-new-name", 123, "image-new.png", 0, 1);
|
||||
var message = getGiftMessage("example-new-name", 123, "image-new.png", 0, 1,false);
|
||||
var result = handler.handleGift(message);
|
||||
|
||||
Assertions.assertEquals(2, result.size());
|
||||
|
||||
var event = (TikTokGiftEvent) result.get(0);
|
||||
var gift = event.getGift();
|
||||
Assertions.assertEquals("image-new.png",gift.getPicture().getLink());
|
||||
Assertions.assertEquals(123,gift.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleStrakableGift() {
|
||||
var message = getGiftMessage("example-new-name", 123, "image-new.png", 0, 1,true);
|
||||
var result = handler.handleGift(message);
|
||||
|
||||
Assertions.assertEquals(1, result.size());
|
||||
@@ -63,12 +79,35 @@ class TikTokGiftEventHandlerTest {
|
||||
Assertions.assertEquals(123,gift.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleStrike()
|
||||
{
|
||||
var message1 = getGiftMessage("example-new-name", 123, "image-new.png", 1, 1,true);
|
||||
var message2 = getGiftMessage("example-new-name", 123, "image-new.png", 2, 1,true);
|
||||
var message3 = getGiftMessage("example-new-name", 123, "image-new.png", 0, 1,true);
|
||||
|
||||
var result1 = handler.handleGift(message1);
|
||||
var result2 = handler.handleGift(message2);
|
||||
var result3 = handler.handleGift(message3);
|
||||
|
||||
var event1 = (TikTokGiftComboEvent) result1.get(0);
|
||||
var event2 = (TikTokGiftComboEvent) result2.get(0);
|
||||
|
||||
Assertions.assertEquals(2, result3.size());
|
||||
var event3 = (TikTokGiftComboEvent) result3.get(0);
|
||||
|
||||
Assertions.assertEquals(GiftSendType.Begin,event1.getComboState());
|
||||
Assertions.assertEquals(GiftSendType.Active,event2.getComboState());
|
||||
Assertions.assertEquals(GiftSendType.Finished,event3.getComboState());
|
||||
}
|
||||
|
||||
|
||||
public WebcastGiftMessage getGiftMessage(String giftName,
|
||||
int giftId,
|
||||
String giftImage,
|
||||
int sendType,
|
||||
int userId) {
|
||||
int userId,
|
||||
boolean streakable) {
|
||||
var builder = WebcastGiftMessage.newBuilder();
|
||||
var giftBuilder = GiftStruct.newBuilder();
|
||||
var userBuilder = User.newBuilder();
|
||||
@@ -77,6 +116,7 @@ class TikTokGiftEventHandlerTest {
|
||||
giftBuilder.setId(giftId);
|
||||
giftBuilder.setName(giftName);
|
||||
giftBuilder.setImage(Image.newBuilder().addUrlList(giftImage).build());
|
||||
giftBuilder.setType(streakable?1:0);
|
||||
userBuilder.setId(userId);
|
||||
|
||||
builder.setGiftId(giftId);
|
||||
@@ -86,4 +126,6 @@ class TikTokGiftEventHandlerTest {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,18 +1,103 @@
|
||||
/*
|
||||
* 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.http;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokLive;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TikTokLiveOnlineCheckerTest {
|
||||
|
||||
private final String TARGET_USER = "bangbetmenygy";
|
||||
public boolean enableTests = false;
|
||||
|
||||
@Test
|
||||
public void shouldTestOnline() {
|
||||
|
||||
if(!enableTests)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var TARGET_USER = "bangbetmenygy";
|
||||
var sut = new TikTokDataChecker();
|
||||
var result = sut.isOnline(TARGET_USER);
|
||||
|
||||
Assertions.assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeOffline() {
|
||||
|
||||
var TARGET_USER = "karacomparetto";
|
||||
var sut = new TikTokDataChecker();
|
||||
var result = sut.isOnline(TARGET_USER);
|
||||
|
||||
Assertions.assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeValid() throws InterruptedException {
|
||||
|
||||
var TARGET_USER = "dostawcavideo";
|
||||
var sut = new TikTokDataChecker();
|
||||
var result = sut.isHostNameValid(TARGET_USER);
|
||||
|
||||
|
||||
TikTokLive.newClient("asdasd")
|
||||
.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
for(var message : event.getResponse().getMessagesList())
|
||||
{
|
||||
if(message.getMethod().equals("WebcastGiftMessage"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var bytes = message.getMethodBytes();
|
||||
var rawMessage = WebcastGiftMessage.parseFrom(bytes);
|
||||
var giftName =rawMessage.getGift().getName();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Assertions.assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotBeValid() {
|
||||
var TARGET_USER = "dqagdagda , asdaaasd";
|
||||
var sut = new TikTokDataChecker();
|
||||
var result = sut.isHostNameValid(TARGET_USER);
|
||||
|
||||
Assertions.assertFalse(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -25,6 +25,7 @@ package io.github.jwdeveloper.tiktok;
|
||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||
import io.github.jwdeveloper.tiktok.live.GiftManager;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
|
||||
public class CustomGiftExample {
|
||||
/**
|
||||
@@ -38,7 +39,20 @@ public class CustomGiftExample {
|
||||
{
|
||||
liveClient.disconnect();
|
||||
})
|
||||
.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
var packets =event.getResponse().getMessagesList();
|
||||
for(var packet : packets)
|
||||
{
|
||||
var name = packet.getMethod();
|
||||
var data = packet.getPayload();
|
||||
if(name.equals("WebcastGiftMessage"))
|
||||
{
|
||||
// var message = WebcastGiftMessage.parseFrom(data);
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
liveClient.getLogger().info(event.getGift().getName());
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokMessageMappingException;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastChatMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import io.github.jwdeveloper.tiktok.utils.ProtocolUtils;
|
||||
|
||||
public class CustomMappingExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TikTokLive.newClient("vadimpyrography")
|
||||
.onCustomEvent(CustomChatEvent.class, (liveClient, event) ->
|
||||
{
|
||||
System.out.println("hello world!");
|
||||
})
|
||||
.onError((liveClient, event) ->
|
||||
{
|
||||
event.getException().printStackTrace();
|
||||
})
|
||||
.onMapping(mapper ->
|
||||
{
|
||||
mapper.webcastObjectToEvent(WebcastChatMessage.class, chatMessage ->
|
||||
{
|
||||
var language = chatMessage.getContentLanguage();
|
||||
var userName = chatMessage.getUser().getNickname();
|
||||
var message = chatMessage.getContent();
|
||||
return new CustomChatEvent(language, userName, message);
|
||||
});
|
||||
mapper.bytesToEvent("WebcastGiftMessage", bytes ->
|
||||
{
|
||||
try
|
||||
{
|
||||
var event = WebcastGiftMessage.parseFrom(bytes);
|
||||
return new TikTokGiftEvent(Gift.ROSA, event);
|
||||
} catch (Exception e) {
|
||||
throw new TikTokMessageMappingException("unable to map gift message!", e);
|
||||
}
|
||||
});
|
||||
|
||||
mapper.bytesToEvent("WebcastMemberMessage",bytes ->
|
||||
{
|
||||
//displaying unknown messages from tiktok
|
||||
var structure = ProtocolUtils.getProtocolBufferStructure(bytes);
|
||||
System.out.println(structure.toJson());
|
||||
return new TikTokErrorEvent(new RuntimeException("Message not implemented"));
|
||||
});
|
||||
}).buildAndConnect();
|
||||
|
||||
}
|
||||
|
||||
public static 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;
|
||||
}
|
||||
|
||||
public String getLangauge() {
|
||||
return langauge;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomChatEvent{" +
|
||||
"language='" + langauge + '\'' +
|
||||
", userName='" + userName + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,34 +22,66 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokSubNotifyEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveOfflineHostException;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class SimpleExample
|
||||
{
|
||||
public static String TIKTOK_HOSTNAME = "seanfitzness";
|
||||
public class SimpleExample {
|
||||
public static String TIKTOK_HOSTNAME = "bangbetmenygy";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
showLogo();
|
||||
// set tiktok username
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Optional checking if host name is correct
|
||||
//Optional checking if host name is correct
|
||||
if(TikTokLive.isHostNameValid(TIKTOK_HOSTNAME))
|
||||
{
|
||||
System.out.println("user name exists!");
|
||||
}
|
||||
*/
|
||||
|
||||
// Optional checking if live is online
|
||||
if (TikTokLive.isLiveOnline(TIKTOK_HOSTNAME)) {
|
||||
System.out.println("Live is online!");
|
||||
}
|
||||
|
||||
Optional checking if live is online
|
||||
if(TikTokLive.isLiveOnline(TIKTOK_HOSTNAME))
|
||||
{
|
||||
System.out.println("Live is online!");
|
||||
}
|
||||
*/
|
||||
|
||||
TikTokLive.newClient("test")
|
||||
.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
var response = event.getResponse();
|
||||
for (var message : response.getMessagesList()) {
|
||||
var name = message.getMethod();
|
||||
var binaryData = message.getPayload();
|
||||
System.out.println("Event name: " + name);
|
||||
if (name.equals("WebcastGiftEvent")) {
|
||||
try {
|
||||
WebcastGiftMessage giftMessage = WebcastGiftMessage.parseFrom(binaryData);
|
||||
var giftName = giftMessage.getGift().getName();
|
||||
var giftId = giftMessage.getGiftId();
|
||||
var userName = giftMessage.getUser().getNickname();
|
||||
System.out.println("Gift: "+giftName+" id: "+giftId+" from user: "+userName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Mapping error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).buildAndConnect();
|
||||
|
||||
|
||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
||||
.configure(clientSettings ->
|
||||
@@ -59,7 +91,6 @@ public class SimpleExample
|
||||
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
|
||||
|
||||
@@ -74,18 +105,42 @@ public class SimpleExample
|
||||
|
||||
//clientSettings.setRoomId("XXXXXXXXXXXXXXXXX");
|
||||
})
|
||||
.onConnected((liveClient, event) ->
|
||||
{
|
||||
for (var gift : liveClient.getGiftManager().getGifts()) {
|
||||
gift.getPicture().downloadImageAsync().thenAccept(image ->
|
||||
{
|
||||
|
||||
});
|
||||
}
|
||||
})
|
||||
.onWebsocketMessage((liveClient, event) ->
|
||||
{
|
||||
|
||||
|
||||
var tiktokLiveEvent = event.getEvent();
|
||||
if (tiktokLiveEvent instanceof TikTokSubNotifyEvent e) {
|
||||
System.out.println("it was subscrible event");
|
||||
}
|
||||
|
||||
})
|
||||
.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
event.getResponse();
|
||||
})
|
||||
.onGift((liveClient, event) ->
|
||||
{
|
||||
switch (event.getGift()) {
|
||||
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());
|
||||
case TIKTOK -> print(ConsoleColors.CYAN, "Thanks for TikTok");
|
||||
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());
|
||||
print(ConsoleColors.RED, "GIFT COMBO", event.getGift().getName(), event.getCombo());
|
||||
})
|
||||
.onConnected((client, event) ->
|
||||
{
|
||||
@@ -93,11 +148,11 @@ public class SimpleExample
|
||||
})
|
||||
.onDisconnected((liveClient, event) ->
|
||||
{
|
||||
print(ConsoleColors.RED,"[Disconnected]");
|
||||
print(ConsoleColors.RED, "[Disconnected]");
|
||||
})
|
||||
.onRoom((liveClient, event) ->
|
||||
.onRoomInfo((liveClient, event) ->
|
||||
{
|
||||
|
||||
var info = event.getRoomInfo();
|
||||
})
|
||||
.onFollow((liveClient, event) ->
|
||||
{
|
||||
@@ -131,9 +186,8 @@ public class SimpleExample
|
||||
System.out.println(sb);
|
||||
}
|
||||
|
||||
private static void showLogo()
|
||||
{
|
||||
System.out.println(ConsoleColors.GREEN+"""
|
||||
private static void showLogo() {
|
||||
System.out.println(ConsoleColors.GREEN + """
|
||||
|
||||
_____ _ _ _____ _ _ _ \s
|
||||
|_ _(_) | _|_ _|__ | | _| | (_)_ _____\s
|
||||
|
||||
Binary file not shown.
695
README.md
695
README.md
@@ -1,9 +1,8 @@
|
||||
<div align="center" >
|
||||
<a target="blank" >
|
||||
<img src="https://github.com/jwdeveloper/TikTokLiveJava/assets/79764581/1f9951b4-a270-4535-bf38-a6f41cdf8f43" width="15%" >
|
||||
<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>
|
||||
@@ -17,7 +16,6 @@
|
||||
</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>
|
||||
@@ -30,11 +28,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
# Introduction
|
||||
A Java library inspired by [TikTokLive](https://github.com/isaackogan/TikTokLive) and [TikTokLiveSharp](https://github.com/sebheron/TikTokLiveSharp). Use it to receive live stream events such as comments and gifts in realtime from [TikTok LIVE](https://www.tiktok.com/live) by connecting to TikTok's internal WebCast push service.
|
||||
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.
|
||||
|
||||
@@ -52,19 +47,12 @@ Do you prefer other programming languages?
|
||||
|
||||
**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
|
||||
@@ -81,7 +69,7 @@ Do you prefer other programming languages?
|
||||
<dependency>
|
||||
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
||||
<artifactId>Client</artifactId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -107,6 +95,13 @@ TikTokLive.newClient("bangbetmenygy")
|
||||
{
|
||||
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! ");
|
||||
@@ -134,7 +129,6 @@ TikTokLive.newClient("bangbetmenygy")
|
||||
settings.setTimeout(Duration.ofSeconds(2)); // Connection timeout
|
||||
settings.setLogLevel(Level.ALL); // Log level
|
||||
settings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
settings.setHandleExistingEvents(true); // Invokes all TikTok events that had occurred before connection
|
||||
settings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline
|
||||
settings.setRetryConnectionTimeout(Duration.ofSeconds(1)); // Timeout before next reconnection
|
||||
|
||||
@@ -156,36 +150,35 @@ TikTokLive.newClient("bangbetmenygy")
|
||||
|
||||
|
||||
|
||||
**Control**:
|
||||
**Control**:
|
||||
|
||||
- [onConnected](#onconnected-tiktokconnectedevent)
|
||||
- [onReconnecting](#onreconnecting-tiktokreconnectingevent)
|
||||
- [onDisconnected](#ondisconnected-tiktokdisconnectedevent)
|
||||
- [onReconnecting](#onreconnecting-tiktokreconnectingevent)
|
||||
- [onError](#onerror-tiktokerrorevent)
|
||||
|
||||
**Message**:
|
||||
**Message**:
|
||||
|
||||
- [onEvent](#onevent-tiktokevent)
|
||||
- [onShare](#onshare-tiktokshareevent)
|
||||
- [onLivePaused](#onlivepaused-tiktoklivepausedevent)
|
||||
- [onRoom](#onroom-tiktokroomevent)
|
||||
- [onGiftCombo](#ongiftcombo-tiktokgiftcomboevent)
|
||||
- [onJoin](#onjoin-tiktokjoinevent)
|
||||
- [onRoomUserInfo](#onroomuserinfo-tiktokroomuserinfoevent)
|
||||
- [onComment](#oncomment-tiktokcommentevent)
|
||||
- [onGift](#ongift-tiktokgiftevent)
|
||||
- [onLike](#onlike-tiktoklikeevent)
|
||||
- [onSubscribe](#onsubscribe-tiktoksubscribeevent)
|
||||
- [onQuestion](#onquestion-tiktokquestionevent)
|
||||
- [onEmote](#onemote-tiktokemoteevent)
|
||||
- [onLiveEnded](#onliveended-tiktokliveendedevent)
|
||||
- [onFollow](#onfollow-tiktokfollowevent)
|
||||
- [onUnhandledSocial](#onunhandledsocial-tiktokunhandledsocialevent)
|
||||
- [onLike](#onlike-tiktoklikeevent)
|
||||
- [onLiveEnded](#onliveended-tiktokliveendedevent)
|
||||
- [onRoomInfo](#onroominfo-tiktokroominfoevent)
|
||||
- [onShare](#onshare-tiktokshareevent)
|
||||
- [onGiftCombo](#ongiftcombo-tiktokgiftcomboevent)
|
||||
- [onEmote](#onemote-tiktokemoteevent)
|
||||
- [onGift](#ongift-tiktokgiftevent)
|
||||
- [onComment](#oncomment-tiktokcommentevent)
|
||||
- [onLivePaused](#onlivepaused-tiktoklivepausedevent)
|
||||
- [onLiveUnpaused](#onliveunpaused-tiktokliveunpausedevent)
|
||||
- [onJoin](#onjoin-tiktokjoinevent)
|
||||
|
||||
**Debug**:
|
||||
**Debug**:
|
||||
|
||||
- [onWebsocketResponse](#onwebsocketresponse-tiktokwebsocketresponseevent)
|
||||
- [onWebsocketUnhandledMessage](#onwebsocketunhandledmessage-tiktokwebsocketunhandledmessageevent)
|
||||
- [onWebsocketResponse](#onwebsocketresponse-tiktokwebsocketresponseevent)
|
||||
- [onWebsocketMessage](#onwebsocketmessage-tiktokwebsocketmessageevent)
|
||||
# Examples
|
||||
<br>
|
||||
@@ -193,7 +186,7 @@ TikTokLive.newClient("bangbetmenygy")
|
||||
## 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.
|
||||
Triggered when the connection is successfully established.
|
||||
|
||||
|
||||
```java
|
||||
@@ -207,6 +200,26 @@ TikTokLive.newClient("host-name")
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
## onReconnecting [TikTokReconnectingEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokReconnectingEvent.java)
|
||||
@@ -224,32 +237,12 @@ TikTokLive.newClient("host-name")
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
## 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.
|
||||
General error event. You should handle this.
|
||||
|
||||
|
||||
```java
|
||||
@@ -268,7 +261,7 @@ TikTokLive.newClient("host-name")
|
||||
## 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
|
||||
Base class for all events
|
||||
|
||||
|
||||
```java
|
||||
@@ -282,190 +275,12 @@ TikTokLive.newClient("host-name")
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
## 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>
|
||||
|
||||
## onRoom [TikTokRoomEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/room/TikTokRoomEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onRoom((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.Finsihed</p>
|
||||
|
||||
Remember if comboState is Finsihed both TikTokGiftComboEvent and TikTokGiftEvent event gets triggered
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onGiftCombo((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>
|
||||
|
||||
## onRoomUserInfo [TikTokRoomUserInfoEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/room/TikTokRoomUserInfoEvent.java)
|
||||
|
||||
|
||||
Only top 5 users in ranking has detailed data
|
||||
rest has only ID
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onRoomUserInfo((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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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.
|
||||
Triggers when a user creates a subscription.
|
||||
|
||||
|
||||
```java
|
||||
@@ -498,50 +313,12 @@ TikTokLive.newClient("host-name")
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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.
|
||||
Triggers when a user follows the streamer. Based on social event.
|
||||
|
||||
|
||||
```java
|
||||
@@ -557,13 +334,228 @@ TikTokLive.newClient("host-name")
|
||||
|
||||
<br>
|
||||
|
||||
## onUnhandledSocial [TikTokUnhandledSocialEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/TikTokUnhandledSocialEvent.java)
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## onRoomInfo [TikTokRoomInfoEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/room/TikTokRoomInfoEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onUnhandledSocial((liveClient, event) ->
|
||||
.onRoomInfo((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>
|
||||
|
||||
## 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.Finsihed</p>
|
||||
|
||||
Remember if comboState is Finsihed both TikTokGiftComboEvent and TikTokGiftEvent event gets triggered
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onGiftCombo((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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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) ->
|
||||
{
|
||||
|
||||
})
|
||||
@@ -580,30 +572,11 @@ TikTokLive.newClient("host-name")
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
.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();
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
@@ -613,16 +586,16 @@ TikTokLive.newClient("host-name")
|
||||
## 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 a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case.
|
||||
Triggered every time a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onWebsocketMessage((liveClient, event) ->
|
||||
{
|
||||
.onWebsocketMessage((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
@@ -635,72 +608,72 @@ TikTokLive.newClient("host-name")
|
||||
|
||||
```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 {
|
||||
/**
|
||||
*
|
||||
* 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();
|
||||
.addListener(customListener)
|
||||
.buildAndConnect();
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method in TikTokEventListener should meet 4 requirements to be detected
|
||||
* - must have @TikTokEventHandler annotation
|
||||
* - must have 2 parameters
|
||||
* - first parameter must be LiveClient
|
||||
* - second must be class that extending TikTokEvent
|
||||
*/
|
||||
|
||||
public static class CustomListener implements TikTokEventListener {
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onLike(LiveClient liveClient, TikTokLikeEvent event) {
|
||||
System.out.println(event.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method in TikTokEventListener should meet 4 requirements to be detected
|
||||
* - must have @TikTokEventHandler annotation
|
||||
* - must have 2 parameters
|
||||
* - first parameter must be LiveClient
|
||||
* - second must be class that extending TikTokEvent
|
||||
*/
|
||||
|
||||
public static class CustomListener implements TikTokEventListener {
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onLike(LiveClient liveClient, TikTokLikeEvent event) {
|
||||
System.out.println(event.toString());
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onError(LiveClient liveClient, TikTokErrorEvent event) {
|
||||
// event.getException().printStackTrace();
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onComment(LiveClient liveClient, TikTokCommentEvent event) {
|
||||
var userName = event.getUser().getName();
|
||||
var text = event.getText();
|
||||
liveClient.getLogger().info(userName + ": " + text);
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onGift(LiveClient liveClient, TikTokGiftEvent event) {
|
||||
var message = switch (event.getGift()) {
|
||||
case ROSE -> "Thanks :)";
|
||||
case APPETIZERS -> ":OO";
|
||||
case APRIL -> ":D";
|
||||
case TIKTOK -> ":P";
|
||||
case CAP -> ":F";
|
||||
default -> ":I";
|
||||
};
|
||||
liveClient.getLogger().info(message);
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onAnyEvent(LiveClient liveClient, TikTokEvent event) {
|
||||
liveClient.getLogger().info(event.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onError(LiveClient liveClient, TikTokErrorEvent event) {
|
||||
// event.getException().printStackTrace();
|
||||
}
|
||||
|
||||
//
|
||||
@TikTokEventHandler
|
||||
public void onComment(LiveClient liveClient, TikTokCommentEvent event) {
|
||||
var userName = event.getUser().getName();
|
||||
var text = event.getText();
|
||||
liveClient.getLogger().info(userName + ": " + text);
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onGift(LiveClient liveClient, TikTokGiftEvent event) {
|
||||
var message = switch (event.getGift()) {
|
||||
case ROSE -> "Thanks :)";
|
||||
case APPETIZERS -> ":OO";
|
||||
case APRIL -> ":D";
|
||||
case TIKTOK -> ":P";
|
||||
case CAP -> ":F";
|
||||
default -> ":I";
|
||||
};
|
||||
liveClient.getLogger().info(message);
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onAnyEvent(LiveClient liveClient, TikTokEvent event) {
|
||||
liveClient.getLogger().info(event.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -22,11 +22,20 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.tools.collector;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokLive;
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
|
||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.client.TikTokMessageCollectorClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class RunCollector {
|
||||
|
||||
@@ -38,22 +47,38 @@ public class RunCollector {
|
||||
public static void main(String[] args) throws SQLException, IOException {
|
||||
|
||||
TikTokMessageCollectorClient.create("giftsCollector")
|
||||
.addUser("crece.sara")
|
||||
.addUser("moniczkka")
|
||||
//.addUser("crece.sara")
|
||||
//.addUser("moniczkka")
|
||||
.addUser("valeria.viral")
|
||||
// .addUser("cbcgod")
|
||||
// .addUser("psychotropnazywo")
|
||||
// .addUser("accordionistka")
|
||||
.addEventFilter(WebcastGiftMessage.class)
|
||||
//.addEventFilter(WebcastGiftMessage.class)
|
||||
.addOnBuilder(liveClientBuilder ->
|
||||
{
|
||||
liveClientBuilder.onGiftCombo((liveClient, event) ->
|
||||
{
|
||||
liveClient.getLogger().setLevel(Level.OFF);
|
||||
var gifts = liveClient.getGiftManager().getGifts();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.append("GIFT COMBO User: " + event.getUser().getProfileName()+" ");
|
||||
sb.append("Name: " + event.getGift().getName() + " ");
|
||||
sb.append("Combo: " + event.getCombo() + " ");
|
||||
sb.append("COST: " + event.getGift().getDiamondCost() + " ");
|
||||
sb.append("STATE: " + event.getComboState() + " ");
|
||||
System.out.println(sb.toString());
|
||||
});
|
||||
|
||||
liveClientBuilder.onGift((liveClient, event) ->
|
||||
{
|
||||
liveClient.getLogger().setLevel(Level.OFF);
|
||||
var gifts = liveClient.getGiftManager().getGifts();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.append("GIFT User: " + event.getUser().getProfileName()+" ");
|
||||
sb.append("Name: " + event.getGift().getName() + " ");
|
||||
sb.append("COST: " + event.getGift().getDiamondCost() + " ");
|
||||
sb.append("Combo: " + event.getCombo() + " ");
|
||||
System.out.println(sb.toString());
|
||||
});
|
||||
|
||||
@@ -31,6 +31,6 @@ public class TikTokMessageCollectorClient
|
||||
|
||||
public static TikTokMessagessCollectorBuilder create(MessageCollector messageCollector, String outputName)
|
||||
{
|
||||
return new TikTokMessagessCollectorBuilder(outputName);
|
||||
return new TikTokMessagessCollectorBuilder(messageCollector,outputName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ import com.google.protobuf.ByteString;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
||||
import io.github.jwdeveloper.tiktok.utils.ProtocolUtils;
|
||||
|
||||
public class MessageUtil
|
||||
{
|
||||
public class MessageUtil {
|
||||
public static String getContent(WebcastResponse.Message message) {
|
||||
try {
|
||||
var methodName = message.getMethod();
|
||||
@@ -38,7 +38,7 @@ public class MessageUtil
|
||||
return JsonUtil.messageToJson(deserialized);
|
||||
} catch (Exception ex) {
|
||||
|
||||
return ConsoleColors.RED+ "Can not find mapper for "+message.getMethod();
|
||||
return ConsoleColors.RED + "Can not find mapper for " + message.getMethod();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,11 +49,13 @@ public class MessageUtil
|
||||
var parseMethod = inputClazz.getDeclaredMethod("parseFrom", byte[].class);
|
||||
var deserialized = parseMethod.invoke(null, bytes);
|
||||
return JsonUtil.messageToJson(deserialized);
|
||||
} catch (Exception ex)
|
||||
{
|
||||
} catch (Exception ex) {
|
||||
var sb = new StringBuilder();
|
||||
sb.append("Can not find mapper for "+methodName);
|
||||
sb.append("Can not find protocolbuffer file message representation for " + methodName);
|
||||
sb.append("\n");
|
||||
var structure = ProtocolUtils.getProtocolBufferStructure(bytes);
|
||||
var json =structure.toJson();
|
||||
sb.append(json);
|
||||
//String jsonString = JsonFormat.printToString(protobufData);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
4344
Tools-EventsCollector/src/main/resources/ab.json
Normal file
4344
Tools-EventsCollector/src/main/resources/ab.json
Normal file
File diff suppressed because one or more lines are too long
1452
Tools-EventsCollector/src/main/resources/dupa.json
Normal file
1452
Tools-EventsCollector/src/main/resources/dupa.json
Normal file
File diff suppressed because one or more lines are too long
1303
Tools-EventsCollector/src/main/resources/giftsCollector.json
Normal file
1303
Tools-EventsCollector/src/main/resources/giftsCollector.json
Normal file
File diff suppressed because one or more lines are too long
264
Tools-EventsCollector/src/main/resources/jw.json
Normal file
264
Tools-EventsCollector/src/main/resources/jw.json
Normal file
@@ -0,0 +1,264 @@
|
||||
{
|
||||
"RoomMessage": [
|
||||
{
|
||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQmofs1NO1z8sXGKGW59iz55WpZSDxhpnNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:06:35.153694400"
|
||||
},
|
||||
{
|
||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQjPTq1re3z8sXGKGW59iz55WpZSCI5ZzNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:07:36.360859900"
|
||||
},
|
||||
{
|
||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQocTpm8nCz8sXGKGW59iz55WpZSDSkrTNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:13:58.969658600"
|
||||
},
|
||||
{
|
||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQ8a6h9abiz8sXGKGW59iz55WpZSDS2PbNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:32:09.427463"
|
||||
}
|
||||
],
|
||||
"WebcastChatMessage": [
|
||||
{
|
||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglqWQ1+2VqWUYoZbn2LPnlallIMjgmc28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAerYmc28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaA2FzZHICemiSAQIwAZoBFAoOdXNlcl90eXBlX3J1bGUQoMIemgEYChFjb21tdW5pdHktZmxhZ2dlZBDZt9oBmgEaCg5jb21tZW50YXRvcl9pZBCFiKX0gI2FlmCaARIKB2RlZmF1bHQQ8LqSkbvBggOaARAKC2RlZmF1bHRfYXBwEJBOmgERCgZyYW5rVjMQ4/2WkbvBggOaARoKD3R0cF9ydWxlX3JlcmFuaxDw5/SVu8GCA5oBGgoOdGltZXN0YW1wX2Rlc2MQkMWV28rtzq4BmgE1Cip0aWtjYXN0X2NvbW11bml0eV9jb21tZW50XzE4ODY2X3Y3X3I2NTUwNjkQkdSYkbvBggOaAToKL3Rpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2OV9kZXNjEO7S95W7wYIDmgEaCg9pZGNfcnVsZV9yZXJhbmsQ8Jv+qLvBggOaARYKC3YxM19yNzEyMDg4EPCb/qi7wYIDmgEWCgt2MTJfcjcwMjA3NRDwm/6ou8GCA5oBFgoLdjEzX3I3NjUxNjYQ8Jv+qLvBggOaARYKC3YxM19yNzY1MTY3EPCb/qi7wYIDmgEWCgt2MTNfcjc2NTE2ORDwm/6ou8GCA5oBFgoLdjEzX3I3NjcxMjIQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA0EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwNRDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MDYQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA3EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwOBDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MTAQ8Jv+qLvBggOaARoKD2lkY19ydWxlX3JlcmFuaxDwm/6ou8GCA6IBAQA=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:06:47.126429700"
|
||||
},
|
||||
{
|
||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglqWQ1+2VqWUYoZbn2LPnlallIMjgmc28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAerYmc28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaA2FzZHICemiSAQIwAZoBFAoOdXNlcl90eXBlX3J1bGUQoMIemgEYChFjb21tdW5pdHktZmxhZ2dlZBDZt9oBmgEaCg5jb21tZW50YXRvcl9pZBCFiKX0gI2FlmCaARIKB2RlZmF1bHQQ8LqSkbvBggOaARAKC2RlZmF1bHRfYXBwEJBOmgERCgZyYW5rVjMQ4/2WkbvBggOaARoKD3R0cF9ydWxlX3JlcmFuaxDw5/SVu8GCA5oBGgoOdGltZXN0YW1wX2Rlc2MQkMWV28rtzq4BmgE1Cip0aWtjYXN0X2NvbW11bml0eV9jb21tZW50XzE4ODY2X3Y3X3I2NTUwNjkQkdSYkbvBggOaAToKL3Rpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2OV9kZXNjEO7S95W7wYIDmgEaCg9pZGNfcnVsZV9yZXJhbmsQ8Jv+qLvBggOaARYKC3YxM19yNzEyMDg4EPCb/qi7wYIDmgEWCgt2MTJfcjcwMjA3NRDwm/6ou8GCA5oBFgoLdjEzX3I3NjUxNjYQ8Jv+qLvBggOaARYKC3YxM19yNzY1MTY3EPCb/qi7wYIDmgEWCgt2MTNfcjc2NTE2ORDwm/6ou8GCA5oBFgoLdjEzX3I3NjcxMjIQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA0EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwNRDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MDYQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA3EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwOBDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MTAQ8Jv+qLvBggOaARoKD2lkY19ydWxlX3JlcmFuaxDwm/6ou8GCA6IBAQA=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:07:36.364450900"
|
||||
},
|
||||
{
|
||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglp7Ix/SVqWUYoZbn2LPnlallIOvxm828MTABSAJQAnoIdXNlYXN0MmGwAQK4AQLAAQLIAfPqm828MRKVCgiFiMi2nP/V4l0aDG5vdGlmaWNhdGlvbkr+BQq6AWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPSUyQmRnaCUyRmxmVDNmUm4zZWZtQjMlMkZCSXU0NHJXUSUzRAqoAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1XRkNLeXMyTVAyMlclMkZGR0lRdzFCMHpIQ1l6RSUzRAqqAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT0lMkZITVJNaEFYQ3lFbXZkbyUyRnB6aVRDNjQ0c2hNJTNECqgBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvODM5MTkxYWVkMjMzNGMxODIxMjVjYzRhMDMzMDRjY2F+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWt2V3FUWmFOclBsTSUyRkVlV2hKakJ5TzkxUG5nJTNEEjwxMDB4MTAwL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvODM5MTkxYWVkMjMzNGMxODIxMjVjYzRhMDMzMDRjY2FSjAMKwgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC84MzkxOTFhZWQyMzM0YzE4MjEyNWNjNGEwMzMwNGNjYX50cGx2LXRpa3Rva3gtY29tcHJlc3NfcXVhbGl0eV8zMDo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNjk5OTE2NDAwJngtc2lnbmF0dXJlPU5vMWN2RXB2Yno1QXFtTnZmQzh1ZDl0d3hKTSUzRArEAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLmpwZWc/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9eEduYkFuVUFFckZKUzFTcW1OME5vJTJGOUVRM1UlM0SyAQgI3QwQ1BEYAboBAIICALICCm5pZXRvcGVyejDyAkxNUzR3TGpBQkFBQUF6emlzM0d0blI4bUJsVEIwQjZCY3RDVHBEd0NrMV9lc1hLckJTZkZOVTRCM0hkYXVESEkxUzl6QTM4TGR0cklWGgVzaWVtYXICcGySAQIgAZoBFAoOdXNlcl90eXBlX3J1bGUQwJoMmgEXChFjb21tdW5pdHktZmxhZ2dlZBCorRqaARoKDmNvbW1lbnRhdG9yX2lkEIWIyLac/9XiXZoBEgoHZGVmYXVsdBDg2uShu8GCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDjsaCku8GCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEMiPx6a7wYIDmgEaCg50aW1lc3RhbXBfZGVzYxC4ncPKyu3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORDhz6Wku8GCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQn7/9qLvBggOaARoKD2lkY19ydWxlX3JlcmFuaxDIw9C5u8GCA5oBFgoLdjEzX3I3MTIwODgQyMPQubvBggOaARYKC3YxMl9yNzAyMDc1EMjD0Lm7wYIDmgEWCgt2MTNfcjc2NTE2NhDIw9C5u8GCA5oBFgoLdjEzX3I3NjUxNjcQyMPQubvBggOaARYKC3YxM19yNzY1MTY5EMjD0Lm7wYIDmgEWCgt2MTNfcjc2NzEyMhDIw9C5u8GCA5oBFgoLdjEzX3I3NzA4MDQQyMPQubvBggOaARYKC3YxM19yNzcwODA1EMjD0Lm7wYIDmgEWCgt2MTNfcjc3MDgwNhDIw9C5u8GCA5oBFgoLdjEzX3I3NzA4MDcQyMPQubvBggOaARYKC3YxM19yNzcwODA4EMjD0Lm7wYIDmgEWCgt2MTNfcjc3MDgxMBDIw9C5u8GCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEMjD0Lm7wYIDogEBAA==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:07:36.364951"
|
||||
},
|
||||
{
|
||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRChlqfexJ+WqWUYoZbn2LPnlallINPCsc28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAcy+sc28MRKfCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvoFCrgBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9eWRWc0c3JTJCYTRUbU9XRXFPSGd6JTJCQmVRU1k2YyUzRAqmAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT02TVhuNmV6WVQzNHFVY3N1TXFRMUcxMFExZVklM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9ODE0Sk91T0M4ZHlvVGQ5U1Y5TkI3UjZSYjY0JTNECqwBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVhFM0toMjVCeXMwRFUlMkYlMkZVa3JlZCUyQkxadUJ4VSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxUo4DCsIBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIud2VicD94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1DVEs2Ukw2dWVOSlJ6Ujl0cEtKNUYzQW90cEklM0QKxgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX50cGx2LXRpa3Rva3gtY29tcHJlc3NfcXVhbGl0eV8zMDo3Mjo3Mi5qcGVnP3gtZXhwaXJlcz0xNjk5OTE2NDAwJngtc2lnbmF0dXJlPUhUbSUyRjdYQUxBMnNKWSUyQkgxanQxM3pBR0ZzTTAlM0SyAQYIhAUQqBW6AQCCAgCyAg1kb3N0YXdjYXZpZGVv8gJMTVM0d0xqQUJBQUFBcWtGdC1FSmZHNERIVXVZeW1RQnNTX2o2ZHJVaXl0WjMzdEVNeWJ1YUdGLWlYejdfV1lJcF9qRDRwSUNWTWp3ZBoDYXNkcgJ6aJIBAjABmgEUCg51c2VyX3R5cGVfcnVsZRCgwh6aARgKEWNvbW11bml0eS1mbGFnZ2VkENm32gGaARoKDmNvbW1lbnRhdG9yX2lkEIWIpfSAjYWWYJoBEgoHZGVmYXVsdBCwxunKvMGCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDj2JLLvMGCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEJj7y8+8wYIDmgEaCg50aW1lc3RhbXBfZGVzYxDosb6hye3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORCRr5TLvMGCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQ7q3zz7zBggOaARoKD2lkY19ydWxlX3JlcmFuaxCYr9XivMGCA5oBFgoLdjEzX3I3MTIwODgQmK/V4rzBggOaARYKC3YxMl9yNzAyMDc1EJiv1eK8wYIDmgEWCgt2MTNfcjc2NTE2NhCYr9XivMGCA5oBFgoLdjEzX3I3NjUxNjcQmK/V4rzBggOaARYKC3YxM19yNzY1MTY5EJiv1eK8wYIDmgEWCgt2MTNfcjc2NzEyMhCYr9XivMGCA5oBFgoLdjEzX3I3NzA4MDQQmK/V4rzBggOaARYKC3YxM19yNzcwODA1EJiv1eK8wYIDmgEWCgt2MTNfcjc3MDgwNhCYr9XivMGCA5oBFgoLdjEzX3I3NzA4MDcQmK/V4rzBggOaARYKC3YxM19yNzcwODA4EJiv1eK8wYIDmgEWCgt2MTNfcjc3MDgxMBCYr9XivMGCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEJiv1eK8wYIDogEBAA==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:13:58.973166900"
|
||||
},
|
||||
{
|
||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRChlt6SlaOWqWUYoZbn2LPnlallIMLsss28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAY7pss28MRKZCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvQFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9ODE0Sk91T0M4ZHlvVGQ5U1Y5TkI3UjZSYjY0JTNECqYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTZNWG42ZXpZVDM0cVVjc3VNcVExRzEwUTFlWSUzRAqoAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YTll0ZU5yaXVjcjJSeGZDVEdZR1JHJTJGNXZTYyUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxUo4DCsIBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIud2VicD94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1DVEs2Ukw2dWVOSlJ6Ujl0cEtKNUYzQW90cEklM0QKxgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX50cGx2LXRpa3Rva3gtY29tcHJlc3NfcXVhbGl0eV8zMDo3Mjo3Mi5qcGVnP3gtZXhwaXJlcz0xNjk5OTE2NDAwJngtc2lnbmF0dXJlPUhUbSUyRjdYQUxBMnNKWSUyQkgxanQxM3pBR0ZzTTAlM0SyAQYIhAUQqBW6AQCCAgCyAg1kb3N0YXdjYXZpZGVv8gJMTVM0d0xqQUJBQUFBcWtGdC1FSmZHNERIVXVZeW1RQnNTX2o2ZHJVaXl0WjMzdEVNeWJ1YUdGLWlYejdfV1lJcF9qRDRwSUNWTWp3ZBoDYXNkcgJ6aJIBAjABmgEUCg51c2VyX3R5cGVfcnVsZRCgwh6aARgKEWNvbW11bml0eS1mbGFnZ2VkENm32gGaARoKDmNvbW1lbnRhdG9yX2lkEIWIpfSAjYWWYJoBEgoHZGVmYXVsdBCY3pnVvMGCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDj37nZvMGCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEICT/Nm8wYIDmgEaCg50aW1lc3RhbXBfZGVzYxCAmo6Xye3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORCRtrvZvMGCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQ7rSa3rzBggOaARoKD2lkY19ydWxlX3JlcmFuaxCAx4XtvMGCA5oBFgoLdjEzX3I3MTIwODgQgMeF7bzBggOaARYKC3YxMl9yNzAyMDc1EIDHhe28wYIDmgEWCgt2MTNfcjc2NTE2NhCAx4XtvMGCA5oBFgoLdjEzX3I3NjUxNjcQgMeF7bzBggOaARYKC3YxM19yNzY1MTY5EIDHhe28wYIDmgEWCgt2MTNfcjc2NzEyMhCAx4XtvMGCA5oBFgoLdjEzX3I3NzA4MDQQgMeF7bzBggOaARYKC3YxM19yNzcwODA1EIDHhe28wYIDmgEWCgt2MTNfcjc3MDgwNhCAx4XtvMGCA5oBFgoLdjEzX3I3NzA4MDcQgMeF7bzBggOaARYKC3YxM19yNzcwODA4EIDHhe28wYIDmgEWCgt2MTNfcjc3MDgxMBCAx4XtvMGCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEIDHhe28wYIDogEBAA==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:13:58.974165"
|
||||
},
|
||||
{
|
||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglq+yx6aWqWUYoZbn2LPnlallIIPXtM28MTABSAJQAnoIdXNlYXN0MmGwAQK4AQLAAQLIAa7StM28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaCGFkYXNkYXNkcgJ0cpIBAjABmgEUCg51c2VyX3R5cGVfcnVsZRCgwh6aARgKEWNvbW11bml0eS1mbGFnZ2VkEPzApwOaARoKDmNvbW1lbnRhdG9yX2lkEIWIpfSAjYWWYJoBEgoHZGVmYXVsdBCIjsPjvMGCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDj5uDnvMGCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEIi7pei8wYIDmgEaCg50aW1lc3RhbXBfZGVzYxD48eSIye3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORCam+PnvMGCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQ5d3A7LzBggOaARoKD2lkY19ydWxlX3JlcmFuaxCI7677vMGCA5oBFgoLdjEzX3I3MTIwODgQiO+u+7zBggOaARYKC3YxMl9yNzAyMDc1EIjvrvu8wYIDmgEWCgt2MTNfcjc2NTE2NhCI7677vMGCA5oBFgoLdjEzX3I3NjUxNjcQiO+u+7zBggOaARYKC3YxM19yNzY1MTY5EIjvrvu8wYIDmgEWCgt2MTNfcjc2NzEyMhCI7677vMGCA5oBFgoLdjEzX3I3NzA4MDQQiO+u+7zBggOaARYKC3YxM19yNzcwODA1EIjvrvu8wYIDmgEWCgt2MTNfcjc3MDgwNhCI7677vMGCA5oBFgoLdjEzX3I3NzA4MDcQiO+u+7zBggOaARYKC3YxM19yNzcwODA4EIjvrvu8wYIDmgEWCgt2MTNfcjc3MDgxMBCI7677vMGCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEPD2rvu8wYIDogEBAA==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:14:07.736142"
|
||||
},
|
||||
{
|
||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRChlqWizKeWqWUYoZbn2LPnlallIN7Htc28MTABSAJQAnoIdXNlYXN0MmGwAQK4AQLAAQLIAafEtc28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaA2FzZHICemiSAQIwAZoBFAoOdXNlcl90eXBlX3J1bGUQoMIemgEYChFjb21tdW5pdHktZmxhZ2dlZBDZt9oBmgEaCg5jb21tZW50YXRvcl9pZBCFiKX0gI2FlmCaARIKB2RlZmF1bHQQ+K2z6rzBggOaARAKC2RlZmF1bHRfYXBwEJBOmgERCgZyYW5rVjMQ45PD7LzBggOaARoKD3R0cF9ydWxlX3JlcmFuaxDg4pXvvMGCA5oBGgoOdGltZXN0YW1wX2Rlc2MQoMr0gcntzq4BmgE1Cip0aWtjYXN0X2NvbW11bml0eV9jb21tZW50XzE4ODY2X3Y3X3I2NTUwNjkQkerE7LzBggOaAToKL3Rpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2OV9kZXNjEO7oo/G8wYIDmgEaCg9pZGNfcnVsZV9yZXJhbmsQ4Jafgr3BggOaARYKC3YxM19yNzEyMDg4EOCWn4K9wYIDmgEWCgt2MTJfcjcwMjA3NRDglp+CvcGCA5oBFgoLdjEzX3I3NjUxNjYQ4Jafgr3BggOaARYKC3YxM19yNzY1MTY3EOCWn4K9wYIDmgEWCgt2MTNfcjc2NTE2ORDglp+CvcGCA5oBFgoLdjEzX3I3NjcxMjIQ4Jafgr3BggOaARYKC3YxM19yNzcwODA0EOCWn4K9wYIDmgEWCgt2MTNfcjc3MDgwNRDglp+CvcGCA5oBFgoLdjEzX3I3NzA4MDYQ4Jafgr3BggOaARYKC3YxM19yNzcwODA3EOCWn4K9wYIDmgEWCgt2MTNfcjc3MDgwOBDglp+CvcGCA5oBFgoLdjEzX3I3NzA4MTAQ4Jafgr3BggOaARoKD2lkY19ydWxlX3JlcmFuaxDglp+CvcGCA6IBAQA=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:14:22.037528800"
|
||||
}
|
||||
],
|
||||
"WebcastLiveIntroMessage": [
|
||||
{
|
||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:06:35.159195800"
|
||||
},
|
||||
{
|
||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:07:36.363450600"
|
||||
},
|
||||
{
|
||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:13:58.972664900"
|
||||
},
|
||||
{
|
||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:32:09.430963500"
|
||||
}
|
||||
],
|
||||
"WebcastRoomUserSeqMessage": [
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZafuvz/lallGKGW59iz55WpZSDshp/NvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAESngUSmQUIhoiO8qqbjuBiGgttYW5pdG91MTIyMUqDBAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqbAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1CUDJDUnd4JTJGM3VUJTJGVHlpUkRycTIzakY1c09zJTNECpcBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPU14ekJvbWpDRWM0RGJNeVdud3N1dWtjYXFFayUzRBItMTAweDEwMC9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0ugEAggIAqAIBsgILbWFuaXRvdTEyMjHyAkxNUzR3TGpBQkFBQUFDUlhtN2d5WHpqdnJOVzhiQVgwMWRIYjRQQ0JmcHBoUUJsTFlsN3QzaVYzNjN6Qi1mOXY2djZJMVByX2UtSjNxokATNzExNTc0OTkyMzEyMzA2OTk1OBgCGAI4AQ==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:08:13.650764700"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZaf2OeClqllGKGW59iz55WpZSDStaDNvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAEYATgC",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:08:36.238853400"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZavypSElqllGKGW59iz55WpZSCJi6HNvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAEYATgC",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:08:46.700698300"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZabh4KFlqllGKGW59iz55WpZSC1wKHNvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAEYATgD",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:08:53.950839200"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaq0vC6l6llGKGW59iz55WpZSD/p/rNvDEYATgK",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:33:08.727200600"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZaTwq67l6llGKGW59iz55WpZSCzw/rNvDEYATgL",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:33:11.956418700"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaYnoa8l6llGKGW59iz55WpZSDG7/rNvDEYAjgM",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:33:17.383803400"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZanrPO9l6llGKGW59iz55WpZSCU5PvNvDEYATgM",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:33:32.712808600"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJah8LnJl6llGKGW59iz55WpZSCks4HOvDES0QQSzAQIhoiJ4Nqz7rtjGglkb21pbmlrNTRKtQMKtQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTQzTmhEU3h4cExKVlNPYmpWOWNUakVQJTJCR25vJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1XZkxXRm5ha0EzWjc0a3hIa1N3Zm9IRmVTJTJGSSUzRBJDMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYboBAIICAKgCAbICDmRvbWluaWt3YXNpbHVr8gJMTVM0d0xqQUJBQUFBaVpaMlpDQl94TjZlYUJwc0wyLU9xMy1yRTdmajV5ZkRWTnotZmZUUmUyWnlLd3dMdlh2ajF2all5RnJ6WXBzN6JAEzcxNjc0MDE0MTg4MzAyNjczOTgYARgCOA0=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:35:05.042649"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJa7+vLPl6llGKGW59iz55WpZSDEyITOvDES2gQS1QQIhoirsOTthPleGhBCcmFqYW4gb2tvbmVyIFhESroDCrgBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9em1nSEN4OXVSZXNYQ1hWaDZoZEJQJTJGMCUyRldMQSUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzZ+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJWQjNYM0N3Y1VDMkFJejIlMkZ3cFVqRDBhbjVNJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNroBAIICAKgCAbICC2FudGVrMTI0NTcx8gJMTVM0d0xqQUJBQUFBM3M2akdBak5wbzFFdTdnWnV0Y3FPZWhIMkFzdGdYOWQwcFBJWHFYSG9KTnRDX29BcTJ5ZXNsb2tVVEpaazBUSKJAEzY4NDE1NTIxNDgyNzE2NDU3MDIYARgCOA4=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:35:56.425306600"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZbtiITbl6llGKGW59iz55WpZSDw/4nOvDEYATgO",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:37:25.577177500"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaKs9fsl6llGKGW59iz55WpZSCa0ZLOvDESxgQSwQQIgICw8vjIy/wDGgTwn6ugSrgDCrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RnFGTERxVWE0V0dLYUklMkJYc0Q3RklWQ3dsYkUlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1idEFla3VPR1NmJTJCZ282RFFwU05GNDNFM3lnUSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNza6AQCCAgCoAgGyAgYxanVsYWfyAkxNUzR3TGpBQkFBQUFydEh0azg5SV9HWTktUlZQc3E3VmtDV2s3SDJ4WmJLUVpoWmEwY2o0a3RxWE5uVHhhQm0zNENwV1FvWWxwT251okASMjg2MzEwOTM2MTc5NjM4MjcyGAEYATgO",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:39:46.883152900"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZbI6NLtl6llGKGW59iz55WpZSCqipPOvDEYATgP",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:39:54.132292500"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaukoXzl6llGKGW59iz55WpZSDt25XOvDESxQQSwAQIhoimzuOSnqdiGgNPTE9KtgMKtAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2Q5MTFhNjkxNDk3ZmUzM2M5MmQwOTUxNGVlOTBhYjkwfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SYlZHdjVReHdwWW4zUDE2VW5lMlRJTG9wOTAlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2Q5MTFhNjkxNDk3ZmUzM2M5MmQwOTUxNGVlOTBhYjkwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1uN3FjRm1HYUsyTyUyQnFsNXBiNmF5VDc4eG4ybyUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTC6AQCCAgCoAgGyAgdvbG9fdjEy8gJMTVM0d0xqQUJBQUFBalFUeHpRcEZXS0RNaHdDQ3QtWWpIQ1dIM3gxRlI4UW82bm4yVkNyRjFKZlVacTFEcnZNclF4Y0VRUF9lWnAzRaJAEzcwODM3MzE4NTA1MTAzMDQyNjIYARgCOBA=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:40:37.563873900"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZaS0rvzl6llGKGW59iz55WpZSC89pXOvDEYATgQ",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:40:40.781947100"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaSot/9l6llGKGW59iz55WpZSCe+JrOvDESzwUSygUIhoDrtqn685FcGgNlbG9KvQQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9akdJc1VBbGxESmNmbWkwaHVzME9PNHVhT0xRJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUdsMTh0V0tCeXA1NUVBNU1oQ1Nhd0pIaVF3dyUzRAqqAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JWUo1ZVVabEJnN0MlMkZEVk1pbkttbCUyRno0MDFJJTNEEjwxMDB4MTAwL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGK6AQCCAgCoAgGyAgpyYW5kb21tZW1q8gJMTVM0d0xqQUJBQUFBWlZsSldueTFLQ0l6T1c2bW4xcmZBOG0yNHhLd2VKRXlHS2g4SDFVclFnZ2hoTm1zaXZxTTV4Y21nSm14ZEFuY6JAEzY2MzkzNzg3NzkwNTUyNDMyNzAYARgCOBE=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:42:03.040632200"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJbMro3+l6llGKGW59iz55WpZSCskJvOvDEYATgR",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:42:06.280761800"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZbzooKEmKllGKGW59iz55WpZSD0/p3OvDES1QQS0AQIhoiD8tXni7lfGgZUb21zb25KuAMKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hREYlMkJrb2tQQ0dKRjV5cDVTTnJCNVA3MjlJOCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTYxZ0Y3VFFVSUpqWDYlMkJ6aHRJcVpjOUdRUXlBJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNLoBAIICAKgCAbICEnVzZXIxNzA4ODEwNzM0MDUwMvICTE1TNHdMakFCQUFBQXY4T1B0OWlNaFkzSWFFTlJoZThjOXE2RkdDOFg5cDJMbmhmSnZWSm5HOWlWelZ6VnhtUnlDUi1wZFNOaFFVV1aiQBM2ODc3NjExNTIxNTY4OTgyMDIyGAEYAjgS",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:42:52.821875300"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJbr0sSEmKllGKGW59iz55WpZSDwn57OvDEYATgS",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:42:57.643174900"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaQheGVmKllGKGW59iz55WpZSDv1abOvDESyQQSxAQImoji2K2D5aVkGgEuSrYDCrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9cDdqVExCMFNvUEhJeWxta3dRMVE0eXBsOTZZJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RHIlMkZmRVYzMm5jdnB5dXFoRTJxcVZ5WUpQTE0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5ugEAggIAqAIBsgINbGl0dGxlX2JveTAyMvICTE1TNHdMakFCQUFBQXc1TWtxMWxMazNvQ2ZidGVobnk0SlY1UkJfR3k5V3pYT3RaVmRrcVhXZXVoUzNRcjZycXBSdEtkazE5am1pcnOiQBM3MjI3MDMyODcwMTExOTcwMzMwGAEYATgS",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:45:15.031268700"
|
||||
},
|
||||
{
|
||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJauqP6VmKllGKGW59iz55WpZSDe5KbOvDEYATgT",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:45:17.450676400"
|
||||
}
|
||||
],
|
||||
"WebcastMemberMessage": [
|
||||
{
|
||||
"eventData": "CtgGChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlrumyf6VqWUYoZbn2LPnlallILC4ns28MTABQpUGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMi2gUICxIMCgcjOENFN0ZGIJADqgHGBQrDBQigiJ2ivsjD8GQaBUFsZWtzSscECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUdnVUhmTHhYeVpLTkNwa2IwTkt4aERPQU5RMCUzRAqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLIBBAgaEAO6AQCCAgCyAglhbGVrczg0NTnyAkxNUzR3TGpBQkFBQUFENFlSMEtTMUVYXzZVN2dZNGhqMlc5WjEyLVVIbWF2eGtpUEdiLVdJSGMxc252cmJ3eVdpb0l2NzVYNVc0ZVRKSAFQAbABArgBAcABARLDBQigiJ2ivsjD8GQaBUFsZWtzSscECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUdnVUhmTHhYeVpLTkNwa2IwTkt4aERPQU5RMCUzRAqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLIBBAgaEAO6AQCCAgCyAglhbGVrczg0NTnyAkxNUzR3TGpBQkFBQUFENFlSMEtTMUVYXzZVN2dZNGhqMlc5WjEyLVVIbWF2eGtpUEdiLVdJSGMxc252cmJ3eVdpb0l2NzVYNVc0ZVRKGAFQAZIBlQYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyLaBQgLEgwKByM4Q0U3RkYgkAOqAcYFCsMFCKCInaK+yMPwZBoFQWxla3NKxwQKtQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyNjkxMDc0ODc5ODU4NjA2NDB+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2dVSGZMeFh5WktOQ3BrYjBOS3hoRE9BTlEwJTNECqcBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JakViejVacGZtUnE5QjRNcGc1ZDE5WE1yVGMlM0QKqQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyNjkxMDc0ODc5ODU4NjA2NDB+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPXJUWXJtc2h4SVd3NU5YaHhKaTclMkZKbkVuMXY4JTNEEjcxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwsgEECBoQA7oBAIICALICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:08:03.396935200"
|
||||
},
|
||||
{
|
||||
"eventData": "CsoHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlsfK8v+VqWUYoZbn2LPnlallIJ+Ln828MTABQocHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMizAYICxIMCgcjOENFN0ZGIJADqgG4Bgq1BgiGiI7yqpuO4GIaC21hbml0b3UxMjIxSq8FCqkBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SUQlMkJvMVJHJTJCdkpPbENQWGNjUHQ1RkZCUUs1cyUzRAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqbAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1CUDJDUnd4JTJGM3VUJTJGVHlpUkRycTIzakY1c09zJTNECpcBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPU14ekJvbWpDRWM0RGJNeVdud3N1dWtjYXFFayUzRBItMTAweDEwMC9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0sgEGCAcQChgBugEAggIAsgILbWFuaXRvdTEyMjHyAkxNUzR3TGpBQkFBQUFDUlhtN2d5WHpqdnJOVzhiQVgwMWRIYjRQQ0JmcHBoUUJsTFlsN3QzaVYzNjN6Qi1mOXY2djZJMVByX2UtSjNxSAFQAbABArgBAcABARK1BgiGiI7yqpuO4GIaC21hbml0b3UxMjIxSq8FCqkBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SUQlMkJvMVJHJTJCdkpPbENQWGNjUHQ1RkZCUUs1cyUzRAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqbAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1CUDJDUnd4JTJGM3VUJTJGVHlpUkRycTIzakY1c09zJTNECpcBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPU14ekJvbWpDRWM0RGJNeVdud3N1dWtjYXFFayUzRBItMTAweDEwMC9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0sgEGCAcQChgBugEAggIAsgILbWFuaXRvdTEyMjHyAkxNUzR3TGpBQkFBQUFDUlhtN2d5WHpqdnJOVzhiQVgwMWRIYjRQQ0JmcHBoUUJsTFlsN3QzaVYzNjN6Qi1mOXY2djZJMVByX2UtSjNxGAJQAZIBhwcKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyLMBggLEgwKByM4Q0U3RkYgkAOqAbgGCrUGCIaIjvKqm47gYhoLbWFuaXRvdTEyMjFKrwUKqQFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JRCUyQm8xUkclMkJ2Sk9sQ1BYY2NQdDVGRkJRSzVzJTNECpkBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVhYJTJCdmVXenVvWDJPTUttSlBGY2lKNXVPQ1ZjJTNECpsBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUJQMkNSd3glMkYzdVQlMkZUeWlSRHJxMjNqRjVzT3MlM0QKlwFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9TXh6Qm9takNFYzREYk15V253c3V1a2NhcUVrJTNEEi0xMDB4MTAwL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTSyAQYIBxAKGAG6AQCCAgCyAgttYW5pdG91MTIyMfICTE1TNHdMakFCQUFBQUNSWG03Z3lYemp2ck5XOGJBWDAxZEhiNFBDQmZwcGhRQmxMWWw3dDNpVjM2M3pCLWY5djZ2NkkxUHJfZS1KM3GaAQlwdXNoLXB1c2iiAQVjbGljaw==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:08:13.651263600"
|
||||
},
|
||||
{
|
||||
"eventData": "CpwIChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglsOaiYSWqWUYoZbn2LPnlallIOuPoc28MTABQtkHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMingcICxIMCgcjOENFN0ZGIJADqgGKBwqHBwiGiKyWl8PO8mIaBnBvbGFuZEqEBgq6AWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTRNQ2hwNlBQRlUlMkIwJTJCNHhQUzBtJTJGY2hLU2ZCVSUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1IWVFuJTJCMUV4Zkw1QmglMkIyU0hQbUM4TEolMkZoZnclM0QKrAFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY35jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9M01rSllpVE5iVVFyR2dOZSUyRiUyQnZhJTJGZ1FQN3ZJJTNECqgBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmN+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJuemRyWkQlMkJCZVVUenpUellWSGRoSURsb3lZJTNEEjwxMDB4MTAwL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmOyAQcI8QwQDxgBugEAggIAsgIMYW50b25pa3Vyenlu8gJMTVM0d0xqQUJBQUFBd3lVV0FUT2RHNC1QdUYtenhhbFdoLUZzVE1YVzVScGpINzJJLUhtUjVYbzQ2OWVSTm15WFp5SDhLS2FvR1FVRkgBUAKwAQG4AQHAAQEShwcIhoislpfDzvJiGgZwb2xhbmRKhAYKugFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY350cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00TUNocDZQUEZVJTJCMCUyQjR4UFMwbSUyRmNoS1NmQlUlM0QKrAFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY35jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SFlRbiUyQjFFeGZMNUJoJTJCMlNIUG1DOExKJTJGaGZ3JTNECqwBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmN+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNNa0pZaVROYlVRckdnTmUlMkYlMkJ2YSUyRmdRUDd2SSUzRAqoAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SbnpkclpEJTJCQmVVVHp6VHpZVkhkaElEbG95WSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjsgEHCPEMEA8YAboBAIICALICDGFudG9uaWt1cnp5bvICTE1TNHdMakFCQUFBQXd5VVdBVE9kRzQtUHVGLXp4YWxXaC1Gc1RNWFc1UnBqSDcySS1IbVI1WG80NjllUk5teVhaeUg4S0thb0dRVUYYAlABkgHZBwoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIp4HCAsSDAoHIzhDRTdGRiCQA6oBigcKhwcIhoislpfDzvJiGgZwb2xhbmRKhAYKugFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY350cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00TUNocDZQUEZVJTJCMCUyQjR4UFMwbSUyRmNoS1NmQlUlM0QKrAFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY35jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SFlRbiUyQjFFeGZMNUJoJTJCMlNIUG1DOExKJTJGaGZ3JTNECqwBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmN+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNNa0pZaVROYlVRckdnTmUlMkYlMkJ2YSUyRmdRUDd2SSUzRAqoAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SbnpkclpEJTJCQmVVVHp6VHpZVkhkaElEbG95WSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjsgEHCPEMEA8YAboBAIICALICDGFudG9uaWt1cnp5bvICTE1TNHdMakFCQUFBQXd5VVdBVE9kRzQtUHVGLXp4YWxXaC1Gc1RNWFc1UnBqSDcySS1IbVI1WG80NjllUk5teVhaeUg4S0thb0dRVUaaARVpbm5lcl9wdXNoLWlubmVyX3B1c2iiAQVjbGljaw==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:08:47.493168800"
|
||||
},
|
||||
{
|
||||
"eventData": "CuIGChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglqbQ8LqXqWUYoZbn2LPnlallIM6r+s28MTABQp8GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMi5AUICxIMCgcjOENFN0ZGIJADqgHQBQrNBQiFiJeU282M42EaCUxlbnVzaWExMUrLBAq3AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1jYW5ZZTNZU3h1em9GNXVHbHJUV25lU3clMkJMRSUzRAqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UlBzcEVkREtVMmFWTVlDWlRpSVR2QkRpSlprJTNECqsBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83Mjk5MzQ2NTE0MTA1NTk3OTg1fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1KeGw4Y29DcHhlSXZja3o3MWFSbHl0eHAlMkYlMkY4JTNEEjcxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83Mjk5MzQ2NTE0MTA1NTk3OTg1sgEECAsQA7oBAIICALICC2p1c3R5bmFzeXN68gJMTVM0d0xqQUJBQUFBcXJWQkViS1RTWXVFZmVJeE5PSGx6WjhYLXVseDNIYVJYZnJZbmFtYl85Y1pOdW44R295ZWJFSXI4c2phRnE0dEgBUAKwAQG4AQHAAQESzQUIhYiXlNvNjONhGglMZW51c2lhMTFKywQKtwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Y2FuWWUzWVN4dXpvRjV1R2xyVFduZVN3JTJCTEUlM0QKpwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJQc3BFZERLVTJhVk1ZQ1pUaUlUdkJEaUpaayUzRAqrAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SnhsOGNvQ3B4ZUl2Y2t6NzFhUmx5dHhwJTJGJTJGOCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NbIBBAgLEAO6AQCCAgCyAgtqdXN0eW5hc3lzevICTE1TNHdMakFCQUFBQXFyVkJFYktUU1l1RWZlSXhOT0hselo4WC11bHgzSGFSWGZyWW5hbWJfOWNaTnVuOEdveWViRUlyOHNqYUZxNHQYAlABkgGfBgoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIuQFCAsSDAoHIzhDRTdGRiCQA6oB0AUKzQUIhYiXlNvNjONhGglMZW51c2lhMTFKywQKtwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Y2FuWWUzWVN4dXpvRjV1R2xyVFduZVN3JTJCTEUlM0QKpwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJQc3BFZERLVTJhVk1ZQ1pUaUlUdkJEaUpaayUzRAqrAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SnhsOGNvQ3B4ZUl2Y2t6NzFhUmx5dHhwJTJGJTJGOCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NbIBBAgLEAO6AQCCAgCyAgtqdXN0eW5hc3lzevICTE1TNHdMakFCQUFBQXFyVkJFYktUU1l1RWZlSXhOT0hselo4WC11bHgzSGFSWGZyWW5hbWJfOWNaTnVuOEdveWViRUlyOHNqYUZxNHSaARNsaXZlX2VuZC1saXZlX2NvdmVyogEFY2xpY2s=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:33:09.521317400"
|
||||
},
|
||||
{
|
||||
"eventData": "CukHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlsyE97uXqWUYoZbn2LPnlallIK3z+s28MTABQqYHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMi6wYICxIMCgcjOENFN0ZGIJADqgHXBgrUBgiGiMS6yfvm6l0aJ/CfpKbigI3imYLvuI/wn6Sm4oCN4pmC77iP8J+kpuKAjeKZgu+4j0qvBQqpAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUlEJTJCbzFSRyUyQnZKT2xDUFhjY1B0NUZGQlFLNXMlM0QKmwFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9QlAyQ1J3eCUyRjN1VCUyRlR5aVJEcnEyM2pGNXNPcyUzRAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqXAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1HbGh4d3A3WjY0b2VLU1ZpcEFzbTk5ZU1RajAlM0QSLTEwMHgxMDAvbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NLIBBQiLARBjugEAggIAsgIPc2lrZS55b3UudG91Z2h08gJMTVM0d0xqQUJBQUFBTWhrZ1JtcWxNNlhQeW1LSEZHOEU0OVVUMXFEV2RzVUxRdG45bHh2VjhDS1ZhczZKaHhWeHhDOGdIaU4xWm10aEgBUAKwAQG4AQHAAQES1AYIhojEusn75updGifwn6Sm4oCN4pmC77iP8J+kpuKAjeKZgu+4j/CfpKbigI3imYLvuI9KrwUKqQFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JRCUyQm8xUkclMkJ2Sk9sQ1BYY2NQdDVGRkJRSzVzJTNECpsBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUJQMkNSd3glMkYzdVQlMkZUeWlSRHJxMjNqRjVzT3MlM0QKmQFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9WFglMkJ2ZVd6dW9YMk9NS21KUEZjaUo1dU9DVmMlM0QKlwFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2xoeHdwN1o2NG9lS1NWaXBBc205OWVNUWowJTNEEi0xMDB4MTAwL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTSyAQUIiwEQY7oBAIICALICD3Npa2UueW91LnRvdWdodPICTE1TNHdMakFCQUFBQU1oa2dSbXFsTTZYUHltS0hGRzhFNDlVVDFxRFdkc1VMUXRuOWx4dlY4Q0tWYXM2Smh4Vnh4QzhnSGlOMVptdGgYAlABkgGmBwoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIusGCAsSDAoHIzhDRTdGRiCQA6oB1wYK1AYIhojEusn75updGifwn6Sm4oCN4pmC77iP8J+kpuKAjeKZgu+4j/CfpKbigI3imYLvuI9KrwUKqQFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JRCUyQm8xUkclMkJ2Sk9sQ1BYY2NQdDVGRkJRSzVzJTNECpsBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUJQMkNSd3glMkYzdVQlMkZUeWlSRHJxMjNqRjVzT3MlM0QKmQFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9WFglMkJ2ZVd6dW9YMk9NS21KUEZjaUo1dU9DVmMlM0QKlwFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2xoeHdwN1o2NG9lS1NWaXBBc205OWVNUWowJTNEEi0xMDB4MTAwL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTSyAQUIiwEQY7oBAIICALICD3Npa2UueW91LnRvdWdodPICTE1TNHdMakFCQUFBQU1oa2dSbXFsTTZYUHltS0hGRzhFNDlVVDFxRFdkc1VMUXRuOWx4dlY4Q0tWYXM2Smh4Vnh4QzhnSGlOMVptdGiaARVsaXZlX21lcmdlLWxpdmVfY292ZXKiAQRkcmF3",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:33:18.203136100"
|
||||
},
|
||||
{
|
||||
"eventData": "CpkHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChltn8pMmXqWUYoZbn2LPnlallIIK0gc68MTABQtYGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMimwYICxIMCgcjOENFN0ZGIJADqgGHBgqEBgiGiIng2rPuu2MaCWRvbWluaWs1NEr9BArFAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hJTJCdmp3VWc1JTJCRkg4NGpwT1dFMDFIb3FMVGdZJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00M05oRFN4eHBMSlZTT2JqVjljVGpFUCUyQkdubyUzRAq1AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9V2ZMV0ZuYWtBM1o3NGt4SGtTd2ZvSEZlUyUyRkklM0QSQzEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmGyAQYIZRA7GAG6AQCCAgCyAg5kb21pbmlrd2FzaWx1a/ICTE1TNHdMakFCQUFBQWlaWjJaQ0JfeE42ZWFCcHNMMi1PcTMtckU3Zmo1eWZEVk56LWZmVFJlMlp5S3d3THZYdmoxdmpZeUZyellwczdIAVACsAEBuAEBwAEBEoQGCIaIieDas+67YxoJZG9taW5pazU0Sv0ECsUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWElMkJ2andVZzUlMkJGSDg0anBPV0UwMUhvcUxUZ1klM0QKtQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTQzTmhEU3h4cExKVlNPYmpWOWNUakVQJTJCR25vJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1XZkxXRm5ha0EzWjc0a3hIa1N3Zm9IRmVTJTJGSSUzRBJDMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYbIBBghlEDsYAboBAIICALICDmRvbWluaWt3YXNpbHVr8gJMTVM0d0xqQUJBQUFBaVpaMlpDQl94TjZlYUJwc0wyLU9xMy1yRTdmajV5ZkRWTnotZmZUUmUyWnlLd3dMdlh2ajF2all5RnJ6WXBzNxgCUAGSAdYGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMimwYICxIMCgcjOENFN0ZGIJADqgGHBgqEBgiGiIng2rPuu2MaCWRvbWluaWs1NEr9BArFAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hJTJCdmp3VWc1JTJCRkg4NGpwT1dFMDFIb3FMVGdZJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00M05oRFN4eHBMSlZTT2JqVjljVGpFUCUyQkdubyUzRAq1AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9V2ZMV0ZuYWtBM1o3NGt4SGtTd2ZvSEZlUyUyRkklM0QSQzEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmGyAQYIZRA7GAG6AQCCAgCyAg5kb21pbmlrd2FzaWx1a/ICTE1TNHdMakFCQUFBQWlaWjJaQ0JfeE42ZWFCcHNMMi1PcTMtckU3Zmo1eWZEVk56LWZmVFJlMlp5S3d3THZYdmoxdmpZeUZyellwczeaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:35:05.044148700"
|
||||
},
|
||||
{
|
||||
"eventData": "CqIHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlpaS8c+XqWUYoZbn2LPnlallIKrMhM68MTABQt8GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMipAYICxIMCgcjOENFN0ZGIJADqgGQBgqNBgiGiKuw5O2E+V4aEEJyYWphbiBva29uZXIgWERKgwUKxgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNseVhFJTJGNWtVa0Npdlhab1YlMkZlS2lSeXliVGMlM0QKuAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT16bWdIQ3g5dVJlc1hDWFZoNmhkQlAlMkYwJTJGV0xBJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UlZCM1gzQ3djVUMyQUl6MiUyRndwVWpEMGFuNU0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2sgEFCKkBEEe6AQCCAgCyAgthbnRlazEyNDU3MfICTE1TNHdMakFCQUFBQTNzNmpHQWpOcG8xRXU3Z1p1dGNxT2VoSDJBc3RnWDlkMHBQSVhxWEhvSk50Q19vQXEyeWVzbG9rVVRKWmswVEhIAVACsAEBuAEBwAEBEo0GCIaIq7Dk7YT5XhoQQnJhamFuIG9rb25lciBYREqDBQrGAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzZ+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9M2x5WEUlMkY1a1VrQ2l2WFpvViUyRmVLaVJ5eWJUYyUzRAq4AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzZ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPXptZ0hDeDl1UmVzWENYVmg2aGRCUCUyRjAlMkZXTEElM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SVkIzWDNDd2NVQzJBSXoyJTJGd3BVakQwYW41TSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzayAQUIqQEQR7oBAIICALICC2FudGVrMTI0NTcx8gJMTVM0d0xqQUJBQUFBM3M2akdBak5wbzFFdTdnWnV0Y3FPZWhIMkFzdGdYOWQwcFBJWHFYSG9KTnRDX29BcTJ5ZXNsb2tVVEpaazBUSBgCUAGSAd8GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMipAYICxIMCgcjOENFN0ZGIJADqgGQBgqNBgiGiKuw5O2E+V4aEEJyYWphbiBva29uZXIgWERKgwUKxgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNseVhFJTJGNWtVa0Npdlhab1YlMkZlS2lSeXliVGMlM0QKuAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT16bWdIQ3g5dVJlc1hDWFZoNmhkQlAlMkYwJTJGV0xBJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UlZCM1gzQ3djVUMyQUl6MiUyRndwVWpEMGFuNU0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2sgEFCKkBEEe6AQCCAgCyAgthbnRlazEyNDU3MfICTE1TNHdMakFCQUFBQTNzNmpHQWpOcG8xRXU3Z1p1dGNxT2VoSDJBc3RnWDlkMHBQSVhxWEhvSk50Q19vQXEyeWVzbG9rVVRKWmswVEiaARdzZWFyY2hfcmVzdWx0LWxpdmVfY2VsbA==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:35:57.223255400"
|
||||
},
|
||||
{
|
||||
"eventData": "CooHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCgls2G0+yXqWUYoZbn2LPnlallINXUks68MTABQscGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMijAYICxIMCgcjOENFN0ZGIJADqgH4BQr1BQiAgLDy+MjL/AMaBPCfq6BK/QQKwgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWJiSTlobVJlZzVsOE1zSkcwTzl3MDJIc2YyUSUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzZ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUZxRkxEcVVhNFdHS2FJJTJCWHNEN0ZJVkN3bGJFJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9YnRBZWt1T0dTZiUyQmdvNkRRcFNORjQzRTN5Z1ElM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2sgEECDgQc7oBAIICALICBjFqdWxhZ/ICTE1TNHdMakFCQUFBQXJ0SHRrODlJX0dZOS1SVlBzcTdWa0NXazdIMnhaYktRWmhaYTBjajRrdHFYTm5UeGFCbTM0Q3BXUW9ZbHBPbnVIAVACsAEBuAEBwAEBEvUFCICAsPL4yMv8AxoE8J+roEr9BArCAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzZ+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9YmJJOWhtUmVnNWw4TXNKRzBPOXcwMkhzZjJRJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RnFGTERxVWE0V0dLYUklMkJYc0Q3RklWQ3dsYkUlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1idEFla3VPR1NmJTJCZ282RFFwU05GNDNFM3lnUSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzayAQQIOBBzugEAggIAsgIGMWp1bGFn8gJMTVM0d0xqQUJBQUFBcnRIdGs4OUlfR1k5LVJWUHNxN1ZrQ1drN0gyeFpiS1FaaFphMGNqNGt0cVhOblR4YUJtMzRDcFdRb1lscE9udRgCUAGSAccGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMijAYICxIMCgcjOENFN0ZGIJADqgH4BQr1BQiAgLDy+MjL/AMaBPCfq6BK/QQKwgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWJiSTlobVJlZzVsOE1zSkcwTzl3MDJIc2YyUSUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzZ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUZxRkxEcVVhNFdHS2FJJTJCWHNEN0ZJVkN3bGJFJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9YnRBZWt1T0dTZiUyQmdvNkRRcFNORjQzRTN5Z1ElM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2sgEECDgQc7oBAIICALICBjFqdWxhZ/ICTE1TNHdMakFCQUFBQXJ0SHRrODlJX0dZOS1SVlBzcTdWa0NXazdIMnhaYktRWmhaYTBjajRrdHFYTm5UeGFCbTM0Q3BXUW9ZbHBPbnWaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:39:47.676401600"
|
||||
},
|
||||
{
|
||||
"eventData": "Co4HChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlrmo+vKXqWUYoZbn2LPnlallIIfelc68MTABQssGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMikAYICxIMCgcjOENFN0ZGIJADqgH8BQr5BQiGiKbO45Kep2IaA09MT0r/BArGAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9bXlwMzBkJTJCUzNCRmRPZm4xV1ElMkZpbXA4WGdrMCUzRAq0AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJiVkd2NVF4d3BZbjNQMTZVbmUyVElMb3A5MCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPW43cWNGbUdhSzJPJTJCcWw1cGI2YXlUNzh4bjJvJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MLIBBgjUExDJBroBAIICALICB29sb192MTLyAkxNUzR3TGpBQkFBQUFqUVR4elFwRldLRE1od0NDdC1ZakhDV0gzeDFGUjhRbzZubjJWQ3JGMUpmVVpxMURydk1yUXhjRVFQX2VacDNFSAFQArABAbgBAcABARL5BQiGiKbO45Kep2IaA09MT0r/BArGAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9bXlwMzBkJTJCUzNCRmRPZm4xV1ElMkZpbXA4WGdrMCUzRAq0AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJiVkd2NVF4d3BZbjNQMTZVbmUyVElMb3A5MCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPW43cWNGbUdhSzJPJTJCcWw1cGI2YXlUNzh4bjJvJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MLIBBgjUExDJBroBAIICALICB29sb192MTLyAkxNUzR3TGpBQkFBQUFqUVR4elFwRldLRE1od0NDdC1ZakhDV0gzeDFGUjhRbzZubjJWQ3JGMUpmVVpxMURydk1yUXhjRVFQX2VacDNFGAJQAZIBywYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyKQBggLEgwKByM4Q0U3RkYgkAOqAfwFCvkFCIaIps7jkp6nYhoDT0xPSv8ECsYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1teXAzMGQlMkJTM0JGZE9mbjFXUSUyRmltcDhYZ2swJTNECrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UmJWR3Y1UXh3cFluM1AxNlVuZTJUSUxvcDkwJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9bjdxY0ZtR2FLMk8lMkJxbDVwYjZheVQ3OHhuMm8lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2Q5MTFhNjkxNDk3ZmUzM2M5MmQwOTUxNGVlOTBhYjkwsgEGCNQTEMkGugEAggIAsgIHb2xvX3YxMvICTE1TNHdMakFCQUFBQWpRVHh6UXBGV0tETWh3Q0N0LVlqSENXSDN4MUZSOFFvNm5uMlZDckYxSmZVWnExRHJ2TXJReGNFUVBfZVpwM0WaARlnZW5lcmFsX3NlYXJjaC12aWRlb19oZWFkogEFY2xpY2s=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:40:37.565374200"
|
||||
},
|
||||
{
|
||||
"eventData": "CoQIChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglpuE1f2XqWUYoZbn2LPnlallIJn6ms68MTABQsEHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMihgcICxIMCgcjOENFN0ZGIJADqgHyBgrvBgiGgOu2qfrzkVwaA2Vsb0r2BQq2AWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVYzM1ozJTJGRDFjcFBMbkI5Y3QxbHgyRVYxaXRjJTNECqYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWpHSXNVQWxsREpjZm1pMGh1czBPTzR1YU9MUSUzRAqmAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1HbDE4dFdLQnlwNTVFQTVNaENTYXdKSGlRd3clM0QKqgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SVlKNWVVWmxCZzdDJTJGRFZNaW5LbWwlMkZ6NDAxSSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRisgECEAO6AQCCAgCyAgpyYW5kb21tZW1q8gJMTVM0d0xqQUJBQUFBWlZsSldueTFLQ0l6T1c2bW4xcmZBOG0yNHhLd2VKRXlHS2g4SDFVclFnZ2hoTm1zaXZxTTV4Y21nSm14ZEFuY0gBUAKwAQG4AQHAAQES7wYIhoDrtqn685FcGgNlbG9K9gUKtgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1WMzNaMyUyRkQxY3BQTG5COWN0MWx4MkVWMWl0YyUzRAqmAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1qR0lzVUFsbERKY2ZtaTBodXMwT080dWFPTFElM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2wxOHRXS0J5cDU1RUE1TWhDU2F3SkhpUXd3JTNECqoBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUlZSjVlVVpsQmc3QyUyRkRWTWluS21sJTJGejQwMUklM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYrIBAhADugEAggIAsgIKcmFuZG9tbWVtavICTE1TNHdMakFCQUFBQVpWbEpXbnkxS0NJek9XNm1uMXJmQThtMjR4S3dlSkV5R0toOEgxVXJRZ2doaE5tc2l2cU01eGNtZ0pteGRBbmMYAlABkgHBBwoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIoYHCAsSDAoHIzhDRTdGRiCQA6oB8gYK7wYIhoDrtqn685FcGgNlbG9K9gUKtgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1WMzNaMyUyRkQxY3BQTG5COWN0MWx4MkVWMWl0YyUzRAqmAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1qR0lzVUFsbERKY2ZtaTBodXMwT080dWFPTFElM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2wxOHRXS0J5cDU1RUE1TWhDU2F3SkhpUXd3JTNECqoBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUlZSjVlVVpsQmc3QyUyRkRWTWluS21sJTJGejQwMUklM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYrIBAhADugEAggIAsgIKcmFuZG9tbWVtavICTE1TNHdMakFCQUFBQVpWbEpXbnkxS0NJek9XNm1uMXJmQThtMjR4S3dlSkV5R0toOEgxVXJRZ2doaE5tc2l2cU01eGNtZ0pteGRBbmOaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:42:03.041132700"
|
||||
},
|
||||
{
|
||||
"eventData": "CqAHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglp+O8oOYqWUYoZbn2LPnlallIPqCns68MTABQt0GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMiogYICxIMCgcjOENFN0ZGIJADqgGOBgqLBgiGiIPy1eeLuV8aBlRvbXNvbkqFBQrKAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9VGo3JTJCblhBeiUyRndEdSUyQm1iblhyaHBlWFNXJTJCajAlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hREYlMkJrb2tQQ0dKRjV5cDVTTnJCNVA3MjlJOCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTYxZ0Y3VFFVSUpqWDYlMkJ6aHRJcVpjOUdRUXlBJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNLIBBAhDEBC6AQCCAgCyAhJ1c2VyMTcwODgxMDczNDA1MDLyAkxNUzR3TGpBQkFBQUF2OE9QdDlpTWhZM0lhRU5SaGU4YzlxNkZHQzhYOXAyTG5oZkp2VkpuRzlpVnpWelZ4bVJ5Q1ItcGRTTmhRVVdWSAFQArABAbgBAcABARKLBgiGiIPy1eeLuV8aBlRvbXNvbkqFBQrKAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9VGo3JTJCblhBeiUyRndEdSUyQm1iblhyaHBlWFNXJTJCajAlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hREYlMkJrb2tQQ0dKRjV5cDVTTnJCNVA3MjlJOCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTYxZ0Y3VFFVSUpqWDYlMkJ6aHRJcVpjOUdRUXlBJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNLIBBAhDEBC6AQCCAgCyAhJ1c2VyMTcwODgxMDczNDA1MDLyAkxNUzR3TGpBQkFBQUF2OE9QdDlpTWhZM0lhRU5SaGU4YzlxNkZHQzhYOXAyTG5oZkp2VkpuRzlpVnpWelZ4bVJ5Q1ItcGRTTmhRVVdWGAJQAZIB3QYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyKiBggLEgwKByM4Q0U3RkYgkAOqAY4GCosGCIaIg/LV54u5XxoGVG9tc29uSoUFCsoBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1UajclMkJuWEF6JTJGd0R1JTJCbWJuWHJocGVYU1clMkJqMCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWFERiUyQmtva1BDR0pGNXlwNVNOckI1UDcyOUk4JTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9NjFnRjdUUVVJSmpYNiUyQnpodElxWmM5R1FReUElM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0sgEECEMQELoBAIICALICEnVzZXIxNzA4ODEwNzM0MDUwMvICTE1TNHdMakFCQUFBQXY4T1B0OWlNaFkzSWFFTlJoZThjOXE2RkdDOFg5cDJMbmhmSnZWSm5HOWlWelZ6VnhtUnlDUi1wZFNOaFFVV1aaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:42:53.616185700"
|
||||
},
|
||||
{
|
||||
"eventData": "Co4HChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglonZ0JWYqWUYoZbn2LPnlallIJbZps68MTABQssGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMikAYICxIMCgcjOENFN0ZGIJADqgH8BQr5BQiaiOLYrYPlpWQaAS5K/QQKxAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWlHSFByTnludTh3aTJNUSUyRmZBV1JQREc0ZURRJTNECrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9cDdqVExCMFNvUEhJeWxta3dRMVE0eXBsOTZZJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RHIlMkZmRVYzMm5jdnB5dXFoRTJxcVZ5WUpQTE0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5sgEECBEQWLoBAIICALICDWxpdHRsZV9ib3kwMjLyAkxNUzR3TGpBQkFBQUF3NU1rcTFsTGszb0NmYnRlaG55NEpWNVJCX0d5OVd6WE90WlZka3FYV2V1aFMzUXI2cnFwUnRLZGsxOWptaXJzSAFQArABAbgBAcABARL5BQiaiOLYrYPlpWQaAS5K/QQKxAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWlHSFByTnludTh3aTJNUSUyRmZBV1JQREc0ZURRJTNECrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9cDdqVExCMFNvUEhJeWxta3dRMVE0eXBsOTZZJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RHIlMkZmRVYzMm5jdnB5dXFoRTJxcVZ5WUpQTE0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5sgEECBEQWLoBAIICALICDWxpdHRsZV9ib3kwMjLyAkxNUzR3TGpBQkFBQUF3NU1rcTFsTGszb0NmYnRlaG55NEpWNVJCX0d5OVd6WE90WlZka3FYV2V1aFMzUXI2cnFwUnRLZGsxOWptaXJzGAJQAZIBywYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyKQBggLEgwKByM4Q0U3RkYgkAOqAfwFCvkFCJqI4titg+WlZBoBLkr9BArEAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZGNiM2Y2MmE4ODcxZWVmNjllYmU3Y2QxYmRkNWMzNTl+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9aUdIUHJOeW51OHdpMk1RJTJGZkFXUlBERzRlRFElM0QKtAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1wN2pUTEIwU29QSEl5bG1rd1ExUTR5cGw5NlklM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1EciUyRmZFVjMybmN2cHl1cWhFMnFxVnlZSlBMTSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZGNiM2Y2MmE4ODcxZWVmNjllYmU3Y2QxYmRkNWMzNTmyAQQIERBYugEAggIAsgINbGl0dGxlX2JveTAyMvICTE1TNHdMakFCQUFBQXc1TWtxMWxMazNvQ2ZidGVobnk0SlY1UkJfR3k5V3pYT3RaVmRrcVhXZXVoUzNRcjZycXBSdEtkazE5am1pcnOaARVsaXZlX21lcmdlLWxpdmVfY292ZXKiAQRkcmF3",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:45:15.827938300"
|
||||
}
|
||||
],
|
||||
"WebcastControlMessage": [
|
||||
{
|
||||
"eventData": "CjQKFVdlYmNhc3RDb250cm9sTWVzc2FnZRCglq+Gv7yWqWUYoZbn2LPnlallINDPvM28MTABEAEiAA==",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:16:17.730662700"
|
||||
},
|
||||
{
|
||||
"eventData": "CjQKFVdlYmNhc3RDb250cm9sTWVzc2FnZRCgluru472WqWUYoZbn2LPnlallIJujvc28MTABEAI=",
|
||||
"uniqueId": "dostawcavideo",
|
||||
"ts": "2023-11-13T18:16:28.978931500"
|
||||
}
|
||||
]
|
||||
}
|
||||
1111
Tools-EventsCollector/src/main/resources/link.json
Normal file
1111
Tools-EventsCollector/src/main/resources/link.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>Tools-EventsWebViewer</artifactId>
|
||||
|
||||
@@ -39,20 +39,30 @@ public class TikTokManager {
|
||||
TikTokMessagessCollectorBuilder client;
|
||||
MessageCollector msgCollector;
|
||||
|
||||
public static String dbName= "log";
|
||||
|
||||
public TikTokManager() {
|
||||
msgCollector = new MessageCollector("ab");
|
||||
msgCollector = new MessageCollector(dbName);
|
||||
}
|
||||
|
||||
public void connect(String name) throws SQLException {
|
||||
disconnect();
|
||||
client = TikTokMessageCollectorClient.create(msgCollector, "ab")
|
||||
client = TikTokMessageCollectorClient.create(msgCollector, dbName)
|
||||
.addOnBuilder(liveClientBuilder ->
|
||||
{
|
||||
liveClientBuilder.onRoomInfo((liveClient, event) ->
|
||||
{
|
||||
|
||||
});
|
||||
liveClientBuilder.onGift((liveClient, event) ->
|
||||
{
|
||||
|
||||
});
|
||||
liveClientBuilder.onWebsocketUnhandledMessage((liveClient, event) ->
|
||||
{
|
||||
System.out.println("UNHANDLED MESSAGE! "+event.getMessage().getMethod());
|
||||
});
|
||||
|
||||
})
|
||||
.addUser(name);
|
||||
client.buildAndRun();
|
||||
|
||||
@@ -49,12 +49,12 @@ public class TikTokHandler {
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void disconnect(Context context) throws SQLException {
|
||||
public void disconnect(Context context){
|
||||
tikTokManager.disconnect();
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void events(Context context) throws SQLException {
|
||||
public void events(Context context) {
|
||||
var events = tikTokManager.getEventsNames();
|
||||
var gson = getGson();
|
||||
var result = gson.toJson(events);
|
||||
|
||||
3655
Tools-EventsWebViewer/src/main/resources/WebcastLog2.json
Normal file
3655
Tools-EventsWebViewer/src/main/resources/WebcastLog2.json
Normal file
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -54,6 +54,13 @@ public class CodeExample {
|
||||
{
|
||||
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! ");
|
||||
@@ -80,7 +87,6 @@ public class CodeExample {
|
||||
settings.setTimeout(Duration.ofSeconds(2)); // Connection timeout
|
||||
settings.setLogLevel(Level.ALL); // Log level
|
||||
settings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
settings.setHandleExistingEvents(true); // Invokes all TikTok events that had occurred before connection
|
||||
settings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline
|
||||
settings.setRetryConnectionTimeout(Duration.ofSeconds(1)); // Timeout before next reconnection
|
||||
|
||||
|
||||
681
Tools-ReadmeGenerator/src/main/resources/output.md
Normal file
681
Tools-ReadmeGenerator/src/main/resources/output.md
Normal file
@@ -0,0 +1,681 @@
|
||||
<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.setTimeout(Duration.ofSeconds(2)); // Connection timeout
|
||||
settings.setLogLevel(Level.ALL); // Log level
|
||||
settings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
settings.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**:
|
||||
|
||||
- [onConnected](#onconnected-tiktokconnectedevent)
|
||||
- [onDisconnected](#ondisconnected-tiktokdisconnectedevent)
|
||||
- [onReconnecting](#onreconnecting-tiktokreconnectingevent)
|
||||
- [onError](#onerror-tiktokerrorevent)
|
||||
|
||||
**Message**:
|
||||
|
||||
- [onEvent](#onevent-tiktokevent)
|
||||
- [onSubscribe](#onsubscribe-tiktoksubscribeevent)
|
||||
- [onQuestion](#onquestion-tiktokquestionevent)
|
||||
- [onFollow](#onfollow-tiktokfollowevent)
|
||||
- [onLike](#onlike-tiktoklikeevent)
|
||||
- [onLiveEnded](#onliveended-tiktokliveendedevent)
|
||||
- [onRoomInfo](#onroominfo-tiktokroominfoevent)
|
||||
- [onShare](#onshare-tiktokshareevent)
|
||||
- [onGiftCombo](#ongiftcombo-tiktokgiftcomboevent)
|
||||
- [onEmote](#onemote-tiktokemoteevent)
|
||||
- [onGift](#ongift-tiktokgiftevent)
|
||||
- [onComment](#oncomment-tiktokcommentevent)
|
||||
- [onLivePaused](#onlivepaused-tiktoklivepausedevent)
|
||||
- [onLiveUnpaused](#onliveunpaused-tiktokliveunpausedevent)
|
||||
- [onJoin](#onjoin-tiktokjoinevent)
|
||||
|
||||
**Debug**:
|
||||
|
||||
- [onWebsocketUnhandledMessage](#onwebsocketunhandledmessage-tiktokwebsocketunhandledmessageevent)
|
||||
- [onWebsocketResponse](#onwebsocketresponse-tiktokwebsocketresponseevent)
|
||||
- [onWebsocketMessage](#onwebsocketmessage-tiktokwebsocketmessageevent)
|
||||
# Examples
|
||||
<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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## onRoomInfo [TikTokRoomInfoEvent](https://github.com/jwdeveloper/TikTokLiveJava/blob/master/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/room/TikTokRoomInfoEvent.java)
|
||||
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onRoomInfo((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>
|
||||
|
||||
## 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.Finsihed</p>
|
||||
|
||||
Remember if comboState is Finsihed both TikTokGiftComboEvent and TikTokGiftEvent event gets triggered
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onGiftCombo((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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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>
|
||||
|
||||
## 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 a protobuf encoded webcast message arrives. You can deserialize the binary object depending on the use case.
|
||||
|
||||
|
||||
```java
|
||||
TikTokLive.newClient("host-name")
|
||||
.onWebsocketMessage((liveClient, event) ->
|
||||
{
|
||||
|
||||
})
|
||||
.buildAndConnect();
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<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 @TikTokEventHandler annotation
|
||||
* - must have 2 parameters
|
||||
* - first parameter must be LiveClient
|
||||
* - second must be class that extending TikTokEvent
|
||||
*/
|
||||
|
||||
public static class CustomListener implements TikTokEventListener {
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onLike(LiveClient liveClient, TikTokLikeEvent event) {
|
||||
System.out.println(event.toString());
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onError(LiveClient liveClient, TikTokErrorEvent event) {
|
||||
// event.getException().printStackTrace();
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onComment(LiveClient liveClient, TikTokCommentEvent event) {
|
||||
var userName = event.getUser().getName();
|
||||
var text = event.getText();
|
||||
liveClient.getLogger().info(userName + ": " + text);
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onGift(LiveClient liveClient, TikTokGiftEvent event) {
|
||||
var message = switch (event.getGift()) {
|
||||
case ROSE -> "Thanks :)";
|
||||
case APPETIZERS -> ":OO";
|
||||
case APRIL -> ":D";
|
||||
case TIKTOK -> ":P";
|
||||
case CAP -> ":F";
|
||||
default -> ":I";
|
||||
};
|
||||
liveClient.getLogger().info(message);
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onAnyEvent(LiveClient liveClient, TikTokEvent event) {
|
||||
liveClient.getLogger().info(event.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
```
|
||||
|
||||
|
||||
## Contributing
|
||||
Your improvements are welcome! Feel free to open an <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>.
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>1.0.3-Release</version>
|
||||
<version>1.0.6-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ public class GiftsDownloader {
|
||||
}
|
||||
|
||||
public List<GiftDto> getGiftsFromFile() {
|
||||
var content = FilesUtility.loadFileContent("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools\\src\\main\\resources\\gifts\\output_1_0_4.json");
|
||||
var version = "";
|
||||
var content = FilesUtility.loadFileContent("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools\\src\\main\\resources\\gifts\\output.json");
|
||||
Type mapType = new TypeToken<Map<Integer, GiftDto>>() {
|
||||
}.getType();
|
||||
var mapper = new Gson().fromJson(content, mapType);
|
||||
@@ -85,7 +86,7 @@ public class GiftsDownloader {
|
||||
var gson = new GsonBuilder().setPrettyPrinting()
|
||||
.create();
|
||||
var json = gson.toJson(outputHashMap);
|
||||
FilesUtility.saveFile("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools\\src\\main\\resources\\gifts\\output_1_0_4.json", json);
|
||||
FilesUtility.saveFile("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools\\src\\main\\resources\\gifts\\output.json", json);
|
||||
System.out.println("Gifts saved to file!");
|
||||
return outputHashMap.values().stream().toList();
|
||||
}
|
||||
|
||||
@@ -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.gifts.downloader;
|
||||
|
||||
import com.google.gson.*;
|
||||
|
||||
@@ -26,8 +26,10 @@ import io.github.jwdeveloper.tiktok.TikTokLiveClientBuilder;
|
||||
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import io.github.jwdeveloper.tiktok.handlers.events.TikTokGiftEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandler;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokGiftEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokRoomInfoEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.mappers.events.TikTokSocialMediaEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokCookieJar;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokHttpClient;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokHttpRequestFactory;
|
||||
@@ -97,11 +99,9 @@ public class TikTokMockBuilder extends TikTokLiveClientBuilder {
|
||||
var requestFactory = new TikTokHttpRequestFactory(cookie);
|
||||
var apiClient = new TikTokHttpClient(cookie, requestFactory);
|
||||
var apiService = new ApiServiceMock(apiClient, logger, clientSettings);
|
||||
var webResponseHandler = new TikTokMessageHandlerRegistration(tikTokEventHandler,
|
||||
tiktokRoomInfo,
|
||||
new TikTokGenericEventMapper(),
|
||||
new TikTokGiftEventHandler(giftManager));
|
||||
var webSocketClient = new WebsocketClientMock(logger, responses, webResponseHandler);
|
||||
var mapper = createMapper(giftManager, tiktokRoomInfo);
|
||||
var handler = new TikTokMessageHandler(tikTokEventHandler, mapper);
|
||||
var webSocketClient = new WebsocketClientMock(logger, responses, handler);
|
||||
|
||||
return new LiveClientMock(tiktokRoomInfo,
|
||||
apiService,
|
||||
|
||||
@@ -1,4 +1,262 @@
|
||||
[
|
||||
{
|
||||
"id": 5547,
|
||||
"name": "Russian Crepes",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8525a07c6bf16a74eee66e9ad119b3b8.png~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5793,
|
||||
"name": "Play Samba",
|
||||
"diamondCost": 99,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/fd3d6cc127464bacded6ed009074ae2f~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5794,
|
||||
"name": "Coconut Tree",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/eb0923dbab5251f4c2e0496b11b55c4f~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5822,
|
||||
"name": "Koala",
|
||||
"diamondCost": 10,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/22c8fa54da366c111f7bb915d4429e2d~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5823,
|
||||
"name": "Fairy Bread",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a42f9ac9cd6b26da03818ff65ac919f1~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5831,
|
||||
"name": "Flower Show",
|
||||
"diamondCost": 500,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b6266323ef3ea0d313cbab6911ff8c46~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5843,
|
||||
"name": "Campfire",
|
||||
"diamondCost": 388,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e280eb1b7fe92b4efe612d98064d5a2d~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5852,
|
||||
"name": "Soccer Ball",
|
||||
"diamondCost": 39,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e1932db6aea81bbddc4e7dc0229ac155~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5890,
|
||||
"name": "Autumn leaves",
|
||||
"diamondCost": 500,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/30adcaf443df63e3bfd2751ad251f87d~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5893,
|
||||
"name": "Footy",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/94f8ac5c7b6f90aba713b44ddac40bf1~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5956,
|
||||
"name": "Fishing Gear",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/1b2353958374f585e25b2f2344c6d0ad~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5983,
|
||||
"name": "Amazing",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/18256fd3f4402601dd07c83adae3e9a2~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5991,
|
||||
"name": "Banana leaf vessel",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8e635863e20cfa3651bd8a5b762ae72d~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 5992,
|
||||
"name": "Frangipani",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7464fad59650123fe0989e426618847d~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6006,
|
||||
"name": "Cricket",
|
||||
"diamondCost": 99,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/408d55c0526ada808be7db3e22c02a56~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6034,
|
||||
"name": "Flower",
|
||||
"diamondCost": 299,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/9c20971eeb28b6b4ba37e57df3983da0~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6050,
|
||||
"name": "Love Bomb",
|
||||
"diamondCost": 299,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a1c1b14f5e9f7be5d76fa4928f574f1~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6113,
|
||||
"name": "Taco ",
|
||||
"diamondCost": 9,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/43d06db8c962623dbed6ecf70fb89ca8~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6194,
|
||||
"name": "Top Host",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5947dc37282c417b411c61f20ee7d6d4~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6240,
|
||||
"name": "ASMR",
|
||||
"diamondCost": 10,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/748e74c8309e08dbc5b03e03f28a0ea0~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6411,
|
||||
"name": "Snag",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/aa2d9b162c766a7fdf71fcead6d7bbcd~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6416,
|
||||
"name": "Choc Chip Cookie",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7dd2731de2e644301a329d3eb437b427~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6428,
|
||||
"name": "Crystal Ball",
|
||||
"diamondCost": 1700,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7e4f9a99b7003ae05186f5324aae9fbf~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6483,
|
||||
"name": "Spinning Top",
|
||||
"diamondCost": 10,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/6cde70e04a6b40a9879f7b99ff191808~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6486,
|
||||
"name": "Cheems Dog",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/d2c9e50efa3b9ff1ed31c96440a9d3a1~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6531,
|
||||
"name": "Llama Greetings",
|
||||
"diamondCost": 299,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a6b95ce6350f5f4bdff6880ac6993789~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6592,
|
||||
"name": "TGIF",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2734231d880b5cd20149f4cc8c760279~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6705,
|
||||
"name": "Loved",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a41781b0a29ba3c409c5dd83eed07f8~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6744,
|
||||
"name": "Fruits Hat ",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2316b31fc5259cc29f281d88fbca0568~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 6813,
|
||||
"name": "Fantastic",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a1b2204b06aa19d45a0338e9f0099ea7~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 7218,
|
||||
"name": "Rio de Janeiro",
|
||||
"diamondCost": 9999,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/34c0eb43c3d50e8ab64408171ebbe733~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 8225,
|
||||
"name": "Coconut Drink",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/ce27ad017f987240dc447e65ae866f4f~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 8267,
|
||||
"name": "Good Evening",
|
||||
"diamondCost": 399,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/0015a756ff783f37a2cf3b5d634b3cd6~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 8268,
|
||||
"name": "Good Night",
|
||||
"diamondCost": 399,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b7b55087141bd5f965eb31a99a5f157b~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 8616,
|
||||
"name": "Rainbow",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5fb7267489192fc77c4c8b647c124680~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 8638,
|
||||
"name": "Festa Junina's Hat",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/61b32ccce11b289b3c1db7438dfb4450~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 8712,
|
||||
"name": "Happy Father's Day",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/193eba78ded4d388a0b5a7ae95943796~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 9135,
|
||||
"name": "Magic Forest",
|
||||
"diamondCost": 6000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/63a758dbef9788f690e97cd65dbbb8d2~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 9333,
|
||||
"name": "LIVE Fest Clappers",
|
||||
"diamondCost": 100,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/63e85e00169ec5be3bfa90bb004cda5e.png~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 9334,
|
||||
"name": "LIVE Fest",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1e98afffef90ed4b2cc9c9ebb88e3608.png~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 9514,
|
||||
"name": "Storms at sea",
|
||||
"diamondCost": 2200,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/4918fbbdf220873dd8cae4c94d1ae037.png~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 9515,
|
||||
"name": "Lightning Storm",
|
||||
"diamondCost": 6000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/6f673fbb0ae6860e2b1e254538c958ba.png~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 9516,
|
||||
"name": "Mountains",
|
||||
"diamondCost": 12000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/51a7d74bcb4a6417be59f0ffc0b77e96.png~tplv-obj.png"
|
||||
},
|
||||
{
|
||||
"id": 7812,
|
||||
"name": "Bravo",
|
||||
|
||||
18358
Tools/src/main/resources/gifts/official/official_05_12_2023.json
Normal file
18358
Tools/src/main/resources/gifts/official/official_05_12_2023.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -391,9 +391,9 @@
|
||||
},
|
||||
"5547": {
|
||||
"id": 5547,
|
||||
"name": "",
|
||||
"name": "Russian Crepes",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/2ad/2ad28ef5a49c72186a45999319ff8caf/185c4643c32c2f28e4c6d06fc268c386.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8525a07c6bf16a74eee66e9ad119b3b8.png~tplv-obj.png"
|
||||
},
|
||||
"5556": {
|
||||
"id": 5556,
|
||||
@@ -925,15 +925,15 @@
|
||||
},
|
||||
"5793": {
|
||||
"id": 5793,
|
||||
"name": "",
|
||||
"name": "Play Samba",
|
||||
"diamondCost": 99,
|
||||
"image": "https://storage.streamdps.com/iblock/864/864f362bf1d66abf1acbb64bf0de43c8/0c5fad0d89d2b2a92ed30829059a59c3.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/fd3d6cc127464bacded6ed009074ae2f~tplv-obj.png"
|
||||
},
|
||||
"5794": {
|
||||
"id": 5794,
|
||||
"name": "",
|
||||
"name": "Coconut Tree",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/369/369b52ad98206ce414bf59b4fde0560f/12854f04151c6e0e76c172fb97c5514a.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/eb0923dbab5251f4c2e0496b11b55c4f~tplv-obj.png"
|
||||
},
|
||||
"5797": {
|
||||
"id": 5797,
|
||||
@@ -979,15 +979,15 @@
|
||||
},
|
||||
"5822": {
|
||||
"id": 5822,
|
||||
"name": "",
|
||||
"name": "Koala",
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/29f/29f5ecab64a8a49be1a22330ccfd7235/1026d754a1c4337bf1dd008f396a4e4d.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/22c8fa54da366c111f7bb915d4429e2d~tplv-obj.png"
|
||||
},
|
||||
"5823": {
|
||||
"id": 5823,
|
||||
"name": "",
|
||||
"name": "Fairy Bread",
|
||||
"diamondCost": 1,
|
||||
"image": "https://storage.streamdps.com/iblock/101/1017a2225a5dad4a7d607fb22ed31eb9/c694724d0be38e01ed4c922050302e13.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a42f9ac9cd6b26da03818ff65ac919f1~tplv-obj.png"
|
||||
},
|
||||
"5826": {
|
||||
"id": 5826,
|
||||
@@ -1009,9 +1009,9 @@
|
||||
},
|
||||
"5831": {
|
||||
"id": 5831,
|
||||
"name": "",
|
||||
"name": "Flower Show",
|
||||
"diamondCost": 500,
|
||||
"image": "https://storage.streamdps.com/iblock/ae4/ae4751eec1418b80b5fc49b296ef7df1/71f974c7842b768c05236b3a12530c3f.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b6266323ef3ea0d313cbab6911ff8c46~tplv-obj.png"
|
||||
},
|
||||
"5832": {
|
||||
"id": 5832,
|
||||
@@ -1051,9 +1051,9 @@
|
||||
},
|
||||
"5843": {
|
||||
"id": 5843,
|
||||
"name": "",
|
||||
"name": "Campfire",
|
||||
"diamondCost": 388,
|
||||
"image": "https://storage.streamdps.com/iblock/583/583b77ae2c961d85a811a67f3966f2f5/591bdbe070b9f5d743f183253d54cdce.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e280eb1b7fe92b4efe612d98064d5a2d~tplv-obj.png"
|
||||
},
|
||||
"5850": {
|
||||
"id": 5850,
|
||||
@@ -1063,9 +1063,9 @@
|
||||
},
|
||||
"5852": {
|
||||
"id": 5852,
|
||||
"name": "",
|
||||
"name": "Soccer Ball",
|
||||
"diamondCost": 39,
|
||||
"image": "https://storage.streamdps.com/iblock/368/368797349fb9ab0d2ad41f6b898c4bad/7c523b69e9c95c1f7e8be9df7b733fe0.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e1932db6aea81bbddc4e7dc0229ac155~tplv-obj.png"
|
||||
},
|
||||
"5860": {
|
||||
"id": 5860,
|
||||
@@ -1135,15 +1135,15 @@
|
||||
},
|
||||
"5890": {
|
||||
"id": 5890,
|
||||
"name": "",
|
||||
"name": "Autumn leaves",
|
||||
"diamondCost": 500,
|
||||
"image": "https://storage.streamdps.com/iblock/538/53861f02a937f02242e9c8ea8c736472/4b4b7c48d0f712f11b643d604a54bd01.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/30adcaf443df63e3bfd2751ad251f87d~tplv-obj.png"
|
||||
},
|
||||
"5893": {
|
||||
"id": 5893,
|
||||
"name": "",
|
||||
"name": "Footy",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/404/40436175c5ac3c124b3eefac8546d38f/75fd0dc90b620a607aa7b66729b9c0fd.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/94f8ac5c7b6f90aba713b44ddac40bf1~tplv-obj.png"
|
||||
},
|
||||
"5894": {
|
||||
"id": 5894,
|
||||
@@ -1297,9 +1297,9 @@
|
||||
},
|
||||
"5956": {
|
||||
"id": 5956,
|
||||
"name": "",
|
||||
"name": "Fishing Gear",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/0c5/0c55246326097edf2cd6418263a94cc7/e1641719baffc2067165fc1ad4a939cb.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/1b2353958374f585e25b2f2344c6d0ad~tplv-obj.png"
|
||||
},
|
||||
"5958": {
|
||||
"id": 5958,
|
||||
@@ -1363,9 +1363,9 @@
|
||||
},
|
||||
"5983": {
|
||||
"id": 5983,
|
||||
"name": "",
|
||||
"name": "Amazing",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/c0f/c0fdf0e2672efd3f9b37794c43c13366/5d13e5d7bec8b0f3c549be78869e7a3d.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/18256fd3f4402601dd07c83adae3e9a2~tplv-obj.png"
|
||||
},
|
||||
"5984": {
|
||||
"id": 5984,
|
||||
@@ -1385,6 +1385,18 @@
|
||||
"diamondCost": 555,
|
||||
"image": "https://storage.streamdps.com/iblock/627/6271a3ecc3614860585a3aa1c337ca1f/6db1ca1d211999a95accf6f3325db5de.png"
|
||||
},
|
||||
"5991": {
|
||||
"id": 5991,
|
||||
"name": "Banana leaf vessel",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8e635863e20cfa3651bd8a5b762ae72d~tplv-obj.png"
|
||||
},
|
||||
"5992": {
|
||||
"id": 5992,
|
||||
"name": "Frangipani",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7464fad59650123fe0989e426618847d~tplv-obj.png"
|
||||
},
|
||||
"5994": {
|
||||
"id": 5994,
|
||||
"name": "Turkish coffee",
|
||||
@@ -1423,9 +1435,9 @@
|
||||
},
|
||||
"6006": {
|
||||
"id": 6006,
|
||||
"name": "",
|
||||
"name": "Cricket",
|
||||
"diamondCost": 99,
|
||||
"image": "https://storage.streamdps.com/iblock/5f0/5f014a2af1e1eec44223880561052a23/951286a4458999e058c8b0d3a29b575b.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/408d55c0526ada808be7db3e22c02a56~tplv-obj.png"
|
||||
},
|
||||
"6007": {
|
||||
"id": 6007,
|
||||
@@ -1459,9 +1471,9 @@
|
||||
},
|
||||
"6034": {
|
||||
"id": 6034,
|
||||
"name": "",
|
||||
"name": "Flower",
|
||||
"diamondCost": 299,
|
||||
"image": "https://storage.streamdps.com/iblock/caa/caa0e3e2cdc87759f657c515d839a7d9/9917cc4ca38657550f29759fa7df1439.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/9c20971eeb28b6b4ba37e57df3983da0~tplv-obj.png"
|
||||
},
|
||||
"6036": {
|
||||
"id": 6036,
|
||||
@@ -1519,9 +1531,9 @@
|
||||
},
|
||||
"6050": {
|
||||
"id": 6050,
|
||||
"name": "",
|
||||
"name": "Love Bomb",
|
||||
"diamondCost": 299,
|
||||
"image": "https://storage.streamdps.com/iblock/06d/06d0d3f807b08aec6b02ffccce87e541/5a93ead8cf35f9e5e6b5689b4f851ecd.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a1c1b14f5e9f7be5d76fa4928f574f1~tplv-obj.png"
|
||||
},
|
||||
"6052": {
|
||||
"id": 6052,
|
||||
@@ -1669,9 +1681,9 @@
|
||||
},
|
||||
"6113": {
|
||||
"id": 6113,
|
||||
"name": "",
|
||||
"name": "Taco ",
|
||||
"diamondCost": 9,
|
||||
"image": "https://storage.streamdps.com/iblock/6d8/6d809e8e6318e64b7e8c80fd325b7a0b/fa9bf2e6d0a5a19b945e6c4cc4e10af8.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/43d06db8c962623dbed6ecf70fb89ca8~tplv-obj.png"
|
||||
},
|
||||
"6116": {
|
||||
"id": 6116,
|
||||
@@ -1795,9 +1807,9 @@
|
||||
},
|
||||
"6194": {
|
||||
"id": 6194,
|
||||
"name": "",
|
||||
"name": "Top Host",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/99f/99ffb3ba22c1882f8f6433c6447b5f4c/e95f311b0e1b19324c2acad263a17d44.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5947dc37282c417b411c61f20ee7d6d4~tplv-obj.png"
|
||||
},
|
||||
"6199": {
|
||||
"id": 6199,
|
||||
@@ -1849,9 +1861,9 @@
|
||||
},
|
||||
"6240": {
|
||||
"id": 6240,
|
||||
"name": "",
|
||||
"name": "ASMR",
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/ec6/ec66e855e1ee52c850d5458d96599d66/8fdbdc30beff2247ad4214392cab00dd.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/748e74c8309e08dbc5b03e03f28a0ea0~tplv-obj.png"
|
||||
},
|
||||
"6242": {
|
||||
"id": 6242,
|
||||
@@ -2083,9 +2095,9 @@
|
||||
},
|
||||
"6411": {
|
||||
"id": 6411,
|
||||
"name": "",
|
||||
"name": "Snag",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/e7d/e7dd9a4fb21a968098e1e7e4ef07a840/3086f9317df9f35c2115570cfca1fdd0.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/aa2d9b162c766a7fdf71fcead6d7bbcd~tplv-obj.png"
|
||||
},
|
||||
"6414": {
|
||||
"id": 6414,
|
||||
@@ -2101,9 +2113,9 @@
|
||||
},
|
||||
"6416": {
|
||||
"id": 6416,
|
||||
"name": "",
|
||||
"name": "Choc Chip Cookie",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/ce5/ce57f012363358333397b6c72704b466/aa71c1c351b698c09a151a434bfd2652.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7dd2731de2e644301a329d3eb437b427~tplv-obj.png"
|
||||
},
|
||||
"6417": {
|
||||
"id": 6417,
|
||||
@@ -2119,9 +2131,9 @@
|
||||
},
|
||||
"6428": {
|
||||
"id": 6428,
|
||||
"name": "",
|
||||
"name": "Crystal Ball",
|
||||
"diamondCost": 1700,
|
||||
"image": "https://storage.streamdps.com/iblock/605/6057daf816ed32ad97ef0250fa02ae1e/92e61863514c008cd0332fa7c37cf2b9.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7e4f9a99b7003ae05186f5324aae9fbf~tplv-obj.png"
|
||||
},
|
||||
"6429": {
|
||||
"id": 6429,
|
||||
@@ -2245,9 +2257,9 @@
|
||||
},
|
||||
"6483": {
|
||||
"id": 6483,
|
||||
"name": "",
|
||||
"name": "Spinning Top",
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/868/8683388d9e7b33f0f7955ebbf00dfff4/23de767c8a572ad27fd25f953ffe8069.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/6cde70e04a6b40a9879f7b99ff191808~tplv-obj.png"
|
||||
},
|
||||
"6484": {
|
||||
"id": 6484,
|
||||
@@ -2257,9 +2269,9 @@
|
||||
},
|
||||
"6486": {
|
||||
"id": 6486,
|
||||
"name": "",
|
||||
"name": "Cheems Dog",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/61e/61e0c2d7e7917f9dbd179034d3b4a330/ce9897ca21aae3a7648f18e67ee2bf2d.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/d2c9e50efa3b9ff1ed31c96440a9d3a1~tplv-obj.png"
|
||||
},
|
||||
"6487": {
|
||||
"id": 6487,
|
||||
@@ -2329,9 +2341,9 @@
|
||||
},
|
||||
"6531": {
|
||||
"id": 6531,
|
||||
"name": "",
|
||||
"name": "Llama Greetings",
|
||||
"diamondCost": 299,
|
||||
"image": "https://storage.streamdps.com/iblock/40f/40f2ab7fa04f23d9d1e5e58840df0251/37793eb58b88e10afb8922056b9ac5a3.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a6b95ce6350f5f4bdff6880ac6993789~tplv-obj.png"
|
||||
},
|
||||
"6532": {
|
||||
"id": 6532,
|
||||
@@ -2465,6 +2477,12 @@
|
||||
"diamondCost": 13999,
|
||||
"image": "https://storage.streamdps.com/iblock/fb1/fb1096568dcc97c2575dec7441d0d651/245c4c7ce9bf5d5378586eb3a2478b42.webp"
|
||||
},
|
||||
"6592": {
|
||||
"id": 6592,
|
||||
"name": "TGIF",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2734231d880b5cd20149f4cc8c760279~tplv-obj.png"
|
||||
},
|
||||
"6593": {
|
||||
"id": 6593,
|
||||
"name": "",
|
||||
@@ -2635,9 +2653,9 @@
|
||||
},
|
||||
"6705": {
|
||||
"id": 6705,
|
||||
"name": "",
|
||||
"name": "Loved",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/5c9/5c911310d7572ad93edc87e69f149eb4/3eb87b251e73846115c5c09e3ed90804.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a41781b0a29ba3c409c5dd83eed07f8~tplv-obj.png"
|
||||
},
|
||||
"6713": {
|
||||
"id": 6713,
|
||||
@@ -2695,9 +2713,9 @@
|
||||
},
|
||||
"6744": {
|
||||
"id": 6744,
|
||||
"name": "",
|
||||
"name": "Fruits Hat ",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/1a6/1a6a52e5b0020a731da399b55866e245/b15e38a68d456a82cc59a213b04020e3.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2316b31fc5259cc29f281d88fbca0568~tplv-obj.png"
|
||||
},
|
||||
"6751": {
|
||||
"id": 6751,
|
||||
@@ -2821,9 +2839,9 @@
|
||||
},
|
||||
"6813": {
|
||||
"id": 6813,
|
||||
"name": "",
|
||||
"name": "Fantastic",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/3d2/3d2707e87e8c92a8e3302cc33abf1d9c/eee97c25a857060dc81f84f13917ea73.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a1b2204b06aa19d45a0338e9f0099ea7~tplv-obj.png"
|
||||
},
|
||||
"6820": {
|
||||
"id": 6820,
|
||||
@@ -3587,6 +3605,12 @@
|
||||
"diamondCost": 1,
|
||||
"image": "https://storage.streamdps.com/iblock/5c3/5c37dce1eab0d67386329f3a2920a874/38104bd52d316ea76464433b3b07dea7.webp"
|
||||
},
|
||||
"7218": {
|
||||
"id": 7218,
|
||||
"name": "Rio de Janeiro",
|
||||
"diamondCost": 9999,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/34c0eb43c3d50e8ab64408171ebbe733~tplv-obj.png"
|
||||
},
|
||||
"7222": {
|
||||
"id": 7222,
|
||||
"name": "Full moon",
|
||||
@@ -4271,6 +4295,12 @@
|
||||
"diamondCost": 30,
|
||||
"image": "https://storage.streamdps.com/iblock/e94/e944534be54186446d7c38563c772029/553d899c4bd4be31e7b051bb36e842f8.webp"
|
||||
},
|
||||
"8225": {
|
||||
"id": 8225,
|
||||
"name": "Coconut Drink",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/ce27ad017f987240dc447e65ae866f4f~tplv-obj.png"
|
||||
},
|
||||
"8232": {
|
||||
"id": 8232,
|
||||
"name": "Gardening",
|
||||
@@ -4343,6 +4373,18 @@
|
||||
"diamondCost": 6000,
|
||||
"image": "https://storage.streamdps.com/iblock/88d/88df4387d65bcc77b691098fd649bd59/ad401a92ddba9aae15bb777f9f38638d.webp"
|
||||
},
|
||||
"8267": {
|
||||
"id": 8267,
|
||||
"name": "Good Evening",
|
||||
"diamondCost": 399,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/0015a756ff783f37a2cf3b5d634b3cd6~tplv-obj.png"
|
||||
},
|
||||
"8268": {
|
||||
"id": 8268,
|
||||
"name": "Good Night",
|
||||
"diamondCost": 399,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b7b55087141bd5f965eb31a99a5f157b~tplv-obj.png"
|
||||
},
|
||||
"8277": {
|
||||
"id": 8277,
|
||||
"name": "Love Drop",
|
||||
@@ -4571,6 +4613,18 @@
|
||||
"diamondCost": 5000,
|
||||
"image": "https://storage.streamdps.com/iblock/48f/48f1a8d280e271929718525560ad42a8/3021d84608e0c5da388f1f6534011a6f.webp"
|
||||
},
|
||||
"8616": {
|
||||
"id": 8616,
|
||||
"name": "Rainbow",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5fb7267489192fc77c4c8b647c124680~tplv-obj.png"
|
||||
},
|
||||
"8638": {
|
||||
"id": 8638,
|
||||
"name": "Festa Junina\u0027s Hat",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/61b32ccce11b289b3c1db7438dfb4450~tplv-obj.png"
|
||||
},
|
||||
"8648": {
|
||||
"id": 8648,
|
||||
"name": "Window basket",
|
||||
@@ -4595,6 +4649,12 @@
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/f34/f34b75494926337d0bede7003aee0af9/1cb25dfee5bac6dc49b19222ed6967f7.webp"
|
||||
},
|
||||
"8712": {
|
||||
"id": 8712,
|
||||
"name": "Happy Father\u0027s Day",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/193eba78ded4d388a0b5a7ae95943796~tplv-obj.png"
|
||||
},
|
||||
"8740": {
|
||||
"id": 8740,
|
||||
"name": "Crocodile",
|
||||
@@ -4799,6 +4859,12 @@
|
||||
"diamondCost": 1,
|
||||
"image": "https://storage.streamdps.com/iblock/5b9/5b9eca4a99e965cb25183681a07a5276/c28f7e9c4a8e42460225ff2d12300ae7.webp"
|
||||
},
|
||||
"9135": {
|
||||
"id": 9135,
|
||||
"name": "Magic Forest",
|
||||
"diamondCost": 6000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/63a758dbef9788f690e97cd65dbbb8d2~tplv-obj.png"
|
||||
},
|
||||
"9138": {
|
||||
"id": 9138,
|
||||
"name": "Trending Figure",
|
||||
@@ -4853,6 +4919,18 @@
|
||||
"diamondCost": 99,
|
||||
"image": "https://storage.streamdps.com/iblock/3d9/3d98c2fbc96922da37a9d22881bb06b9/0a99af132ab8e3fe9806d2412abc6bf0.webp"
|
||||
},
|
||||
"9333": {
|
||||
"id": 9333,
|
||||
"name": "LIVE Fest Clappers",
|
||||
"diamondCost": 100,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/63e85e00169ec5be3bfa90bb004cda5e.png~tplv-obj.png"
|
||||
},
|
||||
"9334": {
|
||||
"id": 9334,
|
||||
"name": "LIVE Fest",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1e98afffef90ed4b2cc9c9ebb88e3608.png~tplv-obj.png"
|
||||
},
|
||||
"9463": {
|
||||
"id": 9463,
|
||||
"name": "Fairy Wings",
|
||||
@@ -4882,5 +4960,65 @@
|
||||
"name": "Rhythmic Bear",
|
||||
"diamondCost": 2999,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/16eacf541e4bd6816e88139d079519f5.png~tplv-obj.jpg"
|
||||
},
|
||||
"9498": {
|
||||
"id": 9498,
|
||||
"name": "Blooming Ribbons",
|
||||
"diamondCost": 1000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/f76750ab58ee30fc022c9e4e11d25c9d.png~tplv-obj.jpg"
|
||||
},
|
||||
"9499": {
|
||||
"id": 9499,
|
||||
"name": "Golden Party",
|
||||
"diamondCost": 3000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/a00450f3e3aa1f01b62774950e5729c3.png~tplv-obj.jpg"
|
||||
},
|
||||
"9500": {
|
||||
"id": 9500,
|
||||
"name": "Flying Jets",
|
||||
"diamondCost": 5000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1d067d13988e8754ed6adbebd89b9ee8.png~tplv-obj.jpg"
|
||||
},
|
||||
"9501": {
|
||||
"id": 9501,
|
||||
"name": "Yacht",
|
||||
"diamondCost": 20000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/e69e2626f6ff43d1c1f2b8ae5ea42514.png~tplv-obj.jpg"
|
||||
},
|
||||
"9514": {
|
||||
"id": 9514,
|
||||
"name": "Storms at sea",
|
||||
"diamondCost": 2200,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/4918fbbdf220873dd8cae4c94d1ae037.png~tplv-obj.png"
|
||||
},
|
||||
"9515": {
|
||||
"id": 9515,
|
||||
"name": "Lightning Storm",
|
||||
"diamondCost": 6000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/6f673fbb0ae6860e2b1e254538c958ba.png~tplv-obj.png"
|
||||
},
|
||||
"9516": {
|
||||
"id": 9516,
|
||||
"name": "Mountains",
|
||||
"diamondCost": 12000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/51a7d74bcb4a6417be59f0ffc0b77e96.png~tplv-obj.png"
|
||||
},
|
||||
"9522": {
|
||||
"id": 9522,
|
||||
"name": "Exclusive Spark",
|
||||
"diamondCost": 1000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/f0bda1eb6856e2feea9cfcb6c575c8a0.png~tplv-obj.jpg"
|
||||
},
|
||||
"9523": {
|
||||
"id": 9523,
|
||||
"name": "Exclusive Jet",
|
||||
"diamondCost": 5000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1cc167a00aa4d5dfe48018afb38c3daa.png~tplv-obj.jpg"
|
||||
},
|
||||
"9524": {
|
||||
"id": 9524,
|
||||
"name": "Exclusive Yacht",
|
||||
"diamondCost": 20000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/da8c85d5ae09ebf320216202e8fa015d.png~tplv-obj.jpg"
|
||||
}
|
||||
}
|
||||
5024
Tools/src/main/resources/gifts/used_outputs/output_1_0_7.json
Normal file
5024
Tools/src/main/resources/gifts/used_outputs/output_1_0_7.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -391,9 +391,9 @@
|
||||
},
|
||||
"5547": {
|
||||
"id": 5547,
|
||||
"name": "",
|
||||
"name": "Russian Crepes",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/2ad/2ad28ef5a49c72186a45999319ff8caf/185c4643c32c2f28e4c6d06fc268c386.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8525a07c6bf16a74eee66e9ad119b3b8.png~tplv-obj.png"
|
||||
},
|
||||
"5556": {
|
||||
"id": 5556,
|
||||
@@ -925,15 +925,15 @@
|
||||
},
|
||||
"5793": {
|
||||
"id": 5793,
|
||||
"name": "",
|
||||
"name": "Play Samba",
|
||||
"diamondCost": 99,
|
||||
"image": "https://storage.streamdps.com/iblock/864/864f362bf1d66abf1acbb64bf0de43c8/0c5fad0d89d2b2a92ed30829059a59c3.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/fd3d6cc127464bacded6ed009074ae2f~tplv-obj.png"
|
||||
},
|
||||
"5794": {
|
||||
"id": 5794,
|
||||
"name": "",
|
||||
"name": "Coconut Tree",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/369/369b52ad98206ce414bf59b4fde0560f/12854f04151c6e0e76c172fb97c5514a.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/eb0923dbab5251f4c2e0496b11b55c4f~tplv-obj.png"
|
||||
},
|
||||
"5797": {
|
||||
"id": 5797,
|
||||
@@ -979,15 +979,15 @@
|
||||
},
|
||||
"5822": {
|
||||
"id": 5822,
|
||||
"name": "",
|
||||
"name": "Koala",
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/29f/29f5ecab64a8a49be1a22330ccfd7235/1026d754a1c4337bf1dd008f396a4e4d.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/22c8fa54da366c111f7bb915d4429e2d~tplv-obj.png"
|
||||
},
|
||||
"5823": {
|
||||
"id": 5823,
|
||||
"name": "",
|
||||
"name": "Fairy Bread",
|
||||
"diamondCost": 1,
|
||||
"image": "https://storage.streamdps.com/iblock/101/1017a2225a5dad4a7d607fb22ed31eb9/c694724d0be38e01ed4c922050302e13.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a42f9ac9cd6b26da03818ff65ac919f1~tplv-obj.png"
|
||||
},
|
||||
"5826": {
|
||||
"id": 5826,
|
||||
@@ -1009,9 +1009,9 @@
|
||||
},
|
||||
"5831": {
|
||||
"id": 5831,
|
||||
"name": "",
|
||||
"name": "Flower Show",
|
||||
"diamondCost": 500,
|
||||
"image": "https://storage.streamdps.com/iblock/ae4/ae4751eec1418b80b5fc49b296ef7df1/71f974c7842b768c05236b3a12530c3f.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b6266323ef3ea0d313cbab6911ff8c46~tplv-obj.png"
|
||||
},
|
||||
"5832": {
|
||||
"id": 5832,
|
||||
@@ -1051,9 +1051,9 @@
|
||||
},
|
||||
"5843": {
|
||||
"id": 5843,
|
||||
"name": "",
|
||||
"name": "Campfire",
|
||||
"diamondCost": 388,
|
||||
"image": "https://storage.streamdps.com/iblock/583/583b77ae2c961d85a811a67f3966f2f5/591bdbe070b9f5d743f183253d54cdce.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e280eb1b7fe92b4efe612d98064d5a2d~tplv-obj.png"
|
||||
},
|
||||
"5850": {
|
||||
"id": 5850,
|
||||
@@ -1063,9 +1063,9 @@
|
||||
},
|
||||
"5852": {
|
||||
"id": 5852,
|
||||
"name": "",
|
||||
"name": "Soccer Ball",
|
||||
"diamondCost": 39,
|
||||
"image": "https://storage.streamdps.com/iblock/368/368797349fb9ab0d2ad41f6b898c4bad/7c523b69e9c95c1f7e8be9df7b733fe0.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/e1932db6aea81bbddc4e7dc0229ac155~tplv-obj.png"
|
||||
},
|
||||
"5860": {
|
||||
"id": 5860,
|
||||
@@ -1135,15 +1135,15 @@
|
||||
},
|
||||
"5890": {
|
||||
"id": 5890,
|
||||
"name": "",
|
||||
"name": "Autumn leaves",
|
||||
"diamondCost": 500,
|
||||
"image": "https://storage.streamdps.com/iblock/538/53861f02a937f02242e9c8ea8c736472/4b4b7c48d0f712f11b643d604a54bd01.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/30adcaf443df63e3bfd2751ad251f87d~tplv-obj.png"
|
||||
},
|
||||
"5893": {
|
||||
"id": 5893,
|
||||
"name": "",
|
||||
"name": "Footy",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/404/40436175c5ac3c124b3eefac8546d38f/75fd0dc90b620a607aa7b66729b9c0fd.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/94f8ac5c7b6f90aba713b44ddac40bf1~tplv-obj.png"
|
||||
},
|
||||
"5894": {
|
||||
"id": 5894,
|
||||
@@ -1297,9 +1297,9 @@
|
||||
},
|
||||
"5956": {
|
||||
"id": 5956,
|
||||
"name": "",
|
||||
"name": "Fishing Gear",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/0c5/0c55246326097edf2cd6418263a94cc7/e1641719baffc2067165fc1ad4a939cb.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/1b2353958374f585e25b2f2344c6d0ad~tplv-obj.png"
|
||||
},
|
||||
"5958": {
|
||||
"id": 5958,
|
||||
@@ -1363,9 +1363,9 @@
|
||||
},
|
||||
"5983": {
|
||||
"id": 5983,
|
||||
"name": "",
|
||||
"name": "Amazing",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/c0f/c0fdf0e2672efd3f9b37794c43c13366/5d13e5d7bec8b0f3c549be78869e7a3d.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/18256fd3f4402601dd07c83adae3e9a2~tplv-obj.png"
|
||||
},
|
||||
"5984": {
|
||||
"id": 5984,
|
||||
@@ -1385,6 +1385,18 @@
|
||||
"diamondCost": 555,
|
||||
"image": "https://storage.streamdps.com/iblock/627/6271a3ecc3614860585a3aa1c337ca1f/6db1ca1d211999a95accf6f3325db5de.png"
|
||||
},
|
||||
"5991": {
|
||||
"id": 5991,
|
||||
"name": "Banana leaf vessel",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/8e635863e20cfa3651bd8a5b762ae72d~tplv-obj.png"
|
||||
},
|
||||
"5992": {
|
||||
"id": 5992,
|
||||
"name": "Frangipani",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7464fad59650123fe0989e426618847d~tplv-obj.png"
|
||||
},
|
||||
"5994": {
|
||||
"id": 5994,
|
||||
"name": "Turkish coffee",
|
||||
@@ -1423,9 +1435,9 @@
|
||||
},
|
||||
"6006": {
|
||||
"id": 6006,
|
||||
"name": "",
|
||||
"name": "Cricket",
|
||||
"diamondCost": 99,
|
||||
"image": "https://storage.streamdps.com/iblock/5f0/5f014a2af1e1eec44223880561052a23/951286a4458999e058c8b0d3a29b575b.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/408d55c0526ada808be7db3e22c02a56~tplv-obj.png"
|
||||
},
|
||||
"6007": {
|
||||
"id": 6007,
|
||||
@@ -1459,9 +1471,9 @@
|
||||
},
|
||||
"6034": {
|
||||
"id": 6034,
|
||||
"name": "",
|
||||
"name": "Flower",
|
||||
"diamondCost": 299,
|
||||
"image": "https://storage.streamdps.com/iblock/caa/caa0e3e2cdc87759f657c515d839a7d9/9917cc4ca38657550f29759fa7df1439.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/9c20971eeb28b6b4ba37e57df3983da0~tplv-obj.png"
|
||||
},
|
||||
"6036": {
|
||||
"id": 6036,
|
||||
@@ -1519,9 +1531,9 @@
|
||||
},
|
||||
"6050": {
|
||||
"id": 6050,
|
||||
"name": "",
|
||||
"name": "Love Bomb",
|
||||
"diamondCost": 299,
|
||||
"image": "https://storage.streamdps.com/iblock/06d/06d0d3f807b08aec6b02ffccce87e541/5a93ead8cf35f9e5e6b5689b4f851ecd.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a1c1b14f5e9f7be5d76fa4928f574f1~tplv-obj.png"
|
||||
},
|
||||
"6052": {
|
||||
"id": 6052,
|
||||
@@ -1669,9 +1681,9 @@
|
||||
},
|
||||
"6113": {
|
||||
"id": 6113,
|
||||
"name": "",
|
||||
"name": "Taco ",
|
||||
"diamondCost": 9,
|
||||
"image": "https://storage.streamdps.com/iblock/6d8/6d809e8e6318e64b7e8c80fd325b7a0b/fa9bf2e6d0a5a19b945e6c4cc4e10af8.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/43d06db8c962623dbed6ecf70fb89ca8~tplv-obj.png"
|
||||
},
|
||||
"6116": {
|
||||
"id": 6116,
|
||||
@@ -1795,9 +1807,9 @@
|
||||
},
|
||||
"6194": {
|
||||
"id": 6194,
|
||||
"name": "",
|
||||
"name": "Top Host",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/99f/99ffb3ba22c1882f8f6433c6447b5f4c/e95f311b0e1b19324c2acad263a17d44.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5947dc37282c417b411c61f20ee7d6d4~tplv-obj.png"
|
||||
},
|
||||
"6199": {
|
||||
"id": 6199,
|
||||
@@ -1849,9 +1861,9 @@
|
||||
},
|
||||
"6240": {
|
||||
"id": 6240,
|
||||
"name": "",
|
||||
"name": "ASMR",
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/ec6/ec66e855e1ee52c850d5458d96599d66/8fdbdc30beff2247ad4214392cab00dd.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/748e74c8309e08dbc5b03e03f28a0ea0~tplv-obj.png"
|
||||
},
|
||||
"6242": {
|
||||
"id": 6242,
|
||||
@@ -2083,9 +2095,9 @@
|
||||
},
|
||||
"6411": {
|
||||
"id": 6411,
|
||||
"name": "",
|
||||
"name": "Snag",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/e7d/e7dd9a4fb21a968098e1e7e4ef07a840/3086f9317df9f35c2115570cfca1fdd0.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/aa2d9b162c766a7fdf71fcead6d7bbcd~tplv-obj.png"
|
||||
},
|
||||
"6414": {
|
||||
"id": 6414,
|
||||
@@ -2101,9 +2113,9 @@
|
||||
},
|
||||
"6416": {
|
||||
"id": 6416,
|
||||
"name": "",
|
||||
"name": "Choc Chip Cookie",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/ce5/ce57f012363358333397b6c72704b466/aa71c1c351b698c09a151a434bfd2652.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7dd2731de2e644301a329d3eb437b427~tplv-obj.png"
|
||||
},
|
||||
"6417": {
|
||||
"id": 6417,
|
||||
@@ -2119,9 +2131,9 @@
|
||||
},
|
||||
"6428": {
|
||||
"id": 6428,
|
||||
"name": "",
|
||||
"name": "Crystal Ball",
|
||||
"diamondCost": 1700,
|
||||
"image": "https://storage.streamdps.com/iblock/605/6057daf816ed32ad97ef0250fa02ae1e/92e61863514c008cd0332fa7c37cf2b9.png"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/7e4f9a99b7003ae05186f5324aae9fbf~tplv-obj.png"
|
||||
},
|
||||
"6429": {
|
||||
"id": 6429,
|
||||
@@ -2245,9 +2257,9 @@
|
||||
},
|
||||
"6483": {
|
||||
"id": 6483,
|
||||
"name": "",
|
||||
"name": "Spinning Top",
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/868/8683388d9e7b33f0f7955ebbf00dfff4/23de767c8a572ad27fd25f953ffe8069.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/6cde70e04a6b40a9879f7b99ff191808~tplv-obj.png"
|
||||
},
|
||||
"6484": {
|
||||
"id": 6484,
|
||||
@@ -2257,9 +2269,9 @@
|
||||
},
|
||||
"6486": {
|
||||
"id": 6486,
|
||||
"name": "",
|
||||
"name": "Cheems Dog",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/61e/61e0c2d7e7917f9dbd179034d3b4a330/ce9897ca21aae3a7648f18e67ee2bf2d.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/d2c9e50efa3b9ff1ed31c96440a9d3a1~tplv-obj.png"
|
||||
},
|
||||
"6487": {
|
||||
"id": 6487,
|
||||
@@ -2329,9 +2341,9 @@
|
||||
},
|
||||
"6531": {
|
||||
"id": 6531,
|
||||
"name": "",
|
||||
"name": "Llama Greetings",
|
||||
"diamondCost": 299,
|
||||
"image": "https://storage.streamdps.com/iblock/40f/40f2ab7fa04f23d9d1e5e58840df0251/37793eb58b88e10afb8922056b9ac5a3.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a6b95ce6350f5f4bdff6880ac6993789~tplv-obj.png"
|
||||
},
|
||||
"6532": {
|
||||
"id": 6532,
|
||||
@@ -2465,6 +2477,12 @@
|
||||
"diamondCost": 13999,
|
||||
"image": "https://storage.streamdps.com/iblock/fb1/fb1096568dcc97c2575dec7441d0d651/245c4c7ce9bf5d5378586eb3a2478b42.webp"
|
||||
},
|
||||
"6592": {
|
||||
"id": 6592,
|
||||
"name": "TGIF",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2734231d880b5cd20149f4cc8c760279~tplv-obj.png"
|
||||
},
|
||||
"6593": {
|
||||
"id": 6593,
|
||||
"name": "",
|
||||
@@ -2635,9 +2653,9 @@
|
||||
},
|
||||
"6705": {
|
||||
"id": 6705,
|
||||
"name": "",
|
||||
"name": "Loved",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/5c9/5c911310d7572ad93edc87e69f149eb4/3eb87b251e73846115c5c09e3ed90804.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2a41781b0a29ba3c409c5dd83eed07f8~tplv-obj.png"
|
||||
},
|
||||
"6713": {
|
||||
"id": 6713,
|
||||
@@ -2695,9 +2713,9 @@
|
||||
},
|
||||
"6744": {
|
||||
"id": 6744,
|
||||
"name": "",
|
||||
"name": "Fruits Hat ",
|
||||
"diamondCost": 199,
|
||||
"image": "https://storage.streamdps.com/iblock/1a6/1a6a52e5b0020a731da399b55866e245/b15e38a68d456a82cc59a213b04020e3.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/2316b31fc5259cc29f281d88fbca0568~tplv-obj.png"
|
||||
},
|
||||
"6751": {
|
||||
"id": 6751,
|
||||
@@ -2821,9 +2839,9 @@
|
||||
},
|
||||
"6813": {
|
||||
"id": 6813,
|
||||
"name": "",
|
||||
"name": "Fantastic",
|
||||
"diamondCost": 5,
|
||||
"image": "https://storage.streamdps.com/iblock/3d2/3d2707e87e8c92a8e3302cc33abf1d9c/eee97c25a857060dc81f84f13917ea73.webp"
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/a1b2204b06aa19d45a0338e9f0099ea7~tplv-obj.png"
|
||||
},
|
||||
"6820": {
|
||||
"id": 6820,
|
||||
@@ -3587,6 +3605,12 @@
|
||||
"diamondCost": 1,
|
||||
"image": "https://storage.streamdps.com/iblock/5c3/5c37dce1eab0d67386329f3a2920a874/38104bd52d316ea76464433b3b07dea7.webp"
|
||||
},
|
||||
"7218": {
|
||||
"id": 7218,
|
||||
"name": "Rio de Janeiro",
|
||||
"diamondCost": 9999,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/34c0eb43c3d50e8ab64408171ebbe733~tplv-obj.png"
|
||||
},
|
||||
"7222": {
|
||||
"id": 7222,
|
||||
"name": "Full moon",
|
||||
@@ -4271,6 +4295,12 @@
|
||||
"diamondCost": 30,
|
||||
"image": "https://storage.streamdps.com/iblock/e94/e944534be54186446d7c38563c772029/553d899c4bd4be31e7b051bb36e842f8.webp"
|
||||
},
|
||||
"8225": {
|
||||
"id": 8225,
|
||||
"name": "Coconut Drink",
|
||||
"diamondCost": 5,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/ce27ad017f987240dc447e65ae866f4f~tplv-obj.png"
|
||||
},
|
||||
"8232": {
|
||||
"id": 8232,
|
||||
"name": "Gardening",
|
||||
@@ -4343,6 +4373,18 @@
|
||||
"diamondCost": 6000,
|
||||
"image": "https://storage.streamdps.com/iblock/88d/88df4387d65bcc77b691098fd649bd59/ad401a92ddba9aae15bb777f9f38638d.webp"
|
||||
},
|
||||
"8267": {
|
||||
"id": 8267,
|
||||
"name": "Good Evening",
|
||||
"diamondCost": 399,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/0015a756ff783f37a2cf3b5d634b3cd6~tplv-obj.png"
|
||||
},
|
||||
"8268": {
|
||||
"id": 8268,
|
||||
"name": "Good Night",
|
||||
"diamondCost": 399,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/b7b55087141bd5f965eb31a99a5f157b~tplv-obj.png"
|
||||
},
|
||||
"8277": {
|
||||
"id": 8277,
|
||||
"name": "Love Drop",
|
||||
@@ -4571,6 +4613,18 @@
|
||||
"diamondCost": 5000,
|
||||
"image": "https://storage.streamdps.com/iblock/48f/48f1a8d280e271929718525560ad42a8/3021d84608e0c5da388f1f6534011a6f.webp"
|
||||
},
|
||||
"8616": {
|
||||
"id": 8616,
|
||||
"name": "Rainbow",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/5fb7267489192fc77c4c8b647c124680~tplv-obj.png"
|
||||
},
|
||||
"8638": {
|
||||
"id": 8638,
|
||||
"name": "Festa Junina\u0027s Hat",
|
||||
"diamondCost": 199,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/61b32ccce11b289b3c1db7438dfb4450~tplv-obj.png"
|
||||
},
|
||||
"8648": {
|
||||
"id": 8648,
|
||||
"name": "Window basket",
|
||||
@@ -4595,6 +4649,12 @@
|
||||
"diamondCost": 10,
|
||||
"image": "https://storage.streamdps.com/iblock/f34/f34b75494926337d0bede7003aee0af9/1cb25dfee5bac6dc49b19222ed6967f7.webp"
|
||||
},
|
||||
"8712": {
|
||||
"id": 8712,
|
||||
"name": "Happy Father\u0027s Day",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/193eba78ded4d388a0b5a7ae95943796~tplv-obj.png"
|
||||
},
|
||||
"8740": {
|
||||
"id": 8740,
|
||||
"name": "Crocodile",
|
||||
@@ -4799,6 +4859,12 @@
|
||||
"diamondCost": 1,
|
||||
"image": "https://storage.streamdps.com/iblock/5b9/5b9eca4a99e965cb25183681a07a5276/c28f7e9c4a8e42460225ff2d12300ae7.webp"
|
||||
},
|
||||
"9135": {
|
||||
"id": 9135,
|
||||
"name": "Magic Forest",
|
||||
"diamondCost": 6000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/63a758dbef9788f690e97cd65dbbb8d2~tplv-obj.png"
|
||||
},
|
||||
"9138": {
|
||||
"id": 9138,
|
||||
"name": "Trending Figure",
|
||||
@@ -4853,6 +4919,18 @@
|
||||
"diamondCost": 99,
|
||||
"image": "https://storage.streamdps.com/iblock/3d9/3d98c2fbc96922da37a9d22881bb06b9/0a99af132ab8e3fe9806d2412abc6bf0.webp"
|
||||
},
|
||||
"9333": {
|
||||
"id": 9333,
|
||||
"name": "LIVE Fest Clappers",
|
||||
"diamondCost": 100,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/63e85e00169ec5be3bfa90bb004cda5e.png~tplv-obj.png"
|
||||
},
|
||||
"9334": {
|
||||
"id": 9334,
|
||||
"name": "LIVE Fest",
|
||||
"diamondCost": 1,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1e98afffef90ed4b2cc9c9ebb88e3608.png~tplv-obj.png"
|
||||
},
|
||||
"9463": {
|
||||
"id": 9463,
|
||||
"name": "Fairy Wings",
|
||||
@@ -4882,5 +4960,65 @@
|
||||
"name": "Rhythmic Bear",
|
||||
"diamondCost": 2999,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/16eacf541e4bd6816e88139d079519f5.png~tplv-obj.jpg"
|
||||
},
|
||||
"9498": {
|
||||
"id": 9498,
|
||||
"name": "Blooming Ribbons",
|
||||
"diamondCost": 1000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/f76750ab58ee30fc022c9e4e11d25c9d.png~tplv-obj.jpg"
|
||||
},
|
||||
"9499": {
|
||||
"id": 9499,
|
||||
"name": "Golden Party",
|
||||
"diamondCost": 3000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/a00450f3e3aa1f01b62774950e5729c3.png~tplv-obj.jpg"
|
||||
},
|
||||
"9500": {
|
||||
"id": 9500,
|
||||
"name": "Flying Jets",
|
||||
"diamondCost": 5000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1d067d13988e8754ed6adbebd89b9ee8.png~tplv-obj.jpg"
|
||||
},
|
||||
"9501": {
|
||||
"id": 9501,
|
||||
"name": "Yacht",
|
||||
"diamondCost": 20000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/e69e2626f6ff43d1c1f2b8ae5ea42514.png~tplv-obj.jpg"
|
||||
},
|
||||
"9514": {
|
||||
"id": 9514,
|
||||
"name": "Storms at sea",
|
||||
"diamondCost": 2200,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/4918fbbdf220873dd8cae4c94d1ae037.png~tplv-obj.png"
|
||||
},
|
||||
"9515": {
|
||||
"id": 9515,
|
||||
"name": "Lightning Storm",
|
||||
"diamondCost": 6000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/6f673fbb0ae6860e2b1e254538c958ba.png~tplv-obj.png"
|
||||
},
|
||||
"9516": {
|
||||
"id": 9516,
|
||||
"name": "Mountains",
|
||||
"diamondCost": 12000,
|
||||
"image": "https://p19-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/51a7d74bcb4a6417be59f0ffc0b77e96.png~tplv-obj.png"
|
||||
},
|
||||
"9522": {
|
||||
"id": 9522,
|
||||
"name": "Exclusive Spark",
|
||||
"diamondCost": 1000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/f0bda1eb6856e2feea9cfcb6c575c8a0.png~tplv-obj.jpg"
|
||||
},
|
||||
"9523": {
|
||||
"id": 9523,
|
||||
"name": "Exclusive Jet",
|
||||
"diamondCost": 5000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/1cc167a00aa4d5dfe48018afb38c3daa.png~tplv-obj.jpg"
|
||||
},
|
||||
"9524": {
|
||||
"id": 9524,
|
||||
"name": "Exclusive Yacht",
|
||||
"diamondCost": 20000,
|
||||
"image": "https://p16-webcast.tiktokcdn.com/img/maliva/webcast-va/resource/da8c85d5ae09ebf320216202e8fa015d.png~tplv-obj.jpg"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
94
collaboration.md
Normal file
94
collaboration.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Collaboration Guide
|
||||
|
||||
Are you willing to help or improve TikTokLiveJava?
|
||||
|
||||
|
||||
|
||||
|
||||
### Project setup
|
||||
|
||||
1. Clone project to your favorite IDE (IntelliJ recommended) https://github.com/jwdeveloper/TikTokLiveJava.git
|
||||
|
||||
2. After project is cloned you can encounter error that some classes are missing
|
||||
Don't worry this is normal! To fix that use `Maven compile` command for the
|
||||
root project
|
||||
|
||||
|
||||
|
||||
### How does library works?
|
||||
|
||||
We can divide working of library to 4 important parts
|
||||
|
||||
- Getting info about live from TikTok
|
||||
Library is making 3 https
|
||||
- first for getting live `Room_ID`
|
||||
- second for getting more specific live metadata such as live title, host name...
|
||||
- third to `Sign API` that returns access token that is later use for connecting
|
||||
to TikTok websocket
|
||||
- Connecting to TikTok websocket (PushServer)
|
||||
After successful connection TikTok starts to send `ProtocolBuffer`
|
||||
messages in binary format. This is very important to understand `ProtocolBuffer`
|
||||
it is not complicated :). All the proto files are included under `API/src/main/proto`
|
||||
After using `Maven compile` command on project, java classes are generated from
|
||||
those files. so then we can easily map incoming bytes to class, for examples
|
||||
`WebcastGiftMessage message = WebcastGiftMessage.parseFrom(incomingBytesArray)`
|
||||
|
||||
- Mapping TikTok data to events
|
||||
at this point we have TikTok data inside protocol-buffer classes now we want
|
||||
to map it to TikTokLiveJava events. Why? because `protocol-buffer classes` might
|
||||
be changed at any point, but we want to keep library code structure keep consistent
|
||||
so for example `WebcastGiftMessage` is mapped manually to `TikTokGiftEvent`
|
||||
|
||||
- trigger events
|
||||
when the events objects are done last step is to trigger then and that's it
|
||||
`tikTokEventObserver.publish(liveClient, tiktokGiftEvent)`
|
||||
|
||||
|
||||
|
||||
### Project structure
|
||||
project is made from few modules the most important one are
|
||||
|
||||
#### API
|
||||
|
||||
Contains interfaces and data classes, all code that is ment
|
||||
to be visible and use for the Library user should be included
|
||||
in this project
|
||||
|
||||
- All the events can be found user `io.github.jwdeveloper.tiktok.data.events`
|
||||
- All the class data that are used in events is under `io.github.jwdeveloper.tiktok.data.models`
|
||||
|
||||
|
||||
#### Client
|
||||
|
||||
Contains implementation of `API` modules interfaces and all the code
|
||||
important classes
|
||||
|
||||
- `TikTokLiveClient` core class that is use to connect/disconnect from TikTok
|
||||
- `TikTokLiveClientBuilder` preparing `TikTokLiveClient` class
|
||||
- `TikTokApiService` use for Http requests to TikTok/Sign API
|
||||
- `TikTokWebSocketClient` receiving all ProtocolBuffer messages from TikTok
|
||||
- `TikTokMessageHandlerRegistration` register all mappings TikTok data -> TikTokLiveJava events
|
||||
- `TikTokEventObserver` used to register and trigger TikTok events
|
||||
|
||||
There are also few more modules made purely for testing and debbuging code
|
||||
|
||||
#### Examples
|
||||
Project made to show up new features and present basic
|
||||
example for library. While developing new features you
|
||||
can use it as playground
|
||||
|
||||
#### Tools
|
||||
Project that contains code generators for automation teadios boilder plate
|
||||
It contains very useful class `GenerateGiftsEnum` that download gifts json from TikTok
|
||||
and generates code for `Gift` enum that is later added to `API` module at path `io.github.jwdeveloper.tiktok.data.models.gifts.Gift`
|
||||
|
||||
#### Tools-EventsCollector
|
||||
Tool that can be used to store all events from live to sqlLite database or Json file
|
||||
It is very handy for later debuging events data
|
||||
|
||||
#### Tools-EventsWebViewer
|
||||
Tools that runs website that collects and display pure data from TikTok incoming events
|
||||
very useful for debuging
|
||||
|
||||
#### Tools-ReadmeGenerator
|
||||
Generates readme file from template
|
||||
Reference in New Issue
Block a user