few changes
diff --git a/src/events/channelCreate.ts b/src/events/channelCreate.ts
index f7ec756..883efd9 100644
--- a/src/events/channelCreate.ts
+++ b/src/events/channelCreate.ts
@@ -3,69 +3,71 @@
 export const event = 'channelCreate'
 
 export async function callback(client, channel) {
-	const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = channel.client.logger
-    let auditLog = await getAuditLog(channel.guild, 'CHANNEL_CREATE');
-    let audit = auditLog.entries.filter(entry => entry.target.id == channel.id).first();
-    if (audit.executor.id == client.user.id) return;
-    let emoji;
-    let readableType;
-    let displayName;
-    switch (channel.type) {
-        case 'GUILD_TEXT': {
-            emoji = "CHANNEL.TEXT.CREATE";
-            readableType = "Text";
-            displayName = "Text Channel"
-            break;
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = channel.client.logger
+        let auditLog = await getAuditLog(channel.guild, 'CHANNEL_CREATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == channel.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let emoji;
+        let readableType;
+        let displayName;
+        switch (channel.type) {
+            case 'GUILD_TEXT': {
+                emoji = "CHANNEL.TEXT.CREATE";
+                readableType = "Text";
+                displayName = "Text Channel"
+                break;
+            }
+            case 'GUILD_NEWS': {
+                emoji = "CHANNEL.TEXT.CREATE";
+                readableType = "Announcement";
+                displayName = "Announcement Channel"
+                break;
+            }
+            case 'GUILD_VOICE': {
+                emoji = "CHANNEL.VOICE.CREATE";
+                readableType = "Voice";
+                displayName = "Voice Channel"
+                break;
+            }
+            case 'GUILD_STAGE': {
+                emoji = "CHANNEL.VOICE.CREATE";
+                readableType = "Stage";
+                displayName = "Stage Channel"
+            }
+            case 'GUILD_CATEGORY': {
+                emoji = "CHANNEL.CATEGORY.CREATE";
+                readableType = "Category";
+                displayName = "Category"
+                break;
+            }
+            default: {
+                emoji = "CHANNEL.TEXT.CREATE";
+                readableType = "Channel";
+                displayName = "Channel"
+            }
         }
-        case 'GUILD_NEWS': {
-            emoji = "CHANNEL.TEXT.CREATE";
-            readableType = "Announcement";
-            displayName = "Announcement Channel"
-            break;
+        let data = {
+            meta: {
+                type: 'channelCreate',
+                displayName: displayName + ' Created',
+                calculateType: 'channelUpdate',
+                color: NucleusColors.green,
+                emoji: emoji,
+                timestamp: channel.createdTimestamp
+            },
+            list: {
+                id: entry(channel.id, `\`${channel.id}\``),
+                name: entry(channel.name, renderChannel(channel)),
+                type: entry(channel.type, readableType),
+                category: entry(channel.parent ? channel.parent.id : null, channel.parent ? channel.parent.name : "Uncategorised"),
+                createdBy: entry(audit.executor.id, renderUser(audit.executor)),
+                created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp))
+            },
+            hidden: {
+                guild: channel.guild.id
+            }
         }
-        case 'GUILD_VOICE': {
-            emoji = "CHANNEL.VOICE.CREATE";
-            readableType = "Voice";
-            displayName = "Voice Channel"
-            break;
-        }
-        case 'GUILD_STAGE': {
-            emoji = "CHANNEL.VOICE.CREATE";
-            readableType = "Stage";
-            displayName = "Stage Channel"
-        }
-        case 'GUILD_CATEGORY': {
-            emoji = "CHANNEL.CATEGORY.CREATE";
-            readableType = "Category";
-            displayName = "Category"
-            break;
-        }
-        default: {
-            emoji = "CHANNEL.TEXT.CREATE";
-            readableType = "Channel";
-            displayName = "Channel"
-        }
-    }
-    let data = {
-        meta: {
-            type: 'channelCreate',
-            displayName: displayName + ' Created',
-            calculateType: 'channelUpdate',
-            color: NucleusColors.green,
-            emoji: emoji,
-            timestamp: channel.createdTimestamp
-        },
-        list: {
-            id: entry(channel.id, `\`${channel.id}\``),
-            name: entry(channel.name, renderChannel(channel)),
-            type: entry(channel.type, readableType),
-            category: entry(channel.parent ? channel.parent.id : null, channel.parent ? channel.parent.name : "Uncategorised"),
-            createdBy: entry(audit.executor.id, renderUser(audit.executor)),
-            created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp))
-        },
-        hidden: {
-            guild: channel.guild.id
-        }
-    }
-    log(data, channel.client);
+        log(data, channel.client);
+    } catch {}
 }
diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts
index ac29238..e8c888a 100644
--- a/src/events/channelDelete.ts
+++ b/src/events/channelDelete.ts
@@ -3,69 +3,71 @@
 export const event = 'channelDelete'
 
 export async function callback(client, channel) {
-	const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = channel.client.logger
+    try{
+        const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = channel.client.logger
 
-	let auditLog = await getAuditLog(channel.guild, 'CHANNEL_DELETE');
-	let audit = auditLog.entries.filter(entry => entry.target.id == channel.id).first();
-    if (audit.executor.id == client.user.id) return;
+        let auditLog = await getAuditLog(channel.guild, 'CHANNEL_DELETE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == channel.id).first();
+        if (audit.executor.id == client.user.id) return;
 
-	let emoji;
-	let readableType;
-	let displayName;
-	switch (channel.type) {
-		case 'GUILD_TEXT': {
-			emoji = "CHANNEL.TEXT.DELETE";
-			readableType = "Text";
-			displayName = "Text Channel"
-			break;
-		}
-		case 'GUILD_VOICE': {
-			emoji = "CHANNEL.VOICE.DELETE";
-			readableType = "Voice";
-			displayName = "Voice Channel"
-			break;
-		}
-		case 'GUILD_CATEGORY': {
-			emoji = "CHANNEL.CATEGORY.DELETE";
-			readableType = "Category";
-			displayName = "Category"
-			break;
-		}
-		default: {
-			emoji = "CHANNEL.TEXT.DELETE";
-			readableType = "Channel";
-			displayName = "Channel"
-		}
-	}
-	let list = {
-		id: entry(channel.id, `\`${channel.id}\``),
-		name: entry(channel.id, `${channel.name}`),
-		topic: null,
-		type: entry(channel.type, readableType),
-		category: entry(channel.parent ? channel.parent.id : null, channel.parent ? channel.parent.name : "Uncategorised"),
-		nsfw: null,
-		created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp)),
-		deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
-		deletedBy: entry(audit.executor.id, renderUser(audit.executor))
-	}
-	if (channel.topic != null ?? false) list.topic = entry(channel.topic, `\`\`\`\n${channel.topic.replace('`', "'")}\n\`\`\``);
-	else delete list.topic;
-	if (channel.nsfw !== null ?? false) list.nsfw = entry(channel.nsfw, channel.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`);
-	else delete list.nsfw;
+        let emoji;
+        let readableType;
+        let displayName;
+        switch (channel.type) {
+            case 'GUILD_TEXT': {
+                emoji = "CHANNEL.TEXT.DELETE";
+                readableType = "Text";
+                displayName = "Text Channel"
+                break;
+            }
+            case 'GUILD_VOICE': {
+                emoji = "CHANNEL.VOICE.DELETE";
+                readableType = "Voice";
+                displayName = "Voice Channel"
+                break;
+            }
+            case 'GUILD_CATEGORY': {
+                emoji = "CHANNEL.CATEGORY.DELETE";
+                readableType = "Category";
+                displayName = "Category"
+                break;
+            }
+            default: {
+                emoji = "CHANNEL.TEXT.DELETE";
+                readableType = "Channel";
+                displayName = "Channel"
+            }
+        }
+        let list = {
+            id: entry(channel.id, `\`${channel.id}\``),
+            name: entry(channel.id, `${channel.name}`),
+            topic: null,
+            type: entry(channel.type, readableType),
+            category: entry(channel.parent ? channel.parent.id : null, channel.parent ? channel.parent.name : "Uncategorised"),
+            nsfw: null,
+            created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp)),
+            deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+            deletedBy: entry(audit.executor.id, renderUser(audit.executor))
+        }
+        if (channel.topic != null ?? false) list.topic = entry(channel.topic, `\`\`\`\n${channel.topic.replace('`', "'")}\n\`\`\``);
+        else delete list.topic;
+        if (channel.nsfw !== null ?? false) list.nsfw = entry(channel.nsfw, channel.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`);
+        else delete list.nsfw;
 
-	let data = {
-		meta:{
-			type: 'channelDelete',
-			displayName: displayName + ' Deleted',
-			calculateType: 'channelUpdate',
-			color: NucleusColors.red,
-			emoji: emoji,
-			timestamp: audit.createdTimestamp
-		},
-		list: list,
-		hidden: {
-			guild: channel.guild.id
-		}
-	}
-	log(data, channel.client);
+        let data = {
+            meta:{
+                type: 'channelDelete',
+                displayName: displayName + ' Deleted',
+                calculateType: 'channelUpdate',
+                color: NucleusColors.red,
+                emoji: emoji,
+                timestamp: audit.createdTimestamp
+            },
+            list: list,
+            hidden: {
+                guild: channel.guild.id
+            }
+        }
+        log(data, channel.client);
+    } catch {}
 }
diff --git a/src/events/channelUpdate.ts b/src/events/channelUpdate.ts
index f374edd..25b7375 100644
--- a/src/events/channelUpdate.ts
+++ b/src/events/channelUpdate.ts
@@ -1,133 +1,135 @@
 import humanizeDuration from 'humanize-duration';
-import readConfig from '../utils/readConfig.js'
 import getEmojiByName from '../utils/getEmojiByName.js';
 
 export const event = 'channelUpdate';
 
 export async function callback(client, oc, nc) {
-	let config = await readConfig(nc.guild.id);
-	const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderChannel } = client.logger
+    try {
+        let config = await client.memory.readGuildInfo(nc.guild.id);
+        const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderChannel } = client.logger
 
-	if (nc.parent && (nc.parent.id == config.tickets.category)) return
+        if (nc.parent && (nc.parent.id == config.tickets.category)) return
 
-	let auditLog = await getAuditLog(nc.guild, 'CHANNEL_UPDATE');
-	let audit = auditLog.entries.filter(entry => entry.target.id == nc.id).first();
-    if (audit.executor.id == client.user.id) return;
+        let auditLog = await getAuditLog(nc.guild, 'CHANNEL_UPDATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == nc.id).first();
+        if (audit.executor.id == client.user.id) return;
 
-	let emoji:string;
-	let readableType:string;
-	let displayName:string ;
-	let changes = {
-		id: entry(nc.id, `\`${nc.id}\``),
-		channel: entry(nc.id, renderChannel(nc)),
-		edited: entry(new Date().getTime(), renderDelta(new Date().getTime())),
-		editedBy: entry(audit.executor.id, renderUser((await nc.guild.members.fetch(audit.executor.id)).user)),
-	}
-	if (oc.name != nc.name) changes["name"] = entry([oc.name, nc.name], `${oc.name} -> ${nc.name}`);
-	if (oc.position != nc.position) changes["position"] = entry([oc.position, nc.position], `${oc.position} -> ${nc.position}`);
+        let emoji:string;
+        let readableType:string;
+        let displayName:string ;
+        let changes = {
+            id: entry(nc.id, `\`${nc.id}\``),
+            channel: entry(nc.id, renderChannel(nc)),
+            edited: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+            editedBy: entry(audit.executor.id, renderUser((await nc.guild.members.fetch(audit.executor.id)).user)),
+        }
+        if (oc.name != nc.name) changes["name"] = entry([oc.name, nc.name], `${oc.name} -> ${nc.name}`);
+        if (oc.position != nc.position) changes["position"] = entry([oc.position, nc.position], `${oc.position} -> ${nc.position}`);
 
-	switch (nc.type) {
-		case 'GUILD_TEXT': {
-			emoji = "CHANNEL.TEXT.EDIT";
-			readableType = "Text";
-			displayName = "Text Channel"
-			let oldTopic = oc.topic, newTopic = nc.topic;
-			if (oldTopic) {
-				if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
-				else oldTopic = `\`\`\`\n${oldTopic.replace('`', "'")}\n\`\`\``
-			} else { oldTopic = "None"; }
-			if (newTopic) {
-				if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
-				else newTopic = `\`\`\`\n${newTopic.replace('`', "'")}\n\`\`\``
-			} else { newTopic = "None"; }
-			let nsfw = ["", ""]
-			nsfw[0] = oc.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
-			nsfw[1] = nc.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
-			if (oc.topic != nc.topic) changes["description"] = entry([oc.topic, nc.topic], `\nBefore: ${oldTopic}\nAfter: ${newTopic}`);
-			if (oc.nsfw != nc.nsfw) changes["nsfw"] = entry([oc.nsfw, nc.nsfw], `${nsfw[0]} -> ${nsfw[1]}`);
-			if (oc.rateLimitPerUser != nc.rateLimitPerUser) changes["rateLimitPerUser"] = entry(
-				[oc.rateLimitPerUser, nc.rateLimitPerUser],
-				`${humanizeDuration(oc.rateLimitPerUser * 1000)} -> ${humanizeDuration(nc.rateLimitPerUser * 1000)}`
-			);
-			break;
-		}
-		case 'GUILD_NEWS': {
-			emoji = "CHANNEL.TEXT.EDIT";
-			readableType = "News";
-			displayName = "News Channel"
-			let oldTopic = oc.topic, newTopic = nc.topic;
-			if (oldTopic) {
-				if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
-				else oldTopic = `\`\`\`\n${oldTopic.replace('`', "'")}\n\`\`\``
-			} else { oldTopic = "None"; }
-			if (newTopic) {
-				if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
-				else newTopic = `\`\`\`\n${newTopic.replace('`', "'")}\n\`\`\``
-			} else { newTopic = "None"; }
-			if (oc.nsfw != nc.nsfw) changes["nsfw"] = entry([oc.nsfw, nc.nsfw], `${oc.nsfw ? "On" : "Off"} -> ${nc.nsfw ? "On" : "Off"}`);
-			break;
-		}
-		case 'GUILD_VOICE': {
-			emoji = "CHANNEL.VOICE.EDIT";
-			readableType = "Voice";
-			displayName = "Voice Channel"
-			if (oc.bitrate != nc.bitrate) changes["bitrate"] = entry([oc.bitrate, nc.bitrate], `${oc.bitrate} -> ${nc.bitrate}`);
-			if (oc.userLimit != nc.userLimit) changes["maxUsers"] = entry([oc.userLimit, nc.userLimit], `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${nc.userLimit}`);
-			if (oc.rtcRegion != nc.rtcRegion) changes["region"] = entry(
-				[oc.rtcRegion, nc.rtcRegion],
-				`${oc.rtcRegion || "Automatic"} -> ${nc.rtcRegion || "Automatic"}`
-			);
-			break;
-		}
-		case 'GUILD_STAGE': {
-			emoji = "CHANNEL.VOICE.EDIT";
-			readableType = "Stage";
-			displayName = "Stage Channel"
-			let oldTopic = oc.topic, newTopic = nc.topic;
-			if (oldTopic) {
-				if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
-				else oldTopic = `\`\`\`\n${oldTopic.replace('`', "'")}\n\`\`\``
-			} else { oldTopic = "None"; }
-			if (newTopic) {
-				if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
-				else newTopic = `\`\`\`\n${newTopic.replace('`', "'")}\n\`\`\``
-			} else { newTopic = "None"; }
-			if (oc.bitrate != nc.bitrate) changes["bitrate"] = entry([oc.bitrate, nc.bitrate], `${oc.bitrate} -> ${nc.bitrate}`);
-			if (oc.userLimit != nc.userLimit) changes["maxUsers"] = entry([oc.userLimit, nc.userLimit], `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${nc.userLimit}`);
-			if (oc.rtcRegion != nc.rtcRegion) changes["region"] = entry(
-				[oc.rtcRegion, nc.rtcRegion],
-				`${oc.rtcRegion || "Automatic"} -> ${nc.rtcRegion || "Automatic"}`
-			);
-			break;
-		}
-		case 'GUILD_CATEGORY': {
-			emoji = "CHANNEL.CATEGORY.EDIT";
-			readableType = "Category";
-			displayName = "Category"
-			break;
-		}
-		default: {
-			emoji = "CHANNEL.TEXT.EDIT";
-			readableType = "Channel";
-			displayName = "Channel"
-		}
-	}
-	let t = oc.type.split("_")[1];
-	if (oc.type != nc.type) changes["type"] = entry([oc.type, nc.type], `${t[0] + t.splice(1).toLowerCase()} -> ${readableType}`);
-	if (!(Object.values(changes).length - 4)) return
-	let data = {
-		meta:{
-			type: 'channelUpdate',
-			displayName: displayName + ' Edited',
-			calculateType: 'channelUpdate',
-			color: NucleusColors.yellow,
-			emoji: emoji,
-			timestamp: audit.createdTimestamp
-		},
-		list: changes,
-		hidden: {
-			guild: nc.guild.id
-		}
-	}
-	log(data, client);
+        switch (nc.type) {
+            case 'GUILD_TEXT': {
+                emoji = "CHANNEL.TEXT.EDIT";
+                readableType = "Text";
+                displayName = "Text Channel"
+                let oldTopic = oc.topic, newTopic = nc.topic;
+                if (oldTopic) {
+                    if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
+                    else oldTopic = `\`\`\`\n${oldTopic.replace('`', "'")}\n\`\`\``
+                } else { oldTopic = "None"; }
+                if (newTopic) {
+                    if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
+                    else newTopic = `\`\`\`\n${newTopic.replace('`', "'")}\n\`\`\``
+                } else { newTopic = "None"; }
+                let nsfw = ["", ""]
+                nsfw[0] = oc.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
+                nsfw[1] = nc.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
+                if (oc.topic != nc.topic) changes["description"] = entry([oc.topic, nc.topic], `\nBefore: ${oldTopic}\nAfter: ${newTopic}`);
+                if (oc.nsfw != nc.nsfw) changes["nsfw"] = entry([oc.nsfw, nc.nsfw], `${nsfw[0]} -> ${nsfw[1]}`);
+                if (oc.rateLimitPerUser != nc.rateLimitPerUser) changes["rateLimitPerUser"] = entry(
+                    [oc.rateLimitPerUser, nc.rateLimitPerUser],
+                    `${humanizeDuration(oc.rateLimitPerUser * 1000)} -> ${humanizeDuration(nc.rateLimitPerUser * 1000)}`
+                );
+
+                break;
+            }
+            case 'GUILD_NEWS': {
+                emoji = "CHANNEL.TEXT.EDIT";
+                readableType = "News";
+                displayName = "News Channel"
+                let oldTopic = oc.topic, newTopic = nc.topic;
+                if (oldTopic) {
+                    if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
+                    else oldTopic = `\`\`\`\n${oldTopic.replace('`', "'")}\n\`\`\``
+                } else { oldTopic = "None"; }
+                if (newTopic) {
+                    if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
+                    else newTopic = `\`\`\`\n${newTopic.replace('`', "'")}\n\`\`\``
+                } else { newTopic = "None"; }
+                if (oc.nsfw != nc.nsfw) changes["nsfw"] = entry([oc.nsfw, nc.nsfw], `${oc.nsfw ? "On" : "Off"} -> ${nc.nsfw ? "On" : "Off"}`);
+                break;
+            }
+            case 'GUILD_VOICE': {
+                emoji = "CHANNEL.VOICE.EDIT";
+                readableType = "Voice";
+                displayName = "Voice Channel"
+                if (oc.bitrate != nc.bitrate) changes["bitrate"] = entry([oc.bitrate, nc.bitrate], `${oc.bitrate} -> ${nc.bitrate}`);
+                if (oc.userLimit != nc.userLimit) changes["maxUsers"] = entry([oc.userLimit, nc.userLimit], `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${nc.userLimit}`);
+                if (oc.rtcRegion != nc.rtcRegion) changes["region"] = entry(
+                    [oc.rtcRegion, nc.rtcRegion],
+                    `${oc.rtcRegion || "Automatic"} -> ${nc.rtcRegion || "Automatic"}`
+                );
+                break;
+            }
+            case 'GUILD_STAGE': {
+                emoji = "CHANNEL.VOICE.EDIT";
+                readableType = "Stage";
+                displayName = "Stage Channel"
+                let oldTopic = oc.topic, newTopic = nc.topic;
+                if (oldTopic) {
+                    if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
+                    else oldTopic = `\`\`\`\n${oldTopic.replace('`', "'")}\n\`\`\``
+                } else { oldTopic = "None"; }
+                if (newTopic) {
+                    if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace('`', "'").substring(0, 253) + '...'}\n\`\`\``
+                    else newTopic = `\`\`\`\n${newTopic.replace('`', "'")}\n\`\`\``
+                } else { newTopic = "None"; }
+                if (oc.bitrate != nc.bitrate) changes["bitrate"] = entry([oc.bitrate, nc.bitrate], `${oc.bitrate} -> ${nc.bitrate}`);
+                if (oc.userLimit != nc.userLimit) changes["maxUsers"] = entry([oc.userLimit, nc.userLimit], `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${nc.userLimit}`);
+                if (oc.rtcRegion != nc.rtcRegion) changes["region"] = entry(
+                    [oc.rtcRegion, nc.rtcRegion],
+                    `${oc.rtcRegion || "Automatic"} -> ${nc.rtcRegion || "Automatic"}`
+                );
+                break;
+            }
+            case 'GUILD_CATEGORY': {
+                emoji = "CHANNEL.CATEGORY.EDIT";
+                readableType = "Category";
+                displayName = "Category"
+                break;
+            }
+            default: {
+                emoji = "CHANNEL.TEXT.EDIT";
+                readableType = "Channel";
+                displayName = "Channel"
+            }
+        }
+        let t = oc.type.split("_")[1];
+        if (oc.type != nc.type) changes["type"] = entry([oc.type, nc.type], `${t[0] + t.splice(1).toLowerCase()} -> ${readableType}`);
+        if (!(Object.values(changes).length - 4)) return
+        let data = {
+            meta:{
+                type: 'channelUpdate',
+                displayName: displayName + ' Edited',
+                calculateType: 'channelUpdate',
+                color: NucleusColors.yellow,
+                emoji: emoji,
+                timestamp: audit.createdTimestamp
+            },
+            list: changes,
+            hidden: {
+                guild: nc.guild.id
+            }
+        }
+        log(data, client);
+    } catch {}
 }
\ No newline at end of file
diff --git a/src/events/emojiCreate.ts b/src/events/emojiCreate.ts
index 3320267..c1ed3c5 100644
--- a/src/events/emojiCreate.ts
+++ b/src/events/emojiCreate.ts
@@ -1,28 +1,30 @@
 export const event = 'emojiCreate'
 
 export async function callback(client, emoji) {
-	const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderEmoji } = emoji.client.logger
-    let auditLog = await getAuditLog(emoji.guild, 'EMOJI_CREATE');
-    let audit = auditLog.entries.filter(entry => entry.target.id == emoji.id).first();
-    if (audit.executor.id == client.user.id) return;
-    let data = {
-        meta: {
-            type: 'emojiCreate',
-            displayName: 'Emoji Created',
-            calculateType: 'emojiUpdate',
-            color: NucleusColors.green,
-            emoji: "GUILD.EMOJI.CREATE",
-            timestamp: emoji.createdTimestamp
-        },
-        list: {
-            id: entry(emoji.id, `\`${emoji.id}\``),
-            emoji: entry(emoji.name, renderEmoji(emoji)),
-            createdBy: entry(audit.executor.id, renderUser(audit.executor)),
-            created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp))
-        },
-        hidden: {
-            guild: emoji.guild.id
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderEmoji } = emoji.client.logger
+        let auditLog = await getAuditLog(emoji.guild, 'EMOJI_CREATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == emoji.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let data = {
+            meta: {
+                type: 'emojiCreate',
+                displayName: 'Emoji Created',
+                calculateType: 'emojiUpdate',
+                color: NucleusColors.green,
+                emoji: "GUILD.EMOJI.CREATE",
+                timestamp: emoji.createdTimestamp
+            },
+            list: {
+                id: entry(emoji.id, `\`${emoji.id}\``),
+                emoji: entry(emoji.name, renderEmoji(emoji)),
+                createdBy: entry(audit.executor.id, renderUser(audit.executor)),
+                created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp))
+            },
+            hidden: {
+                guild: emoji.guild.id
+            }
         }
-    }
-    log(data, client);
+        log(data, client);
+    } catch {}
 }
diff --git a/src/events/emojiDelete.ts b/src/events/emojiDelete.ts
index d31b9c6..59bed1e 100644
--- a/src/events/emojiDelete.ts
+++ b/src/events/emojiDelete.ts
@@ -1,29 +1,31 @@
 export const event = 'emojiDelete'
 
 export async function callback(client, emoji) {
-	const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderEmoji } = emoji.client.logger
-    let auditLog = await getAuditLog(emoji.guild, 'EMOJI_DELETE');
-    let audit = auditLog.entries.filter(entry => entry.target.id == emoji.id).first();
-    if (audit.executor.id == client.user.id) return;
-    let data = {
-        meta: {
-            type: 'emojiDelete',
-            displayName: 'Emoji Deleted',
-            calculateType: 'emojiUpdate',
-            color: NucleusColors.red,
-            emoji: "GUILD.EMOJI.DELETE",
-            timestamp: audit.createdTimestamp,
-        },
-        list: {
-            id: entry(emoji.id, `\`${emoji.id}\``),
-            emoji: entry(emoji.name, renderEmoji(emoji)),
-            deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
-            created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp)),
-			deleted: entry(audit.createdTimestamp, renderDelta(audit.createdTimestamp)),
-        },
-        hidden: {
-            guild: emoji.guild.id
+    try{
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderEmoji } = emoji.client.logger
+        let auditLog = await getAuditLog(emoji.guild, 'EMOJI_DELETE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == emoji.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let data = {
+            meta: {
+                type: 'emojiDelete',
+                displayName: 'Emoji Deleted',
+                calculateType: 'emojiUpdate',
+                color: NucleusColors.red,
+                emoji: "GUILD.EMOJI.DELETE",
+                timestamp: audit.createdTimestamp,
+            },
+            list: {
+                id: entry(emoji.id, `\`${emoji.id}\``),
+                emoji: entry(emoji.name, renderEmoji(emoji)),
+                deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
+                created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp)),
+                deleted: entry(audit.createdTimestamp, renderDelta(audit.createdTimestamp)),
+            },
+            hidden: {
+                guild: emoji.guild.id
+            }
         }
-    }
-    log(data, client);
+        log(data, client);
+    } catch {}
 }
diff --git a/src/events/emojiUpdate.ts b/src/events/emojiUpdate.ts
index 2566fed..2171b18 100644
--- a/src/events/emojiUpdate.ts
+++ b/src/events/emojiUpdate.ts
@@ -3,33 +3,35 @@
 export const event = 'emojiUpdate';
 
 export async function callback(client, oe, ne) {
-	const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderEmoji } = client.logger
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderEmoji } = client.logger
 
-    if (oe.name == ne.name) return
-	let auditLog = await getAuditLog(ne.guild, 'EMOJI_UPDATE');
-	let audit = auditLog.entries.first();
-    if (audit.executor.id == client.user.id) return;
+        if (oe.name == ne.name) return
+        let auditLog = await getAuditLog(ne.guild, 'EMOJI_UPDATE');
+        let audit = auditLog.entries.first();
+        if (audit.executor.id == client.user.id) return;
 
-	let changes = {
-		id: entry(ne.id, `\`${ne.id}\``),
-		emoji: entry(ne.id, renderEmoji(ne)),
-		edited: entry(ne.createdTimestamp, renderDelta(ne.createdTimestamp)),
-		editedBy: entry(audit.executor.id, renderUser((await ne.guild.members.fetch(audit.executor.id)).user)),
-		name: entry([oe.name, ne.name], `\`:${oe.name}:\` -> \`:${ne.name}:\``),
-	}
-	let data = {
-		meta:{
-			type: 'emojiUpdate',
-			displayName: 'Emoji Edited',
-			calculateType: 'emojiUpdate',
-			color: NucleusColors.yellow,
-			emoji: "GUILD.EMOJI.EDIT",
-			timestamp: audit.createdTimestamp
-		},
-		list: changes,
-		hidden: {
-			guild: ne.guild.id
-		}
-	}
-	log(data, client);
+        let changes = {
+            id: entry(ne.id, `\`${ne.id}\``),
+            emoji: entry(ne.id, renderEmoji(ne)),
+            edited: entry(ne.createdTimestamp, renderDelta(ne.createdTimestamp)),
+            editedBy: entry(audit.executor.id, renderUser((await ne.guild.members.fetch(audit.executor.id)).user)),
+            name: entry([oe.name, ne.name], `\`:${oe.name}:\` -> \`:${ne.name}:\``),
+        }
+        let data = {
+            meta:{
+                type: 'emojiUpdate',
+                displayName: 'Emoji Edited',
+                calculateType: 'emojiUpdate',
+                color: NucleusColors.yellow,
+                emoji: "GUILD.EMOJI.EDIT",
+                timestamp: audit.createdTimestamp
+            },
+            list: changes,
+            hidden: {
+                guild: ne.guild.id
+            }
+        }
+        log(data, client);
+    } catch {}
 }
\ No newline at end of file
diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts
new file mode 100644
index 0000000..4209788
--- /dev/null
+++ b/src/events/guildBanAdd.ts
@@ -0,0 +1,39 @@
+import { purgeByUser } from '../automations/tickets/delete.js';
+import { callback as statsChannelRemove } from '../automations/statsChannelRemove.js';
+
+export const event = 'guildBanAdd';
+
+export async function callback(client, ban) {
+    try { await statsChannelRemove(client, ban.user); } catch {}
+    try { purgeByUser(ban.user.id, ban.guild); } catch {}
+    try {
+        const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = ban.user.client.logger
+        let auditLog = await getAuditLog(ban.guild, 'MEMBER_BAN_ADD')
+        let audit = auditLog.entries.filter(entry => entry.target.id == ban.user.id).first();
+        if (audit.executor.id == client.user.id) return
+        console.log(ban.reason)
+        let data = {
+            meta: {
+                type: 'memberBan',
+                displayName: 'Member Banned',
+                calculateType: 'guildMemberPunish',
+                color: NucleusColors.red,
+                emoji: "PUNISH.BAN.RED",
+                timestamp: new Date().getTime()
+            },
+            list: {
+                id: entry(ban.user.id, `\`${ban.user.id}\``),
+                name: entry(ban.user.id, renderUser(ban.user)),
+                banned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+                bannedBy: entry(audit.executor.id, renderUser(audit.executor)),
+                reason: entry(audit.reason, audit.reason ? `\n> ${audit.reason}` : "*No reason provided.*"),
+                accountCreated: entry(ban.user.createdAt, renderDelta(ban.user.createdAt)),
+                serverMemberCount: ban.guild.memberCount,
+            },
+            hidden: {
+                guild: ban.guild.id
+            }
+        }
+        log(data, ban.user.client);
+    } catch {}
+}
diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts
new file mode 100644
index 0000000..11661f7
--- /dev/null
+++ b/src/events/guildBanRemove.ts
@@ -0,0 +1,37 @@
+import humanizeDuration from 'humanize-duration';
+import { purgeByUser } from '../automations/tickets/delete.js';
+import { callback as statsChannelRemove } from '../automations/statsChannelRemove.js';
+
+export const event = 'guildBanRemove';
+
+export async function callback(client, ban) {
+    try { await statsChannelRemove(client, ban.user); } catch {}
+    try { purgeByUser(ban.user.id, ban.guild); } catch {}
+    try {
+        const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = ban.user.client.logger
+        let auditLog = await getAuditLog(ban.guild, 'MEMBER_BAN_REMOVE')
+        let audit = auditLog.entries.filter(entry => entry.target.id == ban.user.id).first();
+        if (audit.executor.id == client.user.id) return
+        let data = {
+            meta: {
+                type: 'memberUnban',
+                displayName: 'Member Unbanned',
+                calculateType: 'guildMemberPunish',
+                color: NucleusColors.green,
+                emoji: "PUNISH.BAN.GREEN",
+                timestamp: new Date().getTime()
+            },
+            list: {
+                id: entry(ban.user.id, `\`${ban.user.id}\``),
+                name: entry(ban.user.id, renderUser(ban.user)),
+                unbanned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+                unbannedBy: entry(audit.executor.id, renderUser(audit.executor)),
+                accountCreated: entry(ban.user.createdAt, renderDelta(ban.user.createdAt)),
+            },
+            hidden: {
+                guild: ban.guild.id
+            }
+        }
+        log(data, ban.user.client);
+    } catch (e) {console.log(e)}
+}
diff --git a/src/events/guildCreate.ts b/src/events/guildCreate.ts
index 4935b4d..0222c7c 100644
--- a/src/events/guildCreate.ts
+++ b/src/events/guildCreate.ts
@@ -6,5 +6,7 @@
 export const event = 'guildCreate';
 
 export async function callback(client, guild) {
-    guide(guild)
+    try{
+        guide(guild)
+    } catch {}
 }
diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts
new file mode 100644
index 0000000..a1601bb
--- /dev/null
+++ b/src/events/guildMemberUpdate.ts
@@ -0,0 +1,36 @@
+import { callback as statsChannelAdd } from '../automations/statsChannelAdd.js';
+import { callback as welcome } from '../automations/welcome.js';
+import log from '../utils/log.js';
+export const event = 'guildMemberUpdate'
+
+export async function callback(client, before, after) {
+    try {
+        const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = after.client.logger
+        if (before.nickname != after.nickname) {
+            let auditLog = await getAuditLog(after.guild, 'MEMBER_UPDATE');
+            let audit = auditLog.entries.filter(entry => entry.target.id == after.id).first();
+            if (audit.executor.id == client.user.id) return;
+            let data = {
+                meta: {
+                    type: 'memberUpdate',
+                    displayName: 'Nickname Changed',
+                    calculateType: 'guildMemberUpdate',
+                    color: NucleusColors.yellow,
+                    emoji: "PUNISH.NICKNAME.YELLOW",
+                    timestamp: new Date().getTime()
+                },
+                list: {
+                    id: entry(after.id, `\`${after.id}\``),
+                    before: entry(before.nickname, before.nickname ? before.nickname : '*None*'),
+                    after: entry(after.nickname, after.nickname ? after.nickname : '*None*'),
+                    updated: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+                    updatedBy: entry(audit.executor.id, renderUser(audit.executor))
+                },
+                hidden: {
+                    guild: after.guild.id
+                }
+            }
+            log(data, after.client);
+        }
+    } catch (e) { console.log(e) }
+}
diff --git a/src/events/guildUpdate.ts b/src/events/guildUpdate.ts
new file mode 100644
index 0000000..400cfe4
--- /dev/null
+++ b/src/events/guildUpdate.ts
@@ -0,0 +1,58 @@
+export const event = 'guildUpdate'
+
+export async function callback(client, before, after) {
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = after.client.logger
+        let auditLog = await getAuditLog(after, 'GUILD_UPDATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == after.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let list = {}
+
+        const verificationLevels = {
+            NONE: 'Unrestricted',
+            LOW: 'Verified email',
+            MEDIUM: 'Registered (5 minutes)',
+            HIGH: 'Member (10 minutes)',
+            VERY_HIGH: 'Verified phone'
+        }
+
+        const explicitContentFilterLevels = {
+            DISABLED: 'Disabled',
+            MEMBERS_WITHOUT_ROLES: 'Members without roles',
+            ALL_MEMBERS: 'All members'
+        }
+
+        const MFALevels = {
+            NONE: 'None',
+            ELEVATED: 'Enabled'
+        }
+
+        if (before.name != after.name) list["name"] = entry([before.name, after.name], `${before.name} -> ${after.name}`);
+        if (before.icon != after.icon) list["icon"] = entry([before.icon, after.icon], `[Before](${before.iconURL()}) -> [After](${after.iconURL()})`);
+        if (before.splash != after.splash) list["splash"] = entry([before.splash, after.splash], `[Before](${before.splashURL()}) -> [After](${after.splashURL()})`);
+        if (before.banner != after.banner) list["banner"] = entry([before.banner, after.banner], `[Before](${before.bannerURL()}) -> [After](${after.bannerURL()})`);
+        if (before.owner != after.owner) list["owner"] = entry([before.owner, after.owner], `${renderUser(before.owner.user)} -> ${renderUser(after.owner.user)}`);
+        if (before.verificationLevel != after.verificationLevel) list["verificationLevel"] = entry([verificationLevels[before.verificationLevel], verificationLevels[after.verificationLevel]], `${verificationLevels[before.verificationLevel]} -> ${verificationLevels[after.verificationLevel]}`);
+        if (before.explicitContentFilter != after.explicitContentFilter) list["explicitContentFilter"] = entry([explicitContentFilterLevels[before.explicitContentFilter], explicitContentFilterLevels[after.explicitContentFilter]], `${explicitContentFilterLevels[before.explicitContentFilter]} -> ${explicitContentFilterLevels[after.explicitContentFilter]}`);
+        if (before.mfaLevel != after.mfaLevel) list["2 factor authentication"] = entry([MFALevels[before.mfaLevel], MFALevels[after.mfaLevel]], `${MFALevels[before.mfaLevel]} -> ${MFALevels[after.mfaLevel]}`);
+
+        if (!(Object.keys(list).length)) return;
+        list["updated"] = entry(new Date().getTime(), renderDelta(new Date().getTime()))
+        list["updatedBy"] = entry(audit.executor.id, renderUser(audit.executor))
+        let data = {
+            meta: {
+                type: 'guildUpdate',
+                displayName: 'Guild Edited',
+                calculateType: 'guildUpdate',
+                color: NucleusColors.yellow,
+                emoji: "GUILD.YELLOW",
+                timestamp: new Date().getTime()
+            },
+            list: list,
+            hidden: {
+                guild: after.id
+            }
+        }
+        log(data, after.client);
+    } catch (e) {}
+}
diff --git a/src/events/inviteCreate.ts b/src/events/inviteCreate.ts
new file mode 100644
index 0000000..bdfeede
--- /dev/null
+++ b/src/events/inviteCreate.ts
@@ -0,0 +1,32 @@
+import humanizeDuration from 'humanize-duration';
+export const event = 'inviteCreate'
+
+export async function callback(client, invite) {
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = invite.client.logger
+        let auditLog = await getAuditLog(invite.guild, 'INVITE_CREATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == invite.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let data = {
+            meta: {
+                type: 'inviteCreate',
+                displayName: 'Invite Created',
+                calculateType: 'guildUpdate',
+                color: NucleusColors.green,
+                emoji: "INVITE.CREATE",
+                timestamp: invite.createdTimestamp
+            },
+            list: {
+                channel: entry(invite.channel.id, renderChannel(invite.channel)),
+                link: entry(invite.url, invite.url),
+                expires: entry(invite.maxAge, invite.maxAge ? humanizeDuration(invite.maxAge * 1000) : 'Never'),
+                createdBy: entry(audit.executor.id, renderUser(audit.executor)),
+                created: entry(invite.createdTimestamp, renderDelta(invite.createdTimestamp))
+            },
+            hidden: {
+                guild: invite.guild.id
+            }
+        }
+        log(data, invite.client);
+    } catch {}
+}
diff --git a/src/events/inviteDelete.ts b/src/events/inviteDelete.ts
new file mode 100644
index 0000000..dec234f
--- /dev/null
+++ b/src/events/inviteDelete.ts
@@ -0,0 +1,32 @@
+import humanizeDuration from 'humanize-duration';
+export const event = 'inviteDelete'
+
+export async function callback(client, invite) {
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = invite.client.logger
+        let auditLog = await getAuditLog(invite.guild, 'INVITE_DELETE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == invite.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let data = {
+            meta: {
+                type: 'inviteDelete',
+                displayName: 'Invite Deleted',
+                calculateType: 'guildUpdate',
+                color: NucleusColors.red,
+                emoji: "INVITE.DELETE",
+                timestamp: new Date().getTime()
+            },
+            list: {
+                channel: entry(invite.channel.id, renderChannel(invite.channel)),
+                link: entry(invite.url, invite.url),
+                expires: entry(invite.maxAge, invite.maxAge ? humanizeDuration(invite.maxAge * 1000) : 'Never'),
+                deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
+                deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+            },
+            hidden: {
+                guild: invite.guild.id
+            }
+        }
+        log(data, invite.client);
+    } catch {}
+}
diff --git a/src/events/memberLeave.ts b/src/events/memberLeave.ts
index ea461ab..22b7cd3 100644
--- a/src/events/memberLeave.ts
+++ b/src/events/memberLeave.ts
@@ -4,31 +4,67 @@
 
 export const event = 'guildMemberRemove'
 
-export async function callback(_, member) {
-    try { await statsChannelRemove(_, member); } catch {}
-    try { purgeByUser(member.id, member.guild); } catch {} // TODO: add this to ban as well
+export async function callback(client, member) {
+    try { await statsChannelRemove(client, member); } catch {}
+    try { purgeByUser(member.id, member.guild); } catch {}
     try {
-        const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
-        let data = {
-            meta: {
-                type: 'memberLeave',
-                displayName: 'Member Left',
-                calculateType: 'guildMemberUpdate',
-                color: NucleusColors.red,
-                emoji: "MEMBER" + (member.user.bot ? ".BOT" : "") + ".LEAVE",
-                timestamp: new Date().getTime()
-            },
-            list: {
-                id: entry(member.id, `\`${member.id}\``),
-                name: entry(member.id, renderUser(member.user)),
-                joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
-                left: entry(new Date().getTime(), renderDelta(new Date().getTime())),
-                timeInServer: entry(new Date().getTime() - member.joinedAt, humanizeDuration(new Date().getTime() - member.joinedAt, { round: true })),
-                accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
-                serverMemberCount: member.guild.memberCount,
-            },
-            hidden: {
-                guild: member.guild.id
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
+        let auditLog = await getAuditLog(member.guild, 'MEMBER_KICK');
+        let audit = auditLog.entries.filter(entry => entry.target.id == member.id).first();
+        let type = "kick"
+        if (audit) {
+            if (audit.createdAt - 100 < new Date().getTime()) {
+                type = "leave"
+            } else if (audit.executor.id == client.user.id) return
+        }
+        let data
+        if (type == "kick") {
+            data = {
+                meta: {
+                    type: 'memberKick',
+                    displayName: 'Member Kicked',
+                    calculateType: 'guildMemberPunish',
+                    color: NucleusColors.red,
+                    emoji: "PUNISH.KICK.RED",
+                    timestamp: new Date().getTime()
+                },
+                list: {
+                    id: entry(member.id, `\`${member.id}\``),
+                    name: entry(member.id, renderUser(member.user)),
+                    joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
+                    kicked: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+                    kickedBy: entry(audit.executor.id, renderUser(audit.executor)),
+                    reason: entry(audit.reason, audit.reason ? `\n> ${audit.reason}` : "*No reason provided.*"),
+                    timeInServer: entry(new Date().getTime() - member.joinedAt, humanizeDuration(new Date().getTime() - member.joinedAt, { round: true })),
+                    accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
+                    serverMemberCount: member.guild.memberCount,
+                },
+                hidden: {
+                    guild: member.guild.id
+                }
+            }
+        } else {
+            data = {
+                meta: {
+                    type: 'memberLeave',
+                    displayName: 'Member Left',
+                    calculateType: 'guildMemberUpdate',
+                    color: NucleusColors.red,
+                    emoji: "MEMBER." + (member.bot ? "BOT." : "") + "LEAVE",
+                    timestamp: new Date().getTime()
+                },
+                list: {
+                    id: entry(member.id, `\`${member.id}\``),
+                    name: entry(member.id, renderUser(member.user)),
+                    joined: entry(member.joinedTimestamp, renderDelta(member.joinedAt)),
+                    left: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+                    timeInServer: entry(new Date().getTime() - member.joinedTimestamp, humanizeDuration(new Date().getTime() - member.joinedAt, { round: true })),
+                    accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
+                    serverMemberCount: member.guild.memberCount,
+                },
+                hidden: {
+                    guild: member.guild.id
+                }
             }
         }
         log(data, member.client);
diff --git a/src/events/messageChecks.ts b/src/events/messageChecks.ts
index 83cfff1..4e99c61 100644
--- a/src/events/messageChecks.ts
+++ b/src/events/messageChecks.ts
@@ -1,101 +1,100 @@
 import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from '../automations/unscan.js'
-import readConfig from '../utils/readConfig.js'
 import { Message } from 'discord.js'
 
 export const event = 'messageCreate'
 
-export async function callback(_, message) {
-	if (message.author.bot) return
-	if (message.channel.type === 'dm') return
+export async function callback(client, message) {
+    if (message.author.bot) return
+    if (message.channel.type === 'dm') return
 
-	let content = message.content.toLowerCase() || ''
-	let config = await readConfig(message.guild.id);
+    let content = message.content.toLowerCase() || ''
+    let config = await client.memory.readGuildInfo(message.guild.id);
 
-	if (config.filters.invite.enabled) {
-		if (!config.filters.invite.allowed.users.includes(message.author.id) ||
-			!config.filters.invite.allowed.channels.includes(message.channel.id) ||
-			!message.author.roles.cache.some(role => config.filters.invite.allowed.roles.includes(role.id))
-		) {
-			if ((/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content))) {
-				message.delete();
-				return toLog(message, 'invite', content.match(/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/))
-			}
-		}
-	}
+    if (config.filters.invite.enabled) {
+        if (!config.filters.invite.allowed.users.includes(message.author.id) ||
+            !config.filters.invite.allowed.channels.includes(message.channel.id) ||
+            !message.author.roles.cache.some(role => config.filters.invite.allowed.roles.includes(role.id))
+        ) {
+            if ((/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content))) {
+                message.delete();
+                return toLog(message, 'invite', content.match(/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/))
+            }
+        }
+    }
 
-	let attachments = message.attachments.map(element => element)
-	attachments = [...attachments, ...content.match(
-		/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi
-	) ?? []].filter(element => (element.url ? element.url : element))
-	if (attachments.length > 0) {
-		attachments.forEach(async element => {
-			if(!message) return;
-			let url = element.url ? element.url : element
-			if (url != undefined) {
-				if(/\.+(webp|png|jpg|jpeg|bmp)/.test(url)) {
-					if (config.filters.images.NSFW && !message.channel.nsfw) {
-						if (await NSFWCheck(url)) {
-							await message.delete()
-							return toLog(message, 'NSFW', url)
-						}
-					}
-					if (config.filters.images.size) {
-						if(!url.match(/\.+(webp|png|jpg)$/gi)) return
-						if(!await SizeCheck(element)) {
-							await message.delete()
-							return toLog(message, 'size', url)
-						}
-					}
-				}
-				if (config.filters.malware) {
-					if (!MalwareCheck(url)) {
-						await message.delete()
-						return toLog(message, 'malware', url)
-					}
-				}
-			}
-		});
-	}
-	if(!message) return;
+    let attachments = message.attachments.map(element => element)
+    attachments = [...attachments, ...content.match(
+        /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi
+    ) ?? []].filter(element => (element.url ? element.url : element))
+    if (attachments.length > 0) {
+        attachments.forEach(async element => {
+            if(!message) return;
+            let url = element.url ? element.url : element
+            if (url != undefined) {
+                if(/\.+(webp|png|jpg|jpeg|bmp)/.test(url)) {
+                    if (config.filters.images.NSFW && !message.channel.nsfw) {
+                        if (await NSFWCheck(url)) {
+                            await message.delete()
+                            return toLog(message, 'NSFW', url)
+                        }
+                    }
+                    if (config.filters.images.size) {
+                        if(!url.match(/\.+(webp|png|jpg)$/gi)) return
+                        if(!await SizeCheck(element)) {
+                            await message.delete()
+                            return toLog(message, 'size', url)
+                        }
+                    }
+                }
+                if (config.filters.malware) {
+                    if (!MalwareCheck(url)) {
+                        await message.delete()
+                        return toLog(message, 'malware', url)
+                    }
+                }
+            }
+        });
+    }
+    if(!message) return;
 
-	if (await LinkCheck(message)) {
-		await message.delete()
-		return toLog(message, 'link')
-	}
+    if (await LinkCheck(message)) {
+        await message.delete()
+        return toLog(message, 'link')
+    }
 
-	if (config.filters.wordFilter.enabled) {
-		let check = TestString(content, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict)
-		if(check != "none") {
-			await message.delete()
-			return toLog(message, 'wordFilter', content)
-		}
-	}
+    if (config.filters.wordFilter.enabled) {
+        let check = TestString(content, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict)
+        if(check != "none") {
+            await message.delete()
+            return toLog(message, 'wordFilter', content)
+        }
+    }
 
-	if (!config.filters.pings.allowed.users.includes(message.author.id) ||
-		!config.filters.pings.allowed.channels.includes(message.channel.id) ||
-		!message.author.roles.cache.some(role => config.filters.pings.allowed.roles.includes(role.id))
-	) {
-		if (config.filters.pings.everyone && message.mentions.everyone) {
-			message.delete();
-			return toLog(message, 'mention everyone')
-		}
-		if (config.filters.pings.roles) {
-			for(let role of message.mentions.roles) {
-				if(!message) return;
-				if (!config.filters.pings.allowed.roles.includes(role.id)) {
-					message.delete();
-					return toLog(message, 'mention role')
-				}
-			}
-		}
-		if(!message) return;
-		if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
-			message.delete();
-			return toLog(message, 'Mass Pings')
-		}
-	}
+    if (!config.filters.pings.allowed.users.includes(message.author.id) ||
+        !config.filters.pings.allowed.channels.includes(message.channel.id) ||
+        !message.author.roles.cache.some(role => config.filters.pings.allowed.roles.includes(role.id))
+    ) {
+        if (config.filters.pings.everyone && message.mentions.everyone) {
+            message.delete();
+            return toLog(message, 'mention everyone')
+        }
+        if (config.filters.pings.roles) {
+            for(let role of message.mentions.roles) {
+                if(!message) return;
+                if (!config.filters.pings.allowed.roles.includes(role.id)) {
+                    message.delete();
+                    return toLog(message, 'mention role')
+                }
+            }
+        }
+        if(!message) return;
+        if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
+            message.delete();
+            return toLog(message, 'Mass Pings')
+        }
+    }
 }
 
 async function toLog(message: Message, reason: string, data?: any) {
-	// log(message.guild.id, {type: reason, data: data})
+    // log(message.guild.id, {type: reason, data: data})
 }
diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts
index ccaacb8..f0f5e00 100644
--- a/src/events/messageDelete.ts
+++ b/src/events/messageDelete.ts
@@ -1,38 +1,45 @@
 export const event = 'messageDelete'
 
 export async function callback(client, message) {
-    if (message.author.id == client.user.id) return;
-	const { log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = message.channel.client.logger
-    message.reference = message.reference || {}
-    let content = message.cleanContent
-    if (content.length > 256) content = content.substring(0, 253) + '...'
-    let data = {
-        meta: {
-            type: 'messageDelete',
-            displayName: 'Message Deleted',
-            calculateType: 'messageDelete',
-            color: NucleusColors.red,
-            emoji: 'MESSAGE.DELETE',
-            timestamp: new Date().getTime()
-        },
-        separate: {
-            start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*',
-        },
-        list: {
-            id: entry(message.id, `\`${message.id}\``),
-            sentBy: entry(message.author.id, renderUser(message.author)),
-            sentIn: entry(message.channel.id, renderChannel(message.channel)),
-            deleted: entry(new Date(message.createdTimestamp), renderDelta(new Date(message.createdTimestamp))),
-            mentions: message.mentions.users.size,
-            attachments: message.attachments.size,
-            repliedTo: entry(
-                message.reference.messageId || null,
-                message.reference.messageId ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})` : "None"
-            )
-        },
-        hidden: {
-            guild: message.channel.guild.id
+    try {
+        if (message.author.id == client.user.id) return;
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = message.channel.client.logger
+        let auditLog = await getAuditLog(message.guild, 'MEMBER_BAN_ADD')
+        let audit = auditLog.entries.filter(entry => entry.target.id == message.author.id).first();
+        if (audit) {
+            if (audit.createdAt - 100 < new Date().getTime()) return;
         }
-    }
-    log(data, client);
+        message.reference = message.reference || {}
+        let content = message.cleanContent
+        if (content.length > 256) content = content.substring(0, 253) + '...'
+        let data = {
+            meta: {
+                type: 'messageDelete',
+                displayName: 'Message Deleted',
+                calculateType: 'messageDelete',
+                color: NucleusColors.red,
+                emoji: 'MESSAGE.DELETE',
+                timestamp: new Date().getTime()
+            },
+            separate: {
+                start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*',
+            },
+            list: {
+                id: entry(message.id, `\`${message.id}\``),
+                sentBy: entry(message.author.id, renderUser(message.author)),
+                sentIn: entry(message.channel.id, renderChannel(message.channel)),
+                deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+                mentions: message.mentions.users.size,
+                attachments: message.attachments.size,
+                repliedTo: entry(
+                    message.reference.messageId || null,
+                    message.reference.messageId ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})` : "None"
+                )
+            },
+            hidden: {
+                guild: message.channel.guild.id
+            }
+        }
+        log(data, client);
+    } catch {}
 }
diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts
index 318b0ef..ec713a2 100644
--- a/src/events/messageEdit.ts
+++ b/src/events/messageEdit.ts
@@ -1,44 +1,46 @@
 export const event = 'messageUpdate'
 
 export async function callback(client, oldMessage, newMessage) {
-    if (newMessage.author.id == client.user.id) return;
-	const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = newMessage.channel.client.logger
-    newMessage.reference = newMessage.reference || {}
-    let newContent = newMessage.cleanContent.replaceAll("`", "‘")
-    let oldContent = oldMessage.cleanContent.replaceAll("`", "‘")
-    if (newContent == oldContent) return;
-    if (newContent.length > 256) newContent = newContent.substring(0, 253) + '...'
-    if (oldContent.length > 256) oldContent = oldContent.substring(0, 253) + '...'
-    let data = {
-        meta: {
-            type: 'messageUpdate',
-            displayName: 'Message Edited',
-            calculateType: 'messageUpdate',
-            color: NucleusColors.yellow,
-            emoji: 'MESSAGE.EDIT',
-            timestamp: newMessage.editedTimestamp
-        },
-        separate: {
-            start: (oldContent ? `**Before:**\n\`\`\`\n${oldContent}\n\`\`\`\n` : '**Before:** *Message had no content*\n') +
-                   (newContent ? `**After:**\n\`\`\`\n${newContent}\n\`\`\`` : '**After:** *Message had no content*'),
-            end: `[[Jump to message]](${newMessage.url})`
-        },
-        list: {
-            id: entry(newMessage.id, `\`${newMessage.id}\``),
-            sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
-            sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel)),
-            sent: entry(new Date(newMessage.createdTimestamp), renderDelta(new Date(newMessage.createdTimestamp))),
-            edited: entry(new Date(newMessage.editedTimestamp), renderDelta(new Date(newMessage.editedTimestamp))),
-            mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size),
-            attachments: renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size),
-            repliedTo: entry(
-                newMessage.reference.messageId || null,
-                newMessage.reference.messageId ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${newMessage.reference.messageId})` : "None"
-            )
-        },
-        hidden: {
-            guild: newMessage.channel.guild.id
+    try {
+        if (newMessage.author.id == client.user.id) return;
+        const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = newMessage.channel.client.logger
+        newMessage.reference = newMessage.reference || {}
+        let newContent = newMessage.cleanContent.replaceAll("`", "‘")
+        let oldContent = oldMessage.cleanContent.replaceAll("`", "‘")
+        if (newContent == oldContent) return;
+        if (newContent.length > 256) newContent = newContent.substring(0, 253) + '...'
+        if (oldContent.length > 256) oldContent = oldContent.substring(0, 253) + '...'
+        let data = {
+            meta: {
+                type: 'messageUpdate',
+                displayName: 'Message Edited',
+                calculateType: 'messageUpdate',
+                color: NucleusColors.yellow,
+                emoji: 'MESSAGE.EDIT',
+                timestamp: newMessage.editedTimestamp
+            },
+            separate: {
+                start: (oldContent ? `**Before:**\n\`\`\`\n${oldContent}\n\`\`\`\n` : '**Before:** *Message had no content*\n') +
+                    (newContent ? `**After:**\n\`\`\`\n${newContent}\n\`\`\`` : '**After:** *Message had no content*'),
+                end: `[[Jump to message]](${newMessage.url})`
+            },
+            list: {
+                id: entry(newMessage.id, `\`${newMessage.id}\``),
+                sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
+                sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel)),
+                sent: entry(new Date(newMessage.createdTimestamp), renderDelta(new Date(newMessage.createdTimestamp))),
+                edited: entry(new Date(newMessage.editedTimestamp), renderDelta(new Date(newMessage.editedTimestamp))),
+                mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size),
+                attachments: renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size),
+                repliedTo: entry(
+                    newMessage.reference.messageId || null,
+                    newMessage.reference.messageId ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${newMessage.reference.messageId})` : "None"
+                )
+            },
+            hidden: {
+                guild: newMessage.channel.guild.id
+            }
         }
-    }
-    log(data, client);
+        log(data, client);
+    } catch {}
 }
diff --git a/src/events/roleCreate.ts b/src/events/roleCreate.ts
index 76af433..2664790 100644
--- a/src/events/roleCreate.ts
+++ b/src/events/roleCreate.ts
@@ -1,29 +1,31 @@
 export const event = 'roleCreate'
 
 export async function callback(client, role) {
-	const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderRole } = role.client.logger
-    if (role.managed) return;
-    let auditLog = await getAuditLog(role.guild, 'ROLE_CREATE');
-    let audit = auditLog.entries.filter(entry => entry.target.id == role.id).first();
-    if (audit.executor.id == client.user.id) return;
-    let data = {
-        meta: {
-            type: 'roleCreate',
-            displayName: 'Role Created',
-            calculateType: 'guildRoleUpdate',
-            color: NucleusColors.green,
-            emoji: "GUILD.ROLES.CREATE",
-            timestamp: role.createdTimestamp
-        },
-        list: {
-            id: entry(role.id, `\`${role.id}\``),
-            role: entry(role.name, renderRole(role)),
-            createdBy: entry(audit.executor.id, renderUser(audit.executor)),
-            created: entry(role.createdTimestamp, renderDelta(role.createdTimestamp))
-        },
-        hidden: {
-            guild: role.guild.id
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderRole } = role.client.logger
+        if (role.managed) return;
+        let auditLog = await getAuditLog(role.guild, 'ROLE_CREATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == role.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let data = {
+            meta: {
+                type: 'roleCreate',
+                displayName: 'Role Created',
+                calculateType: 'guildRoleUpdate',
+                color: NucleusColors.green,
+                emoji: "GUILD.ROLES.CREATE",
+                timestamp: role.createdTimestamp
+            },
+            list: {
+                id: entry(role.id, `\`${role.id}\``),
+                role: entry(role.name, renderRole(role)),
+                createdBy: entry(audit.executor.id, renderUser(audit.executor)),
+                created: entry(role.createdTimestamp, renderDelta(role.createdTimestamp))
+            },
+            hidden: {
+                guild: role.guild.id
+            }
         }
-    }
-    log(data, client);
+        log(data, client);
+    } catch {}
 }
diff --git a/src/events/roleDelete.ts b/src/events/roleDelete.ts
index c5cbe63..6edfeed 100644
--- a/src/events/roleDelete.ts
+++ b/src/events/roleDelete.ts
@@ -3,34 +3,36 @@
 export const event = 'roleDelete'
 
 export async function callback(client, role) {
-	const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = role.client.logger
-    if (role.managed) return;
-    let auditLog = await getAuditLog(role.guild, 'ROLE_DELETE');
-    let audit = auditLog.entries.filter(entry => entry.target.id == role.id).first();
-    if (audit.executor.id == client.user.id) return;
-    let data = {
-        meta: {
-            type: 'roleDelete',
-            displayName: 'Role Deleted',
-            calculateType: 'guildRoleUpdate',
-            color: NucleusColors.red,
-            emoji: "GUILD.ROLES.DELETE",
-            timestamp: audit.createdTimestamp,
-        },
-        list: {
-            id: entry(role.id, `\`${role.id}\``),
-            role: entry(role.name, role.name),
-            color: entry(role.hexColor, `\`${role.hexColor}\``),
-            showInMemberList: entry(role.hoist, role.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`),
-            mentionable: entry(role.mentionable, role.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`),
-            members: entry(role.members.size, `${role.members.size}`),
-            deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
-            created: entry(role.createdTimestamp, renderDelta(role.createdTimestamp)),
-            deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
-        },
-        hidden: {
-            guild: role.guild.id
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = role.client.logger
+        if (role.managed) return;
+        let auditLog = await getAuditLog(role.guild, 'ROLE_DELETE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == role.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let data = {
+            meta: {
+                type: 'roleDelete',
+                displayName: 'Role Deleted',
+                calculateType: 'guildRoleUpdate',
+                color: NucleusColors.red,
+                emoji: "GUILD.ROLES.DELETE",
+                timestamp: audit.createdTimestamp,
+            },
+            list: {
+                id: entry(role.id, `\`${role.id}\``),
+                role: entry(role.name, role.name),
+                color: entry(role.hexColor, `\`${role.hexColor}\``),
+                showInMemberList: entry(role.hoist, role.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`),
+                mentionable: entry(role.mentionable, role.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`),
+                members: entry(role.members.size, `${role.members.size}`),
+                deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
+                created: entry(role.createdTimestamp, renderDelta(role.createdTimestamp)),
+                deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+            },
+            hidden: {
+                guild: role.guild.id
+            }
         }
-    }
-    log(data, client);
+        log(data, client);
+    } catch {}
 }
diff --git a/src/events/roleUpdate.ts b/src/events/roleUpdate.ts
index 28afe0e..faf3237 100644
--- a/src/events/roleUpdate.ts
+++ b/src/events/roleUpdate.ts
@@ -3,43 +3,45 @@
 export const event = 'roleUpdate';
 
 export async function callback(client, or, nr) {
-	const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderRole } = client.logger
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderRole } = client.logger
 
-	let auditLog = await getAuditLog(nr.guild, 'ROLE_UPDATE');
-	let audit = auditLog.entries.first();
-    if (audit.executor.id == client.user.id) return;
+        let auditLog = await getAuditLog(nr.guild, 'ROLE_UPDATE');
+        let audit = auditLog.entries.first();
+        if (audit.executor.id == client.user.id) return;
 
-	let changes = {
-		id: entry(nr.id, `\`${nr.id}\``),
-		role: entry(nr.id, renderRole(nr)),
-		edited: entry(nr.createdTimestamp, renderDelta(nr.createdTimestamp)),
-		editedBy: entry(audit.executor.id, renderUser((await nr.guild.members.fetch(audit.executor.id)).user)),
-	}
-    let mentionable = ["", ""]
-    let hoist = ["", ""]
-    mentionable[0] = or.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
-    mentionable[1] = nr.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
-    hoist[0] = or.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
-    hoist[1] = nr.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
-	if (or.name != nr.name) changes["name"] = entry([or.name, nr.name], `${or.name} -> ${nr.name}`);
-	if (or.position != nr.position) changes["position"] = entry([or.position, nr.position], `${or.position} -> ${nr.position}`);
-    if (or.hoist != nr.hoist) changes["showInMemberList"] = entry([or.hoist, nr.hoist], `${hoist[0]} -> ${hoist[1]}`);
-    if (or.mentionable != nr.mentionable) changes["mentionable"] = entry([or.mentionable, nr.mentionable], `${mentionable[0]} -> ${mentionable[1]}`);
-    if (or.hexColor != nr.hexColor) changes["color"] = entry([or.hexColor, nr.hexColor], `\`${or.hexColor}\` -> \`${nr.hexColor}\``);
+        let changes = {
+            id: entry(nr.id, `\`${nr.id}\``),
+            role: entry(nr.id, renderRole(nr)),
+            edited: entry(nr.createdTimestamp, renderDelta(nr.createdTimestamp)),
+            editedBy: entry(audit.executor.id, renderUser((await nr.guild.members.fetch(audit.executor.id)).user)),
+        }
+        let mentionable = ["", ""]
+        let hoist = ["", ""]
+        mentionable[0] = or.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
+        mentionable[1] = nr.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
+        hoist[0] = or.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
+        hoist[1] = nr.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
+        if (or.name != nr.name) changes["name"] = entry([or.name, nr.name], `${or.name} -> ${nr.name}`);
+        if (or.position != nr.position) changes["position"] = entry([or.position, nr.position], `${or.position} -> ${nr.position}`);
+        if (or.hoist != nr.hoist) changes["showInMemberList"] = entry([or.hoist, nr.hoist], `${hoist[0]} -> ${hoist[1]}`);
+        if (or.mentionable != nr.mentionable) changes["mentionable"] = entry([or.mentionable, nr.mentionable], `${mentionable[0]} -> ${mentionable[1]}`);
+        if (or.hexColor != nr.hexColor) changes["color"] = entry([or.hexColor, nr.hexColor], `\`${or.hexColor}\` -> \`${nr.hexColor}\``);
 
-	let data = {
-		meta:{
-			type: 'roleUpdate',
-			displayName: 'Role Edited',
-			calculateType: 'guildRoleUpdate',
-			color: NucleusColors.yellow,
-			emoji: "GUILD.ROLES.EDIT",
-			timestamp: audit.createdTimestamp
-		},
-		list: changes,
-		hidden: {
-			guild: nr.guild.id
-		}
-	}
-	log(data, client);
+        let data = {
+            meta:{
+                type: 'roleUpdate',
+                displayName: 'Role Edited',
+                calculateType: 'guildRoleUpdate',
+                color: NucleusColors.yellow,
+                emoji: "GUILD.ROLES.EDIT",
+                timestamp: audit.createdTimestamp
+            },
+            list: changes,
+            hidden: {
+                guild: nr.guild.id
+            }
+        }
+        log(data, client);
+    } catch {}
 }
\ No newline at end of file
diff --git a/src/events/threadCreate.ts b/src/events/threadCreate.ts
new file mode 100644
index 0000000..77e9dea
--- /dev/null
+++ b/src/events/threadCreate.ts
@@ -0,0 +1,34 @@
+import humanizeDuration from 'humanize-duration';
+export const event = 'threadCreate'
+
+export async function callback(client, thread) {
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = thread.client.logger
+        let auditLog = await getAuditLog(thread.guild, 'THREAD_CREATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == thread.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let data = {
+            meta: {
+                type: 'channelCreate',
+                displayName: 'Thread Created',
+                calculateType: 'channelUpdate',
+                color: NucleusColors.green,
+                emoji: "CHANNEL.TEXT.CREATE",
+                timestamp: thread.createdTimestamp
+            },
+            list: {
+                id: entry(thread.id, `\`${thread.id}\``),
+                name: entry(thread.name, renderChannel(thread)),
+                parentChannel: entry(thread.parentId, renderChannel(thread.parent)),
+                category: entry(thread.parent.parent ? thread.parent.parent.name : 'None', thread.parent.parent ? renderChannel(thread.parent.parent) : 'None'),
+                autoArchiveDuration: entry(thread.autoArchiveDuration, humanizeDuration(thread.autoArchiveDuration * 60 * 1000, { round: true })),
+                createdBy: entry(audit.executor.id, renderUser(audit.executor)),
+                created: entry(thread.createdTimestamp, renderDelta(thread.createdTimestamp))
+            },
+            hidden: {
+                guild: thread.guild.id
+            }
+        }
+        log(data, thread.client);
+    } catch {}
+}
diff --git a/src/events/threadDelete.ts b/src/events/threadDelete.ts
new file mode 100644
index 0000000..7bf8537
--- /dev/null
+++ b/src/events/threadDelete.ts
@@ -0,0 +1,36 @@
+import humanizeDuration from 'humanize-duration';
+export const event = 'threadDelete'
+
+export async function callback(client, thread) {
+    try {
+    const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = thread.client.logger
+    let auditLog = await getAuditLog(thread.guild, 'THREAD_UPDATE');
+    let audit = auditLog.entries.filter(entry => entry.target.id == thread.id).first();
+    if (audit.executor.id == client.user.id) return;
+    let data = {
+        meta: {
+            type: 'channelDelete',
+            displayName: 'Thread Deleted',
+            calculateType: 'channelUpdate',
+            color: NucleusColors.red,
+            emoji: "CHANNEL.TEXT.DELETE",
+            timestamp: new Date().getTime()
+        },
+        list: {
+            id: entry(thread.id, `\`${thread.id}\``),
+            name: entry(thread.name, thread.name),
+            parentChannel: entry(thread.parentId, renderChannel(thread.parent)),
+            category: entry(thread.parent.parent ? thread.parent.parent.name : 'None', thread.parent.parent ? renderChannel(thread.parent.parent) : 'None'),
+            autoArchiveDuration: entry(thread.autoArchiveDuration, humanizeDuration(thread.autoArchiveDuration * 60 * 1000, { round: true })),
+            membersInThread: entry(thread.memberCount, thread.memberCount),
+            deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
+            created: entry(thread.createdTimestamp, renderDelta(thread.createdTimestamp)),
+            deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+        },
+        hidden: {
+            guild: thread.guild.id
+        }
+    }
+    log(data, thread.client);
+    } catch {}
+}
diff --git a/src/events/threadUpdate.ts b/src/events/threadUpdate.ts
new file mode 100644
index 0000000..4067eba
--- /dev/null
+++ b/src/events/threadUpdate.ts
@@ -0,0 +1,43 @@
+import humanizeDuration from 'humanize-duration';
+export const event = 'threadUpdate'
+
+export async function callback(client, before, after) {
+    try {
+        const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = after.client.logger
+        let auditLog = await getAuditLog(after.guild, 'THREAD_UPDATE');
+        let audit = auditLog.entries.filter(entry => entry.target.id == after.id).first();
+        if (audit.executor.id == client.user.id) return;
+        let list = {
+            id: entry(after.id, `\`${after.id}\``),
+            thread: entry(after.name, renderChannel(after)),
+            parentChannel: entry(after.parentId, renderChannel(after.parent)),
+        }
+        if (before.name != after.name) {
+            list["name"] = entry([before.name, after.name], `${before.name} -> ${after.name}`);
+        }
+        if (before.autoArchiveDuration != after.autoArchiveDuration) {
+            list["autoArchiveDuration"] = entry([before.autoArchiveDuration, after.autoArchiveDuration], `${humanizeDuration(before.autoArchiveDuration * 60 * 1000, { round: true })} -> ${humanizeDuration(after.autoArchiveDuration * 60 * 1000, { round: true })}`);
+        }
+        if (before.rateLimitPerUser != after.rateLimitPerUser) {
+            list["slowmode"] = entry([before.rateLimitPerUser, after.rateLimitPerUser], `${humanizeDuration(before.rateLimitPerUser * 1000)} -> ${humanizeDuration(after.rateLimitPerUser * 1000)}`);
+        }
+        if (!(Object.keys(list).length - 3)) return;
+        list["updated"] = entry(new Date().getTime(), renderDelta(new Date().getTime()))
+        list["updatedBy"] = entry(audit.executor.id, renderUser(audit.executor))
+        let data = {
+            meta: {
+                type: 'channelUpdate',
+                displayName: 'Thread Edited',
+                calculateType: 'channelUpdate',
+                color: NucleusColors.yellow,
+                emoji: "CHANNEL.TEXT.EDIT",
+                timestamp: new Date().getTime()
+            },
+            list: list,
+            hidden: {
+                guild: after.guild.id
+            }
+        }
+        log(data, after.client);
+    } catch {}
+}