changes to how deleting tickets works, and UI when creating mod tickets
diff --git a/.gitignore b/.gitignore
index fcc5e39..72a0e85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,7 @@
 src/utils/temp/*.png
 src/utils/temp/*.webp
 src/utils/temp/*.jpeg
-src/utils/temp/*.jpg
\ No newline at end of file
+src/utils/temp/*.jpg
+
+ClicksMigratingProblems/oldData/
+ClicksMigratingProblems/oldData copy/
\ No newline at end of file
diff --git a/ClicksMigratingProblems/index.js b/ClicksMigratingProblems/index.js
new file mode 100644
index 0000000..3c70cc2
--- /dev/null
+++ b/ClicksMigratingProblems/index.js
@@ -0,0 +1,147 @@
+import fs from 'fs';
+import { MongoClient } from 'mongodb';
+
+const mongoClient = new MongoClient('mongodb://127.0.0.1:27017/local');
+await mongoClient.connect()
+const database = mongoClient.db("Nucleus");
+const collection = database.collection("migrationTesting");
+
+// Loop through all files in the oldData folder
+const files = fs.readdirSync('./oldData');
+let x = 0
+for (const file of files) {
+    console.log(`┌ Processing file ${x} of ${files.length - 1} | ${file}`);
+    // Read the file as a json
+    let data
+    try {
+        data = JSON.parse(fs.readFileSync(`./oldData/${file}`));
+    } catch {
+        console.log(`└ Error reading file ${file}`);
+        x++
+        continue;
+    }
+    // Check if data version is 3
+    if (data.version !== 3) {
+        console.log(`├ Version was too old on ${file}`);
+        console.log(`└ Skipping file`);
+        x++;
+        continue
+    }
+    // Convert to the new format
+    const newData = {
+        "id": data.guild_info.id.toString(),
+        "version": 1,
+        "singleEventNotifications": {
+            "statsChannelDeleted": false
+        },
+        "filters": {
+            "images": {
+                "NSFW": !data.images.nsfw,
+                "size": data.images.toosmall
+            },
+            "wordFilter": {
+                "enabled": true,
+                "words": {
+                    "strict": data.wordfilter.strict,
+                    "loose": data.wordfilter.soft
+                },
+                "allowed": {
+                    "users": data.wordfilter.ignore.members.map(user => user.toString()),
+                    "roles": data.wordfilter.ignore.roles.map(role => role.toString()),
+                    "channels": data.wordfilter.ignore.channels.map(channel => channel.toString())
+                }
+            },
+            "invite": {
+                "enabled": data.invite ? data.invite.enabled : false,
+                "allowed": {
+                    "users": data.invite ? data.invite.whitelist.members.map(user => user.toString()) : [],
+                    "channels": data.invite ? data.invite.whitelist.channels.map(channel => channel.toString()) : [],
+                    "roles": data.invite ? data.invite.whitelist.roles.map(role => role.toString()) : []
+                }
+            },
+            "pings": {
+                "mass": 5,
+                "everyone": true,
+                "roles": true,
+                "allowed": {
+                    "roles": [],
+                    "rolesToMention": null,
+                    "users": null,
+                    "channels": null
+                }
+            }
+        },
+        "welcome": {
+            "enabled": data.welcome ? (data.welcome.message.text !== null) : false,
+            "verificationRequired": {
+                "message": null,
+                "role": null,
+            },
+            "welcomeRole": data.welcome ? (data.welcome.role !== null ? data.welcome.role.toString() : null) : null,
+            "channel": data.welcome ? (data.welcome.message.text !== null ? data.welcome.message.channel.toString() : null) : null,
+            "message": data.welcome ? (data.welcome.message.text) : null
+        },
+        "stats": [],
+        "logging": {
+            "logs": {
+                "enabled": true,
+                "channel": data.log_info.log_channel ? data.log_info.log_channel.toString() : null,
+                "toLog": "3fffff"
+            },
+            "staff": {
+                "channel": data.log_info.staff ? data.log_info.staff.toString() : null,
+            }
+        },
+        "verify": {
+            "enabled": data.verify_role !== null,
+            "role": data.verify_role ? data.verify_role.toString() : null,
+        },
+        "tickets": {
+            "enabled": data.modmail ? (data.modmail.cat !== null) : null,
+            "category": data.modmail ? (data.modmail.cat !== null ? data.modmail.cat.toString() : null) : null,
+            "types": "3f",
+            "customTypes": null,
+            "supportRole": data.modmail ? (data.modmail.mention !== null ? data.modmail.mention.toString() : null) : null,
+            "maxTickets": data.modmail ? (data.modmail.max) : 5
+        },
+        "moderation": {
+            "mute": {
+                "timeout": true,
+                "role": null,
+                "text": null,
+                "link": null
+            },
+            "kick": {
+                "text": null,
+                "link": null
+            },
+            "ban": {
+                "text": null,
+                "link": null
+            },
+            "softban": {
+                "text": null,
+                "link": null
+            },
+            "warn": {
+                "text": null,
+                "link": null
+            },
+            "role": {
+                "role": null
+            }
+        },
+        "tracks": [],
+        "roleMenu": [],
+        "tags": data.tags
+    }
+    // Insert the new data into the database
+    await collection.updateOne({ id: data.guild_info.id.toString() }, { $set: newData }, { upsert: true });
+    // Delete the old file
+    fs.unlinkSync(`./oldData/${file}`);
+    console.log(`└ Successfully migrated file ${file}`);
+    x++;
+}
+
+
+// console.log((await collection.findOne({ id: "your mother" })));
diff --git a/ClicksMigratingProblems/package-lock.json b/ClicksMigratingProblems/package-lock.json
new file mode 100644
index 0000000..d7c59c6
--- /dev/null
+++ b/ClicksMigratingProblems/package-lock.json
@@ -0,0 +1,389 @@
+{
+  "name": "hi",
+  "version": "1.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "hi",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "fs": "^0.0.1-security",
+        "mongodb": "^4.7.0"
+      }
+    },
+    "node_modules/@types/node": {
+      "version": "17.0.41",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.41.tgz",
+      "integrity": "sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw=="
+    },
+    "node_modules/@types/webidl-conversions": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
+      "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
+    },
+    "node_modules/@types/whatwg-url": {
+      "version": "8.2.1",
+      "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
+      "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
+      "dependencies": {
+        "@types/node": "*",
+        "@types/webidl-conversions": "*"
+      }
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/bson": {
+      "version": "4.6.4",
+      "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.4.tgz",
+      "integrity": "sha512-TdQ3FzguAu5HKPPlr0kYQCyrYUYh8tFM+CMTpxjNzVzxeiJY00Rtuj3LXLHSgiGvmaWlZ8PE+4KyM2thqE38pQ==",
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/denque": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
+      "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==",
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/fs": {
+      "version": "0.0.1-security",
+      "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
+      "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w=="
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/ip": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
+      "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
+    },
+    "node_modules/memory-pager": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+      "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+      "optional": true
+    },
+    "node_modules/mongodb": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.7.0.tgz",
+      "integrity": "sha512-HhVar6hsUeMAVlIbwQwWtV36iyjKd9qdhY+s4wcU8K6TOj4Q331iiMy+FoPuxEntDIijTYWivwFJkLv8q/ZgvA==",
+      "dependencies": {
+        "bson": "^4.6.3",
+        "denque": "^2.0.1",
+        "mongodb-connection-string-url": "^2.5.2",
+        "socks": "^2.6.2"
+      },
+      "engines": {
+        "node": ">=12.9.0"
+      },
+      "optionalDependencies": {
+        "saslprep": "^1.0.3"
+      }
+    },
+    "node_modules/mongodb-connection-string-url": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
+      "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
+      "dependencies": {
+        "@types/whatwg-url": "^8.2.1",
+        "whatwg-url": "^11.0.0"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/saslprep": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
+      "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
+      "optional": true,
+      "dependencies": {
+        "sparse-bitfield": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/smart-buffer": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+      "engines": {
+        "node": ">= 6.0.0",
+        "npm": ">= 3.0.0"
+      }
+    },
+    "node_modules/socks": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
+      "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
+      "dependencies": {
+        "ip": "^1.1.5",
+        "smart-buffer": "^4.2.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0",
+        "npm": ">= 3.0.0"
+      }
+    },
+    "node_modules/sparse-bitfield": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+      "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+      "optional": true,
+      "dependencies": {
+        "memory-pager": "^1.0.2"
+      }
+    },
+    "node_modules/tr46": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
+      "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+      "dependencies": {
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/webidl-conversions": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+      "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/whatwg-url": {
+      "version": "11.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
+      "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
+      "dependencies": {
+        "tr46": "^3.0.0",
+        "webidl-conversions": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    }
+  },
+  "dependencies": {
+    "@types/node": {
+      "version": "17.0.41",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.41.tgz",
+      "integrity": "sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw=="
+    },
+    "@types/webidl-conversions": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
+      "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
+    },
+    "@types/whatwg-url": {
+      "version": "8.2.1",
+      "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
+      "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
+      "requires": {
+        "@types/node": "*",
+        "@types/webidl-conversions": "*"
+      }
+    },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+    },
+    "bson": {
+      "version": "4.6.4",
+      "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.4.tgz",
+      "integrity": "sha512-TdQ3FzguAu5HKPPlr0kYQCyrYUYh8tFM+CMTpxjNzVzxeiJY00Rtuj3LXLHSgiGvmaWlZ8PE+4KyM2thqE38pQ==",
+      "requires": {
+        "buffer": "^5.6.0"
+      }
+    },
+    "buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "requires": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "denque": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
+      "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ=="
+    },
+    "fs": {
+      "version": "0.0.1-security",
+      "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
+      "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w=="
+    },
+    "ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+    },
+    "ip": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
+      "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
+    },
+    "memory-pager": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+      "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+      "optional": true
+    },
+    "mongodb": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.7.0.tgz",
+      "integrity": "sha512-HhVar6hsUeMAVlIbwQwWtV36iyjKd9qdhY+s4wcU8K6TOj4Q331iiMy+FoPuxEntDIijTYWivwFJkLv8q/ZgvA==",
+      "requires": {
+        "bson": "^4.6.3",
+        "denque": "^2.0.1",
+        "mongodb-connection-string-url": "^2.5.2",
+        "saslprep": "^1.0.3",
+        "socks": "^2.6.2"
+      }
+    },
+    "mongodb-connection-string-url": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
+      "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
+      "requires": {
+        "@types/whatwg-url": "^8.2.1",
+        "whatwg-url": "^11.0.0"
+      }
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+    },
+    "saslprep": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
+      "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
+      "optional": true,
+      "requires": {
+        "sparse-bitfield": "^3.0.3"
+      }
+    },
+    "smart-buffer": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
+    },
+    "socks": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
+      "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
+      "requires": {
+        "ip": "^1.1.5",
+        "smart-buffer": "^4.2.0"
+      }
+    },
+    "sparse-bitfield": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+      "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+      "optional": true,
+      "requires": {
+        "memory-pager": "^1.0.2"
+      }
+    },
+    "tr46": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
+      "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+      "requires": {
+        "punycode": "^2.1.1"
+      }
+    },
+    "webidl-conversions": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+      "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
+    },
+    "whatwg-url": {
+      "version": "11.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
+      "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
+      "requires": {
+        "tr46": "^3.0.0",
+        "webidl-conversions": "^7.0.0"
+      }
+    }
+  }
+}
diff --git a/ClicksMigratingProblems/package.json b/ClicksMigratingProblems/package.json
new file mode 100644
index 0000000..a4a5ec5
--- /dev/null
+++ b/ClicksMigratingProblems/package.json
@@ -0,0 +1,16 @@
+{
+  "name": "hi",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "fs": "^0.0.1-security",
+    "mongodb": "^4.7.0"
+  },
+  "type": "module"
+}
diff --git a/package.json b/package.json
index 7287aef..9706070 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
     "humanize-duration": "^3.27.1",
     "jshaiku": "file:../haiku",
     "json-diff": "^0.7.1",
+    "mongodb": "^4.7.0",
     "node-tesseract": "^0.2.7",
     "structured-clone": "^0.2.2",
     "tesseract.js": "^2.1.5",
diff --git a/src/automations/createModActionTicket.ts b/src/automations/createModActionTicket.ts
index 4de2924..ef317b7 100644
--- a/src/automations/createModActionTicket.ts
+++ b/src/automations/createModActionTicket.ts
@@ -3,7 +3,7 @@
 import generateEmojiEmbed from '../utils/generateEmojiEmbed.js';
 import getEmojiByName from "../utils/getEmojiByName.js";
 
-export async function create(guild: Discord.Guild, member: Discord.User, client) {
+export async function create(guild: Discord.Guild, member: Discord.User, createdBy: Discord.User, client) {
     let config = await readConfig(guild.id);
     // @ts-ignore
     const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger
@@ -70,6 +70,7 @@
             },
             list: {
                 ticketFor: entry(member.id, renderUser(member)),
+                createdBy: entry(createdBy.id, renderUser(createdBy)),
                 created: entry(new Date().getTime(), renderDelta(new Date().getTime())),
                 ticketChannel: entry(c.id, renderChannel(c)),
             },
diff --git a/src/automations/tickets/delete.ts b/src/automations/tickets/delete.ts
index 32315bc..17d889a 100644
--- a/src/automations/tickets/delete.ts
+++ b/src/automations/tickets/delete.ts
@@ -11,7 +11,7 @@
     let channel = (interaction.channel as Discord.TextChannel)
     if (!channel.parent || config.tickets.category != channel.parent.id) {
         return interaction.reply({embeds: [new generateEmojiEmbed()
-            .setTitle("Close Ticket")
+            .setTitle("Deleting Ticket...")
             .setDescription("This ticket is not in your tickets category, so cannot be deleted. You cannot run close in a thread.") // TODO bridge to cross later!
             .setStatus("Danger")
             .setEmoji("CONTROL.BLOCKCROSS")
@@ -19,96 +19,92 @@
     }
     let status = channel.topic.split(" ")[1];
     if (status == "Archived") {
-        interaction.reply({embeds: [new generateEmojiEmbed()
-            .setTitle("Close Ticket")
-            .setDescription("This ticket will be deleted in 3 seconds.")
+        await interaction.reply({embeds: [new generateEmojiEmbed()
+            .setTitle("Delete Ticket")
+            .setDescription("Your ticket is being deleted...")
             .setStatus("Danger")
             .setEmoji("GUILD.TICKET.CLOSE")
         ]});
-        setTimeout(async () => {
-            let data = {
-                meta:{
-                    type: 'ticketClosed',
-                    displayName: 'Ticket Closed',
-                    calculateType: true,
-                    color: NucleusColors.red,
-                    emoji: 'GUILD.TICKET.CLOSE',
-                    timestamp: new Date().getTime()
-                },
-                list: {
-                    ticketFor: entry(channel.topic.split(" ")[0], renderUser((await interaction.guild.members.fetch(channel.topic.split(" ")[0])).user)),
-                    closedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
-                    closed: entry(new Date().getTime(), renderDelta(new Date().getTime()))
-                },
-                hidden: {
-                    guild: interaction.guild.id
-                }
+        let data = {
+            meta:{
+                type: 'ticketDeleted',
+                displayName: 'Ticket Deleted',
+                calculateType: true,
+                color: NucleusColors.red,
+                emoji: 'GUILD.TICKET.CLOSE',
+                timestamp: new Date().getTime()
+            },
+            list: {
+                ticketFor: entry(channel.topic.split(" ")[0], renderUser((await interaction.guild.members.fetch(channel.topic.split(" ")[0])).user)),
+                deletedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
+                closed: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+            },
+            hidden: {
+                guild: interaction.guild.id
             }
-            log(data, interaction.client);
-            interaction.channel.delete();
-        }, 3000);
+        }
+        log(data, interaction.client);
+        interaction.channel.delete();
         return;
     } else if (status == "Active") {
-        interaction.reply({embeds: [new generateEmojiEmbed()
+        await interaction.reply({embeds: [new generateEmojiEmbed()
             .setTitle("Close Ticket")
-            .setDescription("This ticket will be archived in 3 seconds.")
+            .setDescription("Your ticket is being closed...")
             .setStatus("Warning")
             .setEmoji("GUILD.TICKET.ARCHIVED")
         ]});
-        setTimeout(async () =>{
-            let overwrites = [
-                {
-                    id: channel.topic.split(" ")[0],
-                    deny: ["VIEW_CHANNEL"],
-                    type: "member"
-                },
-                {
-                    id: interaction.guild.id,
-                    deny: ["VIEW_CHANNEL"],
-                    type: "role"
-                }
-            ] as Discord.OverwriteResolvable[];
-            if (config.tickets.supportRole != null) {
-                overwrites.push({
-                    id: interaction.guild.roles.cache.get(config.tickets.supportRole),
-                    allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "ATTACH_FILES", "ADD_REACTIONS", "READ_MESSAGE_HISTORY"],
-                    type: "role"
-                })
+        let overwrites = [
+            {
+                id: channel.topic.split(" ")[0],
+                deny: ["VIEW_CHANNEL"],
+                type: "member"
+            },
+            {
+                id: interaction.guild.id,
+                deny: ["VIEW_CHANNEL"],
+                type: "role"
             }
-            channel.edit({permissionOverwrites: overwrites})
-            channel.setTopic(`${channel.topic.split(" ")[0]} Archived`);
-            let data = {
-                meta:{
-                    type: 'ticketArchive',
-                    displayName: 'Ticket Archived',
-                    calculateType: true,
-                    color: NucleusColors.yellow,
-                    emoji: 'GUILD.TICKET.ARCHIVED',
-                    timestamp: new Date().getTime()
-                },
-                list: {
-                    ticketFor: entry(channel.topic.split(" ")[0], renderUser((await interaction.guild.members.fetch(channel.topic.split(" ")[0])).user)),
-                    archivedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
-                    archived: entry(new Date().getTime(), renderDelta(new Date().getTime())),
-                    ticketChannel: entry(channel.id, renderChannel(channel)),
-                },
-                hidden: {
-                    guild: interaction.guild.id
-                }
+        ] as Discord.OverwriteResolvable[];
+        if (config.tickets.supportRole != null) {
+            overwrites.push({
+                id: interaction.guild.roles.cache.get(config.tickets.supportRole),
+                allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "ATTACH_FILES", "ADD_REACTIONS", "READ_MESSAGE_HISTORY"],
+                type: "role"
+            })
+        }
+        channel.edit({permissionOverwrites: overwrites})
+        channel.setTopic(`${channel.topic.split(" ")[0]} Archived`);
+        let data = {
+            meta:{
+                type: 'ticketClosed',
+                displayName: 'Ticket Closed',
+                calculateType: true,
+                color: NucleusColors.yellow,
+                emoji: 'GUILD.TICKET.ARCHIVED',
+                timestamp: new Date().getTime()
+            },
+            list: {
+                ticketFor: entry(channel.topic.split(" ")[0], renderUser((await interaction.guild.members.fetch(channel.topic.split(" ")[0])).user)),
+                closedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
+                closed: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+                ticketChannel: entry(channel.id, renderChannel(channel)),
+            },
+            hidden: {
+                guild: interaction.guild.id
             }
-            log(data, interaction.client);
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
-                .setTitle("Close Ticket")
-                .setDescription("This ticket has been archived.\nType `/ticket close` to delete it.")
-                .setStatus("Warning")
-                .setEmoji("GUILD.TICKET.ARCHIVED") // TODO:[Premium] Add a transcript option  ||\----/|| <- the bridge we will cross when we come to it
-            ], components: [new MessageActionRow().addComponents([new MessageButton()
-                .setLabel("Close")
-                .setStyle("DANGER")
-                .setCustomId("closeticket")
-                .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
-            ])]});
-        }, 3000);
+        }
+        log(data, interaction.client);
+        await interaction.editReply({embeds: [new generateEmojiEmbed()
+            .setTitle("Close Ticket")
+            .setDescription("This ticket has been closed.\nType `/ticket close` again to delete it.")
+            .setStatus("Warning")
+            .setEmoji("GUILD.TICKET.ARCHIVED") // TODO:[Premium] Add a transcript option  ||\----/|| <- the bridge we will cross when we come to it
+        ], components: [new MessageActionRow().addComponents([new MessageButton()
+            .setLabel("Delete")
+            .setStyle("DANGER")
+            .setCustomId("closeticket")
+            .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+        ])]});
         return;
     }
 }
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index d81a5cc..b2cc94e 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -6,7 +6,6 @@
 import confirmationMessage from "../../utils/confirmationMessage.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import humanizeDuration from "humanize-duration";
-import { create, areTicketsEnabled } from "../../automations/createModActionTicket.js";
 import readConfig from "../../utils/readConfig.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
diff --git a/src/commands/mod/nick.ts b/src/commands/mod/nick.ts
index cd3a7af..e8463f4 100644
--- a/src/commands/mod/nick.ts
+++ b/src/commands/mod/nick.ts
@@ -29,10 +29,10 @@
         + `The user **will${interaction.options.getString("notify") == "yes" ? '' : ' not'}** be notified\n\n`
         + `Are you sure you want to ${interaction.options.getString("name") ? "change" : "clear"} <@!${(interaction.options.getMember("user") as GuildMember).id}>'s nickname?`)
         .setColor("Danger")
-        .addCustomCallback(
+        .addCustomBoolean(
             "Create appeal ticket", !(await areTicketsEnabled(interaction.guild.id)),
-            () => { create(interaction.guild, interaction.options.getUser("user"), interaction.client)},
-            "An appeal ticket was created")
+            async () => await create(interaction.guild, interaction.options.getUser("user"), interaction.user, interaction.client),
+            "An appeal ticket will be created when Confirm is clicked")
 //        pluralize("day", interaction.options.getInteger("delete"))
 //        const pluralize = (word: string, count: number) => { return count === 1 ? word : word + "s" }
     .send()
@@ -96,7 +96,7 @@
         await interaction.editReply({embeds: [new generateEmojiEmbed()
             .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
             .setTitle(`Nickname`)
-            .setDescription("The members nickname was changed" + (failed ? ", but was not notified" : ""))
+            .setDescription("The members nickname was changed" + (failed ? ", but was not notified" : "") + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
             .setStatus(failed ? "Warning" : "Success")
         ], components: []})
     } else {
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index e388ea0..924e507 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -5,7 +5,6 @@
 import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
-import { create, areTicketsEnabled } from "../../automations/createModActionTicket.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
diff --git a/src/commands/mod/unnamed.ts b/src/commands/mod/unnamed.ts
index 20ebc30..ca0bcef 100644
--- a/src/commands/mod/unnamed.ts
+++ b/src/commands/mod/unnamed.ts
@@ -129,10 +129,10 @@
         + `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n\n`
         + `Are you sure you want to mute <@!${(interaction.options.getMember("user") as GuildMember).id}>?`) // TODO
         .setColor("Danger")
-        .addCustomCallback(
+        .addCustomBoolean(
             "Create appeal ticket", !(await areTicketsEnabled(interaction.guild.id)),
-            () => { create(interaction.guild, interaction.options.getUser("user"), interaction.client)},
-            "An appeal ticket was created")
+            async () => await create(interaction.guild, interaction.options.getUser("user"), interaction.user, interaction.client),
+            "An appeal ticket will be created when Confirm is clicked")
 //        pluralize("day", interaction.options.getInteger("delete"))
 //        const pluralize = (word: string, count: number) => { return count === 1 ? word : word + "s" }
     .send()
diff --git a/src/commands/mod/warn.ts b/src/commands/mod/warn.ts
index 3f63cce..ce54cfb 100644
--- a/src/commands/mod/warn.ts
+++ b/src/commands/mod/warn.ts
@@ -30,10 +30,10 @@
         + `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n\n`
         + `Are you sure you want to warn <@!${(interaction.options.getMember("user") as GuildMember).id}>?`)
         .setColor("Danger")
-        .addCustomCallback(
+        .addCustomBoolean(
             "Create appeal ticket", !(await areTicketsEnabled(interaction.guild.id)),
-            () => { create(interaction.guild, interaction.options.getUser("user"), interaction.client)},
-            "An appeal ticket was created")
+            async () => await create(interaction.guild, interaction.options.getUser("user"), interaction.user, interaction.client),
+            "An appeal ticket will be created when Confirm is clicked")
 //        pluralize("day", interaction.options.getInteger("delete"))
 //        const pluralize = (word: string, count: number) => { return count === 1 ? word : word + "s" }
     .send()
@@ -85,7 +85,7 @@
             await interaction.editReply({embeds: [new generateEmojiEmbed()
                 .setEmoji(`PUNISH.WARN.GREEN`)
                 .setTitle(`Warn`)
-                .setDescription("The user was warned")
+                .setDescription("The user was warned" + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
                 .setStatus("Success")
             ], components: []})
         } else {
@@ -135,7 +135,7 @@
                 return await interaction.editReply({embeds: [new generateEmojiEmbed()
                     .setEmoji(`PUNISH.WARN.GREEN`)
                     .setTitle(`Warn`)
-                    .setDescription("The user was warned")
+                    .setDescription("The user was warned" + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
                     .setStatus("Success")
                 ], components: []})
             } else {
diff --git a/src/config/default.json b/src/config/default.json
new file mode 100644
index 0000000..129bfe9
--- /dev/null
+++ b/src/config/default.json
@@ -0,0 +1,108 @@
+{
+    "id": "default",
+    "version": 1,
+    "singleEventNotifications": {
+        "statsChannelDeleted": false
+    },
+    "filters": {
+        "images": {
+            "NSFW": false,
+            "size": false
+        },
+        "malware": false,
+        "wordFilter": {
+            "enabled": false,
+            "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": false,
+        "verificationRequired": {
+            "message": null,
+            "role": null
+        },
+        "welcomeRole": null,
+        "channel": null,
+        "message": null
+    },
+    "stats": [],
+    "logging": {
+        "logs": {
+            "enabled": true,
+            "channel": null,
+            "toLog": "3fffff"
+        },
+        "staff": {
+            "channel": null
+        }
+    },
+    "verify": {
+        "enabled": false,
+        "role": null
+    },
+    "tickets": {
+        "enabled": false,
+        "category": null,
+        "types": "3f",
+        "customTypes": null,
+        "supportRole": null,
+        "maxTickets": 5
+    },
+    "moderation": {
+        "mute": {
+            "timeout": true,
+            "role": null,
+            "text": null,
+            "link": null
+        },
+        "kick": {
+            "text": null,
+            "link": null
+        },
+        "ban": {
+            "text": null,
+            "link": null
+        },
+        "softban": {
+            "text": null,
+            "link": null
+        },
+        "warn": {
+            "text": null,
+            "link": null
+        },
+        "role": {
+            "role": null
+        }
+    },
+    "tracks": [],
+    "roleMenu": [],
+    "tags": {}
+}
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index 306c5ee..2616f40 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,13 +1,10 @@
-import { HaikuClient } from 'jshaiku';
-import { Intents } from 'discord.js';
+
 import config from './config/main.json' assert {type: 'json'};
 import { Logger } from './utils/log.js';
 import runServer from './api/index.js';
 import Memory from './utils/memory.js';
-
-const client = new HaikuClient({
-    intents: new Intents(32767).bitfield,  // This is a way of specifying all intents w/o having to type them out
-}, config);
+import Database from './utils/database.js';
+import client from './utils/client.js';
 
 await client.registerCommandsIn("./commands");
 await client.registerEventsIn("./events");
@@ -19,5 +16,7 @@
 client.verify = {}
 client.roleMenu = {}
 client.memory = new Memory()
+client.database = await new Database(config.mongoUrl).connect()
+
 
 await client.login();
\ No newline at end of file
diff --git a/src/utils/client.ts b/src/utils/client.ts
new file mode 100644
index 0000000..3f4a8a1
--- /dev/null
+++ b/src/utils/client.ts
@@ -0,0 +1,9 @@
+import { HaikuClient } from 'jshaiku';
+import { Intents } from 'discord.js';
+import config from '../config/main.json' assert {type: 'json'};
+
+const client = new HaikuClient({
+    intents: new Intents(32767).bitfield,  // This is a way of specifying all intents w/o having to type them out
+}, config);
+
+export default client;
\ No newline at end of file
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index dd97603..7a06d83 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -14,6 +14,8 @@
     customCallbackString: string = "";
     customCallbackClicked: boolean = false;
     customCallbackResponse: any = null;
+    customBoolean: () => any;
+    customBooleanClicked: boolean = null;
     inverted: boolean;
 
     constructor(interaction: CommandInteraction) {
@@ -23,8 +25,9 @@
         this.emoji = "";
         this.description = "";
         this.color = "";
-        this.inverted = false
-        this.customCallback = () => {}
+        this.inverted = false;
+        this.customCallback = () => {};
+        this.customBoolean = () => {};
     }
 
     setTitle(title: string) { this.title = title; return this }
@@ -33,12 +36,23 @@
     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;
+        return this;
+    }
+
 
     async send(editOnly?: boolean) {
         while (true) {
@@ -49,7 +63,7 @@
                         .setTitle(this.title)
                         .setDescription(this.description)
                         .setStatus(this.color)
-                        .setFooter({text: this.customCallbackClicked ? this.customCallbackString : ""})
+                        .setFooter({text: (this.customBooleanClicked ?? this.customCallbackClicked) ? this.customCallbackString : ""})
                 ],
                 components: [
                     new MessageActionRow().addComponents([
@@ -66,7 +80,10 @@
                     ].concat(this.customButtonTitle ? [new Discord.MessageButton()
                         .setCustomId("custom")
                         .setLabel(this.customButtonTitle)
-                        .setStyle("PRIMARY")
+                        .setStyle(this.customBooleanClicked !== null ?
+                            ( this.customBooleanClicked ? "SUCCESS" : "PRIMARY" ) :
+                            "PRIMARY"
+                        )
                         .setDisabled(this.customButtonDisabled)
                         .setEmoji(getEmojiByName("CONTROL.TICKET", "id"))
                     ] : []))
@@ -84,19 +101,36 @@
             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 };
+                return {
+                    success: false,
+                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
+                    response: this.customCallbackResponse
+                };
             }
             if (component.customId === "yes") {
                 component.deferUpdate();
-                return { success: true, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse };
+                if (this.customBooleanClicked === true) this.customCallbackResponse = await this.customBoolean();
+                return {
+                    success: true,
+                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
+                    response: this.customCallbackResponse
+                };
             } else if (component.customId === "no") {
                 component.deferUpdate();
-                return { success: false, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse };
+                return {
+                    success: false,
+                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
+                    response: this.customCallbackResponse
+                };
             } else if (component.customId === "custom") {
                 component.deferUpdate();
-                this.customCallbackResponse = this.customCallback();
-                this.customCallbackClicked = true;
-                this.customButtonDisabled = true;
+                if (this.customBooleanClicked !== null) {
+                    this.customBooleanClicked = !this.customBooleanClicked;
+                } else {
+                    this.customCallbackResponse = await this.customCallback();
+                    this.customCallbackClicked = true;
+                    this.customButtonDisabled = true;
+                }
                 editOnly = true;
             }
         }
diff --git a/src/utils/database.ts b/src/utils/database.ts
new file mode 100644
index 0000000..53ccb97
--- /dev/null
+++ b/src/utils/database.ts
@@ -0,0 +1,180 @@
+import { Collection, Db, MongoClient } from 'mongodb';
+
+
+export const Entry = data => {
+    data = data ?? {};
+    return {
+        get(target, prop, receiver) {
+            let dataToReturn = data[prop]
+            if (dataToReturn === null ) return Reflect.get(target, prop, receiver);
+            if (typeof dataToReturn === "object" && !Array.isArray(dataToReturn)) dataToReturn = new Proxy(
+                Reflect.get(target, prop, receiver),
+                Entry(dataToReturn),
+            )
+            return dataToReturn ?? Reflect.get(target, prop, receiver);
+        }
+    }
+}
+
+
+export default class Database {
+    mongoClient: MongoClient;
+    database: Db;
+    guilds: Collection<GuildConfig>;
+    defaultData: GuildConfig;
+
+    constructor(url) {
+        this.mongoClient = new MongoClient(url);
+    }
+
+    async connect() {
+        await this.mongoClient.connect()
+        this.database = this.mongoClient.db("Nucleus");
+        this.guilds = this.database.collection<GuildConfig>("guilds");
+        await this.guilds.createIndex({ id: "text" }, { unique: true });
+        this.defaultData = (await import("../config/default.json", { assert: { type: "json" }})).default as unknown as GuildConfig;
+        return this;
+    }
+
+    async read(guild: string) {
+        let entry = await this.guilds.findOne({ id: guild });
+        return new Proxy(this.defaultData, Entry(entry)) as unknown as GuildConfig
+    }
+
+    async write(guild: string, config: GuildConfig) {
+        await this.guilds.updateOne({ id: guild }, { $set: config }, { upsert: true });
+    }
+}
+
+export interface GuildConfig {
+    id: string,
+    version: number,
+    singleEventNotifications: {
+        statsChannelDeleted: boolean
+    }
+    filters: {
+        images: {
+            NSFW: boolean,
+            size: boolean
+        },
+        malware: boolean,
+        wordFilter: {
+            enabled: boolean,
+            words: {
+                strict: string[],
+                loose: string[]
+            },
+            allowed: {
+                users: string[],
+                roles: string[],
+                channels: string[]
+            }
+        },
+        invite: {
+            enabled: boolean,
+            allowed: {
+                users: string[],
+                channels: string[],
+                roles: string[]
+            }
+        },
+        pings: {
+            mass: number,
+            everyone: boolean,
+            roles: boolean,
+            allowed: {
+                roles: string[],
+                rolesToMention: string[],
+                users: string[],
+                channels: string[]
+            }
+        }
+    }
+    welcome: {
+        enabled: boolean,
+        verificationRequired: {
+            message: boolean,
+            role: string
+        },
+        welcomeRole: string,
+        channel: string,
+        message: string
+    }
+    stats: {
+        enabled: boolean,
+        channel: string,
+        text: string
+    }[]
+    logging: {
+        logs: {
+            enabled: boolean,
+            channel: string,
+            toLog: string
+        },
+        staff: {
+            channel: string
+        }
+    }
+    verify: {
+        enabled: boolean,
+        role: string
+    }
+    tickets: {
+        enabled: boolean,
+        category: string,
+        types: string,
+        customTypes: string[],
+        supportRole: string,
+        maxTickets: number
+    }
+    moderation: {
+        mute: {
+            timeout: boolean,
+            role: string,
+            text: string,
+            link: string
+        },
+        kick: {
+            text: string,
+            link: string
+        },
+        ban: {
+            text: string,
+            link: string
+        },
+        softban: {
+            text: string,
+            link: string
+        },
+        warn: {
+            text: string,
+            link: string
+        },
+        role: {
+            role: string
+        }
+    }
+    tracks: {
+        name: string,
+        retainPrevious: boolean,
+        nullable: boolean,
+        track: string[],
+        manageableBy: string[]
+    }[]
+    roleMenu: {
+        enabled: boolean,
+        allowWebUI: boolean,
+        options: {
+            name: string,
+            description: string,
+            min: number,
+            max: number,
+            options: {
+                name: string,
+                description: string,
+                role: string
+            }[]
+        }[]
+    }
+    tags: {}
+};
\ No newline at end of file
diff --git a/src/utils/memory.ts b/src/utils/memory.ts
index a4f9501..0cbf955 100644
--- a/src/utils/memory.ts
+++ b/src/utils/memory.ts
@@ -14,7 +14,7 @@
                 logging: guildData.logging,
                 tickets: guildData.tickets,
             }; // TODO: REMOVE GUILD FROM MEMORY WHEN THESE UPDATE
-        }
+        } // TODO: Add a "lastAccessed" prop, delete after 15 minutes
         return this.memory[guild];
     }
 }
diff --git a/src/utils/readConfig.ts b/src/utils/readConfig.ts
index 50cb6c6..b363fc0 100644
--- a/src/utils/readConfig.ts
+++ b/src/utils/readConfig.ts
@@ -1,165 +1,5 @@
+import client from './client.js';
 
 export default async function readConfig(guild: string): Promise<any> {
-
-    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: "934941369137524816", // TODO: Remove this role after the time
-                text: null,
-                link: null
-            },
-            kick: {
-                text: "Appeal here",
-                link: "https://clicks.codes"
-            },
-            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;
+    return await client.database.read(guild);
 }