3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 20:35:02 +00:00

Add anti-raid levels to automod. Large refactor of spam detection. Add member_join and member_join_spam triggers.

Anti-raid levels don't by themselves do anything, but they can be
used in overrides to activate specific automod items.

Spam detection should now be more reliable and also combine further
spam messages after the initial detection into the archive.

Messages deleted by automod no longer create the normal deletion log
entry. Instead, the AUTOMOD_ACTION log entry contains the deleted
message or an archive if there are multiple (i.e. spam).
This commit is contained in:
Dragory 2020-01-26 19:54:32 +02:00
parent dc27821a63
commit 84135b201b
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
14 changed files with 1179 additions and 550 deletions

View file

@ -61,5 +61,8 @@
"POSTED_SCHEDULED_MESSAGE": "\uD83D\uDCE8 Posted scheduled message (`{messageId}`) to {channelMention(channel)} as scheduled by {userMention(author)}",
"BOT_ALERT": "⚠ {tmplEval(body)}",
"AUTOMOD_ACTION": "\uD83E\uDD16 Automod rule **{rule}** triggered by {userMention(user)}\n{matchSummary}\nActions taken: **{actionsTaken}**"
"AUTOMOD_ACTION": "\uD83E\uDD16 Automod rule **{rule}** triggered by {userMention(users)}\n{matchSummary}\nActions taken: **{actionsTaken}**",
"SET_ANTIRAID_USER": "⚔ {userMention(user)} set anti-raid to **{level}**",
"SET_ANTIRAID_AUTO": "⚔ Anti-raid automatically set to **{level}**"
}

View file

@ -0,0 +1,42 @@
import { BaseGuildRepository } from "./BaseGuildRepository";
import { getRepository, Repository } from "typeorm";
import { AntiraidLevel } from "./entities/AntiraidLevel";
export class GuildAntiraidLevels extends BaseGuildRepository {
protected antiraidLevels: Repository<AntiraidLevel>;
constructor(guildId: string) {
super(guildId);
this.antiraidLevels = getRepository(AntiraidLevel);
}
async get() {
const row = await this.antiraidLevels.findOne({
where: {
guild_id: this.guildId,
},
});
return row?.level ?? null;
}
async set(level: string | null) {
if (level === null) {
await this.antiraidLevels.delete({
guild_id: this.guildId,
});
} else {
// Upsert: https://stackoverflow.com/a/47064558/316944
await this.antiraidLevels
.createQueryBuilder()
.insert()
.values({
guild_id: this.guildId,
level,
})
.onConflict('("guild_id") DO UPDATE SET "guild_id" = :guildId')
.setParameter("guildId", this.guildId)
.execute();
}
}
}

View file

@ -71,10 +71,7 @@ export class GuildArchives extends BaseGuildRepository {
return result.identifiers[0].id;
}
async createFromSavedMessages(savedMessages: SavedMessage[], guild: Guild, expiresAt = null) {
if (expiresAt == null) expiresAt = moment().add(DEFAULT_EXPIRY_DAYS, "days");
const headerStr = await renderTemplate(MESSAGE_ARCHIVE_HEADER_FORMAT, { guild });
protected async renderLinesFromSavedMessages(savedMessages: SavedMessage[], guild: Guild) {
const msgLines = [];
for (const msg of savedMessages) {
const channel = guild.channels.get(msg.channel_id);
@ -89,11 +86,29 @@ export class GuildArchives extends BaseGuildRepository {
});
msgLines.push(line);
}
return msgLines;
}
async createFromSavedMessages(savedMessages: SavedMessage[], guild: Guild, expiresAt = null) {
if (expiresAt == null) expiresAt = moment().add(DEFAULT_EXPIRY_DAYS, "days");
const headerStr = await renderTemplate(MESSAGE_ARCHIVE_HEADER_FORMAT, { guild });
const msgLines = await this.renderLinesFromSavedMessages(savedMessages, guild);
const messagesStr = msgLines.join("\n");
return this.create([headerStr, messagesStr].join("\n\n"), expiresAt);
}
async addSavedMessagesToArchive(archiveId: string, savedMessages: SavedMessage[], guild: Guild) {
const msgLines = await this.renderLinesFromSavedMessages(savedMessages, guild);
const messagesStr = msgLines.join("\n");
const archive = await this.find(archiveId);
archive.body += "\n" + messagesStr;
await this.archives.update({ id: archiveId }, { body: archive.body });
}
getUrl(baseUrl, archiveId) {
return baseUrl ? `${baseUrl}/archives/${archiveId}` : `Archive ID: ${archiveId}`;
}

View file

@ -64,4 +64,9 @@ export enum LogType {
REPEATED_MESSAGE,
MESSAGE_DELETE_AUTO,
SET_ANTIRAID_USER,
SET_ANTIRAID_AUTO,
AUTOMOD_SPAM_NEW,
}

View file

@ -0,0 +1,11 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
@Entity("antiraid_levels")
export class AntiraidLevel {
@Column()
@PrimaryColumn()
guild_id: string;
@Column()
level: string;
}