all repos — stealth-developers @ ffa2c91027d77bb42b875d24dd139172e61aa2c3

src/utils/transcripts.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
import {
	type Attachment,
	type Ticket,
	attachments,
	db,
	ticketMessages,
} from "@/database";
import { getPublicUrl } from "@/utils/s3";
import { and, asc, eq } from "drizzle-orm";

export async function generateTranscript(
	ticket: Ticket,
): Promise<[string, Attachment[]]> {
	const messages = await db
		.select()
		.from(ticketMessages)
		.where(eq(ticketMessages.ticketId, ticket.id))
		.orderBy(asc(ticketMessages.createdAt));

	const messageIds = messages.map((m) => m.id);

	const ticketAttachments = await db
		.select()
		.from(attachments)
		.where(and(eq(attachments.ownerType, "ticket_message")));

	const relevantAttachments = ticketAttachments.filter((att) =>
		messageIds.includes(att.ownerId),
	);

	const attachmentMap = new Map<number, Attachment[]>();
	for (const att of relevantAttachments) {
		const existing = attachmentMap.get(att.ownerId) ?? [];
		attachmentMap.set(att.ownerId, [...existing, att]);
	}

	const lines = messages.map((msg) => {
		const msgAttachments = attachmentMap.get(msg.id) ?? [];
		const time = new Date(msg.createdAt).toISOString();

		let author = "reporter";
		if (msg.authorType === "system") author = "system";
		if (msg.authorType === "staff") author = `<@${msg.authorId}>`;

		let text = `[${time}] ${author}: ${msg.content}`;

		if (msgAttachments.length > 0) {
			const attLines = msgAttachments
				.map((att) => {
					return `\n    (Attachment) ${att.fileName}: ${getPublicUrl(att.key)}`;
				})
				.join("");
			text += attLines;
		}

		return text;
	});

	const separator = "==================================================";
	const header = [
		separator,
		` TRANSCRIPT FOR TICKET #${ticket.anonymousId}`,
		` CREATED : ${new Date(ticket.createdAt).toISOString()}`,
		` CLOSED  : ${ticket.closedAt ? new Date(ticket.closedAt).toISOString() : new Date().toISOString()}`,
		"",
		" Times are displayed in UTC.",
		" All attachments are listed with their public URLs.",
		separator,
		"\n",
	].join("\n");

	return [header + lines.join("\n"), relevantAttachments];
}