forked from haykam821/Discord-RoleReact
-
Notifications
You must be signed in to change notification settings - Fork 0
/
role.js
187 lines (150 loc) · 7.91 KB
/
role.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
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!`, //DONT 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 ((message.author.id !== CONFIG.yourID) && (message.content.toLowerCase() !== CONFIG.setupCMD)) return;
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, true);
else roleEmbed.addField(customEmote, role, 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);
});