mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-16 14:11:50 +00:00
automod: don't use log system for alert actions, require channel id directly instead; allow disabling logging from specific rules
This commit is contained in:
parent
40af0f2359
commit
713333f35e
4 changed files with 50 additions and 22 deletions
|
@ -58,6 +58,5 @@
|
||||||
"POSTED_SCHEDULED_MESSAGE": "\uD83D\uDCE8 Posted scheduled message (`{messageId}`) to {channelMention(channel)} as scheduled by {userMention(author)}",
|
"POSTED_SCHEDULED_MESSAGE": "\uD83D\uDCE8 Posted scheduled message (`{messageId}`) to {channelMention(channel)} as scheduled by {userMention(author)}",
|
||||||
|
|
||||||
"BOT_ALERT": "⚠ {tmplEval(body)}",
|
"BOT_ALERT": "⚠ {tmplEval(body)}",
|
||||||
"AUTOMOD_ALERT": "{text}",
|
|
||||||
"AUTOMOD_ACTION": "\uD83E\uDD16 Automod rule **{rule}** triggered by {userMention(user)}. Actions taken: **{actionsTaken}**\n{matchSummary}"
|
"AUTOMOD_ACTION": "\uD83E\uDD16 Automod rule **{rule}** triggered by {userMention(user)}. Actions taken: **{actionsTaken}**\n{matchSummary}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,5 @@ export enum LogType {
|
||||||
POSTED_SCHEDULED_MESSAGE,
|
POSTED_SCHEDULED_MESSAGE,
|
||||||
|
|
||||||
BOT_ALERT,
|
BOT_ALERT,
|
||||||
AUTOMOD_ALERT,
|
|
||||||
AUTOMOD_ACTION,
|
AUTOMOD_ACTION,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,12 @@ import {
|
||||||
SECONDS,
|
SECONDS,
|
||||||
stripObjectToScalars,
|
stripObjectToScalars,
|
||||||
tNullable,
|
tNullable,
|
||||||
|
UnknownUser,
|
||||||
verboseChannelMention,
|
verboseChannelMention,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
import { decorators as d } from "knub";
|
import { decorators as d } from "knub";
|
||||||
import { mergeConfig } from "knub/dist/configUtils";
|
import { mergeConfig } from "knub/dist/configUtils";
|
||||||
import { Invite, Member, Message } from "eris";
|
import { Invite, Member, Message, TextChannel } from "eris";
|
||||||
import escapeStringRegexp from "escape-string-regexp";
|
import escapeStringRegexp from "escape-string-regexp";
|
||||||
import { SimpleCache } from "../SimpleCache";
|
import { SimpleCache } from "../SimpleCache";
|
||||||
import { Queue } from "../Queue";
|
import { Queue } from "../Queue";
|
||||||
|
@ -32,6 +33,7 @@ import { GuildArchives } from "../data/GuildArchives";
|
||||||
import { GuildLogs } from "../data/GuildLogs";
|
import { GuildLogs } from "../data/GuildLogs";
|
||||||
import { SavedMessage } from "../data/entities/SavedMessage";
|
import { SavedMessage } from "../data/entities/SavedMessage";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
|
import { renderTemplate } from "../templateFormatter";
|
||||||
|
|
||||||
type MessageInfo = { channelId: string; messageId: string };
|
type MessageInfo = { channelId: string; messageId: string };
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ interface RaidSpamTriggerMatchResult extends TriggerMatchResult {
|
||||||
interface OtherSpamTriggerMatchResult extends TriggerMatchResult {
|
interface OtherSpamTriggerMatchResult extends TriggerMatchResult {
|
||||||
type: "otherspam";
|
type: "otherspam";
|
||||||
actionType: RecentActionType;
|
actionType: RecentActionType;
|
||||||
userIds: string[];
|
userId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnyTriggerMatchResult =
|
type AnyTriggerMatchResult =
|
||||||
|
@ -233,6 +235,7 @@ const BanAction = t.type({
|
||||||
});
|
});
|
||||||
|
|
||||||
const AlertAction = t.type({
|
const AlertAction = t.type({
|
||||||
|
channel: t.string,
|
||||||
text: t.string,
|
text: t.string,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -240,6 +243,8 @@ const ChangeNicknameAction = t.type({
|
||||||
name: t.string,
|
name: t.string,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const LogAction = t.boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FULL CONFIG SCHEMA
|
* FULL CONFIG SCHEMA
|
||||||
*/
|
*/
|
||||||
|
@ -273,6 +278,7 @@ const Rule = t.type({
|
||||||
ban: tNullable(BanAction),
|
ban: tNullable(BanAction),
|
||||||
alert: tNullable(AlertAction),
|
alert: tNullable(AlertAction),
|
||||||
change_nickname: tNullable(ChangeNicknameAction),
|
change_nickname: tNullable(ChangeNicknameAction),
|
||||||
|
log: tNullable(LogAction),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
type TRule = t.TypeOf<typeof Rule>;
|
type TRule = t.TypeOf<typeof Rule>;
|
||||||
|
@ -487,6 +493,13 @@ export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable logging of automod actions by default
|
||||||
|
if (rule["actions"] && typeof rule["actions"] === "object") {
|
||||||
|
if (rule["actions"]["log"] == null) {
|
||||||
|
rule["actions"]["log"] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1153,10 +1166,7 @@ export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule.actions.change_nickname) {
|
if (rule.actions.change_nickname) {
|
||||||
const userIdsToChange =
|
const userIdsToChange = matchResult.type === "raidspam" ? matchResult.userIds : [matchResult.userId];
|
||||||
matchResult.type === "raidspam" || matchResult.type === "otherspam"
|
|
||||||
? matchResult.userIds
|
|
||||||
: [matchResult.userId];
|
|
||||||
|
|
||||||
for (const userId of userIdsToChange) {
|
for (const userId of userIdsToChange) {
|
||||||
if (this.recentNicknameChanges.has(userId)) continue;
|
if (this.recentNicknameChanges.has(userId)) continue;
|
||||||
|
@ -1175,30 +1185,45 @@ export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema> {
|
||||||
actionsTaken.push("nickname");
|
actionsTaken.push("nickname");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule.actions.alert || matchResult.type !== "raidspam") {
|
// Don't wait for the rest before continuing to other automod items in the queue
|
||||||
const user = await this.resolveUser((matchResult as any).userId || "0");
|
(async () => {
|
||||||
|
const user = matchResult.type !== "raidspam" ? this.getUser(matchResult.userId) : new UnknownUser();
|
||||||
|
const users = matchResult.type === "raidspam" ? matchResult.userIds.map(id => this.getUser(id)) : [];
|
||||||
|
const safeUser = stripObjectToScalars(user);
|
||||||
|
const safeUsers = users.map(u => stripObjectToScalars(u));
|
||||||
|
|
||||||
if (rule.actions.alert) {
|
if (rule.actions.alert) {
|
||||||
const text = rule.actions.alert.text;
|
const channel = this.guild.channels.get(rule.actions.alert.channel);
|
||||||
this.getLogs().log(LogType.AUTOMOD_ALERT, {
|
if (channel && channel instanceof TextChannel) {
|
||||||
rule: rule.name,
|
const text = rule.actions.alert.text;
|
||||||
user: stripObjectToScalars(user),
|
const rendered = await renderTemplate(rule.actions.alert.text, {
|
||||||
text,
|
rule: rule.name,
|
||||||
matchSummary,
|
user: safeUser,
|
||||||
});
|
users: safeUsers,
|
||||||
|
text,
|
||||||
actionsTaken.push("alert");
|
matchSummary,
|
||||||
|
});
|
||||||
|
channel.createMessage(rendered);
|
||||||
|
actionsTaken.push("alert");
|
||||||
|
} else {
|
||||||
|
this.getLogs().log(LogType.BOT_ALERT, {
|
||||||
|
body: `Invalid channel id \`${rule.actions.alert.channel}\` for alert action in automod rule **${
|
||||||
|
rule.name
|
||||||
|
}**`,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchResult.type !== "raidspam") {
|
if (rule.actions.log) {
|
||||||
this.getLogs().log(LogType.AUTOMOD_ACTION, {
|
this.getLogs().log(LogType.AUTOMOD_ACTION, {
|
||||||
rule: rule.name,
|
rule: rule.name,
|
||||||
user: stripObjectToScalars(user),
|
user: safeUser,
|
||||||
|
users: safeUsers,
|
||||||
actionsTaken: actionsTaken.length ? actionsTaken.join(", ") : "<none>",
|
actionsTaken: actionsTaken.length ? actionsTaken.join(", ") : "<none>",
|
||||||
matchSummary,
|
matchSummary,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onMessageCreate(msg: SavedMessage) {
|
protected onMessageCreate(msg: SavedMessage) {
|
||||||
|
|
|
@ -204,6 +204,11 @@ export class ZeppelinPlugin<TConfig extends {} = IBasePluginConfig> extends Plug
|
||||||
return this.getMergedOptions();
|
return this.getMergedOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUser(userResolvable: string): User | UnknownUser {
|
||||||
|
const id = resolveUserId(this.bot, userResolvable);
|
||||||
|
return id ? this.bot.users.get(id) || new UnknownUser({ id }) : new UnknownUser();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a user from the passed string. The passed string can be a user id, a user mention, a full username (with discrim), etc.
|
* Resolves a user from the passed string. The passed string can be a user id, a user mention, a full username (with discrim), etc.
|
||||||
* If the user is not found in the cache, it's fetched from the API.
|
* If the user is not found in the cache, it's fetched from the API.
|
||||||
|
|
Loading…
Add table
Reference in a new issue