feat(automod): dont rescan images from flagged users
vi did:web:vt3e.cat
Thu, 07 May 2026 19:10:21 +0100
4 files changed,
56 insertions(+),
31 deletions(-)
M
src/automod/index.ts
→
src/automod/index.ts
@@ -1,5 +1,7 @@
import { rest } from "@/discord"; import { + CategoryChannel, + ChannelType, type Client, type Message, type RESTGetAPIGuildMessagesSearchQuery,@@ -81,11 +83,12 @@ if (message.author.bot || !message.guildId || !message.member) return;
const automodFunctions: AutomodFunction[] = [ handleSpamMarker, handleCryptoScamOCR, - ]; + ]; + if (message.channel.type == ChannelType.GuildText && message.channel.name.includes("ticket")) return; + if (message.channel.isThread()) return null; + if (message.content.includes("!bypass")) return null; if ((await hasManagerPermissions(message.member)) && IS_PROD) return null; - if (message.channel.isThread()) return null; - if (message.content.includes("!bypass")) return null; for (const func of automodFunctions) { logger.info(@@ -149,6 +152,22 @@ client: Client,
message: Message, ): Promise<AutomodResult> { if (message.attachments.size === 0) return null; + + if (pendingReports.has(message.author.id) || cooldowns.has(message.author.id)) { + logger.info( + { messageId: message.id, authorId: message.author.id }, + "Skipping OCR as user has already been recently flagged", + ); + + await reportToAutomod( + client, + message, + "User repeatedly sending images after being flagged", + "You sent an image indicative of your account being compromised or a phishing attempt, so we removed it." + ); + + return { delete: true }; + } const scamPatterns = [ "excited announce launch very own crypto casino",
M
src/database/schema/tickets.ts
→
src/database/schema/tickets.ts
@@ -11,7 +11,8 @@
channelId: text("channel_id"), authorId: text("author_id").notNull(), - anonymousId: text("anonymous_id").notNull(), + anonymousId: text("anonymous_id").notNull(), + claimedBy: text("claimed_by"), addedUsers: text("added_users", { mode: "json" }) .$type<string[]>()
M
src/events/messageCreate.ts
→
src/events/messageCreate.ts
@@ -1,11 +1,3 @@
-import { - attachments, - db, - ticketMessages, - tickets, - userPreferences, -} from "@/database"; -import { getPublicUrl, s3 } from "@/utils/s3"; import { AttachmentBuilder, type Client,@@ -15,13 +7,23 @@ type Message,
} from "discord.js"; import { and, eq } from "drizzle-orm"; import { nanoid } from "nanoid"; -import Uwuifier from "uwuifier"; + +import { + attachments, + db, + ticketMessages, + tickets, + userPreferences, +} from "@/database"; +import { getPublicUrl, s3 } from "@/utils/s3"; + import { handleMessage } from "@/automod"; import config from "@/config"; import { hasManagerPermissions } from "@/utils/discord/permissions"; import { loggers } from "@/utils/logging"; import { getRateLimitInfo } from "@/utils/rateLimit"; +import { uwuify } from "@/utils/uwuify"; const logger = loggers.events.child({ name: "messageCreate" }); type UploadStatus = "queued" | "uploading" | "done" | "failed";@@ -61,23 +63,6 @@ }
return false; } - const uwuifier = new Uwuifier(); - const uwuifiedContent = message.content - ? uwuifier.uwuifySentence(message.content) - : ""; - - const blacklistedWords = [ - "twerks", - "sees bulge", - "notices buldge", - "starts twerking", - "wank", - ]; - - const finalText = blacklistedWords.reduce((acc, word) => { - return acc.replace(new RegExp(word, "gi"), "----"); - }, uwuifiedContent); - try { let replyReference = null; if (message.reference?.messageId) {@@ -117,7 +102,7 @@
message.delete(); const contentParts = [ - `**<@${message.author.id}>**: ${finalText || "(no text)"}`, + `**<@${message.author.id}>**: ${uwuify(message.content)}`, ]; if (message.channel.isSendable()) {
A
src/utils/uwuify.ts
@@ -0,0 +1,20 @@
+import Uwuifier from "uwuifier"; + +export function uwuify(input: string) { + const uwuifier = new Uwuifier(); + const uwuifiedContent = input + ? uwuifier.uwuifySentence(input) + : ""; + + const blacklistedWords = [ + "twerks", + "sees bulge", + "notices buldge", + "starts twerking", + "wank", + ]; + + return blacklistedWords.reduce((acc, word) => { + return acc.replace(new RegExp(word, "gi"), "----"); + }, uwuifiedContent); +}