aboutsummaryrefslogtreecommitdiff
path: root/lib/automod/MemberAutomod.ts
blob: 64ee3c142171c8db3bc6d1c8ec4cc7cabce1b808 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { stripIndent } from '#tags';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Automod, BadWordDetails } from './AutomodShared.js';

export class MemberAutomod extends Automod {
	/**
	 * @param member The member that the automod is checking
	 */
	public constructor(member: GuildMember) {
		super(member);

		if (member.id === member.client.user?.id) return;

		void this.handle();
	}

	protected async handle(): Promise<void> {
		if (this.member.user.bot) return;
		if (this.isImmune) return;

		const badWordsRaw = Object.values(this.client.utils.getShared('badWords')).flat();
		const customAutomodPhrases = (await this.guild.getSetting('autoModPhases')) ?? [];

		const phrases = [...badWordsRaw, ...customAutomodPhrases].filter((p) => p.userInfo);

		const result: BadWordDetails[] = [];

		const str = `${this.member.user.username}${this.member.nickname ? `\n${this.member.nickname}` : ''}`;
		const check = this.checkWords(phrases, str);
		if (check.length > 0) {
			result.push(...check);
		}

		if (result.length > 0) {
			const highestOffense = result.sort((a, b) => b.severity - a.severity)[0];
			await this.logMessage(highestOffense, result, str);
		}
	}

	/**
	 * Log an automod infraction to the guild's specified automod log channel
	 * @param highestOffense The highest severity word found in the message
	 * @param offenses The other offenses that were also matched in the message
	 */
	protected async logMessage(highestOffense: BadWordDetails, offenses: BadWordDetails[], str: string) {
		void this.client.console.info(
			'MemberAutomod',
			`Detected a severity <<${highestOffense.severity}>> automod phrase in <<${this.user.tag}>>'s (<<${this.user.id}>>) username or nickname in <<${this.guild.name}>>`
		);

		const color = this.logColor(highestOffense.severity);

		await this.guild.sendLogChannel('automod', {
			embeds: [
				new EmbedBuilder()
					.setTitle(`[Severity ${highestOffense.severity}] Automoderated User Info Detected`)
					.setDescription(
						stripIndent`
						**User:** ${this.user} (${this.user.tag})
						**Blacklisted Words:** ${offenses.map((o) => `\`${o.match}\``).join(', ')}`
					)
					.addFields({
						name: 'Info',
						value: `${await this.client.utils.codeblock(str, 1024)}`
					})
					.setColor(color)
					.setTimestamp()
					.setAuthor({ name: this.user.tag, url: this.user.displayAvatarURL() })
			],
			components: [this.buttons(this.user.id, highestOffense.reason, false)]
		});
	}
}