diff --git a/Addons/hello.js b/Addons/hello.js new file mode 100644 index 0000000..cd1ca34 --- /dev/null +++ b/Addons/hello.js @@ -0,0 +1,34 @@ +// SupportBot | Emerald Services +// Example (default) Addon + +const fs = require("fs"); + +const Discord = require("discord.js"); +const yaml = require('js-yaml'); +const supportbot = yaml.load(fs.readFileSync('./Data/supportbot.yml', 'utf8')); +const cmdconfig = yaml.load(fs.readFileSync('./Data/commands.yml', 'utf8')); + +// Your Addon Config file! Saved in /Addons/Settings/YourAddonConig.yml +// const exampleaddon = yaml.load(fs.readFileSync('./Addons/Settings/YourAddonConig.yml', 'utf8')); + +const Command = require("../Structures/Command.js"); + +module.exports = new Command({ + name: "hello", + description: "hello", + type: "BOTH", + slashCommandOptions: [], + permission: "SEND_MESSAGES", + + async run(message, args, client) { + + const Embed = new Discord.MessageEmbed() + .setDescription("Hello World!") + .setColor(supportbot.InfoColour) + + message.channel.send({ + embeds: [Embed] + }) + + } +}); \ No newline at end of file diff --git a/Commands/TicketAdd.js b/Commands/TicketAdd.js new file mode 100644 index 0000000..cf85f2b --- /dev/null +++ b/Commands/TicketAdd.js @@ -0,0 +1,75 @@ +// SupportBot | Emerald Services +// Info Command + +const fs = require("fs"); + +const Discord = require("discord.js"); +const yaml = require('js-yaml'); +const supportbot = yaml.load(fs.readFileSync('./Data/supportbot.yml', 'utf8')); +const cmdconfig = yaml.load(fs.readFileSync('./Data/commands.yml', 'utf8')); + +const Command = require("../Structures/Command.js"); + +async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array); + } + } + +module.exports = new Command({ + name: cmdconfig.TicketAdd, + description: cmdconfig.TicketAddDesc, + type: "BOTH", + slashCommandOptions: [], + permission: "SEND_MESSAGES", + + async run(message, args, client) { + + let SupportStaff = message.guild.roles.cache.find(SupportTeam => SupportTeam.name === supportbot.Staff) || message.guild.roles.cache.find(SupportTeam => SupportTeam.id === supportbot.Staff) + let Admins = message.guild.roles.cache.find(AdminUser => AdminUser.name === supportbot.Admin) || message.guild.roles.cache.find(AdminUser => AdminUser.id === supportbot.Admin) + + const NoPerms = new Discord.MessageEmbed() + .setTitle("Invalid Permissions!") + .setDescription(`${supportbot.IncorrectPerms}\n\nRole Required: \`${supportbot.Staff}\` or \`${supportbot.Admin}\``) + .setColor(supportbot.WarningColour) + + if (message.member.roles.cache.has(SupportStaff.id) || message.member.roles.cache.has(Admins.id)) { + if (!message.channel.name.startsWith( `${supportbot.TicketChannel}-` )) { + const Exists = new Discord.MessageEmbed() + .setTitle("No Ticket Found!") + .setDescription(`${supportbot.NoValidTicket}`) + .setColor(supportbot.WarningColour); + message.channel.send({ embeds: [Exists] }); + + return; + } + + let uMember = message.mentions.users.first(); + const UserNotExist = new Discord.MessageEmbed() + .setTitle("User Not Found!") + .setDescription(`${supportbot.UserNotFound}\n\nTry Again:\`${supportbot.Prefix}${cmdconfig.TicketAdd} \``) + .setColor(supportbot.ErrorColour) + + if (!uMember) return message.channel.send({ embeds: [UserNotExist] }); + + message.channel.permissionOverwrites.edit(uMember, { + VIEW_CHANNEL: true, + READ_MESSAGE_HISTORY: true, + SEND_MESSAGES: true, + }); + + const Complete = new Discord.MessageEmbed() + .setTitle("User Added!") + .setDescription(supportbot.AddedUser.replace(/%user%/g, uMember.id)) + .setTimestamp() + .setColor(supportbot.EmbedColour) + message.channel.send({ embeds: [Complete] }); + } else { + + return message.channel.send({ embeds: [NoPerms] }); + + } + + } + +}); \ No newline at end of file diff --git a/Commands/TicketRemove.js b/Commands/TicketRemove.js new file mode 100644 index 0000000..aea45c1 --- /dev/null +++ b/Commands/TicketRemove.js @@ -0,0 +1,75 @@ +// SupportBot | Emerald Services +// Info Command + +const fs = require("fs"); + +const Discord = require("discord.js"); +const yaml = require('js-yaml'); +const supportbot = yaml.load(fs.readFileSync('./Data/supportbot.yml', 'utf8')); +const cmdconfig = yaml.load(fs.readFileSync('./Data/commands.yml', 'utf8')); + +const Command = require("../Structures/Command.js"); + +async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array); + } + } + +module.exports = new Command({ + name: cmdconfig.TicketRemove, + description: cmdconfig.TicketRemoveDesc, + type: "BOTH", + slashCommandOptions: [], + permission: "SEND_MESSAGES", + + async run(message, args, client) { + + let SupportStaff = message.guild.roles.cache.find(SupportTeam => SupportTeam.name === supportbot.Staff) || message.guild.roles.cache.find(SupportTeam => SupportTeam.id === supportbot.Staff) + let Admins = message.guild.roles.cache.find(AdminUser => AdminUser.name === supportbot.Admin) || message.guild.roles.cache.find(AdminUser => AdminUser.id === supportbot.Admin) + + const NoPerms = new Discord.MessageEmbed() + .setTitle("Invalid Permissions!") + .setDescription(`${supportbot.IncorrectPerms}\n\nRole Required: \`${supportbot.Staff}\` or \`${supportbot.Admin}\``) + .setColor(supportbot.WarningColour) + + if (message.member.roles.cache.has(SupportStaff.id) || message.member.roles.cache.has(Admins.id)) { + if (!message.channel.name.startsWith( `${supportbot.TicketChannel}-` )) { + const Exists = new Discord.MessageEmbed() + .setTitle("No Ticket Found!") + .setDescription(`${supportbot.NoValidTicket}`) + .setColor(supportbot.WarningColour); + message.channel.send({ embeds: [Exists] }); + + return; + } + + let uMember = message.mentions.users.first(); + const UserNotExist = new Discord.MessageEmbed() + .setTitle("User Not Found!") + .setDescription(`${supportbot.UserNotFound}\n\nTry Again:\`${supportbot.Prefix}${cmdconfig.TicketRemove} \``) + .setColor(supportbot.ErrorColour) + + if (!uMember) return message.channel.send({ embeds: [UserNotExist] }); + + message.channel.permissionOverwrites.edit(uMember, { + VIEW_CHANNEL: false, + READ_MESSAGE_HISTORY: false, + SEND_MESSAGES: false, + }); + + const Complete = new Discord.MessageEmbed() + .setTitle("User Removed!") + .setDescription(supportbot.RemovedUser.replace(/%user%/g, uMember.id)) + .setTimestamp() + .setColor(supportbot.EmbedColour) + message.channel.send({ embeds: [Complete] }); + } else { + + return message.channel.send({ embeds: [NoPerms] }); + + } + + } + +}); \ No newline at end of file diff --git a/Commands/help.js b/Commands/help.js new file mode 100644 index 0000000..5597910 --- /dev/null +++ b/Commands/help.js @@ -0,0 +1,86 @@ +// SupportBot | Emerald Services +// Close Ticket Command + +const fs = require("fs"); + +const Discord = require("discord.js"); +const yaml = require('js-yaml'); +const supportbot = yaml.load(fs.readFileSync('./Data/supportbot.yml', 'utf8')); +const cmdconfig = yaml.load(fs.readFileSync('./Data/commands.yml', 'utf8')); + +const Command = require("../Structures/Command.js"); +const TicketNumberID = require('../Structures/TicketID.js'); + +async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array); + } + } + +module.exports = new Command({ + name: cmdconfig.HelpCommand, + description: cmdconfig.HelpCommandDesc, + type: "BOTH", + slashCommandOptions: [], + permission: "SEND_MESSAGES", + + async run(message, args, client) { + + let SupportStaff = message.guild.roles.cache.find(adminRole => adminRole.name === supportbot.Staff) || message.guild.roles.cache.find(staffRole => staffRole.id === supportbot.Staff); + let AdminStaff = message.guild.roles.cache.find(adminRole => adminRole.name === supportbot.Admin) || message.guild.roles.cache.find(adminRole => adminRole.id === supportbot.Admin); + + if (supportbot.HelpMenu) { + let botCommands = ""; + botCommands += `**${supportbot.Prefix}${cmdconfig.HelpCommand}** ${cmdconfig.HelpCommandDesc}\n`; + botCommands += `**${supportbot.Prefix}${cmdconfig.InfoCommand}** ${cmdconfig.InfoCommandDesc}\n`; + botCommands += `**${supportbot.Prefix}${cmdconfig.PingCommand}** ${cmdconfig.PingCommandDesc}\n` + + let ticketCommands = ""; + ticketCommands += `**${supportbot.Prefix}${cmdconfig.OpenTicket}** ${cmdconfig.OpenTicketDesc}\n`; + ticketCommands += `**${supportbot.Prefix}${cmdconfig.CloseTicket}** ${cmdconfig.CloseTicketDesc}\n` + + let staffCommands = ""; + staffCommands += `**${supportbot.Prefix}${cmdconfig.TicketAdd}** ${cmdconfig.TicketAddDesc}\n` + staffCommands += `**${supportbot.Prefix}${cmdconfig.TicketRemove}** ${cmdconfig.TicketRemoveDesc}\n` + + const HelpEmbed1 = new Discord.MessageEmbed() + .setTitle(supportbot.Name) + .setThumbnail(message.author.displayAvatarURL()) + + .addFields( + { name: '🖥️ General Commands\n', value: `${botCommands}\n`, inline: false }, + { name: '🎫 Support Commands\n', value: `${ticketCommands}\n`, inline: false }, + ) + + .setColor(supportbot.EmbedColour) + .setFooter(supportbot.EmbedFooter, message.author.displayAvatarURL()); + + if (message.member.roles.cache.has(SupportStaff.id)) { + HelpEmbed1.addFields( + { name: '🔐 Staff Commands\n', value: `${staffCommands}\n`, inline: false }, + ) + } else { + if ((message.member.roles.cache.has(AdminStaff.id))) { + HelpEmbed1.addFields( + { name: '🔐 Staff Commands\n', value: `${staffCommands}\n`, inline: false }, + ) + } + } + + if (supportbot.SendHelpPage === "dm") { + message.author.send({ + embeds: [HelpEmbed1] + }); + } + + if (supportbot.SendHelpPage === "channel") { + message.channel.send({ + embeds: [HelpEmbed1] + }); + } + + + } + + } +}); diff --git a/Data/commands.yml b/Data/commands.yml index 5b30388..2c266f9 100644 --- a/Data/commands.yml +++ b/Data/commands.yml @@ -14,18 +14,24 @@ # Commamnd Name Configuration # ------------------------------- +TicketAdd: "ticketadd" +TicketRemove: "ticketremove" OpenTicket: "ticket" CloseTicket: "close" InfoCommand: "info" PingCommand: "ping" +HelpCommand: "help" # --------------------------------------- # Commamnd Description Configuration # --------------------------------------- +TicketAddDesc: "Add a user to a support ticket." +TicketRemoveDesc: "Remove a user from a support ticket." OpenTicketDesc: "Open a new support ticket." -CloseTicketDesc: "Close your support ticket" -InfoCommandDesc: "Get information about the brand" +CloseTicketDesc: "Close your support ticket." +InfoCommandDesc: "Get information about the brand." PingCommandDesc: "Pong!" +HelpCommandDesc: "Get a list of all the commands." diff --git a/Data/supportbot.yml b/Data/supportbot.yml index 08e63d3..be0ab3e 100644 --- a/Data/supportbot.yml +++ b/Data/supportbot.yml @@ -10,7 +10,7 @@ # Discord Support: https:#emeraldsrv.dev/discord # Community Resources: https:#emeraldsrv.dev/resources -SupportBot_Version: "7.2 pre-2" +SupportBot_Version: "7.2 pre-3" # ------------------------- # General Configuration @@ -18,7 +18,7 @@ SupportBot_Version: "7.2 pre-2" Name: "SupportBot" Prefix: "!" -Token: "TOKEN" +Token: "BOT_TOKEN" # ------------------------- # Activity Configuration @@ -54,6 +54,13 @@ InfoButtonText: "Visit Site" InfoURL: "https://emeraldsrv.dev" InfoColour: "#f74343" +# ------------------------- +# Help Configuration +# ------------------------- + +HelpMenu: true # Do not change! +SendHelpPage: "channel" # Set to channel or dm + # ------------------------- # Role Configuration # ------------------------- @@ -171,3 +178,12 @@ ClosingTicket: ":warning: You have requested to close your support ticket." ClosingConfirmation_Word: "confirm" CloseConfirmation: false +# --------------------------- +# Error / Warning Messages +# --------------------------- + +IncorrectPerms: ":x: **Err!** You do not have the correct permissions to use this command." +InvalidChannel: ":x: **Err!** Channel not found. Please create it!" +UserNotFound: ":x: **Err!** This user doesn't exist, Are they in this server?" +NoValidTicket: ":warning: You cannot execute this command here." +TicketExists: ":warning: This ticket cannot be opened, It already exists!" diff --git a/Data/ticket-panel-id.yml b/Data/ticket-panel-id.yml index b129648..a21d6b7 100644 --- a/Data/ticket-panel-id.yml +++ b/Data/ticket-panel-id.yml @@ -1,7 +1 @@ -# Place the Message ID for your Ticket Panel. -# If you do not have one. Leave it blank! It will generate for you! - -TicketPanelID: '' - - - +TicketPanelID: '896035054235574362' diff --git a/Structures/Addons.js b/Structures/Addons.js new file mode 100644 index 0000000..7e708b3 --- /dev/null +++ b/Structures/Addons.js @@ -0,0 +1,24 @@ +// SupportBot | Emerald Services +// Addon Structure + +const fs = require("fs"); + +const Discord = require("discord.js"); + +const yaml = require('js-yaml'); +const supportbot = yaml.load(fs.readFileSync('./Data/supportbot.yml', 'utf8')); + +function RunFunction(message, args, client) {} + +class Addon { + constructor(options) { + this.name = options.name; + this.description = options.description; + this.permission = options.permission; + this.type = ["BOTH", "SLASH", "TEXT"].includes(options.type) ? options.type : "TEXT"; + this.slashCommandOptions = options.slashCommandOptions || []; + this.run = options.run; + } +} + +module.exports = Addon; \ No newline at end of file diff --git a/Structures/Client.js b/Structures/Client.js index 83f0e9a..a902605 100644 --- a/Structures/Client.js +++ b/Structures/Client.js @@ -26,11 +26,35 @@ class Client extends Discord.Client { const commands = commandFiles.map(file => require(`../Commands/${file}`)); + console.log(`\u001b[34;1m`, '▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬') + commands.forEach(cmd => { - console.log(`Command ${cmd.name} loaded`); + console.log(`\u001b[31;1m`, `${cmd.name}`, `\u001b[32;1m`, 'Loaded'); this.commands.set(cmd.name, cmd); }); + console.log(`\u001b[34;1m`, '▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬') + + // Addons + + const addonFiles = fs.readdirSync("./Addons") + .filter(file => file.endsWith(".js")); + + const addons = addonFiles.map(file => require(`../Addons/${file}`)); + + console.log(' ') + console.log(`\u001b[34;1m`, '▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬') + + addons.forEach(addon => { + console.log(`\u001b[31;1m`, `${addon.name}`, `\u001b[32;1m`, 'Loaded'); + this.commands.set(addon.name, addon); + }); + + console.log(`\u001b[34;1m`, '▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬') + console.log(' ') + + // Slash Commands + const slashCommands = commands .filter(cmd => ["BOTH", "SLASH"].includes(cmd.type)) .map(cmd => ({ @@ -46,20 +70,32 @@ class Client extends Discord.Client { this.on("ready", async () => { const cmds = await this.application.commands.set(slashCommands); - cmds.forEach(cmd => console.log(`Slash Command ${cmd.name} registered`)); + console.log(' ') + console.log(`\u001b[34;1m`, '▬▬▬▬▬▬▬ Slash Command ▬▬▬▬▬▬▬'), + console.log(' ') + + cmds.forEach(cmd => + console.log(`Slash Command ${cmd.name} registered`), + ) + }) + console.log(' ') + console.log(`\u001b[34;1m`, '▬▬▬▬▬▬▬ Events ▬▬▬▬▬▬▬') + fs.readdirSync("./Events") .filter(file => file.endsWith(".js")) .forEach(file => { - /** - * @type {Event} - */ + const event = require(`../Events/${file}`); - console.log(`Event ${event.event} loaded`); + console.log(`\u001b[31;1m`, `${event.event}`, `\u001b[32;1m`, 'Loaded'); + this.on(event.event, event.run.bind(null, this)); }); + console.log(`\u001b[34;1m`, '▬▬▬▬▬▬▬ Events ▬▬▬▬▬▬▬') + console.log(' ') + this.login(token); } } diff --git a/events/interactionCreate.js b/events/interactionCreate.js index 60d0118..f7664fb 100644 --- a/events/interactionCreate.js +++ b/events/interactionCreate.js @@ -16,6 +16,37 @@ module.exports = new Event("interactionCreate", (client, interaction) => { const command = client.commands.find(cmd => cmd.name.toLowerCase() == interaction.commandName); + if (interaction.user.bot || !interaction.isCommand() || !interaction.guild) + return; + + const args = [ + interaction.commandName, + ...client.commands + .find(cmd => cmd.name.toLowerCase() == interaction.commandName) + .slashCommandOptions.map(v => `${interaction.options.get(v.name).value}`) + ]; + + const NotValid = new Discord.MessageEmbed() + .setDescription(`:x: \`Invalid Command\` `) + .setColor(supportbot.ErrorColour) + + if (!command) return interaction.reply({ + embeds: [NotValid] + }); + + const permission = interaction.member.permissions.has(command.permission); + + const ValidPerms = new Discord.MessageEmbed() + .setDescription(":x: \`Invalid Permissions\` Do you have the correct permissions to execute this command?") + .setColor(supportbot.ErrorColour) + + if (!permission) + return interaction.reply({ + embeds: [ValidPerms] + }); + + command.run(interaction, args, client); + if(interaction.isButton()) { if(interaction.customId === 'openticket') { interaction.message.fetch() @@ -132,34 +163,4 @@ module.exports = new Event("interactionCreate", (client, interaction) => { } } - if (interaction.user.bot || !interaction.isCommand() || !interaction.guild) - return; - - const args = [ - interaction.commandName, - ...client.commands - .find(cmd => cmd.name.toLowerCase() == interaction.commandName) - .slashCommandOptions.map(v => `${interaction.options.get(v.name).value}`) - ]; - - const NotValid = new Discord.MessageEmbed() - .setDescription(`:x: \`Invalid Command\` `) - .setColor(supportbot.ErrorColour) - - if (!command) return interaction.reply({ - embeds: [NotValid] - }); - - const permission = interaction.member.permissions.has(command.permission); - - const ValidPerms = new Discord.MessageEmbed() - .setDescription(":x: \`Invalid Permissions\` Do you have the correct permissions to execute this command?") - .setColor(supportbot.ErrorColour) - - if (!permission) - return interaction.reply({ - embeds: [ValidPerms] - }); - - command.run(interaction, args, client); }); \ No newline at end of file diff --git a/package.json b/package.json index f23714a..d0626cd 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "homepage": "https://github.com/1tzemerald/GlennBot#readme", "dependencies": { - "discord.js": "^13.1.0", + "discord.js": "^13.2.0", "js-yaml": "^4.1.0" } }