diff --git a/application/config.json.template b/application/config.json.template index c34d9e8635..8f64df1a15 100644 --- a/application/config.json.template +++ b/application/config.json.template @@ -21,10 +21,63 @@ "scamBlocker": { "mode": "AUTO_DELETE_BUT_APPROVE_QUARANTINE", "reportChannelPattern": "commands", - "suspiciousKeywords": ["nitro", "boob", "sexy", "sexi", "esex"], - "hostWhitelist": ["discord.com", "discord.gg", "discord.media", "discordapp.com", "discordapp.net", "discordstatus.com"], - "hostBlacklist": ["bit.ly"], - "suspiciousHostKeywords": ["discord", "nitro", "premium"], + "botTrapChannelPattern": "bot-trap", + "suspiciousKeywords": [ + "nitro", + "boob", + "sexy", + "sexi", + "esex", + "steam", + "gift", + "onlyfans", + "bitcoin", + "btc", + "promo", + "trader", + "trading", + "whatsapp", + "crypto", + "claim", + "teen", + "adobe", + "hack", + "steamcommunity", + "freenitro", + "usd", + "earn", + ".exe" + ], + "hostWhitelist": [ + "discord.com", + "discord.media", + "discordapp.com", + "discordapp.net", + "discordstatus.com" + ], + "hostBlacklist": [ + "bit.ly", + "discord.gg", + "teletype.in", + "t.me", + "corematrix.us", + "u.to", + "steamcommunity.com", + "goo.su", + "telegra.ph", + "shorturl.at", + "cheatings.xyz", + "transfer.sh" + ], + "suspiciousHostKeywords": [ + "discord", + "nitro", + "premium", + "free", + "cheat", + "crypto", + "tele" + ], "isHostSimilarToKeywordDistanceThreshold": 2 }, "wolframAlphaAppId": "79J52T-6239TVXHR7", diff --git a/application/src/main/java/org/togetherjava/tjbot/config/ScamBlockerConfig.java b/application/src/main/java/org/togetherjava/tjbot/config/ScamBlockerConfig.java index c322fa5ce5..d95d9f9cce 100644 --- a/application/src/main/java/org/togetherjava/tjbot/config/ScamBlockerConfig.java +++ b/application/src/main/java/org/togetherjava/tjbot/config/ScamBlockerConfig.java @@ -17,6 +17,7 @@ public final class ScamBlockerConfig { private final Mode mode; private final String reportChannelPattern; + private final String botTrapChannelPattern; private final Set suspiciousKeywords; private final Set hostWhitelist; private final Set hostBlacklist; @@ -27,6 +28,8 @@ public final class ScamBlockerConfig { private ScamBlockerConfig(@JsonProperty(value = "mode", required = true) Mode mode, @JsonProperty(value = "reportChannelPattern", required = true) String reportChannelPattern, + @JsonProperty(value = "botTrapChannelPattern", + required = true) String botTrapChannelPattern, @JsonProperty(value = "suspiciousKeywords", required = true) Set suspiciousKeywords, @JsonProperty(value = "hostWhitelist", required = true) Set hostWhitelist, @@ -37,6 +40,7 @@ private ScamBlockerConfig(@JsonProperty(value = "mode", required = true) Mode mo required = true) int isHostSimilarToKeywordDistanceThreshold) { this.mode = Objects.requireNonNull(mode); this.reportChannelPattern = Objects.requireNonNull(reportChannelPattern); + this.botTrapChannelPattern = Objects.requireNonNull(botTrapChannelPattern); this.suspiciousKeywords = new HashSet<>(Objects.requireNonNull(suspiciousKeywords)); this.hostWhitelist = new HashSet<>(Objects.requireNonNull(hostWhitelist)); this.hostBlacklist = new HashSet<>(Objects.requireNonNull(hostBlacklist)); @@ -63,6 +67,16 @@ public String getReportChannelPattern() { return reportChannelPattern; } + /** + * Gets the REGEX pattern used to identify the channel that is used to as bot-trap. Sending + * messages in this channel identifies the author as bot. + * + * @return the channel name pattern + */ + public String getBotTrapChannelPattern() { + return botTrapChannelPattern; + } + /** * Gets the set of keywords that are considered suspicious if they appear in a message. * diff --git a/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamBlocker.java b/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamBlocker.java index 5330ffd351..f8b06f7eb6 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamBlocker.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamBlocker.java @@ -64,7 +64,9 @@ public final class ScamBlocker extends MessageReceiverAdapter implements UserInt private final ScamBlockerConfig.Mode mode; private final String reportChannelPattern; + private final String botTrapChannelPattern; private final Predicate isReportChannel; + private final Predicate isBotTrapChannel; private final ScamDetector scamDetector; private final Config config; private final ModerationActionsStore actionsStore; @@ -92,6 +94,12 @@ public ScamBlocker(ModerationActionsStore actionsStore, ScamHistoryStore scamHis Predicate isReportChannelName = Pattern.compile(reportChannelPattern).asMatchPredicate(); isReportChannel = channel -> isReportChannelName.test(channel.getName()); + + botTrapChannelPattern = config.getScamBlocker().getBotTrapChannelPattern(); + Predicate isBotTrapChannelName = + Pattern.compile(botTrapChannelPattern).asMatchPredicate(); + isBotTrapChannel = channel -> isBotTrapChannelName.test(channel.getName()); + hasRequiredRole = Pattern.compile(config.getSoftModerationRolePattern()).asMatchPredicate(); componentIdInteractor = new ComponentIdInteractor(getInteractionType(), getName()); @@ -122,9 +130,15 @@ public void onMessageReceived(MessageReceivedEvent event) { return; } + boolean isSafe = !isBotTrapChannel.test(event.getChannel().asTextChannel()); + Message message = event.getMessage(); String content = message.getContentDisplay(); - if (!scamDetector.isScam(content)) { + if (isSafe && scamDetector.isScam(content)) { + isSafe = false; + } + + if (isSafe) { return; } diff --git a/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetector.java b/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetector.java index a3c7061c75..654cd87084 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetector.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetector.java @@ -7,6 +7,7 @@ import java.net.URI; import java.util.Locale; import java.util.regex.Pattern; +import java.util.stream.Stream; /** * Detects whether a text message classifies as scam or not, using certain heuristics. @@ -40,10 +41,16 @@ public boolean isScam(CharSequence message) { } private boolean isScam(AnalyseResults results) { - if (results.pingsEveryone && results.containsSuspiciousKeyword && results.hasUrl) { + if (results.pingsEveryone && (results.containsSuspiciousKeyword || results.hasUrl + || results.containsDollarSign)) { return true; } - return results.containsSuspiciousKeyword && results.hasSuspiciousUrl; + + return Stream + .of(results.containsSuspiciousKeyword, results.hasSuspiciousUrl, + results.containsDollarSign) + .filter(flag -> flag) + .count() >= 2; } private void analyzeToken(String token, AnalyseResults results) { @@ -51,7 +58,8 @@ private void analyzeToken(String token, AnalyseResults results) { return; } - if (!results.pingsEveryone && "@everyone".equalsIgnoreCase(token)) { + if (!results.pingsEveryone + && ("@everyone".equalsIgnoreCase(token) || "@here".equalsIgnoreCase(token))) { results.pingsEveryone = true; } @@ -59,6 +67,10 @@ private void analyzeToken(String token, AnalyseResults results) { results.containsSuspiciousKeyword = true; } + if (!results.containsDollarSign && token.contains("$")) { + results.containsDollarSign = true; + } + if (token.startsWith("http")) { analyzeUrl(token, results); } @@ -131,6 +143,7 @@ private boolean isHostSimilarToKeyword(String host, String keyword) { private static class AnalyseResults { private boolean pingsEveryone; private boolean containsSuspiciousKeyword; + private boolean containsDollarSign; private boolean hasUrl; private boolean hasSuspiciousUrl; } diff --git a/application/src/test/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetectorTest.java b/application/src/test/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetectorTest.java index b9218b368a..f62dd31646 100644 --- a/application/src/test/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetectorTest.java +++ b/application/src/test/java/org/togetherjava/tjbot/features/moderation/scam/ScamDetectorTest.java @@ -27,12 +27,16 @@ void setUp() { when(config.getScamBlocker()).thenReturn(scamConfig); when(scamConfig.getSuspiciousKeywords()) - .thenReturn(Set.of("nitro", "boob", "sexi", "esex")); - when(scamConfig.getHostWhitelist()).thenReturn(Set.of("discord.com", "discord.gg", - "discord.media", "discordapp.com", "discordapp.net", "discordstatus.com")); - when(scamConfig.getHostBlacklist()).thenReturn(Set.of("bit.ly")); + .thenReturn(Set.of("nitro", "boob", "sexy", "sexi", "esex", "steam", "gift", "onlyfans", + "bitcoin", "btc", "promo", "trader", "trading", "whatsapp", "crypto", "claim", + "teen", "adobe", "hack", "steamcommunity", "freenitro", "usd", "earn", ".exe")); + when(scamConfig.getHostWhitelist()).thenReturn(Set.of("discord.com", "discord.media", + "discordapp.com", "discordapp.net", "discordstatus.com")); + when(scamConfig.getHostBlacklist()).thenReturn(Set.of("bit.ly", "discord.gg", "teletype.in", + "t.me", "corematrix.us", "u.to", "steamcommunity.com", "goo.su", "telegra.ph", + "shorturl.at", "cheatings.xyz", "transfer.sh")); when(scamConfig.getSuspiciousHostKeywords()) - .thenReturn(Set.of("discord", "nitro", "premium")); + .thenReturn(Set.of("discord", "nitro", "premium", "free", "cheat", "crypto", "tele")); when(scamConfig.getIsHostSimilarToKeywordDistanceThreshold()).thenReturn(2); scamDetector = new ScamDetector(config); @@ -144,6 +148,83 @@ private static List provideRealScamMessages() { https://discordu.gift/u1CHEX2sjpDuR3T5""", "@everyone join now https://discord.gg/boobise", "@everyone join now https://discord.gg/esexiest", - "@everyone Join Now | Free All 12-18 y.o. https://discord.gg/eesexe"); + "@everyone Join Now | Free All 12-18 y.o. https://discord.gg/eesexe", + "@everyone steam gift 50$ - steamcommunity.com/gift-card/pay/51", """ + @everyone + 20$ from steam + steamcommunity.com/gift/001023 + """, """ + Free Onlyfans leaks and 18+ Content: + https://discord.gg/4ue9esAuR7 🍑 @everyone + """, """ + Bro, don't miss it: + https://teletype.in/@game_insider/valve_promobo + """, + "Stake gives a 1500$! When you register using the promo code \"em4fh4bj67\" - Stake.com/auth/register?promo=em4fh4bj67", + """ + @everyone + 50$ from steam + steamcommunity.com/gift/81237 + """, + """ + 2025📊The best repacks of 24/7 only in our group📊 + IPTVPlayet AtlasVPN TradingView-Premium== Become a real trader with the best offers... + ✍️ https://t.me/repackMEMIaa ✍️ + """, + """ + Check there is btc cost 109k + https://corematrix.us/eni + """, + """ + I’ll teach 10 people to earn $30k or more within 72 hours but you will pay me 10% of your profit when you receive it. Note only interest people should apply, drop a message let's get started by asking (HOW) + https://t.me/Christopher_Schwingo + WhatsApp +1 (571) 598-2749 + """, + """ + I’ll teach 10 interested people on how to earn $30k or more within 24 hours from the crypto market, but you’ll promise to pay me 20% of the profit. Note only interested people should contact me (HOW) let get started + 👇👇👇 + https://t.me/Official_Nichola1o + """, + """ + Bro steam gift 50$ - steamcommunity.com/gift-card/pay/51 + @here @everyone + """, """ + Bro gift 50$ - steamcommunity.com/gift-card/pay/51 + @everyone + """, """ + 50$ + steamcommunity.com/gift/0a9zk2j1man2o + """, """ + Hello, i found good server🔞 + https://discord.gg/e-womanso + @everyone + """, """ + Gift 50$ - steamcommunity.com/gift-card/51 + @everyone @here + """, """ + 50$ From steam + steamcommunity.com/gift/7656685834763978 + @everyone + """, "catch 25$ https://u.to/ExatIO", """ + STEAM 50$ GIFT, CLAIM NOW + steamcommunity.com/1249349825824 + @everyone + """, + "Hot Teen & Onlyfans Leaks :underage: :peach: https://discord.gg/nudesxxxo @everyone", + """ + Adobe Full Espanol GRATiS 2024 + https://telegra.ph/Adobe-GRATIS-2024-FULL-ESPANOL-02-28 + Tutorial video + https://www.youtube.com/watch?v=gmEZLz5xbmp + @everyone + """, + "Get a $50 gift to your steam account balance https://shorturl.at/cpt09 Immerse yourself in the spring atmosphere now!", + "#1 Free Hacks: https://cheatings.xyz/abc", + """ + I’ll help 10 people to earn 55k USDT within 72 hours but you will pay me 10% of your profit when you receive it. Note only interested people should apply, drop a message let’s get started by asking (How) + Or via TG: https://t.me/Charlie_Adamo + """, + "Urgently looking for mods & collab managers https://discord.gg/cryptohireo", + "Check this - https://transfer.sh/get/ajmkh3l7tzop/Setup.exe"); } }