Add word filter function

This commit is contained in:
Lea 2023-04-07 22:14:23 +02:00
parent ab006cdbff
commit 9acc3c6414
Signed by: Lea
GPG key ID: 1BAFFE8347019C42
2 changed files with 81 additions and 2 deletions

View file

@ -1,9 +1,11 @@
import ServerConfig from "automod/dist/types/ServerConfig";
import axios from "axios"; import axios from "axios";
import FormData from "form-data"; import FormData from "form-data";
import { client, dbs } from "../../.."; import { client, dbs } from "../../..";
import CommandCategory from "../../../struct/commands/CommandCategory"; import CommandCategory from "../../../struct/commands/CommandCategory";
import SimpleCommand from "../../../struct/commands/SimpleCommand"; import SimpleCommand from "../../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../../struct/MessageCommandContext"; import MessageCommandContext from "../../../struct/MessageCommandContext";
import { checkMessageForFilteredWords } from "../../modules/antispam";
import { DEFAULT_PREFIX } from "../../modules/command_handler"; import { DEFAULT_PREFIX } from "../../modules/command_handler";
import { embed, EmbedColor, getAutumnURL, getDmChannel, isBotManager, NO_MANAGER_MSG, sanitizeMessageContent } from "../../util"; import { embed, EmbedColor, getAutumnURL, getDmChannel, isBotManager, NO_MANAGER_MSG, sanitizeMessageContent } from "../../util";
@ -295,6 +297,15 @@ export default {
] }); ] });
break; break;
} }
case 'test': {
const match = checkMessageForFilteredWords(args.join(' '), config as ServerConfig);
await message.reply({ embeds: [
match
? embed('Your word list matches this test phrase!', 'Filter Test', EmbedColor.SoftError)
: embed('Your word list does not match this test phrase!', 'Filter Test', EmbedColor.Success)
] });
break;
}
default: { default: {
await message.reply({ embeds: [ await message.reply({ embeds: [
embed( embed(
@ -305,7 +316,8 @@ export default {
`- **${DEFAULT_PREFIX}botctl filter remove** - Remove a word from the list.\n` + `- **${DEFAULT_PREFIX}botctl filter remove** - Remove a word from the list.\n` +
`- **${DEFAULT_PREFIX}botctl filter show** - Send the current filter list.\n` + `- **${DEFAULT_PREFIX}botctl filter show** - Send the current filter list.\n` +
`- **${DEFAULT_PREFIX}botctl filter message [message]** - Set the message sent when a message is matched.\n` + `- **${DEFAULT_PREFIX}botctl filter message [message]** - Set the message sent when a message is matched.\n` +
`- **${DEFAULT_PREFIX}botctl filter action [log|delete|warn]** - Configure the action taken on filtered messages.\n`, `- **${DEFAULT_PREFIX}botctl filter action [log|delete|warn]** - Configure the action taken on filtered messages.\n` +
`- **${DEFAULT_PREFIX}botctl filter test [phrase]** - Test whether a phrase matches your word list.\n`,
'Word filter', 'Word filter',
), ),
embed( embed(

View file

@ -8,6 +8,7 @@ import ModerationAction from "automod/dist/types/antispam/ModerationAction";
import logger from "../logger"; import logger from "../logger";
import { awaitClient, isModerator, storeInfraction } from "../util"; import { awaitClient, isModerator, storeInfraction } from "../util";
import { getDmChannel, sanitizeMessageContent } from "../util"; import { getDmChannel, sanitizeMessageContent } from "../util";
import ServerConfig from "automod/dist/types/ServerConfig";
let msgCountStore: Map<string, { users: any }> = new Map(); let msgCountStore: Map<string, { users: any }> = new Map();
@ -106,6 +107,72 @@ function getWarnMsg(rule: AntispamRule, message: Message) {
} else return `<@${message.author_id}>, please stop spamming.`; } else return `<@${message.author_id}>, please stop spamming.`;
} }
function checkMessageForFilteredWords(message: string, config: ServerConfig): boolean {
if (!config.wordlistEnabled || !config.wordlist?.length || !message) return false;
const words = {
soft: config.wordlist.filter(w => w.strictness == 'SOFT').map(w => w.word),
hard: config.wordlist.filter(w => w.strictness == 'HARD').map(w => w.word),
strict: config.wordlist.filter(w => w.strictness == 'STRICT').map(w => w.word),
}
const softSegments = message.split(/\s/g).map(s => s.toLowerCase());
for (const word of words.soft) {
if (softSegments.includes(word.toLowerCase())) return true;
}
for (const word of words.hard) {
if (message.toLowerCase().includes(word.toLowerCase())) return true;
}
const replace = {
'0': 'o',
'1': 'i',
'4': 'a',
'3': 'e',
'5': 's',
'6': 'g',
'7': 't',
'8': 'b',
'9': 'g',
'@': 'a',
'^': 'a',
'Д': 'a',
'ß': 'b',
'¢': 'c',
'©': 'c',
'<': 'c',
'€': 'e',
'ƒ': 'f',
'ท': 'n',
'И': 'n',
'Ø': 'o',
'Я': 'r',
'®': 'r',
'$': 's',
'§': 's',
'†': 't',
'บ': 'u',
'พ': 'w',
'₩': 'w',
'×': 'x',
'¥': 'y',
}
const replaceChars = (input: string) => {
input = `${input}`;
for (const pair of Object.entries(replace)) {
input = input.replaceAll(pair[0], pair[1]);
}
return input;
}
const replacedMsg = replaceChars(message.toLowerCase().replace(/\s/g, ''));
for (const word of words.strict) {
if (replacedMsg.includes(replaceChars(word.toLowerCase()))) return true;
}
return false;
}
// Scan all servers for the `discoverable` flag and notify their owners that antispam is forcefully enabled // Scan all servers for the `discoverable` flag and notify their owners that antispam is forcefully enabled
const notifyPublicServers = async () => { const notifyPublicServers = async () => {
logger.info('Sending antispam notification to public servers'); logger.info('Sending antispam notification to public servers');
@ -148,4 +215,4 @@ Thanks for being part of Revolt!`);
awaitClient().then(() => notifyPublicServers()); awaitClient().then(() => notifyPublicServers());
export { antispam } export { antispam, checkMessageForFilteredWords }