132 lines
3.5 KiB
TypeScript
132 lines
3.5 KiB
TypeScript
import * as fsp from 'fs/promises';
|
|
import { tmpdir } from 'os';
|
|
import { join } from 'path';
|
|
import { randomBytes } from 'crypto';
|
|
import { Attachment, EmbedBuilder, Guild, GuildPremiumTier, Message, PartialMessage } from 'discord.js';
|
|
|
|
export async function exists(file: string) {
|
|
try {
|
|
await fsp.stat(file);
|
|
return true;
|
|
} catch(_err) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function getSign(n: number) {
|
|
if (n > 0) return '+';
|
|
if (n < 0) return '-';
|
|
return ' ';
|
|
}
|
|
|
|
export async function writeTmpFile(data: string | Buffer, filename?: string, extension?: string): Promise<string> {
|
|
const file = `${filename ? filename + '-' : ''}${randomBytes(8).toString('hex')}${extension ? '.' + extension : (typeof data === 'string' ? '.txt' : '')}`;
|
|
const path = join(tmpdir(), file);
|
|
await fsp.writeFile(path, data);
|
|
return path;
|
|
}
|
|
|
|
export function pickRandom<T>(list: T[]): T {
|
|
return list[Math.floor(Math.random() * list.length)];
|
|
}
|
|
|
|
// WE OUT HERE
|
|
export type Either<L,R> = Left<L> | Right<R>
|
|
|
|
export class Left<L> {
|
|
constructor(private readonly value: L) {}
|
|
public getValue() { return this.value; }
|
|
}
|
|
|
|
export class Right<R> {
|
|
constructor(private readonly value: R) {}
|
|
public getValue() { return this.value; }
|
|
}
|
|
|
|
export function* chunks<T>(arr: T[], n: number) {
|
|
for (let i = 0; i < arr.length; i += n) {
|
|
yield arr.slice(i, i + n);
|
|
}
|
|
}
|
|
|
|
export function shortenStr(str: string, chars: number) {
|
|
if (str.length > chars)
|
|
return str.slice(0, chars - 1) + '…';
|
|
|
|
return str;
|
|
}
|
|
|
|
export const MAX_MESSAGE_SIZE = 2000;
|
|
|
|
export const defaultUploadLimit = 25 * 1024 * 1024;
|
|
|
|
export const getUploadLimitForGuild = (guild: Guild) => {
|
|
switch (guild.premiumTier) {
|
|
case GuildPremiumTier.Tier3: return 100 * 1024 * 1024;
|
|
case GuildPremiumTier.Tier2: return 50 * 1024 * 1024;
|
|
default: return defaultUploadLimit;
|
|
}
|
|
};
|
|
|
|
export function formatMessageAsEmbed(message: Message | PartialMessage, uploadLimit: number): { embed: EmbedBuilder, attach: Attachment | null } {
|
|
const embed = new EmbedBuilder()
|
|
.setTimestamp(message.createdTimestamp);
|
|
|
|
if (message.author) {
|
|
embed.setAuthor({
|
|
name: message.author.tag,
|
|
iconURL: message.author.displayAvatarURL(),
|
|
});
|
|
}
|
|
|
|
let attach = null;
|
|
|
|
message.embeds.forEach(em => {
|
|
if (em.image) {
|
|
embed.setImage(em.image.url);
|
|
} else if (em.thumbnail) {
|
|
embed.setImage(em.thumbnail.url);
|
|
}
|
|
if (em.provider) {
|
|
embed.addFields({
|
|
name: shortenStr(`${em.provider.name}:`, 256),
|
|
value: shortenStr(`${em.author}: **${em.title}**\n${em.description || ''}`, 2048),
|
|
});
|
|
} else if (!em.image) {
|
|
embed.addFields({
|
|
name: 'Embed:',
|
|
value: shortenStr(em.description || em.fields[0]?.value || em.title || 'Unknown content', 2048),
|
|
});
|
|
}
|
|
});
|
|
|
|
let msgEnd = null;
|
|
|
|
const first = message.attachments.first();
|
|
|
|
if (
|
|
message.attachments.size === 1 && first && first.contentType
|
|
&& !first.spoiler
|
|
&& (first.contentType?.startsWith('image/')
|
|
|| first.contentType?.startsWith('video/'))
|
|
&& (first.size <= uploadLimit)
|
|
) {
|
|
attach = first;
|
|
} else {
|
|
for (const attach of message.attachments.values()) {
|
|
msgEnd = (msgEnd || '\n') + `\n[${attach.name}](${attach.url})`;
|
|
}
|
|
}
|
|
|
|
if (message.content) {
|
|
if (!msgEnd) {
|
|
embed.setDescription(shortenStr(message.content, 4096));
|
|
} else {
|
|
embed.setDescription(shortenStr(message.content, 4096 - msgEnd.length) + msgEnd);
|
|
}
|
|
} else if (msgEnd) {
|
|
embed.setDescription('_Content unknown_' + msgEnd);
|
|
}
|
|
|
|
return { embed, attach };
|
|
} |