Skip to content

Commit

Permalink
feat(eventsub): add badges to ChannelChatNotificationEvent (#883)
Browse files Browse the repository at this point in the history
  • Loading branch information
iProdigy committed Nov 10, 2023
1 parent 3022e87 commit 10d557f
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 94 deletions.
192 changes: 100 additions & 92 deletions common/src/main/java/com/github/twitch4j/common/util/TwitchUtils.java
Expand Up @@ -13,6 +13,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

public class TwitchUtils {

Expand Down Expand Up @@ -69,105 +70,112 @@ public static Set<CommandPermission> getPermissionsFromTags(@NonNull Map<String,
return getPermissionsFromTags(null, userId, botOwnerIds, badges);
}

private static Set<CommandPermission> getPermissionsFromTags(@Nullable CharSequence badgesTag, String userId, Collection<String> botOwnerIds, @NonNull Map<String, String> badges) {
Set<CommandPermission> permissionSet = EnumSet.of(CommandPermission.EVERYONE);
@ApiStatus.Internal
public static <T> Set<CommandPermission> getPermissions(Iterable<T> badges, Function<T, String> badgeName, Function<T, String> badgeValue) {
Set<CommandPermission> perms = EnumSet.of(CommandPermission.EVERYONE);
for (T badge : badges) {
String key = badgeName.apply(badge);
switch (key) {
case "premium":
case "turbo":
perms.add(CommandPermission.PRIME_TURBO);
break;

case "partner":
case "ambassador":
perms.add(CommandPermission.PARTNER);
break;

case "subscriber":
perms.add(CommandPermission.SUBSCRIBER);
break;

case "founder":
// note: value contains tier
perms.add(CommandPermission.FOUNDER);
break;

case "sub-gifter":
case "sub-gift-leader":
perms.add(CommandPermission.SUBGIFTER);
break;

case "bits":
case "bits-leader":
case "anonymous-cheerer":
perms.add(CommandPermission.BITS_CHEERER);
break;

case "hype-train":
String hypeBadge = badgeValue.apply(badge);
if ("1".equals(hypeBadge)) {
perms.add(CommandPermission.CURRENT_HYPE_TRAIN_CONDUCTOR);
} else if ("2".equals(hypeBadge)) {
perms.add(CommandPermission.FORMER_HYPE_TRAIN_CONDUCTOR);
}
break;

case "predictions":
String predictionBadge = badgeValue.apply(badge);
if (predictionBadge != null && !predictionBadge.isEmpty()) {
char first = predictionBadge.charAt(0);
if (first == 'b') {
perms.add(CommandPermission.PREDICTIONS_BLUE);
} else if (first == 'p') {
perms.add(CommandPermission.PREDICTIONS_PINK);
}
}
break;

case "no_audio":
perms.add(CommandPermission.NO_AUDIO);
break;

case "no_video":
perms.add(CommandPermission.NO_VIDEO);
break;

case "moments":
perms.add(CommandPermission.MOMENTS);
break;

case "artist-badge":
perms.add(CommandPermission.ARTIST);
break;

case "vip":
perms.add(CommandPermission.VIP);
break;

case "staff":
case "admin":
perms.add(CommandPermission.TWITCHSTAFF);
break;

case "moderator":
perms.add(CommandPermission.MODERATOR);
break;

case "broadcaster":
perms.add(CommandPermission.BROADCASTER);
perms.add(CommandPermission.MODERATOR);
break;

default:
break;
}
}
return perms;
}

private static Set<CommandPermission> getPermissionsFromTags(@Nullable CharSequence badgesTag, String userId, Collection<String> botOwnerIds, @NonNull Map<String, String> badges) {
// Parse badges tag
if (badgesTag != null) {
badges.putAll(parseBadges(badgesTag.toString()));
}

// Check for Permissions
if (!badges.isEmpty()) {
// Broadcaster
if (badges.containsKey("broadcaster")) {
permissionSet.add(CommandPermission.BROADCASTER);
permissionSet.add(CommandPermission.MODERATOR);
}
// Twitch Prime
if (badges.containsKey("premium") || badges.containsKey("turbo")) {
permissionSet.add(CommandPermission.PRIME_TURBO);
}
// Moderator
if (badges.containsKey("moderator")) {
permissionSet.add(CommandPermission.MODERATOR);
}
// Partner
if (badges.containsKey("partner") || badges.containsKey("ambassador")) {
permissionSet.add(CommandPermission.PARTNER);
}
// VIP
if (badges.containsKey("vip")) {
permissionSet.add(CommandPermission.VIP);
}
// Turbo
if (badges.containsKey("turbo")) {
permissionSet.add(CommandPermission.PRIME_TURBO);
}
// Twitch Staff
if (badges.containsKey("staff") || badges.containsKey("admin")) {
permissionSet.add(CommandPermission.TWITCHSTAFF);
}
// Subscriber
if (badges.containsKey("subscriber")) {
permissionSet.add(CommandPermission.SUBSCRIBER);
}
// SubGifter
if (badges.containsKey("sub-gifter") || badges.containsKey("sub-gift-leader")) {
permissionSet.add(CommandPermission.SUBGIFTER);
}
// Cheerer
if (badges.containsKey("bits") || badges.containsKey("bits-leader") || badges.containsKey("anonymous-cheerer")) {
permissionSet.add(CommandPermission.BITS_CHEERER);
}
// Founder
if (badges.containsKey("founder")) {
permissionSet.add(CommandPermission.FOUNDER);

// also contains info about the tier if needed
/*
if (badges.get("founder").equals("0")) {
// Tier 1 Founder
} else if (badges.get("founder").equals("1")) {
// Tier 2 Founder
} else if (badges.get("founder").equals("2")) {
// Tier 3 Founder
}
*/
}
// Hype Train Conductor
String hypeBadge = badges.get("hype-train");
if ("1".equals(hypeBadge)) {
permissionSet.add(CommandPermission.CURRENT_HYPE_TRAIN_CONDUCTOR);
} else if ("2".equals(hypeBadge)) {
permissionSet.add(CommandPermission.FORMER_HYPE_TRAIN_CONDUCTOR);
}
// Predictions Participation
String predictionBadge = badges.get("predictions");
if (StringUtils.isNotEmpty(predictionBadge)) {
char first = predictionBadge.charAt(0);
if (first == 'b') {
permissionSet.add(CommandPermission.PREDICTIONS_BLUE);
} else if (first == 'p') {
permissionSet.add(CommandPermission.PREDICTIONS_PINK);
}
}
// Accessibility
if (badges.containsKey("no_audio")) {
permissionSet.add(CommandPermission.NO_AUDIO);
}
if (badges.containsKey("no_video")) {
permissionSet.add(CommandPermission.NO_VIDEO);
}
// Present for Channel Moment
if (badges.containsKey("moments")) {
permissionSet.add(CommandPermission.MOMENTS);
}
// Channel Emote Artist
if (badges.containsKey("artist-badge")) {
permissionSet.add(CommandPermission.ARTIST);
}
}
Set<CommandPermission> permissionSet = getPermissions(badges.entrySet(), Map.Entry::getKey, Map.Entry::getValue);

if (userId != null && botOwnerIds != null && botOwnerIds.contains(userId))
permissionSet.add(CommandPermission.OWNER);
Expand Down
@@ -0,0 +1,36 @@
package com.github.twitch4j.eventsub.domain.chat;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;

@Data
@Setter(AccessLevel.PRIVATE)
public class Badge {

/**
* An ID that identifies this set of chat badges.
* <p>
* For example: "bits", "subscriber", "vip", "moderator", "broadcaster", "partner", "ambassador", "turbo",
* "hype-train", "no_audio", "no_video", "sub-gifter", "sub-gift-leader", "premium" (i.e., twitch prime)
*/
private String setId;

/**
* An ID that identifies this version of the badge.
* The ID can be any value.
* <p>
* For example, for Bits, the ID is the Bits tier level,
* but for World of Warcraft, it could be Alliance or Horde.
*/
private String id;

/**
* Contains metadata related to the chat badges in the badges tag.
* <p>
* Currently, this tag contains metadata only for subscriber badges,
* to indicate the number of months the user has been a subscriber.
*/
private String info;

}
@@ -1,6 +1,8 @@
package com.github.twitch4j.eventsub.events;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.twitch4j.common.enums.CommandPermission;
import com.github.twitch4j.common.util.TwitchUtils;
import com.github.twitch4j.eventsub.domain.chat.*;
import lombok.AccessLevel;
import lombok.Data;
Expand All @@ -11,6 +13,9 @@
import lombok.experimental.Accessors;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Set;

@Data
@Setter(AccessLevel.PRIVATE)
@NoArgsConstructor
Expand All @@ -19,17 +24,22 @@
public class ChannelChatNotificationEvent extends ChannelChatUserEvent {

/**
* Whether or not the chatter is anonymous.
* Whether the chatter is anonymous.
*/
@Accessors(fluent = true)
@JsonProperty("chatter_is_anonymous")
private Boolean isChatterAnonymous;

/**
* The color of the users name in the chat room.
* The color of the user's name in the chat room.
*/
private String color;

/**
* The user's visible badges in the chat room.
*/
private List<Badge> badges;

/**
* The message Twitch shows in the chat room for this notice.
*/
Expand Down Expand Up @@ -134,4 +144,12 @@ public class ChannelChatNotificationEvent extends ChannelChatUserEvent {
@Nullable
private BitsBadge bitsBadgeTier;

/**
* @return {@link #getBadges()} as {@link CommandPermission}, if {@link #getBadges()} is not null.
*/
@Nullable
public Set<CommandPermission> getPermissions() {
return badges != null ? TwitchUtils.getPermissions(badges, Badge::getSetId, Badge::getId) : null;
}

}

0 comments on commit 10d557f

Please sign in to comment.