summaryrefslogtreecommitdiff
path: root/packages/gateway
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-10-01 13:39:57 -0700
committerFuwn <[email protected]>2025-10-01 13:39:57 -0700
commit397c37327cf27b65bc1510df18f7e2a30c1b0642 (patch)
tree171401a3e46571bebdf9aa79dbb305e9db25e2bf /packages/gateway
parentfix(listeners:messageDeletion): Add additional output channel (diff)
downloadumabotdiscord-397c37327cf27b65bc1510df18f7e2a30c1b0642.tar.xz
umabotdiscord-397c37327cf27b65bc1510df18f7e2a30c1b0642.zip
feat(listeners): Add media moderation for #degeneral
Diffstat (limited to 'packages/gateway')
-rw-r--r--packages/gateway/src/listeners/index.ts2
-rw-r--r--packages/gateway/src/listeners/mediaModeration.ts64
2 files changed, 66 insertions, 0 deletions
diff --git a/packages/gateway/src/listeners/index.ts b/packages/gateway/src/listeners/index.ts
index c640b25..492f9b0 100644
--- a/packages/gateway/src/listeners/index.ts
+++ b/packages/gateway/src/listeners/index.ts
@@ -6,6 +6,7 @@ import { handleMessageDeletion } from "./messageDeletion";
import { handleMessageEdit } from "./messageEdit";
import { handleClientReady } from "./clientReady";
import { handleVoiceConnection } from "./voiceConnection";
+import { handleMediaModeration } from "./mediaModeration";
export const handleListeners = (client: Client) => {
handleVoiceConnection(client);
@@ -15,4 +16,5 @@ export const handleListeners = (client: Client) => {
handleChannelDeletion(client);
handleMessageDeletion(client);
handleMessageEdit(client);
+ handleMediaModeration(client);
};
diff --git a/packages/gateway/src/listeners/mediaModeration.ts b/packages/gateway/src/listeners/mediaModeration.ts
new file mode 100644
index 0000000..36c4e74
--- /dev/null
+++ b/packages/gateway/src/listeners/mediaModeration.ts
@@ -0,0 +1,64 @@
+import { Client, Events, Message } from "discord.js";
+import { GUILD_ID } from "../constants";
+import { IQDBSearchResultItem } from "iqdb-client";
+
+const MONITORED_CHANNEL_ID = "1410333697701314791";
+
+export const handleMediaModeration = (client: Client) => {
+ client.on(Events.MessageCreate, async (message: Message) => {
+ if (message.guildId !== GUILD_ID) return;
+ if (message.channelId !== MONITORED_CHANNEL_ID) return;
+ if (message.author.bot) return;
+
+ if (message.attachments.size > 0) {
+ try {
+ const hasSensitiveFlag = message.attachments.some(attachment =>
+ attachment.flags && (Number(attachment.flags) & 0x10) !== 0
+ );
+
+ if (hasSensitiveFlag) {
+ await message.delete();
+
+ return;
+ }
+
+ const imageAttachments = message.attachments.filter((attachment) =>
+ attachment.contentType?.startsWith("image/"),
+ );
+
+ if (imageAttachments.size > 0) {
+ for (const attachment of imageAttachments.values()) {
+ try {
+ const { searchPic } = await import("iqdb-client");
+ const result = await searchPic(attachment.url, { lib: "www" });
+ const matches =
+ result.data?.filter(
+ (item) => item.similarity !== null && item.similarity > 0.75,
+ ) || [];
+
+ if (matches.length === 0)
+ continue;
+
+ const hasExplicitContent = matches.some(match => {
+ const matchItem = match as unknown as IQDBSearchResultItem & { type: "Explicit" | "Ero" };
+
+ return matchItem.type === "Explicit" || matchItem.type === "Ero"
+ }
+ );
+
+ if (hasExplicitContent) {
+ await message.delete();
+
+ return;
+ }
+ } catch (error) {
+ console.error("Error processing image with IQDB:", error);
+ }
+ }
+ }
+ } catch (error) {
+ console.error("Error checking/deleting message with sensitive content:", error);
+ }
+ }
+ });
+};