Execute word filter actions

This commit is contained in:
Lea 2023-04-07 22:49:41 +02:00
parent afb289b65a
commit 0a0f291cba
Signed by: Lea
GPG key ID: 1BAFFE8347019C42
4 changed files with 90 additions and 7 deletions

View file

@ -233,6 +233,7 @@ export default {
return await message.reply({ embeds: [ return await message.reply({ embeds: [
embed( embed(
'This command lets you change the message the bot will send if a message is filtered.\n' + 'This command lets you change the message the bot will send if a message is filtered.\n' +
'Note that this message will not be sent if the configured action is to log events only.\n' +
'The current message is:\n' + 'The current message is:\n' +
`>${sanitizeMessageContent(config?.wordlistAction?.message ?? WORDLIST_DEFAULT_MESSAGE).trim().replace(/\n/g, '\n>')}\n` + `>${sanitizeMessageContent(config?.wordlistAction?.message ?? WORDLIST_DEFAULT_MESSAGE).trim().replace(/\n/g, '\n>')}\n` +
'`{{user_id}}` will be substituted for the target user\'s ID.', '`{{user_id}}` will be substituted for the target user\'s ID.',
@ -353,3 +354,5 @@ export default {
} }
} }
} as SimpleCommand; } as SimpleCommand;
export { WORDLIST_DEFAULT_MESSAGE }

View file

@ -6,12 +6,16 @@ import Infraction from "automod/dist/types/antispam/Infraction";
import InfractionType from "automod/dist/types/antispam/InfractionType"; import InfractionType from "automod/dist/types/antispam/InfractionType";
import ModerationAction from "automod/dist/types/antispam/ModerationAction"; import ModerationAction from "automod/dist/types/antispam/ModerationAction";
import logger from "../logger"; import logger from "../logger";
import { awaitClient, isModerator, storeInfraction } from "../util"; import { awaitClient, generateInfractionDMEmbed, isModerator, sendLogMessage, storeInfraction } from "../util";
import { getDmChannel, sanitizeMessageContent } from "../util"; import { getDmChannel, sanitizeMessageContent } from "../util";
import ServerConfig from "automod/dist/types/ServerConfig"; import ServerConfig from "automod/dist/types/ServerConfig";
import { WORDLIST_DEFAULT_MESSAGE } from "../commands/configuration/botctl";
let msgCountStore: Map<string, { users: any }> = new Map(); let msgCountStore: Map<string, { users: any }> = new Map();
// Should use redis for this
const SENT_FILTER_MESSAGE: string[] = [];
/** /**
* *
* @param message * @param message
@ -107,6 +111,78 @@ function getWarnMsg(rule: AntispamRule, message: Message) {
} else return `<@${message.author_id}>, please stop spamming.`; } else return `<@${message.author_id}>, please stop spamming.`;
} }
/**
* Run word filter check and act on message if required
*/
async function wordFilterCheck(message: Message, config: ServerConfig) {
try {
if (!message.content) return;
const match = checkMessageForFilteredWords(message.content, config);
if (!match) return;
console.log('Message matched word filter!');
// Lack of `break` is intended here
switch(config.wordlistAction?.action) {
case 'WARN': {
try {
const infraction: Infraction = {
_id: ulid(),
createdBy: null,
date: Date.now(),
reason: 'Word filter triggered',
server: message.channel!.server_id!,
type: InfractionType.Automatic,
user: message.author_id,
}
await storeInfraction(infraction);
if (config.dmOnWarn) {
const embed = generateInfractionDMEmbed(message.channel!.server!, config, infraction, message);
const dmChannel = await getDmChannel(message.author!);
if (dmChannel.havePermission('SendMessage') && dmChannel.havePermission('SendEmbeds')) {
await dmChannel.sendMessage({ embeds: [ embed ] });
}
else logger.warn('Missing permission to DM user.');
}
} catch(e) {
console.error(e);
}
}
case 'DELETE': {
if (message.channel?.havePermission('ManageMessages')) {
const key = `${message.author_id}:${message.channel_id}`;
await message.delete();
if (!SENT_FILTER_MESSAGE.includes(key)) {
SENT_FILTER_MESSAGE.push(key);
setTimeout(() => SENT_FILTER_MESSAGE.splice(SENT_FILTER_MESSAGE.indexOf(key), 1), 30000);
await message.channel.sendMessage((config.wordlistAction.message || WORDLIST_DEFAULT_MESSAGE)
.replaceAll('{{user_id}}', message.author_id));
}
}
}
case 'LOG':
default: {
if (!config.logs?.modAction) break;
await sendLogMessage(config.logs.modAction, {
title: 'Message triggered word filter',
description: `**Author:** @${message.author?.username} (${message.author_id})\n` +
`**Action:** ${config.wordlistAction?.action || 'LOG'}\n` +
`#### Content\n` +
`>${sanitizeMessageContent(message.content.substring(0, 1000)).trim().replace(/\n/g, '\n>')}`,
color: '#ff557f',
});
}
}
} catch(e) {
console.error(e);
}
}
function checkMessageForFilteredWords(message: string, config: ServerConfig): boolean { function checkMessageForFilteredWords(message: string, config: ServerConfig): boolean {
if (!config.wordlistEnabled || !config.wordlist?.length || !message) return false; if (!config.wordlistEnabled || !config.wordlist?.length || !message) return false;
@ -215,4 +291,4 @@ Thanks for being part of Revolt!`);
awaitClient().then(() => notifyPublicServers()); awaitClient().then(() => notifyPublicServers());
export { antispam, checkMessageForFilteredWords } export { antispam, wordFilterCheck, checkMessageForFilteredWords }

View file

@ -3,7 +3,7 @@ import logger from "../logger";
import { client, dbs } from "../../index"; import { client, dbs } from "../../index";
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { antispam } from "./antispam"; import { antispam, wordFilterCheck } from "./antispam";
import checkCustomRules from "./custom_rules/custom_rules"; import checkCustomRules from "./custom_rules/custom_rules";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
@ -65,6 +65,10 @@ let commands: SimpleCommand[];
dbs.USERS.findOne({ id: msg.author_id }), dbs.USERS.findOne({ id: msg.author_id }),
]); ]);
if (config) {
await wordFilterCheck(msg, config);
}
if (userConfig?.ignore) return; if (userConfig?.ignore) return;
let args = msg.content.split(' '); let args = msg.content.split(' ');

View file

@ -465,11 +465,11 @@ const generateInfractionDMEmbed = (
server: Server, server: Server,
serverConfig: ServerConfig, serverConfig: ServerConfig,
infraction: Infraction, infraction: Infraction,
message: MessageCommandContext message: Message
) => { ) => {
const embed: SendableEmbed = { const embed: SendableEmbed = {
title: message.serverContext.name, title: server.name,
icon_url: message.serverContext.generateIconURL({ max_side: 128 }), icon_url: server.generateIconURL({ max_side: 128 }),
colour: "#ff9e2f", colour: "#ff9e2f",
url: message.url, url: message.url,
description: description:
@ -480,7 +480,7 @@ const generateInfractionDMEmbed = (
}** from ` }** from `
: `**warned** in `) + : `**warned** in `) +
`'${sanitizeMessageContent( `'${sanitizeMessageContent(
message.serverContext.name server.name
).trim()}' <t:${Math.round(infraction.date / 1000)}:R>.\n` + ).trim()}' <t:${Math.round(infraction.date / 1000)}:R>.\n` +
`**Reason:** ${infraction.reason}\n` + `**Reason:** ${infraction.reason}\n` +
`**Moderator:** [@${sanitizeMessageContent( `**Moderator:** [@${sanitizeMessageContent(