Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add suspicious users eventsub topics #979

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,22 @@
package com.github.twitch4j.eventsub.domain;

import com.github.twitch4j.eventsub.domain.chat.Message;

import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import lombok.ToString;

@Data
@Setter(AccessLevel.PRIVATE)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AugmentedMessage extends Message {

/**
* The UUID that identifies the message.
*/
private String messageId;

}
@@ -0,0 +1,17 @@
package com.github.twitch4j.eventsub.domain;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;

public enum EvasionEvaluation {

@JsonAlias("likely") // what docs claim
LIKELY_EVADER,

@JsonAlias("possible") // what docs claim
POSSIBLE_EVADER,

@JsonEnumDefaultValue
UNKNOWN

}
@@ -0,0 +1,10 @@
package com.github.twitch4j.eventsub.domain;

import com.fasterxml.jackson.annotation.JsonAlias;

public enum SuspiciousStatus {
@JsonAlias("none") // what docs falsely claim
NO_TREATMENT,
ACTIVE_MONITORING,
RESTRICTED
}
@@ -0,0 +1,20 @@
package com.github.twitch4j.eventsub.domain;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;

public enum SuspiciousType {

@JsonAlias("manual") // what docs falsely claim
MANUALLY_ADDED,

@JsonAlias({"ban_evader_detector", "ban_evader"}) // what docs claim (yes, both)
DETECTED_BAN_EVADER,

@JsonAlias("shared_channel_ban") // what docs claim
BANNED_IN_SHARED_CHANNEL,

@JsonEnumDefaultValue
UNKNOWN

}
Expand Up @@ -3,8 +3,9 @@
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import org.jetbrains.annotations.Nullable;

import java.util.Set;
import java.util.EnumSet;

@Data
@Setter(AccessLevel.PRIVATE)
Expand All @@ -23,6 +24,7 @@ public class Emote {
/**
* The ID of the broadcaster who owns the emote.
*/
@Nullable
private String ownerId;

/**
Expand All @@ -31,7 +33,8 @@ public class Emote {
* For example, if the emote is available only as a static PNG, the array contains only static.
* But if the emote is available as a static PNG and an animated GIF, the array contains static and animated.
*/
private Set<Format> format;
@Nullable
private EnumSet<Format> format;

public enum Format {
/**
Expand Down
@@ -1,5 +1,6 @@
package com.github.twitch4j.eventsub.domain.chat;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.AccessLevel;
import lombok.Data;
Expand Down Expand Up @@ -28,6 +29,7 @@ public class Fragment {
* Optional: Metadata pertaining to the cheermote.
*/
@Nullable
@JsonAlias("Cheermote")
private Cheermote cheermote;

/**
Expand Down
@@ -0,0 +1,51 @@
package com.github.twitch4j.eventsub.events;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.twitch4j.eventsub.domain.AugmentedMessage;
import com.github.twitch4j.eventsub.domain.EvasionEvaluation;
import com.github.twitch4j.eventsub.domain.SuspiciousStatus;
import com.github.twitch4j.eventsub.domain.SuspiciousType;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import lombok.ToString;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.EnumSet;

@Data
@Setter(AccessLevel.PRIVATE)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class SuspiciousUserMessageEvent extends EventSubUserChannelEvent {

/**
* The status set for the suspicious user.
*/
@JsonProperty("low_trust_status")
private SuspiciousStatus status;

/**
* Channel IDs where the suspicious user is also banned.
*/
@Nullable
private Collection<String> sharedBanChannelIds;

/**
* User types (if any) that apply to the suspicious user.
*/
private EnumSet<SuspiciousType> types;

/**
* A ban evasion likelihood value (if any) that as been applied to the user automatically by Twitch.
*/
private EvasionEvaluation banEvasionEvaluation;

/**
* The structured chat message.
*/
private AugmentedMessage message;

}
@@ -0,0 +1,23 @@
package com.github.twitch4j.eventsub.events;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.twitch4j.eventsub.domain.SuspiciousStatus;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import lombok.ToString;

@Data
@Setter(AccessLevel.PRIVATE)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class SuspiciousUserUpdateEvent extends EventSubModerationEvent {

/**
* The status set for the suspicious user.
*/
@JsonProperty("low_trust_status")
private SuspiciousStatus status;

}
Expand Up @@ -47,6 +47,8 @@ public class SubscriptionTypes {
public final ChannelSubscriptionEndType CHANNEL_SUBSCRIPTION_END;
public final ChannelSubscriptionGiftType CHANNEL_SUBSCRIPTION_GIFT;
public final ChannelSubscriptionMessageType CHANNEL_SUBSCRIPTION_MESSAGE;
public final SuspiciousUserMessageType CHANNEL_SUSPICIOUS_USER_MESSAGE;
public final SuspiciousUserUpdateType CHANNEL_SUSPICIOUS_USER_UPDATE;
public final ChannelUnbanType CHANNEL_UNBAN;
public final @Deprecated ChannelUpdateType CHANNEL_UPDATE;
public final ChannelUpdateV2Type CHANNEL_UPDATE_V2;
Expand Down Expand Up @@ -115,6 +117,8 @@ public class SubscriptionTypes {
CHANNEL_SUBSCRIPTION_END = new ChannelSubscriptionEndType(),
CHANNEL_SUBSCRIPTION_GIFT = new ChannelSubscriptionGiftType(),
CHANNEL_SUBSCRIPTION_MESSAGE = new ChannelSubscriptionMessageType(),
CHANNEL_SUSPICIOUS_USER_MESSAGE = new SuspiciousUserMessageType(),
CHANNEL_SUSPICIOUS_USER_UPDATE = new SuspiciousUserUpdateType(),
CHANNEL_UNBAN = new ChannelUnbanType(),
CHANNEL_UPDATE = new ChannelUpdateType(),
CHANNEL_UPDATE_V2 = new ChannelUpdateV2Type(),
Expand Down
@@ -0,0 +1,33 @@
package com.github.twitch4j.eventsub.subscriptions;

import com.github.twitch4j.eventsub.condition.ModeratorEventSubCondition;
import com.github.twitch4j.eventsub.events.SuspiciousUserMessageEvent;

/**
* Fires when a chat message has been sent from a suspicious user.
* <p>
* Requires authorization from a moderator of the channel with the moderator:read:suspicious_users scope.
*
* @see com.github.twitch4j.auth.domain.TwitchScopes#HELIX_SUSPICIOUS_USERS_READ
*/
public class SuspiciousUserMessageType implements SubscriptionType<ModeratorEventSubCondition, ModeratorEventSubCondition.ModeratorEventSubConditionBuilder<?, ?>, SuspiciousUserMessageEvent> {
@Override
public String getName() {
return "channel.suspicious_user.message";
}

@Override
public String getVersion() {
return "1";
}

@Override
public ModeratorEventSubCondition.ModeratorEventSubConditionBuilder<?, ?> getConditionBuilder() {
return ModeratorEventSubCondition.builder();
}

@Override
public Class<SuspiciousUserMessageEvent> getEventClass() {
return SuspiciousUserMessageEvent.class;
}
}
@@ -0,0 +1,33 @@
package com.github.twitch4j.eventsub.subscriptions;

import com.github.twitch4j.eventsub.condition.ModeratorEventSubCondition;
import com.github.twitch4j.eventsub.events.SuspiciousUserUpdateEvent;

/**
* Fires when a suspicious user's treatment has been updated.
* <p>
* Requires authorization from a moderator of the channel with the moderator:read:suspicious_users scope.
*
* @see com.github.twitch4j.auth.domain.TwitchScopes#HELIX_SUSPICIOUS_USERS_READ
*/
public class SuspiciousUserUpdateType implements SubscriptionType<ModeratorEventSubCondition, ModeratorEventSubCondition.ModeratorEventSubConditionBuilder<?, ?>, SuspiciousUserUpdateEvent> {
@Override
public String getName() {
return "channel.suspicious_user.update";
}

@Override
public String getVersion() {
return "1";
}

@Override
public ModeratorEventSubCondition.ModeratorEventSubConditionBuilder<?, ?> getConditionBuilder() {
return ModeratorEventSubCondition.builder();
}

@Override
public Class<SuspiciousUserUpdateEvent> getEventClass() {
return SuspiciousUserUpdateEvent.class;
}
}
@@ -0,0 +1,38 @@
package com.github.twitch4j.eventsub.events;

import com.github.twitch4j.common.util.TypeConvert;
import com.github.twitch4j.eventsub.domain.EvasionEvaluation;
import com.github.twitch4j.eventsub.domain.SuspiciousStatus;
import com.github.twitch4j.eventsub.domain.SuspiciousType;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import java.util.EnumSet;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

@Tag("unittest")
class SuspiciousUserMessageEventTest {

@Test
void deserializeManualMonitor() {
SuspiciousUserMessageEvent event = TypeConvert.jsonToObject(
"{\"broadcaster_user_id\":\"53888434\",\"broadcaster_user_name\":\"OGprodigy\",\"broadcaster_user_login\":\"ogprodigy\",\"user_id\":\"100135110\",\"user_name\":\"StreamElements\",\"user_login\":\"streamelements\",\"low_trust_status\":\"active_monitoring\",\"shared_ban_channel_ids\":null,\"types\":[\"manually_added\"],\"ban_evasion_evaluation\":\"unknown\",\"message\":{\"message_id\":\"0a173734-bd97-4e15-9b00-0fb1d198d881\",\"text\":\"@OGprodigy You can find a list of all Commands here https://StreamElements.com/ogprodigy/commands\",\"fragments\":[]}}",
SuspiciousUserMessageEvent.class
);
assertEquals("53888434", event.getBroadcasterUserId());
assertEquals("100135110", event.getUserId());
assertEquals(SuspiciousStatus.ACTIVE_MONITORING, event.getStatus());
assertNull(event.getSharedBanChannelIds());
assertEquals(EnumSet.of(SuspiciousType.MANUALLY_ADDED), event.getTypes());
assertEquals(EvasionEvaluation.UNKNOWN, event.getBanEvasionEvaluation());
assertNotNull(event.getMessage());
assertEquals("0a173734-bd97-4e15-9b00-0fb1d198d881", event.getMessage().getMessageId());
assertEquals("@OGprodigy You can find a list of all Commands here https://StreamElements.com/ogprodigy/commands", event.getMessage().getText());
assertTrue(event.getMessage().getFragments().isEmpty());
}

}