diff --git a/Commands/ticket.js b/Commands/ticket.js index c540958..ccb5c0b 100644 --- a/Commands/ticket.js +++ b/Commands/ticket.js @@ -100,7 +100,7 @@ module.exports = new Command({ (c) => c.name === supportbot.Ticket.TicketCategory || c.id === supportbot.Ticket.TicketCategory ); - const channel = await getChannel(panelconfig.Channel, interaction.guild); + const channel = await getChannel(supportbot.Ticket.TicketCategory, interaction.guild); const ticketChannel = await channel.threads.create({ name: `${supportbot.Ticket.Channel}${ticketNumberID}`, type: ChannelType.PrivateThread, diff --git a/Configs/supportbot-ai.yml b/Configs/supportbot-ai.yml index 60beab5..4b80809 100644 --- a/Configs/supportbot-ai.yml +++ b/Configs/supportbot-ai.yml @@ -17,11 +17,11 @@ General: # Max tokens you can set is 400 # For more information about tokens, go to https://openai.com/api/pricing/ - OpenAI_Key: "OPEN_AI_APIKEY_HERE" + OpenAI_Key: "OPEN_AI_KEY_HERE" # To create an OpenAI API key, go to https://platform.openai.com/api-keys - PastebinAPI_Key: "PASTEBIN_API_KEY" + PastebinAPI_Key: "PASTEBIN" # You can get your Pastebin API Key from https://pastebin.com PastebinAPI_URL: "https://pastebin.com/api/api_post.php" diff --git a/Configs/supportbot.yml b/Configs/supportbot.yml index 169ffe6..cf8cf50 100644 --- a/Configs/supportbot.yml +++ b/Configs/supportbot.yml @@ -20,7 +20,7 @@ SupportBot_Version: "v8.0" General: Name: "SupportBot" - Token: "BOT_TOKEN_HERE" + Token: "BOT_TOKEN" # To get your Discord Bot Token, Go to https://discord.com/developers/applications Addons: @@ -152,7 +152,7 @@ Ticket: ClaimTickets: Enabled: true - Channel: "0000000000000000000" + Channel: "1249723473757077624" # Channel name or Channel ID ButtonTitle: "Claim Ticket" diff --git a/Configs/ticket-panel.yml b/Configs/ticket-panel.yml index f285673..28072eb 100644 --- a/Configs/ticket-panel.yml +++ b/Configs/ticket-panel.yml @@ -20,9 +20,6 @@ Panel: true # Ticket Panel Message Configuration #2b2d31 # ---------------------------------------- -TicketCategory: "📗┃tickets" -# This is the channel name for the ticket threads to be created, NOT A DISCORD CATEGORY! - PanelTitle: "SupportBot" PanelColour: "#0cc559" diff --git a/Data/SuggestionData.json b/Data/SuggestionData.json index 776e35d..9e26dfe 100644 --- a/Data/SuggestionData.json +++ b/Data/SuggestionData.json @@ -1,16 +1 @@ -{ - "1249719789069402180": { - "suggestion": "test", - "author": "419821884431925260", - "upvotes": [ - "419821884431925260" - ], - "downvotes": [] - }, - "1249762468360884290": { - "suggestion": "test", - "author": "419821884431925260", - "upvotes": [], - "downvotes": [] - } -} \ No newline at end of file +{} \ No newline at end of file diff --git a/Events/interactionCreate.js b/Events/interactionCreate.js index db61e76..9f64240 100644 --- a/Events/interactionCreate.js +++ b/Events/interactionCreate.js @@ -8,6 +8,13 @@ const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8")); const Event = require("../Structures/Event.js"); +let suggestions; +try { + suggestions = require("../Data/SuggestionData.json"); +} catch (error) { + suggestions = {}; +} + module.exports = new Event("interactionCreate", async (client, interaction) => { if (interaction.type == Discord.InteractionType.ApplicationCommand) { const command = client.commands.find( @@ -70,10 +77,6 @@ module.exports = new Event("interactionCreate", async (client, interaction) => { } break; - case "ticketremoveuser": - await removeUserFromThread(interaction); - break; - case "enableinvites": await handleInvites(interaction, true); break; @@ -186,6 +189,55 @@ module.exports = new Event("interactionCreate", async (client, interaction) => { ephemeral: true, }); } + + // SUGGESTION INTERACTIONS [START] + + if (interaction.customId === 'upvote' || interaction.customId === 'downvote' || interaction.customId === 'removevote') { + const suggestion = suggestions[interaction.message.id]; + if (!suggestion) return interaction.reply({ content: 'Suggestion not found.', ephemeral: true }); + + const userId = interaction.user.id; + const hasUpvoted = suggestion.upvotes.includes(userId); + const hasDownvoted = suggestion.downvotes.includes(userId); + + if (interaction.customId === 'upvote') { + if (hasUpvoted) { + suggestion.upvotes = suggestion.upvotes.filter(id => id !== userId); + } else { + suggestion.upvotes.push(userId); + if (hasDownvoted) { + suggestion.downvotes = suggestion.downvotes.filter(id => id !== userId); + } + } + } else if (interaction.customId === 'downvote') { + if (hasDownvoted) { + suggestion.downvotes = suggestion.downvotes.filter(id => id !== userId); + } else { + suggestion.downvotes.push(userId); + if (hasUpvoted) { + suggestion.upvotes = suggestion.upvotes.filter(id => id !== userId); + } + } + } else if (interaction.customId === 'removevote') { + suggestion.upvotes = suggestion.upvotes.filter(id => id !== userId); + suggestion.downvotes = suggestion.downvotes.filter(id => id !== userId); + } + + fs.writeFileSync("./Data/SuggestionData.json", JSON.stringify(suggestions, null, 2)); + + const upvoteCount = suggestion.upvotes.length; + const downvoteCount = suggestion.downvotes.length; + + const updatedEmbed = new Discord.EmbedBuilder(interaction.message.embeds[0].data) + .setFields([ + { name: 'Suggestion', value: suggestion.suggestion, inline: true }, + { name: 'From', value: `<@${suggestion.author}>` }, + { name: `${supportbot.Suggestions.UpvoteEmoji} ${supportbot.Suggestions.UpvoteTitle}`, value: `${upvoteCount}`, inline: true }, + { name: `${supportbot.Suggestions.DownvoteEmoji} ${supportbot.Suggestions.DownvoteTitle}`, value: `${downvoteCount}`, inline: true } + ]); + + await interaction.update({ embeds: [updatedEmbed] }); + } } async function handleInvites(interaction, enable) { @@ -221,4 +273,6 @@ module.exports = new Event("interactionCreate", async (client, interaction) => { ephemeral: true, }); } -}); \ No newline at end of file + + +}); diff --git a/Structures/Client.js b/Structures/Client.js index 074d382..350d80d 100644 --- a/Structures/Client.js +++ b/Structures/Client.js @@ -1,20 +1,15 @@ +// C:\Users\ollie\Documents\GitHub\SupportBot\Structures\Client.js + // SupportBot | Emerald Services // Client Structure const fs = require("fs"); - const Discord = require("discord.js"); const { GatewayIntentBits, Partials } = require('discord.js'); - const yaml = require("js-yaml"); -const supportbot = yaml.load( - fs.readFileSync("./Configs/supportbot.yml", "utf8") -); - -const cmdconfig = yaml.load( - fs.readFileSync("./Configs/commands.yml", "utf8") -); +const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); +const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8")); class Client extends Discord.Client { constructor() { @@ -29,29 +24,34 @@ class Client extends Discord.Client { this.commands = new Discord.Collection(); } - + async getChannel(channel, guild) { + if (!channel) return null; // Add check for undefined channel return guild.channels.cache.find( (c) => (c.type === Discord.ChannelType.GuildText || c.type === Discord.ChannelType.GuildNews) && - (c.id === channel || c.name.toLowerCase() === channel.toLowerCase()) + (c.id === channel || (c.name && c.name.toLowerCase() === channel.toLowerCase())) ); } + async getRole(role, guild) { + if (!role) return null; // Add check for undefined role return guild.roles.cache.find( - (r) => r.id === role || r.name.toLowerCase() === role.toLowerCase() + (r) => r.id === role || (r.name && r.name.toLowerCase() === role.toLowerCase()) ); } + async getCategory(category, guild) { + if (!category) return null; // Add check for undefined category return guild.channels.cache.find( (c) => c.type === Discord.ChannelType.GuildCategory && - (c.id === category || c.name.toLowerCase() === category.toLowerCase()) + (c.id === category || (c.name && c.name.toLowerCase() === category.toLowerCase())) ); } async start(token) { - var tempCommandFiles = fs.readdirSync("./Commands").filter((file) => file.endsWith(".js")); + let tempCommandFiles = fs.readdirSync("./Commands").filter((file) => file.endsWith(".js")); if (cmdconfig.Suggestion.Enabled === false) { tempCommandFiles = tempCommandFiles.filter(item => item !== "suggest.js"); @@ -98,7 +98,6 @@ class Client extends Discord.Client { } const commandFiles = tempCommandFiles; - const commands = commandFiles.map((file) => require(`../Commands/${file}`)); // Commands @@ -112,9 +111,7 @@ class Client extends Discord.Client { console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬"); if (supportbot.General.Addons.Enabled) { - const addonFiles = fs - .readdirSync("./Addons") - .filter((file) => file.endsWith(".js")); + const addonFiles = fs.readdirSync("./Addons").filter((file) => file.endsWith(".js")); const addons = addonFiles.map((file) => { let addon = require(`../Addons/${file}`); @@ -135,17 +132,16 @@ class Client extends Discord.Client { `\u001b[32;1m`, "Loaded" ); - addon.commands?.forEach((command) => { - this.commands.set(command.name, command); + addon.commands?.forEach((command) => { + this.commands.set(command.name, command); + }); + addon.events?.forEach((event) => { + this.on(event.event, (...args) => event.run(this, ...args)); + }); }); - addon.events?.forEach((event) => { - this.on(event.event, (...args) => event.run(this, ...args)); - }); - }); - console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬"); - - } + console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬"); + } // Slash Commands @@ -162,13 +158,11 @@ class Client extends Discord.Client { console.log(" "); console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Events ▬▬▬▬▬▬▬"); - fs.readdirSync("./Events") - .filter((file) => file.endsWith(".js")) - .forEach((file) => { - const event = require(`../Events/${file}`); - console.log(`\u001b[32m`, `[EVENT]`, `\u001b[37;1m`, `${event.event}`, `\u001b[32;1m`, "Loaded"); - this.on(event.event, (...args) => event.run(this, ...args)); - }); + fs.readdirSync("./Events").filter((file) => file.endsWith(".js")).forEach((file) => { + const event = require(`../Events/${file}`); + console.log(`\u001b[32m`, `[EVENT]`, `\u001b[37;1m`, `${event.event}`, `\u001b[32;1m`, "Loaded"); + this.on(event.event, (...args) => event.run(this, ...args)); + }); console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Events ▬▬▬▬▬▬▬"); if (process.argv[2] !== "test") { diff --git a/package.json b/package.json index 96222c1..4aed27f 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,17 @@ { "name": "supportbot", - "version": "8.1", + "version": "8.0.1", "description": "SupportBot is an open-sourced support system for discord. It's completely free to use with high amounts of customization to match your own brand.", "main": "index.js", "scripts": { - "start": "npm i && node index.js", - "test": "node index.js test" + "setup": "npm i && node index.js", + "start": "node index.js" }, "repository": { "type": "git", "url": "git+https://github.com/Emerald-Services/SupportBot.git" }, - "author": "Emerald Development", + "author": "Emerald Services", "license": "MIT", "bugs": { "url": "https://github.com/Emerald-Services/SupportBot/issues"