diff --git a/commands/config.js b/commands/config.js index c8673f7..f93f0c1 100644 --- a/commands/config.js +++ b/commands/config.js @@ -12,7 +12,16 @@ module.exports = { .setDescription('Configure the bot.') .addSubcommand(subcommand => subcommand - .setName('sendapplication') + .setName('sendguildapplication') + .setDescription('Send the application message to a channel.') + .addChannelOption(option => + option + .setName('channel') + .setDescription('The channel to send the application to.') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('sendstaffapplication') .setDescription('Send the application message to a channel.') .addChannelOption(option => option @@ -45,6 +54,38 @@ module.exports = { const channel = interaction.options.getChannel('channel'); + await channel.send({ + embeds: [{ + title: 'Staff Application', + description: "You can apply for the staff team by clicking the button below.", + color: embedColor, + footer: { + text: interaction.guild.name + " | Developed by @Taken#0002", + iconURL: interaction.guild.iconURL({ dynamic: true }) + }, + thumbnail: { + url: interaction.guild.iconURL({ dynamic: true }) + } + }], + components: [ + new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId('staffapply') + .setLabel('Apply') + .setStyle(ButtonStyle.Primary) + .setEmoji({ name: '✅' }) + ) + ] + }) + + await interaction.reply({ content: 'Message sent', ephemeral: true }) + + } + + if (subcommand === 'sendstaffapplication') { + + const channel = interaction.options.getChannel('channel'); + await channel.send({ embeds: [{ title: 'Guild Application', @@ -70,7 +111,6 @@ module.exports = { }) await interaction.reply({ content: 'Message sent', ephemeral: true }) - } if (subcommand === "sendguildinfo") { diff --git a/config/questions.json b/config/questions.json index 14b85fa..0bc9696 100644 --- a/config/questions.json +++ b/config/questions.json @@ -14,5 +14,17 @@ "rq5": "Will you be able to make from 100k to 150k gexp x week?", "rq6": "Tell us about yourself.", "rq7": "How did you find about us?", - "rq8": "What is your time zone?" + "rq8": "What is your time zone?", + "sq1": "What is your IGN?", + "sq2": "", + "sq3": "", + "sq4": "", + "sq5": "", + "sq6": "", + "rsq1": "", + "rsq2": "", + "rsq3": "", + "rsq4": "", + "rsq5": "", + "rsq6": "" } \ No newline at end of file diff --git a/events/buttons/guilapply.js b/events/buttons/guilapply.js index 772b80d..e84da55 100644 --- a/events/buttons/guilapply.js +++ b/events/buttons/guilapply.js @@ -108,7 +108,7 @@ module.exports = { if (answer1.first().content > 16) { await user.send({ embeds: [{ - description: "¸Max character limit is 16.", + description: "Max character limit is 16.", color: embedColor }] }) @@ -459,7 +459,7 @@ module.exports = { await channel.send({ embeds: [{ - title: user.username + "#" + user.discriminator + " - Application", + title: user.username + "#" + user.discriminator + " - Guild Application", color: embedColor, thumbnail: { url: user.avatarURL() diff --git a/events/buttons/staffapply.js b/events/buttons/staffapply.js new file mode 100644 index 0000000..caf49ac --- /dev/null +++ b/events/buttons/staffapply.js @@ -0,0 +1,443 @@ +const { ChannelType, PermissionFlagsBits, ButtonBuilder, ButtonStyle, ActionRowBuilder, EmbedBuilder } = require('discord.js'); +const { color } = require('../../config/options.json'); +const { largeM, smallM, ignM } = require('../../config/limitmessages.json') +const { applicationsCategory } = require('../../config/options.json'); +const { sq1, sq2, sq3, sq4, sq5, sq6 } = require('../../config/questions.json'); +const { rsq1, rsq2, rsq3, rsq4, rsq5, rsq6 } = require('../../config/questions.json'); +const { guildRole, guildStaff } = require('../../config/roles.json') +const path = require('path'); +const fetch = require('axios'); +const fs = require('fs'); + +module.exports = { + name: 'staffapply', + description: 'Apply for the staff team.', + type: 'button', + + async execute(interaction) { + + const user = interaction.user; + const guild = interaction.guild; + const embedColor = Number(color.replace("#", "0x")); + const userRoles = interaction.member.roles.cache; + const mojangAPI = "https://api.mojang.com/users/profiles/minecraft/" + + + if (!userRoles.has(guildRole)) { + await interaction.reply({content: "You must be a member of the guild to apply for staff.", ephemeral: true}); + } + + if (userRoles.has(guildStaff)) { + await interaction.reply({content: "You are already a staff member.", ephemeral: true}); + } + + if (interaction.customId === "staffapply") { + + const applicationFile = path.join(__dirname, '../../staffapplications/' + user.id); + if (fs.existsSync(applicationFile)) { + await interaction.reply({ content: "You already have an application in progress.", ephemeral: true }); + return + } + + const tooLong = new EmbedBuilder() + .setDescription("You took too long to respond.") + .setColor(embedColor) + const cancelled = new EmbedBuilder() + .setDescription("You have cancelled your application.") + .setColor(embedColor) + const attachments = new EmbedBuilder() + .setDescription("You have uploaded an attachment. Please do not upload images, videos, or GIFS.") + .setColor(embedColor) + + try { + await user.send({ + embeds: [{ + title: 'Staff Application', + description: "Please answer the following questions to apply for staff.\n" + + "If you wish to cancel your application, please press type `cancel` at any time.\n" + + "If you wish to proceed with your application, please type `yes`.\n\n" + + "**Do not upload images, videos, or GIFS.**\n" + + "You have a minute to respond to this message.", + color: embedColor, + }] + }) + } catch (error) { + await interaction.reply({ content: "Please enable your DMs.", ephemeral: true }); + return + } + + await interaction.reply({ content: "Please check your DMs.", ephemeral: true}) + + const input = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 + }); + if (input.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (input.size === 0) { + await user.send({ embeds: [tooLong] }); + return + } + if (input.first().content.toLowerCase() !== 'yes') { + await user.send({ embeds: [cancelled]} ); + return + } + + // first question + const question1 = await user.send({ + embeds: [{ + title : "**Question 1**", + description: sq1 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + ignM + "`", + color: embedColor, + footer:{ + text: "You have 5 minutes to respond to this message." + } + }] + }) + const answer1 = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 * 5, + }); + if (answer1.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (answer1.first().content > 16) { + await user.send({ + embeds: [{ + description: "Max character limit is 16.", + color: embedColor + }] + }) + return + } + try { + await fetch(mojangAPI + answer1.first().content) + } catch (error) { + await user.send({ + embeds: [{ + description: "That is not a valid Minecraft username.\n" + + "Application cancelled.", + color: embedColor + }] + }) + return + } + if (answer1.size === 0) { + await user.send({ embeds: [tooLong] }) + return + } + if (answer1.first().content.toLowerCase() === 'cancel') { + await user.send({ embeds: [cancelled] }) + return + } + const answer1_1 = answer1.first().content + + // second question + const question2 = await user.send({ + embeds: [{ + title : "**Question 2**", + description: sq2 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n" + "`(8 characters max)`", + color: embedColor, + footer:{ + text: "You have 15 minutes to respond to this message." + } + }] + }) + const answer2 = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 * 15 + }); + if (answer2.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (answer2.first().content > 8) { + await user.send({ + embeds: [{ + description: "Max character limit is 8.", + color: embedColor + }] + }) + return + } + if (answer2.size === 0) { + await user.send({ embeds: [tooLong] }) + return + } + if (answer2.first().content.toLowerCase() === 'cancel') { + await user.send({ embeds: [cancelled] }) + return + } + const answer2_1 = answer2.first().content + + // third question + const question3 = await user.send({ + embeds: [{ + title : "**Question 3**", + description: sq3 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + smallM + "`", + color: embedColor, + footer:{ + text: "You have 15 minutes to respond to this message." + } + }] + }) + const answer3 = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 * 15 + }); + if (answer3.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (answer3.first().content > 128) { + await user.send({ + embeds: [{ + description: "Max character limit is 128.", + color: embedColor + }] + }) + } + if (answer3.size === 0) { + await user.send({ embeds: [tooLong] }) + return + } + if (answer3.first().content.toLowerCase() === 'cancel') { + await user.send({ embeds: [cancelled] }) + return + } + const answer3_1 = answer3.first().content + + // fourth question + const question4 = await user.send({ + embeds: [{ + title : "**Question 4**", + description: sq4 + "\n\nPlease type your answer below or type `cancel` to cancel your application." + + " `(We expect a longer answer.)`\n`" + largeM + "`", + color: embedColor, + footer:{ + text: "You have 15 minutes to respond to this message." + } + }] + }) + const answer4 = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 * 15 + }); + if (answer4.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (answer4.first().content > 256) { + await user.send({ + embeds: [{ + description: "Max character limit is 256.", + color: embedColor + }] + }) + } + if (answer4.size === 0) { + await user.send({ embeds: [tooLong] }) + return + } + if (answer4.first().content.toLowerCase() === 'cancel') { + await user.send({ embeds: [cancelled] }) + return + } + const answer4_1 = answer4.first().content + + // fifth question + const question5 = await user.send({ + embeds: [{ + title : "**Question 5**", + description: sq5 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + smallM + "`", + color: embedColor, + footer:{ + text: "You have 15 minutes to respond to this message." + } + }] + }) + const answer5 = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 * 15 + }); + if (answer5.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (answer5.first().content > 128) { + await user.send({ + embeds: [{ + description: "Max character limit is 128.", + color: embedColor + }] + }) + } + if (answer5.size === 0) { + await user.send({ embeds: [tooLong] }) + return + } + if (answer5.first().content.toLowerCase() === 'cancel') { + await user.send({ embeds: [cancelled] }) + return + } + const answer5_1 = answer5.first().content + + // sixth question + const question6 = await user.send({ + embeds: [{ + title : "**Question 6**", + description: sq6 + "\n\nPlease type your answer below or type `cancel` to cancel your application.\n`" + largeM + "`", + color: embedColor, + footer:{ + text: "You have 15 minutes to respond to this message." + } + }] + }) + const answer6 = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 * 15 + }); + if (answer6.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (answer6.first().content > 256) { + await user.send({ + embeds: [{ + description: "Max character limit is 256.", + color: embedColor + }] + }) + } + if (answer6.size === 0) { + await user.send({ embeds: [tooLong] }) + return + } + if (answer6.first().content.toLowerCase() === 'cancel') { + await user.send({ embeds: [cancelled] }) + return + } + const answer6_1 = answer6.first().content + + await user.send({ + embeds: [{ + description: "If you want to submit your application, type `yes` if not, type `no`", + color: embedColor + }] + }) + + const final = await user.dmChannel.awaitMessages({ + filter: m => m.author.id === user.id, + max: 1, + time: 1000 * 60 * 5 + }); + if (final.first().attachments.size > 0) { + await user.send({ embeds: [attachments] }); + return + } + if (final.size === 0) { + await user.send({ embeds: [tooLong] }); + return + } + if (final.first().content.toLowerCase() !== 'yes') { + await user.send({ embeds: [cancelled]} ); + return + } + + await user.send({ + embeds: [{ + description: "Your application has been submitted!", + color: embedColor + }] + }) + + const userCheck = await fetch(mojangAPI + answer1_1) + const uuid = userCheck.data.id + + fs.writeFile(`./applications/${user.id}`, uuid, function (err) { + if (err) throw err; + }); + + await user.deleteDM(); + + await guild.channels.create({ + name: `Application-${user.username}`, + type: ChannelType.GuildText, + topic: user.id, + permissionOverwrites: [ + { + id: guild.roles.everyone, + deny: [PermissionFlagsBits.ViewChannel] + } + ] + }).then(async channel => { + + await channel.send({ + embeds: [{ + title: user.username + "#" + user.discriminator + " - Staff Application", + color: embedColor, + thumbnail: { + url: user.avatarURL() + }, + fields: [ + { + name: rsq1, + value: "```" + answer1_1 + "```" + }, + { + name: rsq2, + value: "```" + answer2_1 + "```" + }, + { + name: rsq3, + value: "```" + answer3_1 + "```" + }, + { + name: rsq4, + value: "```" + answer4_1 + "```" + }, + { + name: rsq5, + value: "```" + answer5_1 + "```" + }, + { + name: rsq6, + value: "```" + answer6_1 + "```" + } + + ], + footer: { + iconURL: guild.iconURL(), + text: "ID: " + user.id + } + }], + components: [ + new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId("staffapplicationaccept") + .setLabel("Accept") + .setStyle(ButtonStyle.Primary) + ), + new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId("staffapplicationdeny") + .setLabel("Deny") + .setStyle(ButtonStyle.Danger) + ) + ] + }); + + }) + } + } +} \ No newline at end of file