Add word filter function
This commit is contained in:
parent
ab006cdbff
commit
9acc3c6414
2 changed files with 81 additions and 2 deletions
|
@ -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(
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
Loading…
Reference in a new issue