diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index 7bebd606..2a6cf870 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -235,14 +235,20 @@ export const AutomodPlugin = zeppelinGuildPlugin()("automod", pluginData.state.modActionsListeners.set("note", (userId: string) => runAutomodOnModAction(pluginData, "note", userId), ); - pluginData.state.modActionsListeners.set("warn", (userId: string) => - runAutomodOnModAction(pluginData, "warn", userId), + pluginData.state.modActionsListeners.set( + "warn", + (userId: string, reason: string | undefined, isAutomodAction: boolean) => + runAutomodOnModAction(pluginData, "warn", userId, reason, isAutomodAction), ); - pluginData.state.modActionsListeners.set("kick", (userId: string) => - runAutomodOnModAction(pluginData, "kick", userId), + pluginData.state.modActionsListeners.set( + "kick", + (userId: string, reason: string | undefined, isAutomodAction: boolean) => + runAutomodOnModAction(pluginData, "kick", userId, reason, isAutomodAction), ); - pluginData.state.modActionsListeners.set("ban", (userId: string) => - runAutomodOnModAction(pluginData, "ban", userId), + pluginData.state.modActionsListeners.set( + "ban", + (userId: string, reason: string | undefined, isAutomodAction: boolean) => + runAutomodOnModAction(pluginData, "ban", userId, reason, isAutomodAction), ); pluginData.state.modActionsListeners.set("unban", (userId: string) => runAutomodOnModAction(pluginData, "unban", userId), @@ -251,7 +257,11 @@ export const AutomodPlugin = zeppelinGuildPlugin()("automod", const mutesEvents = pluginData.getPlugin(MutesPlugin).getEventEmitter(); pluginData.state.mutesListeners = new Map(); - pluginData.state.mutesListeners.set("mute", (userId: string) => runAutomodOnModAction(pluginData, "mute", userId)); + pluginData.state.mutesListeners.set( + "mute", + (userId: string, reason: string | undefined, isAutomodAction: boolean) => + runAutomodOnModAction(pluginData, "mute", userId, reason, isAutomodAction), + ); pluginData.state.mutesListeners.set("unmute", (userId: string) => runAutomodOnModAction(pluginData, "unmute", userId), ); diff --git a/backend/src/plugins/Automod/actions/ban.ts b/backend/src/plugins/Automod/actions/ban.ts index 99b6c25b..ab9e811a 100644 --- a/backend/src/plugins/Automod/actions/ban.ts +++ b/backend/src/plugins/Automod/actions/ban.ts @@ -33,7 +33,12 @@ export const BanAction = automodAction({ const modActions = pluginData.getPlugin(ModActionsPlugin); for (const userId of userIdsToBan) { - await modActions.banUserId(userId, reason, { contactMethods, caseArgs, deleteMessageDays }); + await modActions.banUserId(userId, reason, { + contactMethods, + caseArgs, + deleteMessageDays, + isAutomodAction: true, + }); } }, }); diff --git a/backend/src/plugins/Automod/actions/kick.ts b/backend/src/plugins/Automod/actions/kick.ts index c25684f4..b11c44ae 100644 --- a/backend/src/plugins/Automod/actions/kick.ts +++ b/backend/src/plugins/Automod/actions/kick.ts @@ -33,7 +33,7 @@ export const KickAction = automodAction({ const modActions = pluginData.getPlugin(ModActionsPlugin); for (const member of membersToKick) { if (!member) continue; - await modActions.kickMember(member, reason, { contactMethods, caseArgs }); + await modActions.kickMember(member, reason, { contactMethods, caseArgs, isAutomodAction: true }); } }, }); diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index ad964f44..f09fbe34 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -49,7 +49,14 @@ export const MuteAction = automodAction({ const mutes = pluginData.getPlugin(MutesPlugin); for (const userId of userIdsToMute) { try { - await mutes.muteUser(userId, duration, reason, { contactMethods, caseArgs }, rolesToRemove, rolesToRestore); + await mutes.muteUser( + userId, + duration, + reason, + { contactMethods, caseArgs, isAutomodAction: true }, + rolesToRemove, + rolesToRestore, + ); } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, { diff --git a/backend/src/plugins/Automod/actions/warn.ts b/backend/src/plugins/Automod/actions/warn.ts index c705b77c..70240080 100644 --- a/backend/src/plugins/Automod/actions/warn.ts +++ b/backend/src/plugins/Automod/actions/warn.ts @@ -33,7 +33,7 @@ export const WarnAction = automodAction({ const modActions = pluginData.getPlugin(ModActionsPlugin); for (const member of membersToWarn) { if (!member) continue; - await modActions.warnMember(member, reason, { contactMethods, caseArgs }); + await modActions.warnMember(member, reason, { contactMethods, caseArgs, isAutomodAction: true }); } }, }); diff --git a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts index 5831f1eb..59b2b650 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts @@ -9,6 +9,7 @@ export async function runAutomodOnModAction( modAction: ModActionType, userId: string, reason?: string, + isAutomodAction: boolean = false, ) { const user = await resolveUser(pluginData.client, userId); @@ -18,6 +19,7 @@ export async function runAutomodOnModAction( modAction: { type: modAction, reason, + isAutomodAction, }, }; diff --git a/backend/src/plugins/Automod/triggers/ban.ts b/backend/src/plugins/Automod/triggers/ban.ts index 64559e74..a7c16742 100644 --- a/backend/src/plugins/Automod/triggers/ban.ts +++ b/backend/src/plugins/Automod/triggers/ban.ts @@ -5,13 +5,25 @@ import { automodTrigger } from "../helpers"; interface BanTriggerResultType {} export const BanTrigger = automodTrigger()({ - configType: t.type({}), - defaultConfig: {}, + configType: t.type({ + manual: t.boolean, + automatic: t.boolean, + }), - async match({ context }) { + defaultConfig: { + manual: true, + automatic: true, + }, + + async match({ context, triggerConfig }) { if (context.modAction?.type !== "ban") { return; } + console.log(context); + // If automatic && automatic turned off -> return + if (context.modAction.isAutomodAction && !triggerConfig.automatic) return; + // If manual && manual turned off -> return + if (!context.modAction.isAutomodAction && !triggerConfig.manual) return; return { extra: {}, diff --git a/backend/src/plugins/Automod/triggers/kick.ts b/backend/src/plugins/Automod/triggers/kick.ts index 284a867d..116f1252 100644 --- a/backend/src/plugins/Automod/triggers/kick.ts +++ b/backend/src/plugins/Automod/triggers/kick.ts @@ -5,13 +5,24 @@ import { automodTrigger } from "../helpers"; interface KickTriggerResultType {} export const KickTrigger = automodTrigger()({ - configType: t.type({}), - defaultConfig: {}, + configType: t.type({ + manual: t.boolean, + automatic: t.boolean, + }), - async match({ context }) { + defaultConfig: { + manual: true, + automatic: true, + }, + + async match({ context, triggerConfig }) { if (context.modAction?.type !== "kick") { return; } + // If automatic && automatic turned off -> return + if (context.modAction.isAutomodAction && !triggerConfig.automatic) return; + // If manual && manual turned off -> return + if (!context.modAction.isAutomodAction && !triggerConfig.manual) return; return { extra: {}, diff --git a/backend/src/plugins/Automod/triggers/mute.ts b/backend/src/plugins/Automod/triggers/mute.ts index 94d14437..c5e2d2ba 100644 --- a/backend/src/plugins/Automod/triggers/mute.ts +++ b/backend/src/plugins/Automod/triggers/mute.ts @@ -5,13 +5,24 @@ import { automodTrigger } from "../helpers"; interface MuteTriggerResultType {} export const MuteTrigger = automodTrigger()({ - configType: t.type({}), - defaultConfig: {}, + configType: t.type({ + manual: t.boolean, + automatic: t.boolean, + }), - async match({ context }) { + defaultConfig: { + manual: true, + automatic: true, + }, + + async match({ context, triggerConfig }) { if (context.modAction?.type !== "mute") { return; } + // If automatic && automatic turned off -> return + if (context.modAction.isAutomodAction && !triggerConfig.automatic) return; + // If manual && manual turned off -> return + if (!context.modAction.isAutomodAction && !triggerConfig.manual) return; return { extra: {}, diff --git a/backend/src/plugins/Automod/triggers/warn.ts b/backend/src/plugins/Automod/triggers/warn.ts index 711f5cd7..545c4437 100644 --- a/backend/src/plugins/Automod/triggers/warn.ts +++ b/backend/src/plugins/Automod/triggers/warn.ts @@ -5,13 +5,24 @@ import { automodTrigger } from "../helpers"; interface WarnTriggerResultType {} export const WarnTrigger = automodTrigger()({ - configType: t.type({}), - defaultConfig: {}, + configType: t.type({ + manual: t.boolean, + automatic: t.boolean, + }), - async match({ context }) { + defaultConfig: { + manual: true, + automatic: true, + }, + + async match({ context, triggerConfig }) { if (context.modAction?.type !== "warn") { return; } + // If automatic && automatic turned off -> return + if (context.modAction.isAutomodAction && !triggerConfig.automatic) return; + // If manual && manual turned off -> return + if (!context.modAction.isAutomodAction && !triggerConfig.manual) return; return { extra: {}, diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index f85b8429..cd7ebacf 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -122,6 +122,7 @@ export interface AutomodContext { modAction?: { type: ModActionType; reason?: string; + isAutomodAction: boolean; }; antiraid?: { level: string | null; diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index e36dbb86..45526a0c 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -112,7 +112,5 @@ export const WarnCmd = modActionsCmd({ msg.channel, `Warned **${memberToWarn.user.username}#${memberToWarn.user.discriminator}** (Case #${warnResult.case.case_number})${messageResultText}`, ); - - pluginData.state.events.emit("warn", user.id, reason); }, }); diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index 85d05de9..4620ec0f 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -127,7 +127,7 @@ export async function banUserId( banTime: banTime ? humanizeDuration(banTime) : null, }); - pluginData.state.events.emit("ban", user.id, reason); + pluginData.state.events.emit("ban", user.id, reason, banOptions.isAutomodAction); return { status: "success", diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index 9e297af8..b682018e 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -85,7 +85,7 @@ export async function kickMember( reason, }); - pluginData.state.events.emit("kick", member.id, reason); + pluginData.state.events.emit("kick", member.id, reason, kickOptions.isAutomodAction); return { status: "success", diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index 0c07c838..d61b183d 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -82,6 +82,8 @@ export async function warnMember( reason, }); + pluginData.state.events.emit("warn", member.id, reason, warnOptions.isAutomodAction); + return { status: "success", case: createdCase, diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index af4fd8d6..083e5642 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -48,9 +48,9 @@ export type TConfigSchema = t.TypeOf; export interface ModActionsEvents { note: (userId: string, reason?: string) => void; - warn: (userId: string, reason?: string) => void; - kick: (userId: string, reason?: string) => void; - ban: (userId: string, reason?: string) => void; + warn: (userId: string, reason?: string, isAutomodAction?: boolean) => void; + kick: (userId: string, reason?: string, isAutomodAction?: boolean) => void; + ban: (userId: string, reason?: string, isAutomodAction?: boolean) => void; unban: (userId: string, reason?: string) => void; // mute/unmute are in the Mutes plugin } @@ -126,17 +126,20 @@ export interface WarnOptions { caseArgs?: Partial | null; contactMethods?: UserNotificationMethod[] | null; retryPromptChannel?: TextChannel | null; + isAutomodAction?: boolean; } export interface KickOptions { caseArgs?: Partial; contactMethods?: UserNotificationMethod[]; + isAutomodAction?: boolean; } export interface BanOptions { caseArgs?: Partial; contactMethods?: UserNotificationMethod[]; deleteMessageDays?: number; + isAutomodAction?: boolean; } export type ModActionType = "note" | "warn" | "mute" | "unmute" | "kick" | "ban" | "unban"; diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 29ba54ab..622a5b1a 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -247,7 +247,7 @@ export async function muteUser( lock.unlock(); - pluginData.state.events.emit("mute", user.id, reason); + pluginData.state.events.emit("mute", user.id, reason, muteOptions.isAutomodAction); return { case: theCase, diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index 7da2cb0d..ea180e90 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -34,7 +34,7 @@ export const ConfigSchema = t.type({ export type TConfigSchema = t.TypeOf; export interface MutesEvents { - mute: (userId: string, reason?: string) => void; + mute: (userId: string, reason?: string, isAutomodAction?: boolean) => void; unmute: (userId: string, reason?: string) => void; } @@ -75,6 +75,7 @@ export type UnmuteResult = { export interface MuteOptions { caseArgs?: Partial; contactMethods?: UserNotificationMethod[]; + isAutomodAction?: boolean; } export const mutesCmd = guildCommand();