2023-04-01 12:58:17 +01:00
|
|
|
import { Guild, Snowflake } from "discord.js";
|
2018-08-18 19:51:28 +03:00
|
|
|
import moment from "moment-timezone";
|
2021-07-21 22:14:09 +02:00
|
|
|
import { isDefaultSticker } from "src/utils/isDefaultSticker";
|
2018-10-26 06:41:20 +03:00
|
|
|
import { getRepository, Repository } from "typeorm";
|
2021-08-18 01:51:42 +03:00
|
|
|
import { renderTemplate, TemplateSafeValueContainer } from "../templateFormatter";
|
2019-03-16 15:42:55 +02:00
|
|
|
import { trimLines } from "../utils";
|
2023-04-01 12:58:17 +01:00
|
|
|
import { decrypt, encrypt } from "../utils/crypt";
|
|
|
|
import { channelToTemplateSafeChannel, guildToTemplateSafeGuild } from "../utils/templateSafeObjects";
|
2021-06-06 23:51:32 +02:00
|
|
|
import { BaseGuildRepository } from "./BaseGuildRepository";
|
|
|
|
import { ArchiveEntry } from "./entities/ArchiveEntry";
|
2021-10-09 14:21:23 +03:00
|
|
|
import { SavedMessage } from "./entities/SavedMessage";
|
2018-08-18 19:51:28 +03:00
|
|
|
|
|
|
|
const DEFAULT_EXPIRY_DAYS = 30;
|
|
|
|
|
2018-11-24 18:39:17 +02:00
|
|
|
const MESSAGE_ARCHIVE_HEADER_FORMAT = trimLines(`
|
|
|
|
Server: {guild.name} ({guild.id})
|
|
|
|
`);
|
2018-12-22 13:06:40 +02:00
|
|
|
const MESSAGE_ARCHIVE_MESSAGE_FORMAT =
|
2021-07-21 22:14:09 +02:00
|
|
|
"[#{channel.name}] [{user.id}] [{timestamp}] {user.username}#{user.discriminator}: {content}{attachments}{stickers}";
|
2018-11-24 18:39:17 +02:00
|
|
|
|
2021-10-09 14:21:23 +03:00
|
|
|
export class GuildArchives extends BaseGuildRepository<ArchiveEntry> {
|
2018-10-26 06:41:20 +03:00
|
|
|
protected archives: Repository<ArchiveEntry>;
|
2018-08-18 19:51:28 +03:00
|
|
|
|
|
|
|
constructor(guildId) {
|
2018-10-26 06:41:20 +03:00
|
|
|
super(guildId);
|
|
|
|
this.archives = getRepository(ArchiveEntry);
|
|
|
|
}
|
2018-08-18 19:51:28 +03:00
|
|
|
|
2021-10-09 14:21:23 +03:00
|
|
|
protected async _processEntityFromDB(entity: ArchiveEntry | undefined) {
|
|
|
|
if (entity == null) {
|
|
|
|
return entity;
|
|
|
|
}
|
|
|
|
|
2021-10-09 14:51:18 +03:00
|
|
|
entity.body = await decrypt(entity.body);
|
2021-10-09 14:21:23 +03:00
|
|
|
return entity;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected async _processEntityToDB(entity: Partial<ArchiveEntry>) {
|
|
|
|
if (entity.body) {
|
2021-10-09 14:51:18 +03:00
|
|
|
entity.body = await encrypt(entity.body);
|
2021-10-09 14:21:23 +03:00
|
|
|
}
|
|
|
|
return entity;
|
|
|
|
}
|
|
|
|
|
2020-11-09 20:03:57 +02:00
|
|
|
async find(id: string): Promise<ArchiveEntry | undefined> {
|
2021-10-09 14:21:23 +03:00
|
|
|
const result = await this.archives.findOne({
|
2018-10-26 06:41:20 +03:00
|
|
|
where: { id },
|
2019-03-16 15:42:55 +02:00
|
|
|
relations: this.getRelations(),
|
2018-10-26 06:41:20 +03:00
|
|
|
});
|
2021-10-09 14:21:23 +03:00
|
|
|
return this.processEntityFromDB(result);
|
2018-08-18 19:51:28 +03:00
|
|
|
}
|
|
|
|
|
2019-01-13 17:29:26 +02:00
|
|
|
async makePermanent(id: string): Promise<void> {
|
|
|
|
await this.archives.update(
|
|
|
|
{ id },
|
|
|
|
{
|
2019-03-16 15:42:55 +02:00
|
|
|
expires_at: null,
|
|
|
|
},
|
2019-01-13 17:29:26 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-10-26 06:41:20 +03:00
|
|
|
/**
|
2021-10-09 14:21:23 +03:00
|
|
|
* @return - ID of the created archive
|
2018-10-26 06:41:20 +03:00
|
|
|
*/
|
2020-11-09 20:03:57 +02:00
|
|
|
async create(body: string, expiresAt?: moment.Moment): Promise<string> {
|
2018-08-18 19:51:28 +03:00
|
|
|
if (!expiresAt) {
|
2020-08-10 00:24:06 +03:00
|
|
|
expiresAt = moment.utc().add(DEFAULT_EXPIRY_DAYS, "days");
|
2018-08-18 19:51:28 +03:00
|
|
|
}
|
|
|
|
|
2021-10-09 14:21:23 +03:00
|
|
|
const data = await this.processEntityToDB({
|
2018-08-18 19:51:28 +03:00
|
|
|
guild_id: this.guildId,
|
|
|
|
body,
|
2019-03-16 15:42:55 +02:00
|
|
|
expires_at: expiresAt.format("YYYY-MM-DD HH:mm:ss"),
|
2018-08-18 19:51:28 +03:00
|
|
|
});
|
2021-10-09 14:21:23 +03:00
|
|
|
const result = await this.archives.insert(data);
|
2018-08-18 19:51:28 +03:00
|
|
|
|
2018-10-26 06:41:20 +03:00
|
|
|
return result.identifiers[0].id;
|
2018-08-18 19:51:28 +03:00
|
|
|
}
|
2018-11-24 18:39:17 +02:00
|
|
|
|
2021-10-09 14:21:23 +03:00
|
|
|
protected async renderLinesFromSavedMessages(savedMessages: SavedMessage[], guild: Guild): Promise<string[]> {
|
2020-11-09 20:03:57 +02:00
|
|
|
const msgLines: string[] = [];
|
2019-03-16 15:42:55 +02:00
|
|
|
for (const msg of savedMessages) {
|
2021-06-30 04:56:56 +02:00
|
|
|
const channel = guild.channels.cache.get(msg.channel_id as Snowflake);
|
2021-08-18 01:51:42 +03:00
|
|
|
const partialUser = new TemplateSafeValueContainer({ ...msg.data.author, id: msg.user_id });
|
2018-12-22 13:06:40 +02:00
|
|
|
|
2021-08-18 20:09:25 +03:00
|
|
|
const line = await renderTemplate(
|
|
|
|
MESSAGE_ARCHIVE_MESSAGE_FORMAT,
|
|
|
|
new TemplateSafeValueContainer({
|
|
|
|
id: msg.id,
|
|
|
|
timestamp: moment.utc(msg.posted_at).format("YYYY-MM-DD HH:mm:ss"),
|
|
|
|
content: msg.data.content,
|
2021-09-11 19:06:51 +03:00
|
|
|
attachments: msg.data.attachments?.map((att) => {
|
2021-08-18 20:09:25 +03:00
|
|
|
return JSON.stringify({ name: att.name, url: att.url, type: att.contentType });
|
|
|
|
}),
|
2021-09-11 19:06:51 +03:00
|
|
|
stickers: msg.data.stickers?.map((sti) => {
|
2021-08-18 20:09:25 +03:00
|
|
|
return JSON.stringify({ name: sti.name, id: sti.id, isDefault: isDefaultSticker(sti.id) });
|
|
|
|
}),
|
|
|
|
user: partialUser,
|
|
|
|
channel: channel ? channelToTemplateSafeChannel(channel) : null,
|
2021-07-21 22:14:09 +02:00
|
|
|
}),
|
2021-08-18 20:09:25 +03:00
|
|
|
);
|
|
|
|
|
2019-03-16 15:42:55 +02:00
|
|
|
msgLines.push(line);
|
|
|
|
}
|
2020-01-26 19:54:32 +02:00
|
|
|
return msgLines;
|
|
|
|
}
|
|
|
|
|
2021-10-09 14:21:23 +03:00
|
|
|
/**
|
|
|
|
* @return - ID of the created archive
|
|
|
|
*/
|
|
|
|
async createFromSavedMessages(
|
|
|
|
savedMessages: SavedMessage[],
|
|
|
|
guild: Guild,
|
|
|
|
expiresAt?: moment.Moment,
|
|
|
|
): Promise<string> {
|
2020-08-10 00:24:06 +03:00
|
|
|
if (expiresAt == null) {
|
|
|
|
expiresAt = moment.utc().add(DEFAULT_EXPIRY_DAYS, "days");
|
|
|
|
}
|
2020-01-26 19:54:32 +02:00
|
|
|
|
2021-08-18 20:32:45 +03:00
|
|
|
const headerStr = await renderTemplate(
|
|
|
|
MESSAGE_ARCHIVE_HEADER_FORMAT,
|
|
|
|
new TemplateSafeValueContainer({
|
|
|
|
guild: guildToTemplateSafeGuild(guild),
|
|
|
|
}),
|
|
|
|
);
|
2020-01-26 19:54:32 +02:00
|
|
|
const msgLines = await this.renderLinesFromSavedMessages(savedMessages, guild);
|
2018-11-24 18:39:17 +02:00
|
|
|
const messagesStr = msgLines.join("\n");
|
|
|
|
|
2019-01-13 17:29:26 +02:00
|
|
|
return this.create([headerStr, messagesStr].join("\n\n"), expiresAt);
|
2018-11-24 18:39:17 +02:00
|
|
|
}
|
2019-01-15 04:03:04 +02:00
|
|
|
|
2020-01-26 19:54:32 +02:00
|
|
|
async addSavedMessagesToArchive(archiveId: string, savedMessages: SavedMessage[], guild: Guild) {
|
|
|
|
const msgLines = await this.renderLinesFromSavedMessages(savedMessages, guild);
|
|
|
|
const messagesStr = msgLines.join("\n");
|
|
|
|
|
2021-10-09 14:21:23 +03:00
|
|
|
let archive = await this.find(archiveId);
|
2020-11-09 20:03:57 +02:00
|
|
|
if (archive == null) {
|
|
|
|
throw new Error("Archive not found");
|
|
|
|
}
|
|
|
|
|
2020-01-26 19:54:32 +02:00
|
|
|
archive.body += "\n" + messagesStr;
|
2021-10-09 14:21:23 +03:00
|
|
|
archive = await this.processEntityToDB(archive);
|
2020-01-26 19:54:32 +02:00
|
|
|
|
|
|
|
await this.archives.update({ id: archiveId }, { body: archive.body });
|
|
|
|
}
|
|
|
|
|
2019-01-15 04:03:04 +02:00
|
|
|
getUrl(baseUrl, archiveId) {
|
|
|
|
return baseUrl ? `${baseUrl}/archives/${archiveId}` : `Archive ID: ${archiveId}`;
|
|
|
|
}
|
2018-08-18 19:51:28 +03:00
|
|
|
}
|