i have not committed in years
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index 7deb5f5..fc8b76c 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -1,5 +1,5 @@
 import Discord, { CommandInteraction, MessageActionRow, Message } from "discord.js";
-import EmojiEmbed from "./generateEmojiEmbed.js"
+import generateEmojiEmbed from "./generateEmojiEmbed.js"
 import getEmojiByName from "./getEmojiByName.js";
 
 class confirmationMessage {
@@ -8,6 +8,12 @@
     emoji: string;
     description: string;
     color: string;
+    customCallback: () => any;
+    customButtonTitle: string;
+    customButtonDisabled: boolean;
+    customCallbackString: string = "";
+    customCallbackClicked: boolean = false;
+    customCallbackResponse: any = null;
 
     constructor(interaction: CommandInteraction) {
         this.interaction = interaction;
@@ -16,54 +22,81 @@
         this.emoji = "";
         this.description = "";
         this.color = "";
+        this.customCallback = () => {}
     }
 
     setTitle(title: string) { this.title = title; return this }
     setEmoji(emoji: string) { this.emoji = emoji; return this }
     setDescription(description: string) { this.description = description; return this }
     setColor(color: string) { this.color = color; return this }
+    addCustomCallback(title: string, disabled: boolean, callback: () => any, callbackClicked: string) {
+        this.customButtonTitle = title;
+        this.customButtonDisabled = disabled;
+        this.customCallback = callback;
+        this.customCallbackString = callbackClicked;
+        return this;
+    }
 
     async send(editOnly?: boolean) {
-        let object = {
-            embeds: [
-                new EmojiEmbed()
-                    .setEmoji(this.emoji)
-                    .setTitle(this.title)
-                    .setDescription(this.description)
-                    .setStatus(this.color)
-            ],
-            components: [
-                new MessageActionRow().addComponents([
-                    new Discord.MessageButton()
-                        .setCustomId("yes")
-                        .setLabel("Yes")
-                        .setStyle("SUCCESS")
-                        .setEmoji(getEmojiByName("CONTROL.TICK", "id")),
-                    new Discord.MessageButton()
-                        .setCustomId("no")
-                        .setLabel("Cancel")
-                        .setStyle("DANGER")
-                        .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
-                ])
-            ],
-            ephemeral: true,
-            fetchReply: true
+        while (true) {
+            let object = {
+                embeds: [
+                    new generateEmojiEmbed()
+                        .setEmoji(this.emoji)
+                        .setTitle(this.title)
+                        .setDescription(this.description)
+                        .setStatus(this.color)
+                        .setFooter({text: this.customCallbackClicked ? this.customCallbackString : ""})
+                ],
+                components: [
+                    new MessageActionRow().addComponents([
+                        new Discord.MessageButton()
+                            .setCustomId("yes")
+                            .setLabel("Yes")
+                            .setStyle("SUCCESS")
+                            .setEmoji(getEmojiByName("CONTROL.TICK", "id")),
+                        new Discord.MessageButton()
+                            .setCustomId("no")
+                            .setLabel("Cancel")
+                            .setStyle("DANGER")
+                            .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+                    ].concat(this.customButtonTitle ? [new Discord.MessageButton()
+                        .setCustomId("custom")
+                        .setLabel(this.customButtonTitle)
+                        .setStyle("SECONDARY")
+                        .setDisabled(this.customButtonDisabled)
+                        .setEmoji(getEmojiByName("CONTROL.RIGHT", "id")) // TODO: add an emoji
+                    ] : []))
+                ],
+                ephemeral: true,
+                fetchReply: true
+            }
+            let m;
+            if ( editOnly ) {
+                m = await this.interaction.editReply(object);
+            } else {
+                m = await this.interaction.reply(object)
+            }
+            let component;
+            try {
+                component = await (m as Message).awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 2.5 * 60 * 1000});
+            } catch (e) {
+                return {success: false, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse};  // TODO: Check the type of the error; change the error message here
+            }
+            if (component.customId === "yes") {
+                component.deferUpdate();
+                return {success: true, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse};
+            } else if (component.customId === "no") {
+                component.deferUpdate();
+                return {success: false, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse};
+            } else if (component.customId === "custom") {
+                component.deferUpdate();
+                this.customCallbackResponse = this.customCallback();
+                this.customCallbackClicked = true;
+                this.customButtonDisabled = true;
+                editOnly = true;
+            }
         }
-        let m;
-        if ( editOnly ) {
-            m = await this.interaction.editReply(object);
-        } else {
-            m = await this.interaction.reply(object)
-        }
-        let component;
-        try {
-            component = await (m as Message).awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 2.5 * 60 * 1000});
-        } catch (e) {
-            return false;  // TODO: Check the type of the error; change the error message here
-        }
-        component.deferUpdate();
-
-        return component.customId === "yes"
     }
 }
 
diff --git a/src/utils/generateKeyValueList.ts b/src/utils/generateKeyValueList.ts
index b3e276f..c9eb0c8 100644
--- a/src/utils/generateKeyValueList.ts
+++ b/src/utils/generateKeyValueList.ts
@@ -5,7 +5,14 @@
 
 export function capitalize(s: string) {
     s = s.replace(/([A-Z])/g, ' $1');
-    return forceCaps.includes(s.toUpperCase()) ? s.toUpperCase() : s[0].toUpperCase() + s.slice(1).toLowerCase();
+    return forceCaps.includes(s.toUpperCase()) ? s.toUpperCase() : s[0]
+        .toUpperCase() + s.slice(1)
+        .toLowerCase()
+        .replace("discord", "Discord");
+}
+
+export function toCapitals(s: string) {
+    return s[0].toUpperCase() + s.slice(1).toLowerCase();
 }
 
 function keyValueList(data) {
diff --git a/src/utils/getEmojiByName.ts b/src/utils/getEmojiByName.ts
index bbc8f24..80410df 100644
--- a/src/utils/getEmojiByName.ts
+++ b/src/utils/getEmojiByName.ts
@@ -11,11 +11,11 @@
         return id.toString();
     }
     if (id === undefined) {
-        return `<a:a:946346549271732234>`
+        return `<a:_:946346549271732234>`
     } else if (id.toString().startsWith("a")) {
-        return `<a:a:${id.toString().slice(1, id.toString().length)}>`
+        return `<a:_:${id.toString().slice(1, id.toString().length)}>`
     }
-    return `<:a:${id}>`;
+    return `<:_:${id}>`;
 }
 
 export default getEmojiByName;
diff --git a/src/utils/log.ts b/src/utils/log.ts
index d807831..14e9750 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -10,7 +10,8 @@
 
 
 export class Logger {
-	renderUser(user: Discord.User) {
+	renderUser(user: Discord.User | string) {
+		if (typeof user == 'string') return `${user} [<@${user}>]`;
 		return `${user.username} [<@${user.id}>]`;
 	}
 	renderTime(t: number) {
@@ -45,7 +46,6 @@
 
 	}
 
-
 	async getAuditLog(guild: Discord.Guild, event) {
 		await wait(250)
 		let auditLog = await guild.fetchAuditLogs({type: event});
diff --git a/src/utils/readConfig.ts b/src/utils/readConfig.ts
index c53d2cc..fb6835b 100644
--- a/src/utils/readConfig.ts
+++ b/src/utils/readConfig.ts
@@ -1,85 +1,165 @@
 
 export default async function readConfig(guild: string): Promise<any> {
 
-	let config = {
-		filters: {
-			images: {
-				NSFW: true,
-				size: true
-			},
-			malware: true,
-			wordFilter: {
-				enabled: true,
-				words: {
-					strict: [],
-					loose: []
-				},
-				allowed: {
-					users: [],
-					roles: [],
-					channels: []
-				}
-			},
-			invite: {
-				enabled: false,
-				allowed: {
-					users: [],
-					channels: [],
-					roles: []
-				}
-			},
-			pings: {
-				mass: 5,
-				everyone: true,
-				roles: true,
-				allowed: {
-					roles: [],
-					rolesToMention: [],
-					users: [],
-					channels: []
-				}
-			}
-		},
-		welcome: {
-			enabled: true,
-			verificationRequired: {
-				message: false,
-				role: false
-			},
-			welcomeRole: null,
-			channel: '895209752315961344', // null, channel ID or 'dm'
-			message: "Welcome to the server, {@}!"
-		},
-		stats: [
-			{
-				enabled: true,
-				channel: '951910554291818526',
-				text: "{count} members | {count:bots} bots | {count:humans} humans"
-			}
-		],
-		logging: {
-			logs: {
-				enabled: true,
-				channel: '952247098437427260',
-				toLog: "3fffff" // "3ffffe" = - channelUpdate, "3fffff" = all
-			},
-			staff: {}
-		},
-		verify: {
-			enabled: true,
-			channel: '895210691479355392',
-			role: '934941369137524816',
-		},
-		tickets: {
-			enabled: true,
-			category: "952302254302584932",
-			types: "3f",
-			customTypes: null,
-			supportRole: null,
-			maxTickets: 5
-		}
-	};
-
-	return config
-
-}
\ No newline at end of file
+    let config = {
+        singleEventNotifications: {
+            statsChannelDeleted: false
+        },
+        filters: {
+            images: {
+                NSFW: true,
+                size: true
+            },
+            malware: true,
+            wordFilter: {
+                enabled: true,
+                words: {
+                    strict: [],
+                    loose: []
+                },
+                allowed: {
+                    users: [],
+                    roles: [],
+                    channels: []
+                }
+            },
+            invite: {
+                enabled: false,
+                allowed: {
+                    users: [],
+                    channels: [],
+                    roles: []
+                }
+            },
+            pings: {
+                mass: 5,
+                everyone: true,
+                roles: true,
+                allowed: {
+                    roles: [],
+                    rolesToMention: [],
+                    users: [],
+                    channels: []
+                }
+            }
+        },
+        welcome: {
+            enabled: true,
+            verificationRequired: {
+                message: false,
+                role: false
+            },
+            welcomeRole: null,
+            channel: '895209752315961344', // null, channel ID or 'dm'
+            message: "Welcome to the server, {@}!"
+        },
+        stats: [
+            {
+                enabled: true,
+                channel: '951910554291818526',
+                text: "{count} members | {count:bots} bots | {count:humans} humans"
+            }
+        ],
+        logging: {
+            logs: {
+                enabled: true,
+                channel: '952247098437427260',
+                toLog: "3fffff" // "3ffffe" = - channelUpdate, "3fffff" = all
+            },
+            staff: {
+                channel: "895212366252367933"
+            }
+        },
+        verify: {
+            enabled: true,
+            role: '934941369137524816',
+        },
+        tickets: {
+            enabled: true,
+            category: "952302254302584932",
+            types: "3f",
+            customTypes: null,
+            supportRole: null,
+            maxTickets: 5
+        },
+        moderation: {
+            mute: {
+                timeout: true,
+                role: null, // TODO: actually give it
+                text: null,
+                link: null
+            },
+            kick: {
+                text: "Appeal here",
+                link: "https://clicksminuteper.net"
+            },
+            ban: {
+                text: null,
+                link: null
+            },
+            softban: {
+                text: null,
+                link: null
+            },
+            warn: {
+                text: null,
+                link: null
+            },
+            role: {
+                role: "934941369137524816"
+            },
+        },
+        tracks: [
+            {
+                name: "Moderation",
+                retainPrevious: false,
+                nullable: true,
+                track: [
+                    "934941369137524816",
+                    "934941399806246984",
+                    "934941408849186856",
+                    "934941466734764092"
+                ],
+                manageableBy: []
+            },
+            {
+                name: "Verification",
+                retainPrevious: false,
+                nullable: true,
+                track: [
+                    "963166531318067250"
+                ],
+                manageableBy: []
+            }
+        ],
+        roleMenu: {
+            enabled: true,
+            allowWebUI: true,
+            options: [
+                {
+                    name: "Gender",
+                    description: "What's your gender?",
+                    min: 1,
+                    max: 1,
+                    options: [
+                        { name: "Male", role: "959901318019948574" },
+                        { name: "Female", role: "959901346000154674" },
+                        { name: "Non Binary", description: "Better than the others", role: "959901378363420704"}
+                    ]
+                },
+                {
+                    name: "Pick",
+                    min: 0,
+                    max: 4,
+                    options: [
+                        { name: "Test Role 1", role: "934941369137524816" },
+                        { name: "Test Role 2", role: "934941399806246984" },
+                        { name: "Test Role 3", role: "934941408849186856" },
+                        { name: "Test Role 4", role: "934941466734764092" }
+                    ]
+                }
+            ]
+        }
+    };
+    return config;
+}