From 4448659dc0a7ceaff3028f3373ba76c2b07dfa88 Mon Sep 17 00:00:00 2001 From: Almeida Date: Wed, 28 Apr 2021 19:59:56 +0100 Subject: [PATCH 1/7] fix(SetCounterCmd): misleading messages (#188) --- backend/src/plugins/Counters/commands/SetCounterCmd.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index edabe2e7..0503b2fd 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -67,7 +67,7 @@ export const SetCounterCmd = guildCommand()({ let channel = args.channel; if (!channel && counter.per_channel) { - message.channel.createMessage(`Which channel's counter value would you like to add to?`); + message.channel.createMessage(`Which channel's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -85,7 +85,7 @@ export const SetCounterCmd = guildCommand()({ let user = args.user; if (!user && counter.per_user) { - message.channel.createMessage(`Which user's counter value would you like to add to?`); + message.channel.createMessage(`Which user's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -103,7 +103,7 @@ export const SetCounterCmd = guildCommand()({ let value = args.value; if (!value) { - message.channel.createMessage("How much would you like to add to the counter's value?"); + message.channel.createMessage("What would you like to set the counter's value to?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); From 00f368d62bab6a73a780b6fea6590c0620c89ca0 Mon Sep 17 00:00:00 2001 From: Shoaib Sajid Date: Thu, 29 Apr 2021 00:02:25 +0500 Subject: [PATCH 2/7] Fix typo in automod docs (#185) --- backend/src/plugins/Automod/info.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/plugins/Automod/info.ts b/backend/src/plugins/Automod/info.ts index c2c87dbf..9fcdced0 100644 --- a/backend/src/plugins/Automod/info.ts +++ b/backend/src/plugins/Automod/info.ts @@ -64,9 +64,9 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { reason: 'Auto-muted for spam' my_second_filter: triggers: - - message_spam: - amount: 5 - within: 10s + - emoji_spam: + amount: 2 + within: 5s actions: clean: true overrides: From 6b9131c353a578eb3af839a620f7edd9e4072306 Mon Sep 17 00:00:00 2001 From: Usoka <27248545+Usoka@users.noreply.github.com> Date: Thu, 29 Apr 2021 07:03:26 +1200 Subject: [PATCH 3/7] Fix 0 not being accepted in SetCounterCmd (#186) --- backend/src/plugins/Counters/commands/SetCounterCmd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 0503b2fd..f74c2045 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -111,7 +111,7 @@ export const SetCounterCmd = guildCommand()({ } const potentialValue = parseInt(reply.content, 10); - if (!potentialValue) { + if (Number.isNaN(potentialValue)) { sendErrorMessage(pluginData, message.channel, "Not a number, cancelling"); return; } From 90b6f4bc86d6e5756dbcc97956cfc05b99176643 Mon Sep 17 00:00:00 2001 From: Shoaib Sajid Date: Thu, 29 Apr 2021 00:04:01 +0500 Subject: [PATCH 4/7] Add !reminder as an alias for !remind (#181) --- backend/src/plugins/Reminders/commands/RemindCmd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts index 67a2cfc1..ad9cd355 100644 --- a/backend/src/plugins/Reminders/commands/RemindCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts @@ -7,7 +7,7 @@ import { remindersCmd } from "../types"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; export const RemindCmd = remindersCmd({ - trigger: ["remind", "remindme"], + trigger: ["remind", "remindme", "reminder"], usage: "!remind 3h Remind me of this in 3 hours please", permission: "can_use", From 51db942d977cfae2b0411248e0991d30b0b398cb Mon Sep 17 00:00:00 2001 From: Nils <7890309+DarkView@users.noreply.github.com> Date: Wed, 28 Apr 2021 21:06:33 +0200 Subject: [PATCH 5/7] Allow Automod to distinguish whether mod actions are manual or automatic (#179) --- backend/src/plugins/Automod/AutomodPlugin.ts | 24 +++++++++++++------ backend/src/plugins/Automod/actions/ban.ts | 7 +++++- backend/src/plugins/Automod/actions/kick.ts | 2 +- backend/src/plugins/Automod/actions/mute.ts | 9 ++++++- backend/src/plugins/Automod/actions/warn.ts | 2 +- .../Automod/events/runAutomodOnModAction.ts | 2 ++ backend/src/plugins/Automod/triggers/ban.ts | 18 +++++++++++--- backend/src/plugins/Automod/triggers/kick.ts | 17 ++++++++++--- backend/src/plugins/Automod/triggers/mute.ts | 17 ++++++++++--- backend/src/plugins/Automod/triggers/warn.ts | 17 ++++++++++--- backend/src/plugins/Automod/types.ts | 1 + .../plugins/ModActions/commands/WarnCmd.ts | 2 -- .../plugins/ModActions/functions/banUserId.ts | 2 +- .../ModActions/functions/kickMember.ts | 2 +- .../ModActions/functions/warnMember.ts | 2 ++ backend/src/plugins/ModActions/types.ts | 9 ++++--- .../src/plugins/Mutes/functions/muteUser.ts | 2 +- backend/src/plugins/Mutes/types.ts | 3 ++- 18 files changed, 106 insertions(+), 32 deletions(-) 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(); From dfc1bf2ba09e317583f27bf5a9e5522b5f12d3b3 Mon Sep 17 00:00:00 2001 From: Shoaib Sajid Date: Thu, 29 Apr 2021 00:08:37 +0500 Subject: [PATCH 6/7] Add !infractions as an alias for !cases (#177) --- backend/src/plugins/ModActions/commands/CasesModCmd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 6d84fc77..f9f4667d 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -17,7 +17,7 @@ const opts = { const casesPerPage = 5; export const CasesModCmd = modActionsCmd({ - trigger: ["cases", "modlogs"], + trigger: ["cases", "modlogs", "infractions"], permission: "can_view", description: "Show the most recent 5 cases by the specified -mod", From 20b1c869cd040d1d8bbf7e9a490153db4ca6d861 Mon Sep 17 00:00:00 2001 From: Nils <7890309+DarkView@users.noreply.github.com> Date: Wed, 28 Apr 2021 21:15:16 +0200 Subject: [PATCH 7/7] Add -update/-up argument to automatically update latest/chosen case with !clean (#173) --- .../plugins/ModActions/ModActionsPlugin.ts | 9 +++- .../plugins/ModActions/commands/UpdateCmd.ts | 42 +---------------- .../ModActions/functions/updateCase.ts | 44 +++++++++++++++++ backend/src/plugins/Utility/UtilityPlugin.ts | 3 +- .../src/plugins/Utility/commands/CleanCmd.ts | 47 +++++++++++++++---- 5 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 backend/src/plugins/ModActions/functions/updateCase.ts diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 672e4630..2d583e06 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -30,7 +30,7 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { ForceUnmuteCmd } from "./commands/ForceunmuteCmd"; import { warnMember } from "./functions/warnMember"; -import { Member } from "eris"; +import { Member, Message } from "eris"; import { kickMember } from "./functions/kickMember"; import { banUserId } from "./functions/banUserId"; import { MassmuteCmd } from "./commands/MassmuteCmd"; @@ -43,6 +43,7 @@ import { EventEmitter } from "events"; import { mapToPublicFn } from "../../pluginUtils"; import { onModActionsEvent } from "./functions/onModActionsEvent"; import { offModActionsEvent } from "./functions/offModActionsEvent"; +import { updateCase } from "./functions/updateCase"; const defaultOptions = { config: { @@ -170,6 +171,12 @@ export const ModActionsPlugin = zeppelinGuildPlugin()("mod }; }, + updateCase(pluginData) { + return (msg: Message, caseNumber: number | null, note: string) => { + updateCase(pluginData, msg, { caseNumber, note }); + }; + }, + on: mapToPublicFn(onModActionsEvent), off: mapToPublicFn(offModActionsEvent), getEventEmitter(pluginData) { diff --git a/backend/src/plugins/ModActions/commands/UpdateCmd.ts b/backend/src/plugins/ModActions/commands/UpdateCmd.ts index 3a048b42..6c8d78ca 100644 --- a/backend/src/plugins/ModActions/commands/UpdateCmd.ts +++ b/backend/src/plugins/ModActions/commands/UpdateCmd.ts @@ -1,11 +1,6 @@ import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { Case } from "../../../data/entities/Case"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogType } from "../../../data/LogType"; -import { CaseTypes } from "../../../data/CaseTypes"; +import { updateCase } from "../functions/updateCase"; export const UpdateCmd = modActionsCmd({ trigger: ["update", "reason"], @@ -24,39 +19,6 @@ export const UpdateCmd = modActionsCmd({ ], async run({ pluginData, message: msg, args }) { - let theCase: Case | undefined; - if (args.caseNumber != null) { - theCase = await pluginData.state.cases.findByCaseNumber(args.caseNumber); - } else { - theCase = await pluginData.state.cases.findLatestByModId(msg.author.id); - } - - if (!theCase) { - sendErrorMessage(pluginData, msg.channel, "Case not found"); - return; - } - - if (!args.note && msg.attachments.length === 0) { - sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); - return; - } - - const note = formatReasonWithAttachments(args.note, msg.attachments); - - const casesPlugin = pluginData.getPlugin(CasesPlugin); - await casesPlugin.createCaseNote({ - caseId: theCase.id, - modId: msg.author.id, - body: note, - }); - - pluginData.state.serverLogs.log(LogType.CASE_UPDATE, { - mod: msg.author, - caseNumber: theCase.case_number, - caseType: CaseTypes[theCase.type], - note, - }); - - sendSuccessMessage(pluginData, msg.channel, `Case \`#${theCase.case_number}\` updated`); + await updateCase(pluginData, msg, args); }, }); diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts new file mode 100644 index 00000000..12257269 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -0,0 +1,44 @@ +import { Message } from "eris"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { Case } from "../../../data/entities/Case"; +import { LogType } from "../../../data/LogType"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; + +export async function updateCase(pluginData, msg: Message, args) { + let theCase: Case | undefined; + if (args.caseNumber != null) { + theCase = await pluginData.state.cases.findByCaseNumber(args.caseNumber); + } else { + theCase = await pluginData.state.cases.findLatestByModId(msg.author.id); + } + + if (!theCase) { + sendErrorMessage(pluginData, msg.channel, "Case not found"); + return; + } + + if (!args.note && msg.attachments.length === 0) { + sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); + return; + } + + const note = formatReasonWithAttachments(args.note, msg.attachments); + + const casesPlugin = pluginData.getPlugin(CasesPlugin); + await casesPlugin.createCaseNote({ + caseId: theCase.id, + modId: msg.author.id, + body: note, + }); + + pluginData.state.serverLogs.log(LogType.CASE_UPDATE, { + mod: msg.author, + caseNumber: theCase.case_number, + caseType: CaseTypes[theCase.type], + note, + }); + + sendSuccessMessage(pluginData, msg.channel, `Case \`#${theCase.case_number}\` updated`); +} diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 90c44c49..e2ba30b0 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -35,6 +35,7 @@ import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd"; import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { VcdisconnectCmd } from "./commands/VcdisconnectCmd"; +import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; import { refreshMembersIfNeeded } from "./refreshMembers"; const defaultOptions: PluginOptions = { @@ -106,7 +107,7 @@ export const UtilityPlugin = zeppelinGuildPlugin()("utility", prettyName: "Utility", }, - dependencies: [TimeAndDatePlugin], + dependencies: [TimeAndDatePlugin, ModActionsPlugin], configSchema: ConfigSchema, defaultOptions, diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index e75da2f8..8a1a2328 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -8,6 +8,7 @@ import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { allowTimeout } from "../../../RegExpRunner"; +import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; const MAX_CLEAN_COUNT = 150; const MAX_CLEAN_TIME = 1 * DAYS; @@ -49,23 +50,36 @@ async function cleanMessages( return { archiveUrl }; } +const opts = { + user: ct.userId({ option: true, shortcut: "u" }), + channel: ct.channelId({ option: true, shortcut: "c" }), + bots: ct.switchOption({ shortcut: "b" }), + "delete-pins": ct.switchOption({ shortcut: "p" }), + "has-invites": ct.switchOption({ shortcut: "i" }), + match: ct.regex({ option: true, shortcut: "m" }), + "to-id": ct.anyId({ option: true, shortcut: "id" }), +}; + export const CleanCmd = utilityCmd({ trigger: ["clean", "clear"], description: "Remove a number of recent messages", usage: "!clean 20", permission: "can_clean", - signature: { - count: ct.number(), + signature: [ + { + count: ct.number(), + update: ct.number({ option: true, shortcut: "up" }), - user: ct.userId({ option: true, shortcut: "u" }), - channel: ct.channelId({ option: true, shortcut: "c" }), - bots: ct.switchOption({ shortcut: "b" }), - "delete-pins": ct.switchOption({ shortcut: "p" }), - "has-invites": ct.switchOption({ shortcut: "i" }), - match: ct.regex({ option: true, shortcut: "m" }), - "to-id": ct.anyId({ option: true, shortcut: "id" }), - }, + ...opts, + }, + { + count: ct.number(), + update: ct.switchOption({ shortcut: "up" }), + + ...opts, + }, + ], async run({ message: msg, args, pluginData }) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { @@ -155,6 +169,19 @@ export const CleanCmd = utilityCmd({ responseText += ` in <#${targetChannel.id}>\n${cleanResult.archiveUrl}`; } + if (args.update) { + const modActions = pluginData.getPlugin(ModActionsPlugin); + const channelId = targetChannel.id !== msg.channel.id ? targetChannel.id : msg.channel.id; + const updateMessage = `Cleaned ${messagesToClean.length} ${ + messagesToClean.length === 1 ? "message" : "messages" + } in <#${channelId}>: ${cleanResult.archiveUrl}`; + if (typeof args.update === "number") { + modActions.updateCase(msg, args.update, updateMessage); + } else { + modActions.updateCase(msg, null, updateMessage); + } + } + responseMsg = await sendSuccessMessage(pluginData, msg.channel, responseText); } else { responseMsg = await sendErrorMessage(pluginData, msg.channel, `Found no messages to clean!`);