From c2f5d889f599d81330cc82889cdc297cc790dc57 Mon Sep 17 00:00:00 2001 From: janderedev Date: Thu, 13 Jan 2022 20:20:48 +0100 Subject: [PATCH] fix crash when message is deleted before replying --- src/bot/commands/eval.ts | 3 ++- src/bot/commands/help.ts | 3 ++- src/bot/commands/ping.ts | 3 ++- src/bot/commands/prefix.ts | 3 ++- src/bot/commands/purge.ts | 3 ++- src/bot/commands/shell_eval.ts | 3 ++- src/bot/commands/test.ts | 3 ++- src/bot/modules/command_handler.ts | 2 ++ src/bot/modules/custom_rules/custom_rules.ts | 3 ++- src/bot/modules/prepare_message.ts | 26 ++++++++++++++++++++ src/struct/MessageCommandContext.ts | 1 + 11 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 src/bot/modules/prepare_message.ts diff --git a/src/bot/commands/eval.ts b/src/bot/commands/eval.ts index e294285..b5ec43d 100644 --- a/src/bot/commands/eval.ts +++ b/src/bot/commands/eval.ts @@ -2,6 +2,7 @@ import Command from "../../struct/Command"; import { Message } from "revolt.js/dist/maps/Messages"; import { inspect } from 'util'; import { client } from "../.."; +import MessageCommandContext from "../../struct/MessageCommandContext"; export default { name: 'eval', @@ -10,7 +11,7 @@ export default { restrict: 'BOTOWNER', removeEmptyArgs: false, category: 'owner', - run: async (message: Message, args: string[]) => { + run: async (message: MessageCommandContext, args: string[]) => { let cmd = args.join(' '); let m = await message.channel?.sendMessage(`Executing...`); diff --git a/src/bot/commands/help.ts b/src/bot/commands/help.ts index b1626dc..cc65701 100644 --- a/src/bot/commands/help.ts +++ b/src/bot/commands/help.ts @@ -2,6 +2,7 @@ import Command from "../../struct/Command"; import { Message } from "revolt.js/dist/maps/Messages"; import { commands, DEFAULT_PREFIX, ownerIDs } from "../modules/command_handler"; import CommandCategory from "../../struct/CommandCategory"; +import MessageCommandContext from "../../struct/MessageCommandContext"; const categories: { [key: string]: CommandCategory } = { 'moderation': { @@ -37,7 +38,7 @@ export default { description: 'Help command.', removeEmptyArgs: true, category: 'misc', - run: async (message: Message, args: string[]) => { + run: async (message: MessageCommandContext, args: string[]) => { const isBotOwner = ownerIDs.includes(message.author_id); const prefix = DEFAULT_PREFIX; // TODO: fetch prefix from server config diff --git a/src/bot/commands/ping.ts b/src/bot/commands/ping.ts index a6285d1..426ba4b 100644 --- a/src/bot/commands/ping.ts +++ b/src/bot/commands/ping.ts @@ -1,13 +1,14 @@ import Command from "../../struct/Command"; import { Message } from "revolt.js/dist/maps/Messages"; import { client } from "../.."; +import MessageCommandContext from "../../struct/MessageCommandContext"; export default { name: 'ping', aliases: null, description: 'ping pong', category: 'misc', - run: async (message: Message, args: string[]) => { + run: async (message: MessageCommandContext, args: string[]) => { let now = Date.now(); message.reply(`Measuring...`) ?.catch(console.error) diff --git a/src/bot/commands/prefix.ts b/src/bot/commands/prefix.ts index df86f1e..3010ee2 100644 --- a/src/bot/commands/prefix.ts +++ b/src/bot/commands/prefix.ts @@ -4,6 +4,7 @@ import { client } from "../.."; import ServerConfig from "../../struct/ServerConfig"; import { DEFAULT_PREFIX } from "../modules/command_handler"; import { hasPerm, isBotManager, NO_MANAGER_MSG } from "../util"; +import MessageCommandContext from "../../struct/MessageCommandContext"; const SYNTAX = '/prefix set [new prefix]; /prefix get; prefix clear'; const MENTION_TEXT = 'You can also @mention me instead of using the prefix.'; @@ -14,7 +15,7 @@ export default { description: 'Configure AutoMod\'s prefix', syntax: SYNTAX, category: 'configuration', - run: async (message: Message, args: string[]) => { + run: async (message: MessageCommandContext, args: string[]) => { let config: ServerConfig = (await client.db.get('servers').findOne({ id: message.channel?.server_id })) ?? {}; switch(args[0]?.toLowerCase()) { diff --git a/src/bot/commands/purge.ts b/src/bot/commands/purge.ts index 4439f4b..29f2dce 100644 --- a/src/bot/commands/purge.ts +++ b/src/bot/commands/purge.ts @@ -2,6 +2,7 @@ import Command from "../../struct/Command"; import { Message } from "revolt.js/dist/maps/Messages"; import { decodeTime } from 'ulid'; import { isModerator, parseUser } from "../util"; +import MessageCommandContext from "../../struct/MessageCommandContext"; const SYNTAX = '/purge [SELECTOR] [@user?[m @user?[, ...]]]; where SELECTOR: [number] || [messageID]-[messageID]'; const MAX_PURGE_AMOUNT = 100; @@ -12,7 +13,7 @@ export default { description: 'Mass delete messages', syntax: SYNTAX, category: 'moderation', - run: async (message: Message, args: string[]) => { + run: async (message: MessageCommandContext, args: string[]) => { try { if (!message.member || !await isModerator(message.member!, message.channel?.server!)) return message.reply('🔒 Access denied'); diff --git a/src/bot/commands/shell_eval.ts b/src/bot/commands/shell_eval.ts index fe61ddc..466309b 100644 --- a/src/bot/commands/shell_eval.ts +++ b/src/bot/commands/shell_eval.ts @@ -1,6 +1,7 @@ import Command from "../../struct/Command"; import { Message } from "revolt.js/dist/maps/Messages"; import { exec } from 'child_process'; +import MessageCommandContext from "../../struct/MessageCommandContext"; export default { name: 'shell', @@ -9,7 +10,7 @@ export default { restrict: 'BOTOWNER', removeEmptyArgs: false, category: 'owner', - run: async (message: Message, args: string[]) => { + run: async (message: MessageCommandContext, args: string[]) => { let cmd = args.join(' '); let m = await message.channel?.sendMessage(`Executing...`); diff --git a/src/bot/commands/test.ts b/src/bot/commands/test.ts index c763cbf..03077e6 100644 --- a/src/bot/commands/test.ts +++ b/src/bot/commands/test.ts @@ -1,12 +1,13 @@ import Command from "../../struct/Command"; import { Message } from "revolt.js/dist/maps/Messages"; +import MessageCommandContext from "../../struct/MessageCommandContext"; export default { name: 'test', aliases: [ 'testalias' ], description: 'Test command', category: 'misc', - run: (message: Message, args: string[]) => { + run: (message: MessageCommandContext, args: string[]) => { message.reply('Beep boop.'); } } as Command; diff --git a/src/bot/modules/command_handler.ts b/src/bot/modules/command_handler.ts index d86beb2..bfc16ea 100644 --- a/src/bot/modules/command_handler.ts +++ b/src/bot/modules/command_handler.ts @@ -9,6 +9,7 @@ import checkCustomRules from "./custom_rules/custom_rules"; import MessageCommandContext from "../../struct/MessageCommandContext"; import { fileURLToPath } from 'url'; import { getOwnMemberInServer, hasPermForChannel } from "../util"; +import { prepareMessage } from "./prepare_message"; // thanks a lot esm const filename = fileURLToPath(import.meta.url); @@ -88,6 +89,7 @@ let commands: Command[]; let message: MessageCommandContext = msg as MessageCommandContext; message.serverContext = serverCtx; + prepareMessage(message); logger.info(`Command: ${message.author?.username} (${message.author?._id}) in ${message.channel?.server?.name} (${message.channel?.server?._id}): ${message.content}`); diff --git a/src/bot/modules/custom_rules/custom_rules.ts b/src/bot/modules/custom_rules/custom_rules.ts index c4e990a..f004078 100644 --- a/src/bot/modules/custom_rules/custom_rules.ts +++ b/src/bot/modules/custom_rules/custom_rules.ts @@ -7,7 +7,8 @@ import messageContentTrigger from "./message_content_trigger"; import custom_sendMessage from "./actions/sendMessage"; import custom_delete from "./actions/delete"; import custom_warn from "./actions/warn"; -import { getOwnMemberInServer, hasPerm, hasPermForChannel } from "../../util"; +import { getOwnMemberInServer, hasPermForChannel } from "../../util"; +import MessageCommandContext from "../../../struct/MessageCommandContext"; async function checkCustomRules(message: Message, isEdit: boolean = false) { let serverConfig: ServerConfig = await client.db.get('servers').findOne({ id: message.channel?.server_id }) ?? {}; diff --git a/src/bot/modules/prepare_message.ts b/src/bot/modules/prepare_message.ts new file mode 100644 index 0000000..54c5236 --- /dev/null +++ b/src/bot/modules/prepare_message.ts @@ -0,0 +1,26 @@ +import { Message } from "revolt.js/dist/maps/Messages"; +import logger from "../logger"; + +// We modify the way `reply()` works to make sure we +// don't crash if the original message was deleted. + +export function prepareMessage(message: Message) { + message.reply = (...args: Parameters) => { + return new Promise((resolve, reject) => { + message.channel?.sendMessage({ + content: typeof args[0] == 'string' ? args[0] : args[0].content, + replies: [ { id: message._id, mention: args[1] ?? true } ], + }) + ?.then(m => resolve(m)) + .catch(e => { + if (e?.response?.status == 404) { + logger.warn("Replying to message gave 404, trying again without reply"); + if (!message.channel) return reject("Channel does not exist"); + message.channel?.sendMessage(typeof args[0] == 'string' ? { content: args[0] } : args[0]) + .then(resolve) + .catch(reject); + } else reject(e); + }); + }); + } +} diff --git a/src/struct/MessageCommandContext.ts b/src/struct/MessageCommandContext.ts index 020a9f7..557564e 100644 --- a/src/struct/MessageCommandContext.ts +++ b/src/struct/MessageCommandContext.ts @@ -1,5 +1,6 @@ import { Message } from "revolt.js/dist/maps/Messages"; import { Server } from "revolt.js/dist/maps/Servers"; +import logger from "../bot/logger"; class MessageCommandContext extends Message { // The server to which the command should be applied.