diff options
| author | 8cy <[email protected]> | 2020-07-19 02:10:00 -0700 |
|---|---|---|
| committer | 8cy <[email protected]> | 2020-07-19 02:10:00 -0700 |
| commit | 4014ac46b4e5e515f133ca2c04859824cd43738c (patch) | |
| tree | 5842824afd615f70e8a4959704f9cf3492fa54f2 /role.js | |
| download | water-waifu-4014ac46b4e5e515f133ca2c04859824cd43738c.tar.xz water-waifu-4014ac46b4e5e515f133ca2c04859824cd43738c.zip | |
:star:
Diffstat (limited to 'role.js')
| -rw-r--r-- | role.js | 187 |
1 files changed, 187 insertions, 0 deletions
@@ -0,0 +1,187 @@ +// Import constructors, configuration and login the client +const { Client, RichEmbed, Emoji, MessageReaction } = require('discord.js'); +const CONFIG = require('./config'); + +const client = new Client({ disableEveryone: true }); +if (CONFIG.botToken === '') + throw new Error("The 'botToken' property is not set in the config.js file. Please do this!"); + +client.login(CONFIG.botToken); + +// If there isn't a reaction for every role, alert the user +if (CONFIG.roles.length !== CONFIG.reactions.length) + throw "Roles list and reactions list are not the same length! Please double check this in the config.js file"; + +// Function to generate the role messages, based on your settings +function generateMessages() { + return CONFIG.roles.map((r, e) => { + return { + role: r, + message: `React below to get the **"${r}"** role!`, // DON'T CHANGE THIS + emoji: CONFIG.reactions[e] + }; + }); +} + +// Function to generate the embed fields, based on your settings and if you set "const embed = true;" +function generateEmbedFields() { + return CONFIG.roles.map((r, e) => { + return { + emoji: CONFIG.reactions[e], + role: r + }; + }); +} + +// Client events to let you know if the bot is online and to handle any Discord.js errors +client.on("ready", () => console.log("Role Reactions is online!")); +client.on('error', console.error); + +// Handles the creation of the role reactions. Will either send the role messages separately or in an embed +client.on("message", message => { + // Make sure bots can't run this command + if (message.author.bot) return; + + // Make sure the command can only be ran in a server + if (!message.guild) return; + + // We don't want the bot to do anything further if it can't send messages in the channel + if (message.guild && !message.channel.permissionsFor(message.guild.me).missing('SEND_MESSAGES')) return; + + if ((CONFIG.validIDs.includes(message.author.id)) || (message.content.toLowerCase() !== CONFIG.setupCMD)) return; // message.author.id !== CONFIG.yourID + + if (CONFIG.deleteSetupCMD) { + const missing = message.channel.permissionsFor(message.guild.me).missing('MANAGE_MESSAGES'); + // Here we check if the bot can actually delete messages in the channel the command is being ran in + if (missing.includes('MANAGE_MESSAGES')) + throw new Error("I need permission to delete your command message! Please assign the 'Manage Messages' permission to me in this channel!"); + message.delete().catch(O_o=>{}); + } + + const missing = message.channel.permissionsFor(message.guild.me).missing('MANAGE_MESSAGES'); + // Here we check if the bot can actually add recations in the channel the command is being ran in + if (missing.includes('ADD_REACTIONS')) + throw new Error("I need permission to add reactions to these messages! Please assign the 'Add Reactions' permission to me in this channel!"); + + if (!CONFIG.embed) { + if (!CONFIG.initialMessage || (CONFIG.initialMessage === '')) + throw "The 'initialMessage' property is not set in the config.js file. Please do this!"; + + message.channel.send(CONFIG.initialMessage); + + const messages = generateMessages(); + for (const { role, message: msg, emoji } of messages) { + if (!message.guild.roles.find(r => r.name === role)) + throw `The role '${role}' does not exist!`; + + message.channel.send(msg).then(async m => { + const customCheck = message.guild.emojis.find(e => e.name === emoji); + if (!customCheck) await m.react(emoji); + else await m.react(customCheck.id); + }).catch(console.error); + } + } else { + if (!CONFIG.embedMessage || (CONFIG.embedMessage === '')) + throw "The 'embedMessage' property is not set in the config.js file. Please do this!"; + if (!CONFIG.embedFooter || (CONFIG.embedMessage === '')) + throw "The 'embedFooter' property is not set in the config.js file. Please do this!"; + + const roleEmbed = new RichEmbed() + .setDescription(CONFIG.embedMessage) + .setFooter(CONFIG.embedFooter); + + if (CONFIG.embedColor) roleEmbed.setColor(CONFIG.embedColor); + + if (CONFIG.embedThumbnail && (CONFIG.embedThumbnailLink !== '')) + roleEmbed.setThumbnail(CONFIG.embedThumbnailLink); + else if (CONFIG.embedThumbnail && message.guild.icon) + roleEmbed.setThumbnail(message.guild.iconURL); + + const fields = generateEmbedFields(); + if (fields.length > 25) throw "That maximum roles that can be set for an embed is 25!"; + + for (const { emoji, role } of fields) { + if (!message.guild.roles.find(r => r.name === role)) + throw `The role '${role}' does not exist!`; + + const customEmote = client.emojis.find(e => e.name === emoji); + + if (!customEmote) roleEmbed.addField(emoji, role, false); + else roleEmbed.addField(customEmote, role, false); // true + } + + message.channel.send(roleEmbed).then(async m => { + for (const r of CONFIG.reactions) { + const emoji = r; + const customCheck = client.emojis.find(e => e.name === emoji); + + if (!customCheck) await m.react(emoji); + else await m.react(customCheck.id); + } + }); + } +}); + +// This makes the events used a bit more readable +const events = { + MESSAGE_REACTION_ADD: 'messageReactionAdd', + MESSAGE_REACTION_REMOVE: 'messageReactionRemove', +}; + +// This event handles adding/removing users from the role(s) they chose based on message reactions +client.on('raw', async event => { + if (!events.hasOwnProperty(event.t)) return; + + const { d: data } = event; + const user = client.users.get(data.user_id); + const channel = client.channels.get(data.channel_id); + + const message = await channel.fetchMessage(data.message_id); + const member = message.guild.members.get(user.id); + + const emojiKey = (data.emoji.id) ? `${data.emoji.name}:${data.emoji.id}` : data.emoji.name; + let reaction = message.reactions.get(emojiKey); + + if (!reaction) { + // Create an object that can be passed through the event like normal + const emoji = new Emoji(client.guilds.get(data.guild_id), data.emoji); + reaction = new MessageReaction(message, emoji, 1, data.user_id === client.user.id); + } + + let embedFooterText; + if (message.embeds[0]) embedFooterText = message.embeds[0].footer.text; + + if ( + (message.author.id === client.user.id) && (message.content !== CONFIG.initialMessage || + (message.embeds[0] && (embedFooterText !== CONFIG.embedFooter))) + ) { + + if (!CONFIG.embed && (message.embeds.length < 1)) { + const re = `\\*\\*"(.+)?(?="\\*\\*)`; + const role = message.content.match(re)[1]; + + if (member.id !== client.user.id) { + const guildRole = message.guild.roles.find(r => r.name === role); + if (event.t === "MESSAGE_REACTION_ADD") member.addRole(guildRole.id); + else if (event.t === "MESSAGE_REACTION_REMOVE") member.removeRole(guildRole.id); + } + } else if (CONFIG.embed && (message.embeds.length >= 1)) { + const fields = message.embeds[0].fields; + + for (const { name, value } of fields) { + if (member.id !== client.user.id) { + const guildRole = message.guild.roles.find(r => r.name === value); + if ((name === reaction.emoji.name) || (name === reaction.emoji.toString())) { + if (event.t === "MESSAGE_REACTION_ADD") member.addRole(guildRole.id); + else if (event.t === "MESSAGE_REACTION_REMOVE") member.removeRole(guildRole.id); + } + } + } + } + } +}); + +process.on('unhandledRejection', err => { + const msg = err.stack.replace(new RegExp(`${__dirname}/`, 'g'), './'); + console.error("Unhandled Rejection", msg); +}); |