make /purge user filter work with uncached users

This commit is contained in:
Jan 2022-11-27 19:27:00 +01:00
parent a26d11d832
commit 3dc10d34a4
Signed by: Lea
GPG key ID: 5D5E18ACB990F57A

View file

@ -1,29 +1,33 @@
import SimpleCommand from "../../../struct/commands/SimpleCommand"; import SimpleCommand from "../../../struct/commands/SimpleCommand";
import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
import { decodeTime } from 'ulid'; import { decodeTime } from 'ulid';
import { isModerator, parseUser } from "../../util"; import { isModerator, parseUserOrId } from "../../util";
import MessageCommandContext from "../../../struct/MessageCommandContext"; import MessageCommandContext from "../../../struct/MessageCommandContext";
import CommandCategory from "../../../struct/commands/CommandCategory"; import CommandCategory from "../../../struct/commands/CommandCategory";
const SYNTAX = '/purge [number] [user[,user...]]'; const SYNTAX = "/purge [number] [user[,user...]]";
const MAX_PURGE_AMOUNT = 100; const MAX_PURGE_AMOUNT = 100;
export default { export default {
name: 'purge', name: "purge",
aliases: [ 'clear' ], aliases: ["clear"],
description: 'Mass delete messages', description: "Mass delete messages",
syntax: SYNTAX, syntax: SYNTAX,
category: CommandCategory.Moderation, category: CommandCategory.Moderation,
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
try { try {
if (!message.member || !await isModerator(message)) return message.reply('🔒 Access denied'); if (!message.member || !(await isModerator(message)))
return message.reply("🔒 Access denied");
let messages: Array<Message> = []; let messages: Array<Message> = [];
// X amount of messages from bottom // X amount of messages from bottom
if (/^[0-9]+$/g.test(args[0])) { if (/^[0-9]+$/g.test(args[0])) {
let amount = Number(args[0]); let amount = Number(args[0]);
if (isNaN(amount)) return message.reply('Invalid number'); if (isNaN(amount)) return message.reply("Invalid number");
if (amount > MAX_PURGE_AMOUNT) return message.reply(`Message count exceeds the limit of ${MAX_PURGE_AMOUNT}.`); if (amount > MAX_PURGE_AMOUNT)
return message.reply(
`Message count exceeds the limit of ${MAX_PURGE_AMOUNT}.`
);
messages = await message.channel!.fetchMessages({ messages = await message.channel!.fetchMessages({
limit: amount, limit: amount,
@ -32,8 +36,12 @@ export default {
} }
// delete messages between [id] and [id] // delete messages between [id] and [id]
// [0-9A-HJ-KM-NP-TV-Z]{26} -> matches ULIDs // [0-9A-HJ-KM-NP-TV-Z]{26} -> matches ULIDs
else if (/^[0-9A-HJ-KM-NP-TV-Z]{26}-[0-9A-HJ-KM-NP-TV-Z]{26}$/g.test(args[0])) { else if (
let [id1, id2] = args[0].split('-'); /^[0-9A-HJ-KM-NP-TV-Z]{26}-[0-9A-HJ-KM-NP-TV-Z]{26}$/g.test(
args[0]
)
) {
let [id1, id2] = args[0].split("-");
let [msg1, msg2] = await Promise.all([ let [msg1, msg2] = await Promise.all([
message.channel!.fetchMessage(id1), message.channel!.fetchMessage(id1),
@ -49,39 +57,51 @@ export default {
before: id2, before: id2,
after: id1, after: id1,
limit: MAX_PURGE_AMOUNT, limit: MAX_PURGE_AMOUNT,
sort: 'Latest', sort: "Latest",
}); });
if (!messages.find(m => m._id == msg1._id)) messages = [ msg1, ...messages ]; if (!messages.find((m) => m._id == msg1._id))
if (!messages.find(m => m._id == msg2._id)) messages = [ ...messages, msg2 ]; messages = [msg1, ...messages];
if (!messages.find((m) => m._id == msg2._id))
messages = [...messages, msg2];
// Discard messages that are not in the selected range, // Discard messages that are not in the selected range,
// because Revolt returns more messages than expected for some reason // because Revolt returns more messages than expected for some reason
messages = messages.filter( messages = messages.filter(
m => decodeTime(m._id) <= decodeTime(id2) && (m) =>
decodeTime(m._id) >= decodeTime(id1) decodeTime(m._id) <= decodeTime(id2) &&
decodeTime(m._id) >= decodeTime(id1)
); );
} }
// allow single messages too, because why not? // allow single messages too, because why not?
else if (/^[0-9A-HJ-KM-NP-TV-Z]{26}$/g.test(args[0])) { else if (/^[0-9A-HJ-KM-NP-TV-Z]{26}$/g.test(args[0])) {
messages = [ await message.channel!.fetchMessage(args[0]) ]; messages = [await message.channel!.fetchMessage(args[0])];
} else { } else {
return message.reply(`I can't parse that message range.\nSyntax: \`${SYNTAX}\``); return message.reply(
`I can't parse that message range.\nSyntax: \`${SYNTAX}\``
);
} }
if (args[1]) { if (args[1]) {
let p = args[1].split(',').map(u => parseUser(u)); let p = args[1].split(",").map((u) => parseUserOrId(u));
let users = await Promise.all(p); let users = await Promise.all(p);
if (users.filter(u => !u).length > 0) if (users.filter((u) => !u).length > 0)
return message.reply('At least one of the supplied users could not be found.'); return message.reply(
"At least one of the supplied users could not be found."
);
messages = messages.filter(m => users.find(u => u?._id == m.author_id)); messages = messages.filter((m) =>
users.find((u) => u?._id == m.author_id)
);
} }
await message.channel?.deleteMessages(messages.map(m => m._id)); await message.channel?.deleteMessages(messages.map((m) => m._id));
const replyMsg = await message.channel?.sendMessage({ content: `Deleted ${messages.length} messages.` }) const replyMsg = await message.channel
?.sendMessage({
content: `Deleted ${messages.length} messages.`,
})
.catch(console.error); .catch(console.error);
setTimeout(async () => { setTimeout(async () => {
@ -90,11 +110,13 @@ export default {
replyMsg!._id, replyMsg!._id,
message._id, message._id,
]); ]);
} catch(e) { console.error(e) } } catch (e) {
console.error(e);
}
}, 6000); }, 6000);
} catch(e) { } catch (e) {
console.error(e); console.error(e);
message.channel?.sendMessage(`An error has occurred: ${e}`); message.channel?.sendMessage(`An error has occurred: ${e}`);
} }
} },
} as SimpleCommand; } as SimpleCommand;