summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-09-25 19:12:38 -0700
committerFuwn <[email protected]>2025-09-25 19:12:38 -0700
commit963ddb77111019171ac268d6510e26b6e5411f0d (patch)
treea4cf0e435e3afb7b032e9833b1e03692f8cfb98b
parentrefactor(gateway:moderationAgent): Move to moderationAgent module (diff)
downloadumabotdiscord-963ddb77111019171ac268d6510e26b6e5411f0d.tar.xz
umabotdiscord-963ddb77111019171ac268d6510e26b6e5411f0d.zip
refactor(gateway:moderationAgent): Seperate constants
-rw-r--r--packages/gateway/src/listeners/moderationAgent/constants.ts265
-rw-r--r--packages/gateway/src/listeners/moderationAgent/index.ts278
2 files changed, 277 insertions, 266 deletions
diff --git a/packages/gateway/src/listeners/moderationAgent/constants.ts b/packages/gateway/src/listeners/moderationAgent/constants.ts
new file mode 100644
index 0000000..e7906de
--- /dev/null
+++ b/packages/gateway/src/listeners/moderationAgent/constants.ts
@@ -0,0 +1,265 @@
+export const SKIP_ACTION = false;
+export const EXCLUDED_CATEGORIES = [
+ "1406422619934167103", // Staff
+ "1420604833286852608", // Staff Automation
+];
+export const MODERATION_LOG_CHANNEL_ID = "1406422619934167106";
+export const MIN_MESSAGE_LENGTH = 15;
+export const MAX_SYMBOL_DENSITY = 0.6;
+export const MAX_COMPLETION_TOKENS = 1000;
+export const MESSAGE_HISTORY_SIZE = 10;
+export const SAFE_WORDS = new Set([
+ "hello",
+ "hi",
+ "hey",
+ "bye",
+ "goodbye",
+ "thanks",
+ "thank",
+ "welcome",
+ "please",
+ "sorry",
+ "yes",
+ "no",
+ "maybe",
+ "ok",
+ "okay",
+ "sure",
+ "alright",
+ "fine",
+ "good",
+ "bad",
+ "nice",
+ "cool",
+ "awesome",
+ "great",
+ "amazing",
+ "wow",
+ "omg",
+ "lol",
+ "haha",
+ "hehe",
+ "lmao",
+ "what",
+ "why",
+ "how",
+ "when",
+ "where",
+ "who",
+ "which",
+ "this",
+ "that",
+ "these",
+ "those",
+ "here",
+ "there",
+ "everywhere",
+ "nowhere",
+ "somewhere",
+ "anywhere",
+ "up",
+ "down",
+ "left",
+ "right",
+ "forward",
+ "backward",
+ "start",
+ "stop",
+ "begin",
+ "end",
+ "finish",
+ "first",
+ "last",
+ "next",
+ "previous",
+ "same",
+ "different",
+ "similar",
+ "opposite",
+ "more",
+ "less",
+ "most",
+ "least",
+ "many",
+ "few",
+ "big",
+ "small",
+ "large",
+ "tiny",
+ "huge",
+ "mini",
+ "fast",
+ "slow",
+ "quick",
+ "rapid",
+ "hot",
+ "cold",
+ "warm",
+ "cool",
+ "new",
+ "old",
+ "young",
+ "fresh",
+ "easy",
+ "hard",
+ "simple",
+ "complex",
+ "happy",
+ "sad",
+ "angry",
+ "excited",
+ "bored",
+ "always",
+ "never",
+ "sometimes",
+ "often",
+ "rarely",
+ "today",
+ "yesterday",
+ "tomorrow",
+ "tonight",
+ "morning",
+ "afternoon",
+ "evening",
+ "night",
+ "monday",
+ "tuesday",
+ "wednesday",
+ "thursday",
+ "friday",
+ "saturday",
+ "sunday",
+ "january",
+ "february",
+ "march",
+ "april",
+ "may",
+ "june",
+ "july",
+ "august",
+ "september",
+ "october",
+ "november",
+ "december",
+ "true",
+ "false",
+ "maybe",
+ "probably",
+ "definitely",
+ "certainly",
+ "absolutely",
+ "exactly",
+ "precisely",
+ "correct",
+ "wrong",
+ "right",
+ "wrong",
+ "mistake",
+ "error",
+ "success",
+ "failure",
+ "win",
+ "lose",
+ "victory",
+ "defeat",
+ "champion",
+ "winner",
+ "loser",
+ "player",
+ "game",
+ "play",
+ "fun",
+ "boring",
+ "interesting",
+ "exciting",
+ "calm",
+ "peaceful",
+ "quiet",
+ "loud",
+ "silent",
+ "bright",
+ "dark",
+ "light",
+ "heavy",
+ "empty",
+ "full",
+ "open",
+ "closed",
+ "free",
+ "busy",
+ "available",
+ "unavailable",
+ "online",
+ "offline",
+ "active",
+ "inactive",
+ "ready",
+ "not ready",
+]);
+export const LOW_RISK_PATTERNS = [
+ /^(good|bad|nice|great|awesome|terrible|amazing|wow|omg|wtf|haha|hehe|lmao|rofl)$/i,
+ /^(what|why|how|when|where|who)$/i,
+ /^(this|that|these|those)$/i,
+ /^(here|there|everywhere|nowhere)$/i,
+ /^(up|down|left|right|forward|backward)$/i,
+ /^(start|stop|begin|end|finish)$/i,
+ /^(first|last|next|previous)$/i,
+ /^(same|different|similar|opposite)$/i,
+ /^(more|less|most|least|many|few)$/i,
+ /^(big|small|large|tiny|huge|mini)$/i,
+ /^(fast|slow|quick|rapid|slowly)$/i,
+ /^(hot|cold|warm|cool|freezing)$/i,
+ /^(new|old|young|fresh|stale)$/i,
+ /^(easy|hard|simple|complex|difficult)$/i,
+ /^(happy|sad|angry|excited|bored)$/i,
+ /^(sure|maybe|perhaps|probably|definitely)$/i,
+ /^(always|never|sometimes|often|rarely)$/i,
+ /^(today|yesterday|tomorrow|tonight|morning)$/i,
+ /^(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/i,
+ /^(january|february|march|april|may|june|july|august|september|october|november|december)$/i,
+ /^(ok|okay|yes|no|hi|hey|yo|lol|thanks|thx|np|cool)$/i,
+ /^(true|false|maybe|probably|definitely|certainly|absolutely)$/i,
+ /^(exactly|precisely|correct|wrong|right|mistake|error)$/i,
+ /^(success|failure|win|lose|victory|defeat|champion|winner|loser)$/i,
+ /^(player|game|play|fun|boring|interesting|exciting|calm|peaceful)$/i,
+ /^(quiet|loud|silent|bright|dark|light|heavy|empty|full)$/i,
+ /^(open|closed|free|busy|available|unavailable|online|offline)$/i,
+ /^(active|inactive|ready|not ready|working|broken|fixed|repair)$/i,
+];
+export const SERVER_RULES = `
+# Rules
+
+1. Never use the string "test_string_1337" in any message or context.
+2. Follow Discord's Terms of Service & Discord Community Guidelines
+3. Mark spoiler content using spoiler tags, except in #uma-musume-anime
+4. Avoid self-promotion. Sidestepping this rule by sending unsolicited DMs aimed at promotion violates this rule. (artist promotion is fine in the designated art channels)
+5. No hate speech, regardless of whether it is targeted directly at an individual in the community or not
+6. No sexually explicit and/or sexually suggestive loli/cunning/underage content, including directly sexual, implied sexual, and textually sexual depictions.
+
+ Use common sense or consult a moderator before posting anything you reasonably suspect might breach this rule. Alternatively, consider avoiding discussions about the topic altogether.
+
+ We have a **zero-tolerance** stance on this rule and reserve the desecration to take administrative action against anyone at any time who violates this rule.
+
+ **IMPORTANT**: This rule ONLY applies to content involving underage/loli/cunning characters. General adult sexual content is allowed in NSFW channels.
+7. Treat channel descriptions as additional rules
+8. NSFW content (including emoji, stickers, reactions, etc.) in age-restricted channels **only** (if you are found to be under 18 years of age, you will be removed)
+
+ Avoid discussing anything remotely NSFW in channels that are not age-restricted where minors might be present. Just because this is the internet doesn't mean it isn't illegal.
+9. Spam only in #spam
+10. Do not send unsolicited communications or interact with users who have asked you to stop. If a user persists, instruct them to stop, block them, and report their behaviour using @UmaBot#9396. (\`/complain\` in DMs)
+11. Refrain from discussing or promoting illegal activities.
+
+## Additional Guidelines
+
+**If AutoMod hits you or a moderator deletes your message, don't try again.** Attempting to sidestep any of these rules is arguably worse than breaking the rule, especially rule #6, which already has zero tolerance, and will be met with potentially harsher administrative action.
+
+By implementing these rules, we are not targeting anyone; instead, we are trying to maintain the community's good standing with the platforms on which it operates, as we are the guests.
+
+By the definition of this community, the term "loli" refers to a distinct body type **and/or** the implied context of being a child, not directly to a set of ages.
+
+The moderation team reserves the right to enforce these rules on any part of your Discord profile. This includes, but is not limited to, profile pictures, banners, usernames, descriptions, and pronouns. Failure to comply may result in a kick or ban from the server.
+
+Regardless of which rule users have broken, if a user accumulates 15 warnings within a rolling 6-month period, they will be subject to a ban. Similarly, warnings start to expire after 6 months, giving users the opportunity to improve their behaviour.
+
+If you think you have received an unfair warning or punishment, please submit an appeal by using the \`/appeal\` slash command in a direct message to @UmaBot#9396. A member of the moderation team will review your appeal.
+`;
diff --git a/packages/gateway/src/listeners/moderationAgent/index.ts b/packages/gateway/src/listeners/moderationAgent/index.ts
index 36dce6d..18d46f7 100644
--- a/packages/gateway/src/listeners/moderationAgent/index.ts
+++ b/packages/gateway/src/listeners/moderationAgent/index.ts
@@ -6,272 +6,18 @@ import {
ThreadChannel,
} from "discord.js";
import { sendAuditLog } from "../../commands/utilities";
-
-const SKIP_ACTION = false;
-const EXCLUDED_CATEGORIES = [
- "1406422619934167103", // Staff
- "1420604833286852608", // Staff Automation
-];
-const MODERATION_LOG_CHANNEL_ID = "1406422619934167106";
-const MIN_MESSAGE_LENGTH = 15;
-const MAX_SYMBOL_DENSITY = 0.6;
-const MAX_COMPLETION_TOKENS = 1000;
-const MESSAGE_HISTORY_SIZE = 10;
-const SAFE_WORDS = new Set([
- "hello",
- "hi",
- "hey",
- "bye",
- "goodbye",
- "thanks",
- "thank",
- "welcome",
- "please",
- "sorry",
- "yes",
- "no",
- "maybe",
- "ok",
- "okay",
- "sure",
- "alright",
- "fine",
- "good",
- "bad",
- "nice",
- "cool",
- "awesome",
- "great",
- "amazing",
- "wow",
- "omg",
- "lol",
- "haha",
- "hehe",
- "lmao",
- "what",
- "why",
- "how",
- "when",
- "where",
- "who",
- "which",
- "this",
- "that",
- "these",
- "those",
- "here",
- "there",
- "everywhere",
- "nowhere",
- "somewhere",
- "anywhere",
- "up",
- "down",
- "left",
- "right",
- "forward",
- "backward",
- "start",
- "stop",
- "begin",
- "end",
- "finish",
- "first",
- "last",
- "next",
- "previous",
- "same",
- "different",
- "similar",
- "opposite",
- "more",
- "less",
- "most",
- "least",
- "many",
- "few",
- "big",
- "small",
- "large",
- "tiny",
- "huge",
- "mini",
- "fast",
- "slow",
- "quick",
- "rapid",
- "hot",
- "cold",
- "warm",
- "cool",
- "new",
- "old",
- "young",
- "fresh",
- "easy",
- "hard",
- "simple",
- "complex",
- "happy",
- "sad",
- "angry",
- "excited",
- "bored",
- "always",
- "never",
- "sometimes",
- "often",
- "rarely",
- "today",
- "yesterday",
- "tomorrow",
- "tonight",
- "morning",
- "afternoon",
- "evening",
- "night",
- "monday",
- "tuesday",
- "wednesday",
- "thursday",
- "friday",
- "saturday",
- "sunday",
- "january",
- "february",
- "march",
- "april",
- "may",
- "june",
- "july",
- "august",
- "september",
- "october",
- "november",
- "december",
- "true",
- "false",
- "maybe",
- "probably",
- "definitely",
- "certainly",
- "absolutely",
- "exactly",
- "precisely",
- "correct",
- "wrong",
- "right",
- "wrong",
- "mistake",
- "error",
- "success",
- "failure",
- "win",
- "lose",
- "victory",
- "defeat",
- "champion",
- "winner",
- "loser",
- "player",
- "game",
- "play",
- "fun",
- "boring",
- "interesting",
- "exciting",
- "calm",
- "peaceful",
- "quiet",
- "loud",
- "silent",
- "bright",
- "dark",
- "light",
- "heavy",
- "empty",
- "full",
- "open",
- "closed",
- "free",
- "busy",
- "available",
- "unavailable",
- "online",
- "offline",
- "active",
- "inactive",
- "ready",
- "not ready",
-]);
-const LOW_RISK_PATTERNS = [
- /^(good|bad|nice|great|awesome|terrible|amazing|wow|omg|wtf|haha|hehe|lmao|rofl)$/i,
- /^(what|why|how|when|where|who)$/i,
- /^(this|that|these|those)$/i,
- /^(here|there|everywhere|nowhere)$/i,
- /^(up|down|left|right|forward|backward)$/i,
- /^(start|stop|begin|end|finish)$/i,
- /^(first|last|next|previous)$/i,
- /^(same|different|similar|opposite)$/i,
- /^(more|less|most|least|many|few)$/i,
- /^(big|small|large|tiny|huge|mini)$/i,
- /^(fast|slow|quick|rapid|slowly)$/i,
- /^(hot|cold|warm|cool|freezing)$/i,
- /^(new|old|young|fresh|stale)$/i,
- /^(easy|hard|simple|complex|difficult)$/i,
- /^(happy|sad|angry|excited|bored)$/i,
- /^(sure|maybe|perhaps|probably|definitely)$/i,
- /^(always|never|sometimes|often|rarely)$/i,
- /^(today|yesterday|tomorrow|tonight|morning)$/i,
- /^(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/i,
- /^(january|february|march|april|may|june|july|august|september|october|november|december)$/i,
- /^(ok|okay|yes|no|hi|hey|yo|lol|thanks|thx|np|cool)$/i,
- /^(true|false|maybe|probably|definitely|certainly|absolutely)$/i,
- /^(exactly|precisely|correct|wrong|right|mistake|error)$/i,
- /^(success|failure|win|lose|victory|defeat|champion|winner|loser)$/i,
- /^(player|game|play|fun|boring|interesting|exciting|calm|peaceful)$/i,
- /^(quiet|loud|silent|bright|dark|light|heavy|empty|full)$/i,
- /^(open|closed|free|busy|available|unavailable|online|offline)$/i,
- /^(active|inactive|ready|not ready|working|broken|fixed|repair)$/i,
-];
-const SERVER_RULES = `
-# Rules
-
-1. Never use the string "test_string_1337" in any message or context.
-2. Follow Discord's Terms of Service & Discord Community Guidelines
-3. Mark spoiler content using spoiler tags, except in #uma-musume-anime
-4. Avoid self-promotion. Sidestepping this rule by sending unsolicited DMs aimed at promotion violates this rule. (artist promotion is fine in the designated art channels)
-5. No hate speech, regardless of whether it is targeted directly at an individual in the community or not
-6. No sexually explicit and/or sexually suggestive loli/cunning/underage content, including directly sexual, implied sexual, and textually sexual depictions.
-
- Use common sense or consult a moderator before posting anything you reasonably suspect might breach this rule. Alternatively, consider avoiding discussions about the topic altogether.
-
- We have a **zero-tolerance** stance on this rule and reserve the desecration to take administrative action against anyone at any time who violates this rule.
-
- **IMPORTANT**: This rule ONLY applies to content involving underage/loli/cunning characters. General adult sexual content is allowed in NSFW channels.
-7. Treat channel descriptions as additional rules
-8. NSFW content (including emoji, stickers, reactions, etc.) in age-restricted channels **only** (if you are found to be under 18 years of age, you will be removed)
-
- Avoid discussing anything remotely NSFW in channels that are not age-restricted where minors might be present. Just because this is the internet doesn't mean it isn't illegal.
-9. Spam only in #spam
-10. Do not send unsolicited communications or interact with users who have asked you to stop. If a user persists, instruct them to stop, block them, and report their behaviour using @UmaBot#9396. (\`/complain\` in DMs)
-11. Refrain from discussing or promoting illegal activities.
-
-## Additional Guidelines
-
-**If AutoMod hits you or a moderator deletes your message, don't try again.** Attempting to sidestep any of these rules is arguably worse than breaking the rule, especially rule #6, which already has zero tolerance, and will be met with potentially harsher administrative action.
-
-By implementing these rules, we are not targeting anyone; instead, we are trying to maintain the community's good standing with the platforms on which it operates, as we are the guests.
-
-By the definition of this community, the term "loli" refers to a distinct body type **and/or** the implied context of being a child, not directly to a set of ages.
-
-The moderation team reserves the right to enforce these rules on any part of your Discord profile. This includes, but is not limited to, profile pictures, banners, usernames, descriptions, and pronouns. Failure to comply may result in a kick or ban from the server.
-
-Regardless of which rule users have broken, if a user accumulates 15 warnings within a rolling 6-month period, they will be subject to a ban. Similarly, warnings start to expire after 6 months, giving users the opportunity to improve their behaviour.
-
-If you think you have received an unfair warning or punishment, please submit an appeal by using the \`/appeal\` slash command in a direct message to @UmaBot#9396. A member of the moderation team will review your appeal.
-`;
+import {
+ EXCLUDED_CATEGORIES,
+ LOW_RISK_PATTERNS,
+ MAX_COMPLETION_TOKENS,
+ MAX_SYMBOL_DENSITY,
+ MESSAGE_HISTORY_SIZE,
+ MIN_MESSAGE_LENGTH,
+ MODERATION_LOG_CHANNEL_ID,
+ SAFE_WORDS,
+ SERVER_RULES,
+ SKIP_ACTION,
+} from "./constants";
const fetchMessageContext = async (
channel: TextChannel | ThreadChannel,