stats channels
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index da10cfb..988fd37 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -3,20 +3,24 @@
 import EmojiEmbed from "./generateEmojiEmbed.js"
 import getEmojiByName from "./getEmojiByName.js";
 
+
+interface CustomBoolean<T> {
+    title: string;
+    disabled: boolean;
+    value: string | null;
+    emoji: string | null;
+    active: boolean;
+    onClick: () => Promise<T>;
+    response: T | null;
+}
+
 class confirmationMessage {
     interaction: CommandInteraction;
     title: string = "";
     emoji: string = "";
     description: string = "";
     color: string = "";
-    customCallback: () => any = () => {};
-    customButtonTitle: string;
-    customButtonDisabled: boolean;
-    customCallbackString: string = "";
-    customCallbackClicked: boolean = false;
-    customCallbackResponse: any = null;
-    customBoolean: () => any = () => {}; // allow multiple booleans
-    customBooleanClicked: boolean = null;
+    customButtons: {[index:string]: CustomBoolean<unknown>} = {};
     inverted: boolean = false;
     reason: string | null = null;
 
@@ -29,21 +33,15 @@
     setDescription(description: string) { this.description = description; return this }
     setColor(color: string) { this.color = color; return this }
     setInverted(inverted: boolean) { this.inverted = inverted; return this }
-    addCustomCallback(title: string, disabled: boolean, callback: () => any, callbackClicked: string) {
-        if (this.customButtonTitle) return this
-        this.customButtonTitle = title;
-        this.customButtonDisabled = disabled;
-        this.customCallback = callback;
-        this.customCallbackString = callbackClicked;
-        return this;
-    }
-    addCustomBoolean(title: string, disabled: boolean, callback: () => any, callbackClicked: string) {
-        if (this.customButtonTitle) return this
-        this.customButtonTitle = title;
-        this.customButtonDisabled = disabled;
-        this.customBoolean = callback;
-        this.customCallbackString = callbackClicked;
-        this.customBooleanClicked = false;
+    addCustomBoolean(customId: string, title: string, disabled: boolean, callback: () => Promise<unknown> | null, callbackClicked: string | null, emoji?: string, initial?: boolean) {        this.customButtons[customId] = {
+            title: title,
+            disabled: disabled,
+            value: callbackClicked,
+            emoji: emoji,
+            active: initial ?? false,
+            onClick: callback ?? (() => null),
+            response: null,
+        }
         return this;
     }
     addReasonButton(reason: string) {
@@ -52,92 +50,80 @@
     }
     async send(editOnly?: boolean) {
         while (true) {
+            let fullComponents = [
+                new Discord.MessageButton()
+                    .setCustomId("yes")
+                    .setLabel("Confirm")
+                    .setStyle(this.inverted ? "SUCCESS" : "DANGER")
+                    .setEmoji(getEmojiByName("CONTROL.TICK", "id")),
+                new Discord.MessageButton()
+                    .setCustomId("no")
+                    .setLabel("Cancel")
+                    .setStyle("SECONDARY")
+                    .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+            ]
+            Object.entries(this.customButtons).forEach(([k, v]) => {
+                fullComponents.push(new Discord.MessageButton()
+                    .setCustomId(k)
+                    .setLabel(v.title)
+                    .setStyle(v.active ? "SUCCESS" : "PRIMARY")
+                    .setEmoji(getEmojiByName(v.emoji, "id"))
+                    .setDisabled(v.disabled))
+            })
+            if (this.reason !== null) fullComponents.push(new Discord.MessageButton()
+                .setCustomId("reason")
+                .setLabel(`Edit Reason`)
+                .setStyle("PRIMARY")
+                .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
+                .setDisabled(false)
+            )
+            let components = []
+            for (let i = 0; i < fullComponents.length; i += 5) {
+                components.push(new MessageActionRow().addComponents(fullComponents.slice(i, i + 5)));
+            }
             let object = {
                 embeds: [
                     new EmojiEmbed()
                         .setEmoji(this.emoji)
                         .setTitle(this.title)
-                        .setDescription(this.description)
+                        .setDescription(this.description + "\n\n" + Object.values(this.customButtons).map(v => {
+                            if (v.value === null) return "";
+                            return v.active ? `*${v.value}*\n` : "";
+                        }).join(""))
                         .setStatus(this.color)
-                        .setFooter({text: (this.customBooleanClicked ?? this.customCallbackClicked) ? this.customCallbackString : ""})
                 ],
-                components: [
-                    new MessageActionRow().addComponents([
-                        new Discord.MessageButton()
-                            .setCustomId("yes")
-                            .setLabel("Confirm")
-                            .setStyle(this.inverted ? "SUCCESS" : "DANGER")
-                            .setEmoji(getEmojiByName("CONTROL.TICK", "id")),
-                        new Discord.MessageButton()
-                            .setCustomId("no")
-                            .setLabel("Cancel")
-                            .setStyle("SECONDARY")
-                            .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
-                    ].concat(this.customButtonTitle ? [new Discord.MessageButton()
-                        .setCustomId("custom")
-                        .setLabel(this.customButtonTitle)
-                        .setStyle(this.customBooleanClicked !== null ?
-                            ( this.customBooleanClicked ? "SUCCESS" : "PRIMARY" ) :
-                            "PRIMARY"
-                        )
-                        .setDisabled(this.customButtonDisabled)
-                        .setEmoji(getEmojiByName("CONTROL.TICKET", "id"))
-                    ] : [])
-                    .concat(this.reason !== null ? [new Discord.MessageButton()
-                        .setCustomId("reason")
-                        .setLabel(`Edit Reason`)
-                        .setStyle("PRIMARY")
-                        .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
-                    ] : []))
-                ],
+                components: components,
                 ephemeral: true,
                 fetchReply: true
             }
             let m;
-            if ( editOnly ) {
-                m = await this.interaction.editReply(object);
-            } else {
-                m = await this.interaction.reply(object)
-            }
+            try {
+                if ( editOnly ) {
+                    m = await this.interaction.editReply(object);
+                } else {
+                    m = await this.interaction.reply(object)
+                }
+            } catch { return { cancelled: true } }
             let component;
             try {
                 component = await (m as Message).awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 300000});
             } catch (e) {
-                return {
-                    success: false,
-                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
-                    response: this.customCallbackResponse
-                };
+                return { success: false, components: this.customButtons };
             }
             if (component.customId === "yes") {
                 component.deferUpdate();
-                if (this.customBooleanClicked === true) this.customCallbackResponse = await this.customBoolean();
-                return {
-                    success: true,
-                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
-                    response: this.customCallbackResponse
+                for (let [k, v] of Object.entries(this.customButtons)) {
+                    if (!v.active) continue
+                    try { v.response = await v.onClick(); }
+                    catch (e) { console.log(e) }
                 };
+                return { success: true, components: this.customButtons };
             } else if (component.customId === "no") {
                 component.deferUpdate();
-                return {
-                    success: false,
-                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
-                    response: this.customCallbackResponse
-                };
-            } else if (component.customId === "custom") {
-                component.deferUpdate();
-                if (this.customBooleanClicked !== null) {
-                    this.customBooleanClicked = !this.customBooleanClicked;
-                } else {
-                    this.customCallbackResponse = await this.customCallback();
-                    this.customCallbackClicked = true;
-                    this.customButtonDisabled = true;
-                }
-                editOnly = true;
+                return { success: false, components: this.customButtons };
             } else if (component.customId === "reason") {
                 await component.showModal(new Discord.Modal().setCustomId("modal").setTitle(`Editing reason`).addComponents(
-                    // @ts-ignore
-                    new MessageActionRow().addComponents(new TextInputComponent()
+                    new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
                         .setCustomId("reason")
                         .setLabel("Reason")
                         .setMaxLength(2000)
@@ -163,10 +149,13 @@
                 let out;
                 try {
                     out = await modalInteractionCollector(m, (m) => m.channel.id == this.interaction.channel.id, (m) => m.customId == "reason")
-                } catch (e) { continue }
-                if (out.fields) {
-                    return {newReason: out.fields.getTextInputValue("reason") ?? ""};
-                } else { return { newReason: this.reason } }
+                } catch (e) { return {} }
+                if (out.fields) { return { newReason: out.fields.getTextInputValue("reason") ?? "" }; }
+                else { return { newReason: this.reason } }
+            } else {
+                component.deferUpdate();
+                this.customButtons[component.customId].active = !this.customButtons[component.customId].active;
+                return { components: this.customButtons };
             }
         }
     }
diff --git a/src/utils/convertCurlyBracketString.ts b/src/utils/convertCurlyBracketString.ts
index 0277751..6ffdc8f 100644
--- a/src/utils/convertCurlyBracketString.ts
+++ b/src/utils/convertCurlyBracketString.ts
@@ -2,12 +2,12 @@
     let memberCount = (await members.fetch()).size
     let bots = (await members.fetch()).filter(m => m.user.bot).size
     str = str
-        .replace("{@}", `<@${memberID}>`)
-        .replace("{server}", `${serverName}`)
-        .replace("{name}", `${memberName}`)
-        .replace("{count}", `${memberCount}`)
-        .replace("{count:bots}", `${bots}`)
-        .replace("{count:humans}", `${memberCount - bots}`);
+        .replace("{member:mention}", memberID ? `<@${memberID}>` : "{member:mention}")
+        .replace("{member:name}", memberName ? `${memberName}` : "{member:name}")
+        .replace("{serverName}", serverName ? `${serverName}` : "{serverName}")
+        .replace("{memberCount}", memberCount ? `${memberCount}` : "{memberCount}")
+        .replace("{memberCount:bots}", bots ? `${bots}` : "{memberCount:bots}")
+        .replace("{memberCount:humans}", (memberCount && bots) ? `${memberCount - bots}` : "{memberCount:humans}");
 
     return str
 }
diff --git a/src/utils/database.ts b/src/utils/database.ts
index c0ae9be..5b1d6d9 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -63,8 +63,13 @@
         }
     }
 
-    async remove(guild: string, key: string, value: any) {
-        if (Array.isArray(value)) {
+    async remove(guild: string, key: string, value: any, innerKey?: string) {
+        if (innerKey) {
+            await this.guilds.updateOne({ id: guild }, {
+                $pull: { [key]: { [innerKey]: { $eq: value } } }
+            }, { upsert: true });
+        }
+        else if (Array.isArray(value)) {
             await this.guilds.updateOne({ id: guild }, {
                 $pullAll: { [key]: value }
             }, { upsert: true });
@@ -200,11 +205,7 @@
         channel: string | null,
         message: string | null,
     }
-    stats: {
-        enabled: boolean,
-        channel: string | null,
-        text: string | null,
-    }[]
+    stats: {}
     logging: {
         logs: {
             enabled: boolean,