updated /nucleus suggest to be nice, fixed help, added needs saving to footer for automod settings.
diff --git a/package.json b/package.json
index c619c61..79bd570 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,7 @@
 {
     "dependencies": {
         "@hokify/agenda": "^6.2.12",
+        "@octokit/graphql": "^5.0.5",
         "@tensorflow/tfjs": "^3.18.0",
         "@tensorflow/tfjs-node": "^3.18.0",
         "@total-typescript/ts-reset": "^0.3.7",
@@ -25,6 +26,7 @@
         "node-fetch": "^3.3.0",
         "node-tesseract-ocr": "^2.2.1",
         "nsfwjs": "^2.4.2",
+        "octokit": "^2.0.14",
         "seedrandom": "^3.0.5",
         "structured-clone": "^0.2.2",
         "systeminformation": "^5.17.3"
@@ -48,7 +50,7 @@
         "lint-list": "echo 'Style checking...'; prettier --check .; echo 'Linting...'; eslint src; echo 'To view errors in more detail, please run `yarn lint`'; true",
         "lint-ci": "echo 'Style checking...' && prettier --check . && echo 'Linting...' && eslint src",
         "setup": "node Installer.js",
-        "win-force-build": "clear | rm -r dist | tsc-suppress",
+        "win-force-build": "clear | rm -r dist | tsc-suppress | yarn copy-files",
         "audit-fix": "yarn-audit-fix",
         "versions": "yarn versions && yarn list && node --version"
     },
diff --git a/src/commands/help.ts b/src/commands/help.ts
index 96971e6..041fb47 100644
--- a/src/commands/help.ts
+++ b/src/commands/help.ts
@@ -22,7 +22,7 @@
 import { getCommandByName, getCommandMentionByName } from "../utils/getCommandDataByName.js";
 import getEmojiByName from "../utils/getEmojiByName.js";
 
-const command = new SlashCommandBuilder().setName("help").setDescription("Shows help for commands");
+const command = new SlashCommandBuilder().setName("help").setDescription("Shows help for commands").setDMPermission(true);
 
 const styles: Record<string, { emoji: string }> = {
     help: { emoji: "NUCLEUS.LOGO" },
@@ -127,7 +127,7 @@
                 );
             }
             for (const option of options) {
-                optionString += `> \`${option.name}\` (${ApplicationCommandOptionType[option.type]}) - ${
+                optionString += ` - \`${option.name}\` (${ApplicationCommandOptionType[option.type].replace("Integer", "Number").replace("String", "Text")}) - ${
                     option.description
                 }\n`;
             }
@@ -136,14 +136,12 @@
                     "commands/" + currentPath.filter((value) => value !== "" && value !== "none").join("/")
                 ]![0];
             let allowedToRun = true;
-            if (APICommand?.check) {
+            if (interaction.guild && APICommand?.check) {
                 allowedToRun = await APICommand.check(interaction as Interaction, true);
             }
             embed.setDescription(
-                `${getEmojiByName(styles[currentPath[0]]!.emoji)} **${capitalize(currentData.name)}**\n> ${
-                    currentData.mention
-                }\n\n` +
-                    `> ${currentData.description}\n\n` +
+                `${getEmojiByName(styles[currentPath[0]]!.emoji)} **${capitalize(currentData.name)}** | ${currentData.mention}\n\n` +
+                    `${currentData.description}\n\n` +
                     (APICommand
                         ? `${getEmojiByName(allowedToRun ? "CONTROL.TICK" : "CONTROL.CROSS")} You ${
                               allowedToRun ? "" : "don't "
diff --git a/src/commands/mod/nick.ts b/src/commands/mod/nick.ts
index a8d4ab8..ed14efb 100644
--- a/src/commands/mod/nick.ts
+++ b/src/commands/mod/nick.ts
@@ -81,7 +81,7 @@
                 "Change nickname",
                 "ICONS.EDIT",
                 "modal",
-                newNickname ?? "",
+                {default: newNickname ?? ""},
                 new ModalBuilder().setTitle("Editing nickname").addComponents(
                     new ActionRowBuilder<TextInputBuilder>().addComponents(
                         new TextInputBuilder()
@@ -103,7 +103,7 @@
             notify = confirmation.components["notify"]!.active;
             createAppealTicket = confirmation.components["appeal"]!.active;
         }
-        if (confirmation.modals) newNickname = confirmation.modals![0]!.value;
+        if (confirmation.modals) newNickname = confirmation.modals![0]!.values["default"];
     } while (!timedOut && !success);
     if (timedOut || !success) return;
     let dmSent = false;
@@ -222,7 +222,7 @@
     });
 };
 
-const check = async (interaction: CommandInteraction | ButtonInteraction, partial: boolean, target?: GuildMember) => {
+const check = (interaction: CommandInteraction | ButtonInteraction, partial: boolean, target?: GuildMember) => {
     const member = interaction.member as GuildMember;
     // Check if the user has manage_nicknames permission
     if (!member.permissions.has("ManageNicknames")) return "You do not have the *Manage Nicknames* permission";
diff --git a/src/commands/nucleus/stats.ts b/src/commands/nucleus/stats.ts
index b2658bc..c2bf9a1 100644
--- a/src/commands/nucleus/stats.ts
+++ b/src/commands/nucleus/stats.ts
@@ -21,6 +21,54 @@
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder.setName("stats").setDescription("Gets the bot's stats");
 
+
+const confirm = async (interaction: CommandInteraction) => {
+    const requiredTexts = [
+        "just do it",
+        "yes, do as i say!",
+        "clicksminuteper/nucleus",
+        "i've said it once i'll say it again",
+        "no, i've changed my mind",
+        "this incident will be reported",
+        "coded told me to",
+        "mini told me to",
+        "pinea told me to",
+        "what's a java script",
+        "it's a feature not a bug",
+        "that never happened during testing"
+    ]
+    const chosen = requiredTexts[Math.floor(Math.random() * (requiredTexts.length - 1))]!;
+
+    const modal = new ModalBuilder()
+            .addComponents(
+                new ActionRowBuilder<TextInputBuilder>().addComponents(
+                    new TextInputBuilder()
+                        .setStyle(TextInputStyle.Short)
+                        .setLabel(`Type "${chosen}" below`)
+                        .setCustomId("confirm")
+                        .setPlaceholder("Guild ID")
+                        .setMinLength(chosen.length)
+                        .setMaxLength(chosen.length)
+                )
+            )
+            .setTitle("Admin Panel")
+            .setCustomId("adminPanel");
+    await interaction.showModal(modal);
+    let out: ModalSubmitInteraction;
+    try {
+        out = await interaction.awaitModalSubmit({
+            filter: (i) => i.customId === "adminPanel" && i.user.id === interaction.user.id,
+            time: 300000
+        });
+    } catch {
+        return;
+    }
+    await out.deferUpdate();
+    const typed = out.fields.getTextInputValue("confirm");
+    return typed.toLowerCase() === chosen.toLowerCase()
+}
+
+
 const callback = async (interaction: CommandInteraction): Promise<void> => {
     const description = `**Servers:** ${client.guilds.cache.size}\n` + `**Ping:** \`${client.ws.ping * 2}ms\``;
     const m = await interaction.reply({
@@ -45,11 +93,7 @@
             ],
             components: [
                 new ActionRowBuilder<ButtonBuilder>().addComponents(
-                    new ButtonBuilder().setCustomId("admin").setLabel("Admin Panel").setStyle(ButtonStyle.Primary),
-                    new ButtonBuilder()
-                        .setCustomId("mod:nickname:599498449733550102")
-                        .setLabel("Testing")
-                        .setStyle(ButtonStyle.Primary)
+                    new ButtonBuilder().setCustomId("admin").setLabel("Admin Panel").setStyle(ButtonStyle.Primary)
                 )
             ]
         });
@@ -77,28 +121,30 @@
             return;
         // console.log(interaction)
         if (!("awaitMessageComponent" in channel)) return;
-        try {
-            i1 = await channel!.awaitMessageComponent<ComponentType.Button>({
-                filter: (i) => i.customId === "admin" && i.user.id === interaction.user.id && i.message.id === m.id,
-                time: 300000
-            });
-        } catch (e) {
-            console.log(e);
-            return;
-        }
-        await i1.showModal(modal);
-        let out: ModalSubmitInteraction;
-        try {
-            out = await i1.awaitModalSubmit({
-                filter: (i) => i.customId === "adminPanel" && i.user.id === interaction.user.id,
-                time: 300000
-            });
-        } catch {
-            return;
-        }
-        await out.deferUpdate();
-        const GuildID = out.fields.getTextInputValue("guildID");
-        if (!client.guilds.cache.has(GuildID)) {
+        let GuildID = interaction.guildId;
+        if (!GuildID) {
+            try {
+                i1 = await channel!.awaitMessageComponent<ComponentType.Button>({
+                    filter: (i) => i.customId === "admin" && i.user.id === interaction.user.id && i.message.id === m.id,
+                    time: 300000
+                });
+            } catch (e) {
+                console.log(e);
+                return;
+            }
+            await i1.showModal(modal);
+            let out: ModalSubmitInteraction;
+            try {
+                out = await i1.awaitModalSubmit({
+                    filter: (i) => i.customId === "adminPanel" && i.user.id === interaction.user.id,
+                    time: 300000
+                });
+            } catch {
+                return;
+            }
+            await out.deferUpdate();
+            GuildID = out.fields.getTextInputValue("guildID");
+        } else if (!client.guilds.cache.has(GuildID)) {
             await interaction.editReply({
                 embeds: [new EmojiEmbed().setTitle("Admin").setDescription("Not in server").setStatus("Danger")],
                 components: []
@@ -110,10 +156,10 @@
             components: [
                 new ActionRowBuilder<ButtonBuilder>().addComponents(
                     new ButtonBuilder().setCustomId("stats").setLabel("Stats").setStyle(ButtonStyle.Primary),
-                    new ButtonBuilder().setCustomId("leave").setLabel("Leave").setStyle(ButtonStyle.Danger),
                     new ButtonBuilder().setCustomId("data").setLabel("Guild data").setStyle(ButtonStyle.Secondary),
+                    new ButtonBuilder().setCustomId("cache").setLabel("Reset cache").setStyle(ButtonStyle.Success),
+                    new ButtonBuilder().setCustomId("leave").setLabel("Leave").setStyle(ButtonStyle.Danger),
                     new ButtonBuilder().setCustomId("purge").setLabel("Delete data").setStyle(ButtonStyle.Danger),
-                    new ButtonBuilder().setCustomId("cache").setLabel("Reset cache").setStyle(ButtonStyle.Success)
                 )
             ]
         });
@@ -126,9 +172,9 @@
         } catch {
             return;
         }
-        await i.deferUpdate();
         const guild = (await client.guilds.fetch(GuildID)) as Guild | null;
         if (!guild) {
+            await i.deferUpdate();
             await interaction.editReply({
                 embeds: [new EmojiEmbed().setTitle("Admin").setDescription("Not in server").setStatus("Danger")],
                 components: []
@@ -136,66 +182,91 @@
             return;
         }
         if (i.customId === "stats") {
+            await i.deferUpdate();
             await interaction.editReply({
                 embeds: [
                     new EmojiEmbed()
-                        .setTitle("Stats")
-                        .setDescription(
-                            `**Name:** ${guild.name}\n` +
-                                `**ID:** \`${guild.id}\`\n` +
-                                `**Owner:** ${client.users.cache.get(guild.ownerId)!.tag}\n` +
-                                `**Member Count:** ${guild.memberCount}\n` +
-                                `**Created:** <t:${guild.createdTimestamp}:F>\n` +
-                                `**Added Nucleus:** <t:${guild.members.me!.joinedTimestamp}:R>\n` +
-                                `**Nucleus' Perms:** https://discordapi.com/permissions.html#${guild.members.me!.permissions.valueOf()}\n`
+                    .setTitle("Stats")
+                    .setDescription(
+                        `**Name:** ${guild.name}\n` +
+                        `**ID:** \`${guild.id}\`\n` +
+                        `**Owner:** ${client.users.cache.get(guild.ownerId)!.tag}\n` +
+                        `**Member Count:** ${guild.memberCount}\n` +
+                        `**Created:** <t:${guild.createdTimestamp}:F>\n` +
+                        `**Added Nucleus:** <t:${guild.members.me!.joinedTimestamp}:R>\n` +
+                        `**Nucleus' Perms:** https://discordapi.com/permissions.html#${guild.members.me!.permissions.valueOf()}\n`
                         )
                         .setStatus("Success")
                         .setEmoji("SETTINGS.STATS.GREEN")
-                ]
-            });
-        } else if (i.customId === "leave") {
-            await guild.leave();
-            await interaction.editReply({
-                embeds: [
-                    new EmojiEmbed()
+                    ]
+                });
+            } else if (i.customId === "leave") {
+                if (!await confirm(interaction)) {
+                    await interaction.editReply({
+                        embeds: [
+                            new EmojiEmbed()
+                            .setTitle("No changes were made")
+                            .setStatus("Danger")
+                        ],
+                        components: []
+                    });
+                    return;
+                }
+                await guild.leave();
+                await interaction.editReply({
+                    embeds: [
+                        new EmojiEmbed()
                         .setTitle("Left")
                         .setDescription(`Left ${guild.name}`)
                         .setStatus("Success")
                         .setEmoji("SETTINGS.STATS.GREEN")
-                ],
-                components: []
-            });
-        } else if (i.customId === "data") {
-            // Get all the data and convert to a string
-            const data = await client.database.guilds.read(guild.id);
-            const stringified = JSON.stringify(data, null, 2);
-            const buffer = Buffer.from(stringified);
-            const attachment = new AttachmentBuilder(buffer).setName("data.json");
-            await interaction.editReply({
-                embeds: [
-                    new EmojiEmbed().setTitle("Data").setDescription(`Data for ${guild.name}`).setStatus("Success")
-                ],
-                components: [],
-                files: [attachment]
-            });
-        } else if (i.customId === "purge") {
-            await client.database.guilds.delete(GuildID);
-            await client.database.history.delete(GuildID);
-            await client.database.notes.delete(GuildID);
-            await client.database.transcripts.deleteAll(GuildID);
-            await interaction.editReply({
-                embeds: [
-                    new EmojiEmbed()
+                    ],
+                    components: []
+                });
+            } else if (i.customId === "data") {
+                await i.deferUpdate();
+                // Get all the data and convert to a string
+                const data = await client.database.guilds.read(guild.id);
+                const stringified = JSON.stringify(data, null, 2);
+                const buffer = Buffer.from(stringified);
+                const attachment = new AttachmentBuilder(buffer).setName("data.json");
+                await interaction.editReply({
+                    embeds: [
+                        new EmojiEmbed().setTitle("Data").setDescription(`Data for ${guild.name}`).setStatus("Success")
+                    ],
+                    components: [],
+                    files: [attachment]
+                });
+            } else if (i.customId === "purge") {
+                if (!await confirm(interaction)) {
+                    await interaction.editReply({
+                        embeds: [
+                            new EmojiEmbed()
+                            .setTitle("No changes were made")
+                            .setStatus("Danger")
+                        ],
+                        components: []
+                    });
+                    return;
+                }
+                await client.database.guilds.delete(GuildID);
+                await client.database.history.delete(GuildID);
+                await client.database.notes.delete(GuildID);
+                await client.database.transcripts.deleteAll(GuildID);
+                await interaction.editReply({
+                    embeds: [
+                        new EmojiEmbed()
                         .setTitle("Purge")
                         .setDescription(`Deleted data for ${guild.name}`)
                         .setStatus("Success")
                         .setEmoji("SETTINGS.STATS.GREEN")
-                ],
-                components: []
-            });
-        } else if (i.customId === "cache") {
-            await client.memory.forceUpdate(guild.id);
-            await interaction.editReply({
+                    ],
+                    components: []
+                });
+            } else if (i.customId === "cache") {
+                await i.deferUpdate();
+                await client.memory.forceUpdate(guild.id);
+                await interaction.editReply({
                 embeds: [
                     new EmojiEmbed()
                         .setTitle("Cache")
diff --git a/src/commands/nucleus/suggest.ts b/src/commands/nucleus/suggest.ts
index 79a0673..44926c7 100644
--- a/src/commands/nucleus/suggest.ts
+++ b/src/commands/nucleus/suggest.ts
@@ -1,64 +1,115 @@
 import { LoadingEmbed } from "../../utils/defaults.js";
-import { ButtonStyle, CommandInteraction } from "discord.js";
-import Discord from "discord.js";
+import Discord, { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js";
 import type { SlashCommandSubcommandBuilder } from "discord.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
 import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import client from "../../utils/client.js";
-import getEmojiByName from "../../utils/getEmojiByName.js";
+import config from "../../config/main.js"
+import _ from "lodash";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
         .setName("suggest")
         .setDescription("Sends a suggestion to the developers")
-        .addStringOption((option) =>
-            option.setName("suggestion").setDescription("The suggestion to send").setRequired(true)
-        );
 
 const callback = async (interaction: CommandInteraction): Promise<void> => {
     await interaction.guild?.members.fetch(interaction.member!.user.id);
-    const { renderUser } = client.logger;
-    const suggestion = interaction.options.get("suggestion")?.value as string;
     await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
-    const confirmation = await new confirmationMessage(interaction)
-        .setEmoji("ICONS.OPP.ADD")
-        .setTitle("Suggest")
-        .setDescription(
-            `**Suggestion:**\n> ${suggestion}\n` +
-                "Your username and ID will also be sent with your suggestion.\n\nAre you sure you want to send this suggestion?"
-        )
-        .setColor("Danger")
-        .setInverted(true)
-        .setFailedMessage("Your suggestion was deleted", "Success", "ICONS.ADD")
-        .send(true);
-    if (confirmation.cancelled || !confirmation.success) return;
-    await (client.channels.cache.get("955161206459600976") as Discord.TextChannel).send({
+    let closed = false;
+    let suggestionTitle: string | null = null
+    let suggestionDesc: string | null = null;
+    do {
+        const modal = new ModalBuilder()
+            .setTitle("Suggestion")
+            .setComponents(
+                new ActionRowBuilder<TextInputBuilder>()
+                    .addComponents(
+                        new TextInputBuilder()
+                            .setLabel("Suggestion Title")
+                            .setRequired(false)
+                            .setStyle(TextInputStyle.Short)
+                            .setCustomId("suggestionTitle")
+                            .setPlaceholder("Summarize your suggestion in 1 sentence...")
+                            .setMaxLength(256)
+                    ),
+                new ActionRowBuilder<TextInputBuilder>()
+                    .addComponents(
+                        new TextInputBuilder()
+                            .setLabel("Suggestion Description")
+                            .setCustomId("suggestionDesc")
+                            .setStyle(TextInputStyle.Paragraph)
+                            .setRequired(true)
+                            .setPlaceholder("Put the full details of your suggestion here...")
+                            .setMinLength(50)
+                    ),
+            )
+        const o: {suggestionDesc?: string, suggestionTitle?: string} = {};
+        if(suggestionTitle) {
+            o.suggestionTitle = suggestionTitle;
+            modal.components[0]!.components[0]!.setValue(suggestionTitle);
+        }
+        if(suggestionDesc) {
+            o.suggestionDesc = suggestionDesc
+            modal.components[1]!.components[0]!.setValue(suggestionDesc);
+        };
+        const confirmation = await new confirmationMessage(interaction)
+            .setEmoji("ICONS.ADD")
+            .setTitle("Suggest")
+            .setDescription(suggestionDesc ? (`Are you sure you want to send this suggestion?\n\n**Title ${suggestionTitle ? "" : "(*Placeholder*)"}:**\n> ${suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`}\n\n**Suggestion:**\n> ${suggestionDesc}`) : "Please enter your suggestion below.")
+            .addModal("Edit Suggestion", "ICONS.EDIT", "editSuggestion", _.cloneDeep(o), modal)
+            .setColor("Success")
+            .setInverted(true)
+            .setFailedMessage("Your suggestion was deleted", "Success", "ICONS.ADD")
+            .send(true);
+        if(confirmation.modals?.[0] && !_.isEqual(confirmation.modals[0].values, o)) {
+            suggestionTitle = confirmation.modals[0].values["suggestionTitle"] as string | null;
+            suggestionDesc = confirmation.modals[0].values["suggestionDesc"] as string | null;
+            continue;
+        }
+        if(confirmation.cancelled || confirmation.success === false) {
+            closed = true;
+            return;
+        }
+        if (confirmation.success) {
+            closed = true;
+        };
+    } while (!closed);
+    if(!suggestionDesc) return;
+    suggestionTitle = suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`;
+    const channel = client.channels.cache.get(config.suggestionChannel) as Discord.TextChannel;
+    const m = await channel.send({ embeds: LoadingEmbed});
+    const issue = await client.GitHub.rest.issues.create({
+        owner: "ClicksMinutePer",
+        repo: "Nucleus",
+        title: suggestionTitle,
+        body: `Linked Suggestion in Private Developer Channel: [Message](${m.url})\n\n**Suggestion:**\n> ${
+            suggestionDesc.replaceAll("@", "@<!-- -->").replaceAll("/issues", "/issues<!-- -->").replaceAll("/pull", "/pull<!-- -->")
+        }\n\n`,
+        labels: ["🤖 Auto", "📝 Suggestion"]
+    })
+    await m.edit({
         embeds: [
             new EmojiEmbed()
-                .setTitle("Suggestion")
-                .setDescription(
-                    `**From:** ${renderUser(
-                        interaction.member!.user as Discord.User
-                    )}\n**Suggestion:**\n> ${suggestion}\n\n` +
-                        `**Server:** ${interaction.guild!.name} (${interaction.guild!.id})\n`
-                )
-                .setStatus("Warning")
+                .setEmoji("ICONS.ADD")
+                .setTitle(`Suggestion from ${interaction.user.tag} (${interaction.user.id})`)
+                .setDescription(`**Suggestion:**\n> ${suggestionDesc}\n\n`)
+                .setStatus("Success")
+                .setFooter({text: `${issue.data.number}`})
         ],
         components: [
-            new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
-                new Discord.ButtonBuilder()
-                    .setCustomId("suggestionAccept")
-                    .setLabel("Accept")
-                    .setStyle(ButtonStyle.Secondary)
-                    .setEmoji(getEmojiByName("ICONS.ADD", "id")),
-                new Discord.ButtonBuilder()
-                    .setCustomId("suggestionDeny")
-                    .setLabel("Delete")
-                    .setStyle(ButtonStyle.Secondary)
-                    .setEmoji(getEmojiByName("ICONS.REMOVE", "id"))
+            new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
+                new ButtonBuilder().setCustomId("accept:Suggestion").setLabel("Accept").setStyle(ButtonStyle.Success),
+                new ButtonBuilder().setCustomId("deny:Suggestion").setLabel("Deny").setStyle(ButtonStyle.Danger),
+                new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary),
+                new ButtonBuilder().setCustomId("implemented:Suggestion").setLabel("Implemented").setStyle(ButtonStyle.Secondary),
+                new ButtonBuilder().setLabel(`Open Issue #${issue.data.number}`).setStyle(ButtonStyle.Link).setURL(`https://github.com/ClicksMinutePer/Nucleus/issues/${issue.data.number}`),
+            ),
+            new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
+                new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger),
+                new ButtonBuilder().setCustomId("spam:Suggestion").setLabel("Mark as Spam").setStyle(ButtonStyle.Danger),
             )
         ]
-    });
+    })
     await interaction.editReply({
         embeds: [
             new EmojiEmbed()
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index 3a671ed..7fefa36 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -29,11 +29,11 @@
                     .setDescription(
                         "Nucleus is a bot that naturally needs to store data about servers.\n" +
                             "We are entirely [open source](https://github.com/ClicksMinutePer/Nucleus), so you can check exactly what we store, and how it works.\n\n" +
-                            "Any questions about Nucleus, how it works, and what data is stored can be asked in [our server](https://discord.gg/bPaNnxe)."
+                            "Any questions about Nucleus, how it works, and what data is stored can be asked in [our server](https://discord.gg/bPaNnxe)." +
+                            "\n\n[[Privacy Policy]](https://clicksminuteper.github.io/policies/nucleus) | [[Terms of Service]](https://clicksminuteper.github.io/policies/nucleustos)"
                     )
                     .setEmoji("NUCLEUS.LOGO")
                     .setStatus("Danger")
-                    .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
             )
             .setTitle("Welcome")
             .setDescription("General privacy information")
@@ -43,15 +43,16 @@
                 new EmojiEmbed()
                     .setTitle("Scanners")
                     .setDescription(
-                        "Nucleus uses [unscan](https://rapidapi.com/abcdan/api/unscan/) to scan links, images and files for malware and other threats.\n" +
-                            'This service\'s [privacy policy](https://unscan.co/policies) is public, and they "do not store or sell your data."'
+                        "Nucleus scans content sent by users for malware and NSFW content\n" +
+                            'Malware is detected using [ClamAV](https://clamav.net/), and the standard ClamAV database."\n' +
+                            'NSFW detection is provided by [NsfwJS](https://nsfwjs.com/), with a model provided by [GantMan](https://github.com/GantMan/nsfw_model/releases/tag/1.1.0)\n\n' +
+                            'All data is processed on our servers and is not processed by a 3rd party.'
                     )
                     .setEmoji("NUCLEUS.LOGO")
                     .setStatus("Danger")
-                    .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
             )
             .setTitle("Scanners")
-            .setDescription("About Unscan")
+            .setDescription("About Scanners")
             .setPageId(1),
         new Embed()
             .setEmbed(
@@ -62,13 +63,12 @@
                     )
                     .setEmoji("NUCLEUS.LOGO")
                     .setStatus("Danger")
-                    .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
             )
             .setTitle("Link scanning and Transcripts")
             .setDescription("Information about how links and images are scanned, and transcripts are stored")
             .setPageId(2)
     ].concat(
-        (interaction.member as Discord.GuildMember).permissions.has("Administrator")
+        (interaction.member as Discord.GuildMember).id === interaction.guild!.ownerId
             ? [
                   new Embed()
                       .setEmbed(
@@ -77,7 +77,6 @@
                               .setDescription("Below are buttons for controlling this servers privacy settings")
                               .setEmoji("NUCLEUS.LOGO")
                               .setStatus("Danger")
-                              .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
                       )
                       .setTitle("Options")
                       .setDescription("Options")
@@ -88,7 +87,6 @@
                                   .setLabel("Clear all data")
                                   .setCustomId("clear-all-data")
                                   .setStyle(ButtonStyle.Danger)
-                                  .setDisabled(!(interaction.user.id === interaction.guild!.ownerId))
                           ])
                       ])
               ]
diff --git a/src/commands/settings/automod.ts b/src/commands/settings/automod.ts
index b65eb4c..68454e4 100644
--- a/src/commands/settings/automod.ts
+++ b/src/commands/settings/automod.ts
@@ -28,6 +28,7 @@
 import getEmojiByName from "../../utils/getEmojiByName.js";
 import { modalInteractionCollector } from "../../utils/dualCollector.js";
 import listToAndMore from "../../utils/listToAndMore.js";
+import _ from "lodash";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder.setName("automod").setDescription("Setting for automatic moderation features");
@@ -157,6 +158,7 @@
 const imageMenu = async (
     interaction: StringSelectMenuInteraction,
     m: Message,
+    unsavedChanges: boolean,
     current: {
         NSFW: boolean;
         size: boolean;
@@ -186,7 +188,10 @@
             .setTitle("Image Settings")
             .setDescription(
                 `${emojiFromBoolean(current.NSFW)} **NSFW**\n` + `${emojiFromBoolean(current.size)} **Size**\n`
-            );
+            )
+            .setFooter({
+                text: unsavedChanges ? "No changes made" : "Changes not saved"
+            });
 
         await interaction.editReply({ embeds: [embed], components: [options] });
 
@@ -207,10 +212,12 @@
             }
             case "nsfw": {
                 current.NSFW = !current.NSFW;
+                unsavedChanges = true;
                 break;
             }
             case "size": {
                 current.size = !current.size;
+                unsavedChanges = true;
                 break;
             }
         }
@@ -221,6 +228,7 @@
 const wordMenu = async (
     interaction: StringSelectMenuInteraction,
     m: Message,
+    unsavedChanges: boolean,
     current: {
         enabled: boolean;
         words: { strict: string[]; loose: string[] };
@@ -296,7 +304,10 @@
                     )
             )
             .setStatus("Success")
-            .setEmoji("GUILD.SETTINGS.GREEN");
+            .setEmoji("GUILD.SETTINGS.GREEN")
+            .setFooter({
+                text: unsavedChanges ? "No changes made" : "Changes not saved"
+            });
 
         await interaction.editReply({ embeds: [embed], components: [selectMenu, buttons] });
 
@@ -320,6 +331,7 @@
                 }
                 case "enabled": {
                     current.enabled = !current.enabled;
+                    unsavedChanges = true;
                     break;
                 }
             }
@@ -391,6 +403,7 @@
                         .split(",")
                         .map((s) => s.trim())
                         .filter((s) => s.length > 0);
+                    unsavedChanges = true;
                     break;
                 }
                 case "allowedUsers": {
@@ -402,6 +415,7 @@
                         "member",
                         "Word Filter"
                     );
+                    unsavedChanges = true;
                     break;
                 }
                 case "allowedRoles": {
@@ -413,6 +427,7 @@
                         "role",
                         "Word Filter"
                     );
+                    unsavedChanges = true;
                     break;
                 }
                 case "allowedChannels": {
@@ -424,6 +439,7 @@
                         "channel",
                         "Word Filter"
                     );
+                    unsavedChanges = true;
                     break;
                 }
             }
@@ -435,6 +451,7 @@
 const inviteMenu = async (
     interaction: StringSelectMenuInteraction,
     m: Message,
+    unsavedChanges: boolean,
     current: {
         enabled: boolean;
         allowed: { users: string[]; roles: string[]; channels: string[] };
@@ -503,7 +520,10 @@
                     )
             )
             .setStatus("Success")
-            .setEmoji("GUILD.SETTINGS.GREEN");
+            .setEmoji("GUILD.SETTINGS.GREEN")
+            .setFooter({
+                text: unsavedChanges ? "No changes made" : "Changes not saved"
+            });
 
         await interaction.editReply({ embeds: [embed], components: [menu, buttons] });
 
@@ -526,6 +546,7 @@
                 }
                 case "enabled": {
                     current.enabled = !current.enabled;
+                    unsavedChanges = true;
                     break;
                 }
             }
@@ -540,6 +561,7 @@
                         "member",
                         "Invite Settings"
                     );
+                    unsavedChanges = true;
                     break;
                 }
                 case "roles": {
@@ -550,6 +572,7 @@
                         "role",
                         "Invite Settings"
                     );
+                    unsavedChanges = true;
                     break;
                 }
                 case "channels": {
@@ -560,6 +583,7 @@
                         "channel",
                         "Invite Settings"
                     );
+                    unsavedChanges = true;
                     break;
                 }
             }
@@ -571,6 +595,7 @@
 const mentionMenu = async (
     interaction: StringSelectMenuInteraction,
     m: Message,
+    unsavedChanges: boolean,
     current: {
         mass: number;
         everyone: boolean;
@@ -690,7 +715,10 @@
                     }`
             )
             .setStatus("Success")
-            .setEmoji("GUILD.SETTINGS.GREEN");
+            .setEmoji("GUILD.SETTINGS.GREEN")
+            .setFooter({
+                text: unsavedChanges ? "No changes made" : "Changes not saved"
+            });;
 
         await interaction.editReply({ embeds: [embed], components: [menu, allowedMenu, buttons] });
 
@@ -714,10 +742,12 @@
                 }
                 case "everyone": {
                     current.everyone = !current.everyone;
+                    unsavedChanges = true;
                     break;
                 }
                 case "roles": {
                     current.roles = !current.roles;
+                    unsavedChanges = true;
                     break;
                 }
             }
@@ -767,6 +797,7 @@
                             if (!out) break;
                             if (out.isButton()) break;
                             current.mass = parseInt(out.fields.getTextInputValue("mass"));
+                            unsavedChanges = true;
                             break;
                         }
                         case "roles": {
@@ -778,6 +809,7 @@
                                 "role",
                                 "Mention Settings"
                             );
+                            unsavedChanges = true;
                             break;
                         }
                     }
@@ -794,6 +826,7 @@
                                 "member",
                                 "Mention Settings"
                             );
+                            unsavedChanges = true;
                             break;
                         }
                         case "roles": {
@@ -804,6 +837,7 @@
                                 "role",
                                 "Mention Settings"
                             );
+                            unsavedChanges = true;
                             break;
                         }
                         case "channels": {
@@ -814,6 +848,7 @@
                                 "channel",
                                 "Mention Settings"
                             );
+                            unsavedChanges = true;
                             break;
                         }
                     }
@@ -828,6 +863,7 @@
 const cleanMenu = async (
     interaction: StringSelectMenuInteraction,
     m: Message,
+    unsavedChanges: boolean,
     current?: {
         channels?: string[];
         allowed?: {
@@ -890,7 +926,10 @@
                             : "None"
                     }\n\n`
             )
-            .setStatus("Success");
+            .setStatus("Success")
+            .setFooter({
+                text: unsavedChanges ? "No changes made" : "Changes not saved"
+            });
 
         await interaction.editReply({ embeds: [embed], components: [channelMenu, allowedMenu, buttons] });
 
@@ -958,6 +997,7 @@
                             }
                         }
                     }
+                    unsavedChanges = true;
                     break;
                 }
                 case "allowed": {
@@ -970,6 +1010,7 @@
                                 "member",
                                 "Mention Settings"
                             );
+                            unsavedChanges = true;
                             break;
                         }
                         case "roles": {
@@ -980,6 +1021,7 @@
                                 "role",
                                 "Mention Settings"
                             );
+                            unsavedChanges = true;
                             break;
                         }
                     }
@@ -1001,15 +1043,16 @@
 const callback = async (interaction: CommandInteraction): Promise<void> => {
     if (!interaction.guild) return;
     const m = await interaction.reply({ embeds: LoadingEmbed, fetchReply: true, ephemeral: true });
-    const config = (await client.database.guilds.read(interaction.guild.id)).filters;
+    let config = (await client.database.guilds.read(interaction.guild.id)).filters;
 
     let closed = false;
 
-    const button = new ActionRowBuilder<ButtonBuilder>().addComponents(
-        new ButtonBuilder().setCustomId("save").setLabel("Save").setStyle(ButtonStyle.Success)
-    );
 
+    let current = _.cloneDeep(config);
     do {
+        const button = new ActionRowBuilder<ButtonBuilder>().addComponents(
+            new ButtonBuilder().setCustomId("save").setLabel("Save").setStyle(ButtonStyle.Success).setDisabled(_.isEqual(config, current))
+        );
         const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
             new StringSelectMenuBuilder()
                 .setCustomId("filter")
@@ -1055,7 +1098,10 @@
                     `${emojiFromBoolean(config.clean.channels.length > 0)} **Clean**\n`
             )
             .setStatus("Success")
-            .setEmoji("GUILD.SETTINGS.GREEN");
+            .setEmoji("GUILD.SETTINGS.GREEN")
+            .setFooter({
+                text: _.isEqual(config, current) ? "No changes made" : "Changes not saved"
+            });
 
         await interaction.editReply({ embeds: [embed], components: [selectMenu, button] });
 
@@ -1069,41 +1115,37 @@
             closed = true;
             continue;
         }
-        if (i.isButton()) {
-            await i.deferUpdate();
-            await client.database.guilds.write(interaction.guild.id, { filters: config });
+        await i.deferUpdate();
+        if(i.isButton()) {
+            await client.database.guilds.write(interaction.guild.id, { filters: current });
             await client.memory.forceUpdate(interaction.guild.id);
+            config = current;
+            current = _.cloneDeep(config);
         } else {
             switch (i.values[0]) {
                 case "invites": {
-                    await i.deferUpdate();
-                    config.invite = await inviteMenu(i, m, config.invite);
+                    config.invite = await inviteMenu(i, m, _.isEqual(config, current), config.invite);
                     break;
                 }
                 case "mentions": {
-                    await i.deferUpdate();
-                    config.pings = await mentionMenu(i, m, config.pings);
+                    config.pings = await mentionMenu(i, m, _.isEqual(config, current), config.pings);
                     break;
                 }
                 case "words": {
-                    await i.deferUpdate();
-                    config.wordFilter = await wordMenu(i, m, config.wordFilter);
+                    config.wordFilter = await wordMenu(i, m, _.isEqual(config, current), config.wordFilter);
                     break;
                 }
                 case "malware": {
-                    await i.deferUpdate();
                     config.malware = !config.malware;
                     break;
                 }
                 case "images": {
-                    await i.deferUpdate();
-                    const next = await imageMenu(i, m, config.images);
+                    const next = await imageMenu(i, m, _.isEqual(config, current), config.images);
                     config.images = next;
                     break;
                 }
                 case "clean": {
-                    await i.deferUpdate();
-                    const next = await cleanMenu(i, m, config.clean);
+                    const next = await cleanMenu(i, m, _.isEqual(config, current), config.clean);
                     config.clean = next;
                     break;
                 }
diff --git a/src/config/format.ts b/src/config/format.ts
index b63debd..da1815c 100644
--- a/src/config/format.ts
+++ b/src/config/format.ts
@@ -1,7 +1,7 @@
 import fs from "fs";
 import * as readLine from "node:readline/promises";
 
-const defaultDict: Record<string, string | string[] | boolean | Record<string, string | number>> = {
+const defaultDict: Record<string, string | string[] | boolean | Record<string, string | number | undefined>> = {
     developmentToken: "Your development bot token (Used for testing in one server, rather than production)",
     developmentGuildID: "Your development guild ID",
     enableDevelopment: true,
@@ -26,15 +26,16 @@
         authSource: ""
     },
     baseUrl: "Your website where buttons such as Verify and Role menu will link to, e.g. https://example.com/",
-    pastebinApiKey: "An API key for pastebin (optional)",
-    pastebinUsername: "Your pastebin username (optional)",
-    pastebinPassword: "Your pastebin password (optional)",
-    rapidApiKey: "Your RapidAPI key (optional), used for Unscan",
+    clamAVSocket: "Your ClamAV socket file (optional)",
+    clamAVHost: "Your ClamAV host (optional)",
+    clamAVPort: "Your ClamAV port (optional)",
     clamav: {
-        socket: "Your ClamAV socket file (optional)",
-        host: "Your ClamAV host (optional)",
-        port: "Your ClamAV port (optional)"
-    }
+        socket: "",
+        host: "",
+        port: 0
+    },
+    githubPAT: "Your GitHub Personal Access Token (optional)",
+    suggestionChannel: "Your suggestion channel ID (optional)"
 };
 
 const readline = readLine.createInterface({
@@ -116,6 +117,9 @@
                     case "mongoOptions": {
                         break;
                     }
+                    case "clamav": {
+                        break;
+                    }
                     default: {
                         json[key] = await getInput(`\x1b[36m${key} \x1b[0m(\x1b[35m${defaultDict[key]}\x1b[0m) > `);
                     }
@@ -127,22 +131,9 @@
     }
     if (walkthrough && !(json["mongoUrl"] ?? false)) json["mongoUrl"] = "mongodb://127.0.0.1:27017";
     if (!((json["baseUrl"] as string | undefined) ?? "").endsWith("/")) (json["baseUrl"] as string) += "/";
-    let hosts;
-    try {
-        hosts = fs.readFileSync("/etc/hosts", "utf8").toString().split("\n");
-    } catch (e) {
-        return console.log(
-            "\x1b[31m⚠ No /etc/hosts found. Please ensure the file exists and is readable. (Windows is not supported, Mac and Linux users should not experience this error)"
-        );
-    }
-    let localhost: string | undefined = hosts.find((line) => line.split(" ")[1] === "localhost");
-    if (localhost) {
-        localhost = localhost.split(" ")[0];
-    } else {
-        localhost = "127.0.0.1";
-    }
-    json["mongoUrl"] = (json["mongoUrl"]! as string).replace("localhost", localhost!);
-    json["baseUrl"] = (json["baseUrl"]! as string).replace("localhost", localhost!);
+    const localhost = "127.0.0.1"
+    json["mongoUrl"] = (json["mongoUrl"]! as string).replace("localhost", localhost);
+    json["baseUrl"] = (json["baseUrl"]! as string).replace("localhost", localhost);
     json["mongoOptions"] = {
         username: json["username"] as string,
         password: json["password"] as string,
@@ -150,6 +141,11 @@
         host: json["host"] as string,
         authSource: json["authSource"] as string
     };
+    json["clamav"] = {
+        socket: json["clamAVSocket"] as string | undefined,
+        host: json["clamAVHost"] as string | undefined,
+        port: json["clamAVPort"] as number | undefined
+    }
 
     fs.writeFileSync("./src/config/main.ts", "export default " + JSON.stringify(json, null, 4) + ";");
 
diff --git a/src/config/main.d.ts b/src/config/main.d.ts
index 8953c52..6c610e0 100644
--- a/src/config/main.d.ts
+++ b/src/config/main.d.ts
@@ -18,12 +18,13 @@
         authSource: string;
     };
     baseUrl: string;
-    rapidApiKey: string;
     clamav: {
         socket?: string;
         host?: string;
         port?: number;
     };
+    githubPAT: string;
+    suggestionChannel: string;
 };
 
 export default config;
diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts
index 3b0cd62..e27ee69 100644
--- a/src/events/interactionCreate.ts
+++ b/src/events/interactionCreate.ts
@@ -4,8 +4,7 @@
 import close from "../actions/tickets/delete.js";
 import createTranscript from "../premium/createTranscript.js";
 
-import type { ButtonInteraction, Interaction } from "discord.js";
-import type Discord from "discord.js";
+import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, Interaction, InteractionEditReplyOptions, ModalBuilder, ModalSubmitInteraction, TextInputBuilder, TextInputStyle } from "discord.js";
 import type { NucleusClient } from "../utils/client.js";
 import EmojiEmbed from "../utils/generateEmojiEmbed.js";
 
@@ -14,6 +13,7 @@
 import { callback as muteCallback, check as muteCheck } from "../commands/mod/mute.js";
 import { callback as nicknameCallback, check as nicknameCheck } from "../commands/mod/nick.js";
 import { callback as warnCallback, check as warnCheck } from "../commands/mod/warn.js";
+import client from "../utils/client.js";
 
 export const event = "interactionCreate";
 
@@ -27,6 +27,10 @@
 
 async function interactionCreate(interaction: Interaction) {
     if (interaction.isButton()) {
+        if (interaction.customId.endsWith(":Suggestion")) {
+            const value = interaction.customId.startsWith("accept") || interaction.customId.startsWith("implement") ? true : false
+            return await modifySuggestion(interaction, value);
+        }
         switch (interaction.customId) {
             case "rolemenu": {
                 return await roleMenu(interaction);
@@ -43,12 +47,6 @@
             case "createtranscript": {
                 return await createTranscript(interaction);
             }
-            case "suggestionAccept": {
-                return await modifySuggestion(interaction, true);
-            }
-            case "suggestionDeny": {
-                return await modifySuggestion(interaction, false);
-            }
         }
         // Mod actions
         if (interaction.customId.startsWith("mod:")) {
@@ -57,27 +55,27 @@
             const member = await interaction.guild?.members.fetch(memberId!);
             switch (action) {
                 case "kick": {
-                    const check = await kickCheck(interaction, false, member);
+                    const check = kickCheck(interaction, false, member);
                     if (check !== true) return await errorMessage(interaction, check!);
                     return await kickCallback(interaction, member);
                 }
                 case "ban": {
-                    const check = await banCheck(interaction, false, member);
+                    const check = banCheck(interaction, false, member);
                     if (check !== true) return await errorMessage(interaction, check!);
                     return await banCallback(interaction, member);
                 }
                 case "mute": {
-                    const check = await muteCheck(interaction, false, member);
+                    const check = muteCheck(interaction, false, member);
                     if (check !== true) return await errorMessage(interaction, check!);
                     return await muteCallback(interaction, member);
                 }
                 case "nickname": {
-                    const check = await nicknameCheck(interaction, false, member);
+                    const check = nicknameCheck(interaction, false, member);
                     if (check !== true) return await errorMessage(interaction, check || "Something went wrong");
                     return await nicknameCallback(interaction, member);
                 }
                 case "warn": {
-                    const check = await warnCheck(interaction, false, member);
+                    const check = warnCheck(interaction, false, member);
                     if (check !== true) return await errorMessage(interaction, check!);
                     return await warnCallback(interaction, member);
                 }
@@ -86,24 +84,120 @@
     }
 }
 
-async function modifySuggestion(interaction: Discord.MessageComponentInteraction, accept: boolean) {
-    const message = await interaction.message;
+const getReason = async (buttonInteraction: ButtonInteraction, prompt: string) => {
+    const modal = new ModalBuilder()
+        .addComponents(
+            new ActionRowBuilder<TextInputBuilder>().addComponents(
+                new TextInputBuilder()
+                    .setStyle(TextInputStyle.Paragraph)
+                    .setLabel(prompt)
+                    .setCustomId("typed")
+            )
+        )
+        .setTitle("Reason")
+        .setCustomId("modal");
+    await buttonInteraction.showModal(modal);
+    let out: ModalSubmitInteraction;
+    try {
+        out = await buttonInteraction.awaitModalSubmit({
+            filter: (i) => i.customId === "modal" && i.user.id === buttonInteraction.user.id,
+            time: 300000
+        });
+    } catch {
+        return null;
+    }
+    await out.deferUpdate();
+    return out.fields.getTextInputValue("typed");
+}
+
+async function modifySuggestion(interaction: ButtonInteraction, accept: boolean) {
+    const message = interaction.message;
     await message.fetch();
     if (message.embeds.length === 0) return;
-    const embed = message.embeds[0];
+    const embed = message.embeds[0]!;
+    const issueNum = embed.footer!.text
+    if(!issueNum) return;
+    const issue = {
+        owner: "ClicksMinutePer",
+        repo: "Nucleus",
+        issue_number: parseInt(issueNum)
+    }
+    let name = "Unknown";
+    const components: InteractionEditReplyOptions["components"] = [];
+    switch(interaction.customId) {
+        case "accept:Suggestion": {
+            name = "Accepted";
+            await interaction.deferUpdate();
+            await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion accepted by " + interaction.user.tag});
+            components.push(new ActionRowBuilder<ButtonBuilder>().addComponents(
+                new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary),
+                new ButtonBuilder().setCustomId("implemented:Suggestion").setLabel("Implemented").setStyle(ButtonStyle.Secondary)
+            ))
+            break;
+        }
+        case "deny:Suggestion": {
+            name = "Denied";
+            const reason = await getReason(interaction, "Reason for denial");
+            await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion denied by " + interaction.user.tag + " for reason:\n>" + reason});
+            await client.GitHub.rest.issues.update({...issue, state: "closed", state_reason: "not_planned"});
+            // await client.GitHub.rest.issues.lock({...issue, lock_reason: "resolved"})
+            components.push(new ActionRowBuilder<ButtonBuilder>().addComponents(
+                new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
+            ))
+            break;
+        }
+        case "close:Suggestion": {
+            name = "Closed";
+            const reason = await getReason(interaction, "Reason for closing");
+            await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion closed by " + interaction.user.tag + " for reason:\n>" + reason});
+            await client.GitHub.rest.issues.update({...issue, state: "closed"});
+            // await client.GitHub.rest.issues.lock({...issue})
+            components.push(new ActionRowBuilder<ButtonBuilder>().addComponents(
+                new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
+            ))
+            break;
+        }
+        case "implement:Suggestion": {
+            name = "Implemented";
+            await interaction.deferUpdate();
+            await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion implemented"});
+            await client.GitHub.rest.issues.update({...issue, state: "closed", state_reason: "completed"});
+            await client.GitHub.rest.issues.lock({...issue, lock_reason: "resolved"})
+            break;
+        }
+        case "lock:Suggestion": {
+            name = "Locked";
+            await interaction.deferUpdate();
+            await client.GitHub.rest.issues.lock({...issue});
+            break;
+        }
+        case "spam:Suggestion": {
+            name = "Marked as Spam";
+            await interaction.deferUpdate();
+            await client.GitHub.rest.issues.update({...issue, state: "closed", state_reason: "not_planned"});
+            await client.GitHub.rest.issues.lock({...issue, lock_reason: "spam"})
+            break;
+        }
+    }
+
     const newcolor = accept ? "Success" : "Danger";
-    const footer = {
-        text: `Suggestion ${accept ? "accepted" : "denied"} by ${interaction.user.tag}`,
-        iconURL: interaction.user.displayAvatarURL()
-    };
+    const newEmoji = accept ? "ICONS.ADD" : "ICONS.OPP.ADD";
 
     const newEmbed = new EmojiEmbed()
-        .setTitle(embed!.title!)
+        .setEmoji(newEmoji)
+        .setTitle(embed!.title!.replace(/.+> /, ""))
         .setDescription(embed!.description!)
-        .setFooter(footer)
-        .setStatus(newcolor);
+        .setFields({
+            name: name + " by",
+            value: interaction.user.tag,
+        })
+        .setStatus(newcolor)
+        .setFooter(embed!.footer);
 
-    await interaction.update({ embeds: [newEmbed], components: [] });
+    await interaction.editReply({
+        embeds: [newEmbed],
+        components: components
+    });
 }
 
 export async function callback(_client: NucleusClient, interaction: Interaction) {
diff --git a/src/utils/client.ts b/src/utils/client.ts
index 43f8c5f..6899b90 100644
--- a/src/utils/client.ts
+++ b/src/utils/client.ts
@@ -6,6 +6,7 @@
 import EventScheduler from "../utils/eventScheduler.js";
 import type { RoleMenuSchema } from "../actions/roleMenu.js";
 import config from "../config/main.js";
+import { Octokit } from "octokit";
 
 class NucleusClient extends Client {
     logger = Logger;
@@ -24,6 +25,7 @@
         scanCache: ScanCache;
         transcripts: Transcript;
     };
+    GitHub = new Octokit({ auth: config.githubPAT });
     preloadPage: Record<string, { command: string; argument: string }> = {}; // e.g. { channelID: { command: privacy, page: 3}}
     commands: Record<
         string,
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index 59befe6..f1229eb 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -42,7 +42,7 @@
         emoji: string;
         customId: string;
         modal: Discord.ModalBuilder;
-        value: string | undefined;
+        values: Record<string, string>;
     }[] = [];
 
     constructor(interaction: CommandInteraction | ButtonInteraction) {
@@ -106,9 +106,9 @@
         this.reason = reason;
         return this;
     }
-    addModal(buttonText: string, emoji: string, customId: string, current: string, modal: Discord.ModalBuilder) {
+    addModal(buttonText: string, emoji: string, customId: string, current: Record<string, string>, modal: Discord.ModalBuilder) {
         modal.setCustomId(customId);
-        this.modals.push({ buttonText, emoji, customId, modal, value: current });
+        this.modals.push({ buttonText, emoji, customId, modal, values: current });
         return this;
     }
     async send(editOnly?: boolean): Promise<{
@@ -121,7 +121,7 @@
             emoji: string;
             customId: string;
             modal: Discord.ModalBuilder;
-            value: string | undefined;
+            values: Record<string, string>;
         }[];
     }> {
         let cancelled = false;
@@ -131,19 +131,19 @@
 
         while (!cancelled && success === undefined && !returnComponents && !newReason) {
             const fullComponents = [
-                new Discord.ButtonBuilder()
+                new ButtonBuilder()
                     .setCustomId("yes")
                     .setLabel("Confirm")
                     .setStyle(this.inverted ? ButtonStyle.Success : ButtonStyle.Danger)
                     .setEmoji(getEmojiByName("CONTROL.TICK", "id")),
-                new Discord.ButtonBuilder()
+                new ButtonBuilder()
                     .setCustomId("no")
                     .setLabel("Cancel")
-                    .setStyle(ButtonStyle.Secondary)
+                    .setStyle(ButtonStyle.Danger)
                     .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
             ];
             Object.entries(this.customButtons).forEach(([k, v]) => {
-                const button = new Discord.ButtonBuilder()
+                const button = new ButtonBuilder()
                     .setCustomId(k)
                     .setLabel(v.title)
                     .setStyle(v.active ? ButtonStyle.Success : ButtonStyle.Primary)
@@ -153,7 +153,7 @@
             });
             for (const modal of this.modals) {
                 fullComponents.push(
-                    new Discord.ButtonBuilder()
+                    new ButtonBuilder()
                         .setCustomId(modal.customId)
                         .setLabel(modal.buttonText)
                         .setStyle(ButtonStyle.Primary)
@@ -163,7 +163,7 @@
             }
             if (this.reason !== null)
                 fullComponents.push(
-                    new Discord.ButtonBuilder()
+                    new ButtonBuilder()
                         .setCustomId("reason")
                         .setLabel("Edit Reason")
                         .setStyle(ButtonStyle.Primary)
@@ -174,7 +174,7 @@
             for (let i = 0; i < fullComponents.length; i += 5) {
                 components.push(
                     new ActionRowBuilder<
-                        | Discord.ButtonBuilder
+                        | ButtonBuilder
                         | Discord.StringSelectMenuBuilder
                         | Discord.RoleSelectMenuBuilder
                         | Discord.UserSelectMenuBuilder
@@ -272,7 +272,7 @@
                             .setEmoji(this.emoji)
                     ],
                     components: [
-                        new ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
+                        new ActionRowBuilder<ButtonBuilder>().addComponents(
                             new ButtonBuilder()
                                 .setLabel("Back")
                                 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
@@ -322,7 +322,7 @@
                             .setEmoji(this.emoji)
                     ],
                     components: [
-                        new ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
+                        new ActionRowBuilder<ButtonBuilder>().addComponents(
                             new ButtonBuilder()
                                 .setLabel("Back")
                                 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
@@ -350,7 +350,9 @@
                     continue;
                 }
                 if (out instanceof ModalSubmitInteraction) {
-                    chosenModal!.value = out.fields.getTextInputValue("default");
+                    out.fields.fields.forEach((f, k) => {
+                        chosenModal!.values[k] = f.value;
+                    });
                 }
                 returnComponents = true;
                 continue;