yees

Co-authored-by: PineappleFan <PineaFan@users.noreply.github.com>
Co-authored-by: Skyler <skyler3665@gmail.com>
diff --git a/src/utils/client.ts b/src/utils/client.ts
index 857fb1d..00f8c05 100644
--- a/src/utils/client.ts
+++ b/src/utils/client.ts
@@ -2,7 +2,7 @@
 import { Logger } from "../utils/log.js";
 import Memory from "../utils/memory.js";
 import type { VerifySchema } from "../reflex/verify.js";
-import { Guilds, History, ModNotes, Premium, PerformanceTest, ScanCache } from "../utils/database.js";
+import { Guilds, History, ModNotes, Premium, PerformanceTest, ScanCache, Transcript } from "../utils/database.js";
 import EventScheduler from "../utils/eventScheduler.js";
 import type { RoleMenuSchema } from "../actions/roleMenu.js";
 import config from "../config/main.js";
@@ -23,6 +23,7 @@
         eventScheduler: EventScheduler;
         performanceTest: PerformanceTest;
         scanCache: ScanCache;
+        transcripts: Transcript
     };
     preloadPage: Record<string, {command: string, argument: string}> = {};  // e.g. { channelID: { command: privacy, page: 3}}
     commands: Record<string, [{
@@ -46,7 +47,8 @@
     premium: new Premium(),
     eventScheduler: new EventScheduler(),
     performanceTest: new PerformanceTest(),
-    scanCache: new ScanCache()
+    scanCache: new ScanCache(),
+    transcripts: new Transcript()
 });
 
 export default client;
diff --git a/src/utils/database.ts b/src/utils/database.ts
index 48d0077..7e80f96 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -1,4 +1,4 @@
-import type { GuildMember } from "discord.js";
+import type { ButtonStyle, GuildMember } from "discord.js";
 import type Discord from "discord.js";
 import { Collection, MongoClient } from "mongodb";
 import config from "../config/main.js";
@@ -101,6 +101,96 @@
     }
 }
 
+interface TranscriptEmbed {
+    title?: string;
+    description?: string;
+    fields?: {
+        name: string;
+        value: string;
+        inline: boolean;
+    }[];
+    footer?: {
+        text: string;
+        iconURL?: string;
+    };
+}
+
+interface TranscriptComponent {
+    type: number;
+    style?: ButtonStyle;
+    label?: string;
+    description?: string;
+    placeholder?: string;
+    emojiURL?: string;
+}
+
+interface TranscriptAuthor {
+    username: string;
+    discriminator: number;
+    nickname?: string;
+    id: string;
+    iconURL?: string;
+    topRole: {
+        color: number;
+        badgeURL?: string;
+    }
+}
+
+interface TranscriptAttachment {
+    url: string;
+    filename: string;
+    size: number;
+    log?: string;
+}
+
+interface TranscriptMessage {
+    id: string;
+    author: TranscriptAuthor;
+    content?: string;
+    embeds?: TranscriptEmbed[];
+    components?: TranscriptComponent[][];
+    editedTimestamp?: number;
+    createdTimestamp: number;
+    flags?: string[];
+    attachments?: TranscriptAttachment[];
+    stickerURLs?: string[];
+    referencedMessage?: string | [string, string, string];
+}
+
+interface TranscriptSchema {
+    code: string;
+    for: TranscriptAuthor;
+    type: "ticket" | "purge"
+    guild: string;
+    channel: string;
+    messages: TranscriptMessage[];
+    createdTimestamp: number;
+    createdBy: TranscriptAuthor;
+}
+
+export class Transcript {
+    transcripts: Collection<TranscriptSchema>;
+
+    constructor() {
+        this.transcripts = database.collection<TranscriptSchema>("transcripts");
+    }
+
+    async create(transcript: Omit<TranscriptSchema, "code">) {
+        let code;
+        do {
+            code = Math.random().toString(36).substring(2, 16) + Math.random().toString(36).substring(2, 16);
+        } while (await this.transcripts.findOne({ code: code }));
+
+        const doc = await this.transcripts.insertOne(Object.assign(transcript, { code: code }));
+        if(doc.acknowledged) return code;
+        else return null;
+    }
+
+    async read(code: string) {
+        return await this.transcripts.findOne({ code: code });
+    }
+}
+
 export class History {
     histories: Collection<HistorySchema>;