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!`);