3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 04:25:01 +00:00
zeppelin/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts
BanTheNons d09e0566b3
fix: reactions in the channel archiver command (#308)
Co-authored-by: Almeida <github@almeidx.dev>
2023-12-28 20:43:46 +00:00

120 lines
4.2 KiB
TypeScript

import { Snowflake } from "discord.js";
import moment from "moment-timezone";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { isOwner, sendErrorMessage } from "../../../pluginUtils";
import { SECONDS, confirm, noop, renderUsername } from "../../../utils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { rehostAttachment } from "../rehostAttachment";
import { channelArchiverCmd } from "../types";
const MAX_ARCHIVED_MESSAGES = 5000;
const MAX_MESSAGES_PER_FETCH = 100;
const PROGRESS_UPDATE_INTERVAL = 5 * SECONDS;
export const ArchiveChannelCmd = channelArchiverCmd({
trigger: "archive_channel",
permission: null,
config: {
preFilters: [
(command, context) => {
return isOwner(context.pluginData, context.message.author.id);
},
],
},
signature: {
channel: ct.textChannel(),
"attachment-channel": ct.textChannel({ option: true }),
messages: ct.number({ option: true }),
},
async run({ message: msg, args, pluginData }) {
if (!args["attachment-channel"]) {
const confirmed = await confirm(msg.channel, msg.author.id, {
content:
"No `-attachment-channel` specified. Continue? Attachments will not be available in the log if their message is deleted.",
});
if (!confirmed) {
sendErrorMessage(pluginData, msg.channel, "Canceled");
return;
}
}
const maxMessagesToArchive = args.messages ? Math.min(args.messages, MAX_ARCHIVED_MESSAGES) : MAX_ARCHIVED_MESSAGES;
if (maxMessagesToArchive <= 0) return;
const archiveLines: string[] = [];
let archivedMessages = 0;
let previousId: string | undefined;
const startTime = Date.now();
const progressMsg = await msg.channel.send("Creating archive...");
const progressUpdateInterval = setInterval(() => {
const secondsSinceStart = Math.round((Date.now() - startTime) / 1000);
progressMsg
.edit(`Creating archive...\n**Status:** ${archivedMessages} messages archived in ${secondsSinceStart} seconds`)
.catch(() => clearInterval(progressUpdateInterval));
}, PROGRESS_UPDATE_INTERVAL);
while (archivedMessages < maxMessagesToArchive) {
const messagesToFetch = Math.min(MAX_MESSAGES_PER_FETCH, maxMessagesToArchive - archivedMessages);
const messages = await args.channel.messages.fetch({
limit: messagesToFetch,
before: previousId as Snowflake,
});
if (messages.size === 0) break;
for (const message of messages.values()) {
const ts = moment.utc(message.createdTimestamp).format("YYYY-MM-DD HH:mm:ss");
let content = `[${ts}] [${message.author.id}] [${renderUsername(
message.author.username,
message.author.discriminator,
)}]: ${message.content || "<no text content>"}`;
if (message.attachments.size) {
if (args["attachment-channel"]) {
const rehostedAttachmentUrl = await rehostAttachment(message.attachments[0], args["attachment-channel"]);
content += `\n-- Attachment: ${rehostedAttachmentUrl}`;
} else {
content += `\n-- Attachment: ${message.attachments[0].url}`;
}
}
if (message.reactions.cache.size > 0) {
const reactionCounts: string[] = [];
for (const [emoji, info] of message.reactions.cache) {
reactionCounts.push(`${info.count}x ${emoji}`);
}
content += `\n-- Reactions: ${reactionCounts.join(", ")}`;
}
archiveLines.push(content);
previousId = message.id;
archivedMessages++;
}
}
clearInterval(progressUpdateInterval);
archiveLines.reverse();
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
const nowTs = timeAndDate.inGuildTz().format(timeAndDate.getDateFormat("pretty_datetime"));
let result = `Archived ${archiveLines.length} messages from #${args.channel.name} at ${nowTs}`;
result += `\n\n${archiveLines.join("\n")}\n`;
progressMsg.delete().catch(noop);
msg.channel.send({
content: "Archive created!",
files: [
{
attachment: Buffer.from(result),
name: `archive-${args.channel.name}-${moment.utc().format("YYYY-MM-DD-HH-mm-ss")}.txt`,
},
],
});
},
});