From 623976f7397f7d9f3d6b4d2a76e0567ffa2d8011 Mon Sep 17 00:00:00 2001 From: Carl Vitullo Date: Tue, 18 Jan 2022 15:13:38 -0500 Subject: [PATCH 1/6] Remove "discord" as a trigger word --- src/features/autodelete-spam.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/autodelete-spam.ts b/src/features/autodelete-spam.ts index 057900f3..82b395bf 100644 --- a/src/features/autodelete-spam.ts +++ b/src/features/autodelete-spam.ts @@ -1,7 +1,7 @@ import { ChannelHandlers } from "../types"; import { isStaff } from "../helpers/discord"; -const spamKeywords = ["discord", "nitro", "steam", "free", "gift", "airdrop"]; +const spamKeywords = ["nitro", "steam", "free", "gift", "airdrop"]; const safeKeywords = ["hiring", "remote", "onsite"]; From 13f7e5bc8abc1be7097fc917f895bc756091a0a2 Mon Sep 17 00:00:00 2001 From: Carl Vitullo Date: Tue, 18 Jan 2022 15:14:02 -0500 Subject: [PATCH 2/6] Adjust simplifyString to not remove whitespace or URL characters --- src/helpers/modLog.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/modLog.ts b/src/helpers/modLog.ts index efbd2d99..053988fd 100644 --- a/src/helpers/modLog.ts +++ b/src/helpers/modLog.ts @@ -17,7 +17,7 @@ const NORMALIZED_CODEPOINTS = /[\u0300-\u036f]/g; const EMOJI_RANGE = /[\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF]/g; const SPECIAL_CHARACTERS = - /[\s≤≥¯˘÷¿…“”‘’«»–—≠±ºª•¶§∞¢£™¡`~`∑´®†¨ˆØ∏\-=_+<>?,./;':"[\]\\{}|!@#$%^&*()]/g; + /[≤≥¯˘÷¿…“”‘’«»–—≠±ºª•¶§∞¢£™¡`~`∑´®†¨ˆØ∏\-=_<>,;'"[\]\\{}|!@#$%^*()]/g; export const simplifyString = (s: string) => s .toLowerCase() From 8b8013a41f679266336004084326c29b8a17e302 Mon Sep 17 00:00:00 2001 From: Carl Vitullo Date: Tue, 18 Jan 2022 15:19:27 -0500 Subject: [PATCH 3/6] Add "forhire" as a safe word --- src/features/autodelete-spam.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/autodelete-spam.ts b/src/features/autodelete-spam.ts index 82b395bf..c9646850 100644 --- a/src/features/autodelete-spam.ts +++ b/src/features/autodelete-spam.ts @@ -3,7 +3,7 @@ import { isStaff } from "../helpers/discord"; const spamKeywords = ["nitro", "steam", "free", "gift", "airdrop"]; -const safeKeywords = ["hiring", "remote", "onsite"]; +const safeKeywords = ["forhire", "hiring", "remote", "onsite"]; const safeDomains = [ "https://discord.com", From 8d324f418cf142dade65b3d88f1bb3ba50ce6c1f Mon Sep 17 00:00:00 2001 From: Carl Vitullo Date: Tue, 18 Jan 2022 15:19:45 -0500 Subject: [PATCH 4/6] Use a simple spam score to determine whether to delete or not --- src/features/autodelete-spam.ts | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/features/autodelete-spam.ts b/src/features/autodelete-spam.ts index c9646850..79845ef7 100644 --- a/src/features/autodelete-spam.ts +++ b/src/features/autodelete-spam.ts @@ -1,5 +1,6 @@ import { ChannelHandlers } from "../types"; import { isStaff } from "../helpers/discord"; +import { simplifyString } from "../helpers/modLog"; const spamKeywords = ["nitro", "steam", "free", "gift", "airdrop"]; @@ -18,11 +19,6 @@ const safeDomains = [ const checkWords = (message: string, wordList: string[]) => message.split(/\b/).some((word) => wordList.includes(word.toLowerCase())); -const atLeast = - (count: number) => - (...bools: boolean[]) => - bools.filter(Boolean).length >= count; - const autodelete: ChannelHandlers = { handleMessage: async ({ msg: maybeMessage }) => { if (isStaff(maybeMessage.member)) return; @@ -35,22 +31,27 @@ const autodelete: ChannelHandlers = { msg.content.includes(pingKeyword), ); - const msgHasSpamKeywords = checkWords(msg.content, spamKeywords); + const content = simplifyString(msg.content); + const words = content.split(" "); + const msgSpamKeywords = words + .map((word) => spamKeywords.includes(word)) + .filter(Boolean); - const msgHasNoSafeKeywords = !checkWords(msg.content, safeKeywords); + const msgHasSafeKeywords = checkWords(msg.content, safeKeywords); const msgHasLink = msg.content.includes("http") && !safeDomains.some((domain) => msg.content.includes(domain)); - if ( - atLeast(3)( - msgHasPingKeywords, - msgHasSpamKeywords, - msgHasNoSafeKeywords, - msgHasLink, - ) - ) { + const spamScore = + Number(msgHasLink) + + msgSpamKeywords.length + + // Pinging everyone is always treated as spam + Number(msgHasPingKeywords) * 5 - + // If it's a job post, then it's probably not spam + Number(msgHasSafeKeywords) * 10; + + if (spamScore > 3) { await msg.react("💩"); } }, From e48f6749e38fb6cd51c4f071efcafca0e4afc262 Mon Sep 17 00:00:00 2001 From: Carl Vitullo Date: Tue, 18 Jan 2022 15:27:09 -0500 Subject: [PATCH 5/6] Consolidate spam responses --- src/features/autodelete-spam.ts | 19 +++++++++++++++++++ src/features/commands.ts | 33 --------------------------------- 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/features/autodelete-spam.ts b/src/features/autodelete-spam.ts index 79845ef7..3be428a9 100644 --- a/src/features/autodelete-spam.ts +++ b/src/features/autodelete-spam.ts @@ -1,6 +1,7 @@ import { ChannelHandlers } from "../types"; import { isStaff } from "../helpers/discord"; import { simplifyString } from "../helpers/modLog"; +import { sleep } from "../helpers/misc"; const spamKeywords = ["nitro", "steam", "free", "gift", "airdrop"]; @@ -26,11 +27,29 @@ const autodelete: ChannelHandlers = { const msg = maybeMessage.partial ? await maybeMessage.fetch() : maybeMessage; + if (!msg.guild) return; const msgHasPingKeywords = ["@everyone", "@here"].some((pingKeyword) => msg.content.includes(pingKeyword), ); + if (msgHasPingKeywords) { + msg + .reply({ + embeds: [ + { + title: "Tsk tsk.", + description: `Please do **not** try to use \`@here\` or \`@everyone\` - there are ${msg.guild.memberCount} members in Reactiflux. Everybody here is a volunteer, and somebody will respond when they can.`, + color: "#BA0C2F", + }, + ], + }) + .then(async (tsk) => { + await sleep(15); + tsk.delete(); + }); + } + const content = simplifyString(msg.content); const words = content.split(" "); const msgSpamKeywords = words diff --git a/src/features/commands.ts b/src/features/commands.ts index 6b4c1676..42fedcbc 100644 --- a/src/features/commands.ts +++ b/src/features/commands.ts @@ -4,7 +4,6 @@ import { Message, TextChannel } from "discord.js"; import cooldown from "./cooldown"; import { ChannelHandlers } from "../types"; import { isStaff } from "../helpers/discord"; -import { sleep } from "../helpers/misc"; export const EMBED_COLOR = 7506394; @@ -637,38 +636,6 @@ Instead: }); }, }, - { - words: ["@here", "@everyone"], - help: "", - category: "Communication", - cooldown: 0, - handleMessage: async (msg) => { - if (!msg || !msg.guild) { - return; - } - - const member = await msg.guild.members.fetch(msg.author.id); - - if (!member || isStaff(member)) { - return; - } - - await msg.react("💩"); - - const tsk = await msg.reply({ - embeds: [ - { - title: "Tsk tsk.", - description: `Please do **not** try to use \`@here\` or \`@everyone\` - there are ${msg.guild.memberCount} members in Reactiflux. Everybody here is a volunteer, and somebody will respond when they can.`, - color: "#BA0C2F", - }, - ], - }); - await msg.delete(); - await sleep(120); - await tsk.delete(); - }, - }, { words: ["!lock"], help: "", From 94a370237b990d5562bbe8728edd9689caa85f7a Mon Sep 17 00:00:00 2001 From: Carl Vitullo Date: Tue, 18 Jan 2022 15:30:27 -0500 Subject: [PATCH 6/6] Fix linter warnings --- src/features/autothread.ts | 2 +- src/features/emojiMod.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/autothread.ts b/src/features/autothread.ts index 4886bd95..a96c2742 100644 --- a/src/features/autothread.ts +++ b/src/features/autothread.ts @@ -1,5 +1,5 @@ import { differenceInHours, format } from "date-fns"; -import { Client, Message, PartialMessage } from "discord.js"; +import { Client } from "discord.js"; import { CHANNELS } from "../constants"; import { constructDiscordLink, diff --git a/src/features/emojiMod.ts b/src/features/emojiMod.ts index a2b1a7e6..57bbef56 100644 --- a/src/features/emojiMod.ts +++ b/src/features/emojiMod.ts @@ -195,7 +195,7 @@ Thanks! const emojiMod: ChannelHandlers = { handleReaction: async ({ reaction, user, bot }) => { - const { message, users } = reaction; + const { message } = reaction; const { author, guild } = message; if (!guild || !author || author?.id === bot.user?.id) {