aboutsummaryrefslogtreecommitdiff
path: root/role.js
diff options
context:
space:
mode:
author8cy <[email protected]>2020-07-19 02:10:00 -0700
committer8cy <[email protected]>2020-07-19 02:10:00 -0700
commit4014ac46b4e5e515f133ca2c04859824cd43738c (patch)
tree5842824afd615f70e8a4959704f9cf3492fa54f2 /role.js
downloadwater-waifu-4014ac46b4e5e515f133ca2c04859824cd43738c.tar.xz
water-waifu-4014ac46b4e5e515f133ca2c04859824cd43738c.zip
:star:
Diffstat (limited to 'role.js')
-rw-r--r--role.js187
1 files changed, 187 insertions, 0 deletions
diff --git a/role.js b/role.js
new file mode 100644
index 0000000..5ca2885
--- /dev/null
+++ b/role.js
@@ -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);
+});