From 64906af8e217cff4dd0ed861ec964ef471c8fac2 Mon Sep 17 00:00:00 2001 From: barsherror404 Date: Wed, 25 Mar 2026 19:38:24 +0300 Subject: [PATCH 1/2] Track emoji usage in messages and reactions --- .../togetherjava/tjbot/features/Features.java | 2 + .../analytics/EmojiTrackerListener.java | 70 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java diff --git a/application/src/main/java/org/togetherjava/tjbot/features/Features.java b/application/src/main/java/org/togetherjava/tjbot/features/Features.java index 1f6acbef2e..c360bacdd1 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/Features.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/Features.java @@ -6,6 +6,7 @@ import org.togetherjava.tjbot.config.FeatureBlacklist; import org.togetherjava.tjbot.config.FeatureBlacklistConfig; import org.togetherjava.tjbot.db.Database; +import org.togetherjava.tjbot.features.analytics.EmojiTrackerListener; import org.togetherjava.tjbot.features.analytics.Metrics; import org.togetherjava.tjbot.features.basic.MemberCountDisplayRoutine; import org.togetherjava.tjbot.features.basic.PingCommand; @@ -159,6 +160,7 @@ public static Collection createFeatures(JDA jda, Database database, Con // Message receivers features.add(new TopHelpersMessageListener(database, config)); features.add(new SuggestionsUpDownVoter(config, metrics)); + features.add(new EmojiTrackerListener(metrics)); features.add(new ScamBlocker(actionsStore, scamHistoryStore, config, metrics)); features.add(new MediaOnlyChannelListener(config, metrics)); features.add(new FileSharingMessageListener(config, metrics)); diff --git a/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java new file mode 100644 index 0000000000..1d0f274760 --- /dev/null +++ b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java @@ -0,0 +1,70 @@ +package org.togetherjava.tjbot.features.analytics; + +import net.dv8tion.jda.api.entities.emoji.CustomEmoji; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; + +import org.togetherjava.tjbot.features.MessageReceiverAdapter; + +import java.util.regex.Pattern; + +/** + * Listener that tracks emoji usage across all channels for analytics purposes. + *

+ * Counts emojis used in messages and reactions so admins can see which emojis are unused and should + * be removed. + *

+ * Custom emojis are tracked by their Discord ID (e.g. {@code emoji-custom-123456789}) rather than + * by name, since emoji names are not unique and may change over time. Animated custom emojis are + * tracked separately (e.g. {@code emoji-custom-animated-123456789}). Unicode emojis are tracked by + * name (e.g. {@code emoji-unicode-thumbsup}). + */ +public final class EmojiTrackerListener extends MessageReceiverAdapter { + private static final Pattern ALL_CHANNELS = Pattern.compile(".*"); + + private final Metrics metrics; + + /** + * Creates a new listener to track emoji usage across all channels. + * + * @param metrics to track emoji usage events + */ + public EmojiTrackerListener(Metrics metrics) { + super(ALL_CHANNELS); + + this.metrics = metrics; + } + + @Override + public void onMessageReceived(MessageReceivedEvent event) { + if (event.getAuthor().isBot() || event.isWebhookMessage()) { + return; + } + + event.getMessage().getMentions().getCustomEmojis().forEach(this::trackCustomEmoji); + } + + @Override + public void onMessageReactionAdd(MessageReactionAddEvent event) { + if (event.getUser() != null && event.getUser().isBot()) { + return; + } + + trackEmojiUnion(event.getEmoji()); + } + + private void trackEmojiUnion(EmojiUnion emoji) { + if (emoji.getType() == Emoji.Type.CUSTOM) { + trackCustomEmoji(emoji.asCustom()); + } else { + metrics.count("emoji-unicode-" + emoji.asUnicode().getName()); + } + } + + private void trackCustomEmoji(CustomEmoji emoji) { + String prefix = emoji.isAnimated() ? "emoji-custom-animated-" : "emoji-custom-"; + metrics.count(prefix + emoji.getIdLong()); + } +} From 8a930b4bf7a2aebe968cc574cc08f94e1225f1f0 Mon Sep 17 00:00:00 2001 From: barsherror404 Date: Thu, 26 Mar 2026 00:13:41 +0300 Subject: [PATCH 2/2] Track emoji usage in messages and reactions --- .../analytics/EmojiTrackerListener.java | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java index 1d0f274760..f90b11b68b 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java @@ -8,22 +8,16 @@ import org.togetherjava.tjbot.features.MessageReceiverAdapter; -import java.util.regex.Pattern; - /** - * Listener that tracks emoji usage across all channels for analytics purposes. + * Listener that tracks custom emoji usage across all channels for analytics purposes. *

- * Counts emojis used in messages and reactions so admins can see which emojis are unused and should - * be removed. + * Counts custom emojis used in messages and reactions so admins can see which emojis are unused and + * should be removed. *

- * Custom emojis are tracked by their Discord ID (e.g. {@code emoji-custom-123456789}) rather than - * by name, since emoji names are not unique and may change over time. Animated custom emojis are - * tracked separately (e.g. {@code emoji-custom-animated-123456789}). Unicode emojis are tracked by - * name (e.g. {@code emoji-unicode-thumbsup}). + * Custom emojis are tracked by their Discord ID (e.g. {@code emoji-custom-123456789}). Animated + * custom emojis are tracked separately (e.g. {@code emoji-custom-animated-123456789}). */ public final class EmojiTrackerListener extends MessageReceiverAdapter { - private static final Pattern ALL_CHANNELS = Pattern.compile(".*"); - private final Metrics metrics; /** @@ -32,14 +26,14 @@ public final class EmojiTrackerListener extends MessageReceiverAdapter { * @param metrics to track emoji usage events */ public EmojiTrackerListener(Metrics metrics) { - super(ALL_CHANNELS); + super(); this.metrics = metrics; } @Override public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot() || event.isWebhookMessage()) { + if (event.isWebhookMessage()) { return; } @@ -48,19 +42,12 @@ public void onMessageReceived(MessageReceivedEvent event) { @Override public void onMessageReactionAdd(MessageReactionAddEvent event) { - if (event.getUser() != null && event.getUser().isBot()) { + EmojiUnion emoji = event.getEmoji(); + if (emoji.getType() != Emoji.Type.CUSTOM) { return; } - trackEmojiUnion(event.getEmoji()); - } - - private void trackEmojiUnion(EmojiUnion emoji) { - if (emoji.getType() == Emoji.Type.CUSTOM) { - trackCustomEmoji(emoji.asCustom()); - } else { - metrics.count("emoji-unicode-" + emoji.asUnicode().getName()); - } + trackCustomEmoji(emoji.asCustom()); } private void trackCustomEmoji(CustomEmoji emoji) {