// Base requires const { Client, GatewayIntentBits, Events, ApplicationCommandPermissionType } = require("discord.js") const fs = require("fs") const { type } = require("os") const { parse } = require("path") const types = require("util/types") // TOKEN is stored in the .env file (node --env-file=.env index.js) const token = process.env.TOKEN // Creating a client const client = new Client({ intents: [ GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.DirectMessages, GatewayIntentBits.Guilds ]} ) // Exporting the client for event and command files to use it module.exports.client = client module.exports.dir = __dirname // Requiring all the event files. fs.readdir(`${__dirname}/events/`, (err, files) => { files.forEach(file => { if (!file.endsWith(".js")) { return } require(`${__dirname}/events/${file}`) }) }) // Command list const commands = [] // Requiring the command files fs.readdir(`${__dirname}/commands`, (err, files) => { files.forEach(file => { if (!file.endsWith("js")) { return } const commandList = require(`${__dirname}/commands/${file}`).commands commands.push(commandList) }) }) // Function to get the command with that name function getCommand(commandName) { var command; commands.forEach(commandList => { commandList.forEach(commandArray => { if (commandArray.name == commandName) { command = commandArray } }) }) return command; } // Parsing commands on message create client.on("messageCreate", async (message) => { var content = message.content // Continue only if starts with the prefix if (!content.startsWith('!')) { return } // Need to remove the prefix after the check content = content.slice(1, content.length) // Splitting the message into command and args const parsed = content.split(" ") // Getting command name const command = parsed[0] // Actual command const realCommand = getCommand(command) // Only continue if command exists if (!realCommand) { return } if (!realCommand.arguments) { // No arguments so no need to parse them // Run command with no args if (realCommand.run.constructor.name == "AsyncFunction"){ await realCommand.run(message) } else { realCommand.run(message) } } else { // Removing command from the args const args = parsed.filter(value => {return value != command}) if (args.length < realCommand.arguments.length) { const missing = realCommand.arguments.slice(realCommand.arguments.length - args.length) missing.forEach((argument, index) => { if (typeof argument == "object" || typeof argument == "function") { missing[index] = argument.name } }) return message.reply(`Missing arguments ${missing}`) } var wrongArg = false // Parsing args.forEach((arg, index) => { if (arg.startsWith("<@")) { // User, lets get the id const id = arg.slice(2, arg.length - 1) const member = message.guild.members.cache.find(member => member.user.id == id) if (member) { args[index] = member } } else if (arg.startsWith("<#")) { // Channel, lets get the id const id = arg.slice(2, arg.length - 1) const channel = message.guild.channels.cache.find(channel => channel.id == id) if (channel) { args[index] = channel } } else if (Number(arg)) { args[index] = Number(arg) } else if (arg == "true" || arg == "false") { args[index] = arg == "true" // This is awful man. } // Checks if the type is wrong if (typeof args[index] != typeof realCommand.arguments[index] && !(args[index] instanceof realCommand.arguments[index])) { wrongArg = true // So it cant continue return message.reply(`Argument ${index} supposed to be ${realCommand.arguments[index].name}`) } }) if (wrongArg) { return } // Run command if (realCommand.run.constructor.name == "AsyncFunction"){ await realCommand.run(message, ...args) } else { realCommand.run(message, ...args) } //...args passes it as separate args rather than an Array } } ) /* Command preset: module.exports.commands = [ //module.exports.commands exports ONLY COMMANDLISTS. { name: "name", // !name description: "description", // (opt) run: (ctx, link, member, num) => {}, // run function hide: false, // hide from !help or not arguments: ["link", GuildMember, 1] // argument types, } ] */ // After getting the command list we can export it module.exports.commands = commands // Time to login client.login(token)