src/utils/tickets/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 74 75 76 77 78 |
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";
} else if (msg.authorType === "staff") {
author = `<@${msg.authorId}>`;
} else if (ticket.addedUsers?.includes(msg.authorId)) {
author = `Guest ${ticket.addedUsers.indexOf(msg.authorId) + 1}`;
}
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];
}
|