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 |
import {
type Ticket,
db,
type ticketAttachment,
ticketAttachments,
ticketMessages,
} from "@/database";
import { getPublicUrl } from "@/utils/s3";
import { asc, eq } from "drizzle-orm";
export async function generateTranscript(
ticket: Ticket,
): Promise<[string, ticketAttachment[]]> {
const messages = await db
.select()
.from(ticketMessages)
.where(eq(ticketMessages.ticketId, ticket.id))
.orderBy(asc(ticketMessages.createdAt));
const attachments = await db
.select()
.from(ticketAttachments)
.where(eq(ticketAttachments.ticketId, ticket.id));
const attachmentMap = new Map<number, typeof attachments>();
for (const att of attachments) {
const existing = attachmentMap.get(att.messageId ?? 0) ?? [];
attachmentMap.set(att.messageId ?? 0, [...existing, att]);
}
const lines = messages.map((msg) => {
const msgAttachments = attachmentMap.get(msg.id) ?? [];
const time = new Date(msg.createdAt).toISOString();
const author =
msg.authorType === "user" ? "reporter" : `<@${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"), attachments];
}
|