fixed up a few commands
diff --git a/src/actions/createModActionTicket.ts b/src/actions/createModActionTicket.ts
index 61a94ba..bdc5e07 100644
--- a/src/actions/createModActionTicket.ts
+++ b/src/actions/createModActionTicket.ts
@@ -1,3 +1,4 @@
+import { getCommandMentionByName } from './../utils/getCommandMentionByName.js';
 import Discord, { ActionRowBuilder, ButtonBuilder, OverwriteType, ChannelType, ButtonStyle } from "discord.js";
 import EmojiEmbed from "../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../utils/getEmojiByName.js";
@@ -62,7 +63,7 @@
                             `**Support type:** ${customReason ? customReason : "Appeal submission"}\n` +
                             (reason !== null ? `**Reason:**\n> ${reason}\n` : "") +
                             `**Ticket ID:** \`${c.id}\`\n` +
-                            "Type `/ticket close` to close this ticket."
+                            `Type ${getCommandMentionByName("ticket/close")} to close this ticket.`
                     )
                     .setStatus("Success")
                     .setEmoji("GUILD.TICKET.OPEN")
diff --git a/src/actions/tickets/delete.ts b/src/actions/tickets/delete.ts
index 48d2a51..3263580 100644
--- a/src/actions/tickets/delete.ts
+++ b/src/actions/tickets/delete.ts
@@ -1,5 +1,5 @@
 import { getCommandMentionByName } from '../../utils/getCommandMentionByName.js';
-import Discord, { ActionRowBuilder, ButtonBuilder, ButtonInteraction, PrivateThreadChannel, TextChannel, ButtonStyle } from "discord.js";
+import Discord, { ActionRowBuilder, ButtonBuilder, ButtonInteraction, PrivateThreadChannel, TextChannel, ButtonStyle, CategoryChannel } from "discord.js";
 import client from "../../utils/client.js";
 import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -142,47 +142,60 @@
 
 
 async function purgeByUser(member: string, guild: string) {
-    const config = await client.database.guilds.read(guild.id);
+    const config = await client.database.guilds.read(guild);
     const fetchedGuild = await client.guilds.fetch(guild);
     if (!config.tickets.category) return;
-    const tickets = fetchedGuild.channels.cache.get(config.tickets.category);
+    const tickets: CategoryChannel | TextChannel | undefined = fetchedGuild.channels.cache.get(config.tickets.category) as CategoryChannel | TextChannel | undefined;
     if (!tickets) return;
-    const ticketChannels = tickets.children;
     let deleted = 0;
-    ticketChannels.forEach((element) => {
-        if (element.type !== "GUILD_TEXT") return;
-        if (element.topic.split(" ")[0] === member) {
+    if (tickets.type === Discord.ChannelType.GuildCategory) {
+        // For channels, the topic is the user ID, then the word Active
+        const category = tickets as Discord.CategoryChannel;
+        category.children.cache.forEach((element) => {
+            if (!(element.type === Discord.ChannelType.GuildText)) return;
+            if (!(((element as Discord.TextChannel).topic ?? "").includes(member))) return;
             try {
                 element.delete();
-            } catch {
-                /* Errors if the channel does not exist (deleted already) */
+                deleted++;
+            } catch (e) {
+                console.error(e);
             }
-            deleted++;
-        }
-    });
-    if (deleted) {
-        const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger;
-        const data = {
-            meta: {
-                type: "ticketPurge",
-                displayName: "Tickets Purged",
-                calculateType: "ticketUpdate",
-                color: NucleusColors.red,
-                emoji: "GUILD.TICKET.DELETE",
-                timestamp: new Date().getTime()
-            },
-            list: {
-                ticketFor: entry(member, renderUser(member)),
-                deletedBy: entry(null, "Member left server"),
-                deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
-                ticketsDeleted: deleted
-            },
-            hidden: {
-                guild: guild.id
+        });
+    } else {
+        // For threads, the name is the users name, id, then the word Active
+        const channel = tickets as Discord.TextChannel;
+        channel.threads.cache.forEach((element: Discord.ThreadChannel) => {
+            if (!element.name.includes(member)) return;
+            try {
+                element.delete();
+                deleted++;
+            } catch (e) {
+                console.error(e);
             }
-        };
-        log(data);
+        });
     }
+    if (!deleted) return
+    const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+    const data = {
+        meta: {
+            type: "ticketPurge",
+            displayName: "Tickets Purged",
+            calculateType: "ticketUpdate",
+            color: NucleusColors.red,
+            emoji: "GUILD.TICKET.DELETE",
+            timestamp: new Date().getTime()
+        },
+        list: {
+            ticketFor: entry(member, renderUser(member)),
+            deletedBy: entry(null, "Member left server"),
+            deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+            ticketsDeleted: deleted
+        },
+        hidden: {
+            guild: guild
+        }
+    };
+    log(data);
 }
 
 export { purgeByUser };
\ No newline at end of file
diff --git a/src/commands/mod/ban.ts b/src/commands/mod/ban.ts
index 18b6c7e..70e904c 100644
--- a/src/commands/mod/ban.ts
+++ b/src/commands/mod/ban.ts
@@ -97,7 +97,7 @@
                         .addComponents(new ButtonBuilder()
                             .setStyle(ButtonStyle.Link)
                             .setLabel(config.moderation.ban.text)
-                            .setURL(config.moderation.ban.link)
+                            .setURL(config.moderation.ban.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
                         )
                 )
             }
diff --git a/src/commands/mod/kick.ts b/src/commands/mod/kick.ts
index bdbb9ee..380bcc9 100644
--- a/src/commands/mod/kick.ts
+++ b/src/commands/mod/kick.ts
@@ -86,7 +86,7 @@
                         .addComponents(new ButtonBuilder()
                             .setStyle(ButtonStyle.Link)
                             .setLabel(config.moderation.kick.text)
-                            .setURL(config.moderation.kick.link)
+                            .setURL(config.moderation.kick.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
                         )
                 )
             }
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index 3270d37..86291e5 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -252,7 +252,7 @@
                     .addComponents(new ButtonBuilder()
                         .setStyle(ButtonStyle.Link)
                         .setLabel(config.moderation.mute.text)
-                        .setURL(config.moderation.mute.link)
+                        .setURL(config.moderation.mute.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
                     )
                 )
             };
diff --git a/src/commands/mod/softban.ts b/src/commands/mod/softban.ts
index 35f275f..2787e91 100644
--- a/src/commands/mod/softban.ts
+++ b/src/commands/mod/softban.ts
@@ -97,7 +97,7 @@
                         .addComponents(new ButtonBuilder()
                             .setStyle(ButtonStyle.Link)
                             .setLabel(config.moderation.softban.text)
-                            .setURL(config.moderation.softban.link)
+                            .setURL(config.moderation.softban.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
                         )
                 )
             }
diff --git a/src/commands/mod/warn.ts b/src/commands/mod/warn.ts
index 93241e1..8e96078 100644
--- a/src/commands/mod/warn.ts
+++ b/src/commands/mod/warn.ts
@@ -99,7 +99,7 @@
                         .addComponents(new ButtonBuilder()
                             .setStyle(ButtonStyle.Link)
                             .setLabel(config.moderation.warn.text)
-                            .setURL(config.moderation.warn.link)
+                            .setURL(config.moderation.warn.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
                         )
                 )
             }
diff --git a/src/commands/settings/commands.ts b/src/commands/settings/commands.ts
index ac2cd81..25034b2 100644
--- a/src/commands/settings/commands.ts
+++ b/src/commands/settings/commands.ts
@@ -1,5 +1,5 @@
 import { LoadingEmbed } from "../../utils/defaults.js";
-import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, TextInputComponent, Role, ButtonStyle, ButtonComponent, TextInputBuilder } from "discord.js";
+import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, Role, ButtonStyle, ButtonComponent, TextInputBuilder } from "discord.js";
 import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
 import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -43,7 +43,7 @@
     let timedOut = false;
     while (!timedOut) {
         const config = await client.database.guilds.read(interaction.guild!.id);
-        const moderation = config["moderation"];
+        const moderation = config.moderation;
         m = await interaction.editReply({
             embeds: [
                 new EmojiEmbed()
@@ -117,7 +117,7 @@
             continue;
         }
         type modIDs = "mute" | "kick" | "ban" | "softban" | "warn" | "role";
-        let chosen = moderation[i.customId as modIDs] ?? { text: null, url: null };
+        let chosen = moderation[i.customId as modIDs];
         if ((i.component as ButtonComponent).customId === "clearMuteRole") {
             i.deferUpdate();
             if (clicked === "clearMuteRole") {
@@ -181,31 +181,28 @@
                     ])
                 ]
             });
-            let out: Discord.ModalSubmitInteraction;
+            let out: Discord.ModalSubmitInteraction | null;
             try {
                 out = await modalInteractionCollector(
                     m,
                     (m) => m.channel!.id === interaction.channel!.id,
                     (_) => true
-                ) as Discord.ModalSubmitInteraction;
+                ) as Discord.ModalSubmitInteraction | null;
             } catch (e) {
                 continue;
             }
-            if ((out!).fields) {
-                const buttonText = out.fields.getTextInputValue("name");
-                const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
-                const current = chosen;
-                if (current.text !== buttonText || current.link !== buttonLink) {
-                    chosen = { text: buttonText, link: buttonLink };
-                    await client.database.guilds.write(interaction.guild!.id, {
-                        ["moderation." + i.customId]: {
-                            text: buttonText,
-                            link: buttonLink
-                        }
-                    });
-                }
-            } else {
-                continue;
+            if (!out) continue
+            const buttonText = out.fields.getTextInputValue("name");
+            const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
+            const current = chosen;
+            if (current.text !== buttonText || current.link !== buttonLink) {
+                chosen = { text: buttonText, link: buttonLink };
+                await client.database.guilds.write(interaction.guild!.id, {
+                    ["moderation." + i.customId]: {
+                        text: buttonText,
+                        link: buttonLink
+                    }
+                });
             }
         }
     }
diff --git a/src/commands/settings/stats.ts b/src/commands/settings/stats.ts
index b840fb0..cdd218b 100644
--- a/src/commands/settings/stats.ts
+++ b/src/commands/settings/stats.ts
@@ -20,7 +20,8 @@
                 .setAutocomplete(true)
         );
 
-const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+const callback = async (interaction: CommandInteraction): Promise<unknown> => {  // TODO: This command feels unintuitive. Clicking a channel in the select menu deletes it
+    // instead, it should give a submenu to edit the channel, enable/disable or delete it
     singleNotify("statsChannelDeleted", interaction.guild!.id, true);
     const m = (await interaction.reply({
         embeds: LoadingEmbed,
@@ -30,7 +31,7 @@
     let config = await client.database.guilds.read(interaction.guild!.id);
     if (interaction.options.get("name")?.value as string) {
         let channel;
-        if (Object.keys(config["stats"]).length >= 25) {
+        if (Object.keys(config.stats).length >= 25) {
             return await interaction.editReply({
                 embeds: [
                     new EmojiEmbed()
@@ -151,7 +152,7 @@
     let timedOut = false;
     while (!timedOut) {
         config = await client.database.guilds.read(interaction.guild!.id);
-        const stats = config["stats"];
+        const stats = config.stats;
         const selectMenu = new StringSelectMenuBuilder()
             .setCustomId("remove")
             .setMinValues(1)
diff --git a/src/config/emojis.json b/src/config/emojis.json
index 4bdadee..26d4c98 100644
--- a/src/config/emojis.json
+++ b/src/config/emojis.json
@@ -82,10 +82,6 @@
             "EDIT": "951957316071223336",
             "DELETE": "729064530981683200"
         },
-        "STORE": {
-            "CREATE": "729064530709315715",
-            "DELETE": "729064530768035922"
-        },
         "CATEGORY": {
             "CREATE": "787987508465238026",
             "EDIT": "787987508565770300",
diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts
index 2c48b02..4780700 100644
--- a/src/events/channelDelete.ts
+++ b/src/events/channelDelete.ts
@@ -1,5 +1,7 @@
 import {
+    AuditLogEvent,
     BaseGuildTextChannel,
+    ChannelType,
     GuildAuditLogsEntry,
     GuildBasedChannel,
     StageChannel,
@@ -13,34 +15,47 @@
 
 export async function callback(client: NucleusClient, channel: GuildBasedChannel) {
     const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
-
-    const auditLog = await getAuditLog(channel.guild, "CHANNEL_DELETE");
-    const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === channel.id).first();
-    if (audit.executor.id === client.user.id) return;
+    // const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === channel.id).first();
+    const auditLog = (await getAuditLog(channel.guild, AuditLogEvent.ChannelDelete))
+        .filter((entry: GuildAuditLogsEntry) => (entry.target as GuildBasedChannel)!.id === channel.id)[0];
+    if (!auditLog) return;
+    if (auditLog.executor!.id === client.user!.id) return;
 
     let emoji;
     let readableType;
     let displayName;
     switch (channel.type) {
-        case "GUILD_TEXT": {
+        case ChannelType.GuildText: {
             emoji = "CHANNEL.TEXT.DELETE";
             readableType = "Text";
             displayName = "Text Channel";
             break;
-        }
-        case "GUILD_VOICE": {
+        } case ChannelType.GuildAnnouncement: {
+            emoji = "CHANNEL.TEXT.DELETE";
+            readableType = "Announcement";
+            displayName = "Announcement Channel";
+            break;
+        } case ChannelType.GuildVoice: {
             emoji = "CHANNEL.VOICE.DELETE";
             readableType = "Voice";
             displayName = "Voice Channel";
             break;
-        }
-        case "GUILD_CATEGORY": {
+        } case ChannelType.GuildCategory: {
             emoji = "CHANNEL.CATEGORY.DELETE";
             readableType = "Category";
             displayName = "Category";
             break;
-        }
-        default: {
+        } case ChannelType.GuildStageVoice: {
+            emoji = "CHANNEL.VOICE.DELETE";
+            readableType = "Stage";
+            displayName = "Stage Channel";
+            break;
+        } case ChannelType.GuildForum: {
+            emoji = "CHANNEL.TEXT.DELETE";
+            readableType = "Forum";
+            displayName = "Forum Channel";
+            break;
+        } default: {
             emoji = "CHANNEL.TEXT.DELETE";
             readableType = "Channel";
             displayName = "Channel";
@@ -66,9 +81,9 @@
             channel.parent ? channel.parent.name : "Uncategorised"
         ),
         nsfw: null,
-        created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp)),
+        created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp!)),
         deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
-        deletedBy: entry(audit.executor.id, renderUser(audit.executor))
+        deletedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
     };
     if ((channel instanceof BaseGuildTextChannel || channel instanceof StageChannel) && channel.topic !== null)
         list.topic = entry(channel.topic, `\`\`\`\n${channel.topic.replace("`", "'")}\n\`\`\``);
@@ -94,7 +109,7 @@
             calculateType: "channelUpdate",
             color: NucleusColors.red,
             emoji: emoji,
-            timestamp: audit.createdTimestamp
+            timestamp: auditLog.createdTimestamp
         },
         list: list,
         hidden: {
diff --git a/src/events/commandError.ts b/src/events/commandError.ts
index ce50122..8ed01d2 100644
--- a/src/events/commandError.ts
+++ b/src/events/commandError.ts
@@ -1,14 +1,17 @@
+import type { ButtonInteraction, ContextMenuCommandInteraction } from 'discord.js';
+import type { CommandInteraction } from 'discord.js';
+import type { NucleusClient } from "../utils/client.js";
 import EmojiEmbed from "../utils/generateEmojiEmbed.js";
 
 export const event = "commandError";
 
-export async function callback(client, interaction, error) {
+export async function callback(_: NucleusClient, interaction: CommandInteraction | ButtonInteraction | ContextMenuCommandInteraction, error: string) {
     if (interaction.replied || interaction.deferred) {
         await interaction.followUp({
             embeds: [
                 new EmojiEmbed()
                     .setTitle("Something went wrong")
-                    .setDescription(error.message ?? error.toString())
+                    .setDescription(error)
                     .setStatus("Danger")
                     .setEmoji("CONTROL.BLOCKCROSS")
             ],
@@ -19,7 +22,7 @@
             embeds: [
                 new EmojiEmbed()
                     .setTitle("Something went wrong")
-                    .setDescription(error.message ?? error.toString())
+                    .setDescription(error)
                     .setStatus("Danger")
                     .setEmoji("CONTROL.BLOCKCROSS")
             ],
diff --git a/src/utils/log.ts b/src/utils/log.ts
index 3f46f86..4565251 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -25,7 +25,7 @@
         const delta = num2 - num1;
         return `${num1} -> ${num2} (${delta > 0 ? "+" : ""}${delta})`;
     },
-    entry(value: string | number | null, displayValue: string): { value: string | null; displayValue: string } {
+    entry(value: string | number | boolean | null, displayValue: string): { value: string | boolean | null; displayValue: string } {
         if (typeof value === "number") value = value.toString();
         return { value: value, displayValue: displayValue };
     },
diff --git a/tsconfig.json b/tsconfig.json
index 6bb1cff..a39c584 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -14,5 +14,5 @@
         "noImplicitReturns": false
     },
     "include": ["src/**/*"],
-    "exclude": []
+    "exclude": ["src/Unfinished/**/*"]
 }