I’m trying to make a “add role by reaction” command. So when a member reacts to a specific message, the member gets a role. It actually works but when I restart my bot, it doesn’t add a role anymore. Can anyone help?
here the code:
bot.on('message', msg=>{ if(msg.content.startsWith(prefix + "react")){ let embed = new Discord.MessageEmbed() .setTitle("Reactions Roles") .setDescription("React to get a role!") .setColor("BLUE") msg.channel.send(embed).then(m=> m.react("emoji_id")) } }) bot.on("messageReactionAdd", async (reaction, user)=>{ if (reaction.message.partial) await reaction.message.fetch(); if (reaction.partial) await reaction.fetch(); if(user.bot) return; if(!reaction.message.guild) return; if(reaction.message.channel.id === "channel_id"){ if(reaction.emoji.id === "emoji_id"){ await reaction.message.guild.members.cache.get(user.id).roles.add("role_id") } } }) bot.on('messageReactionRemove', async (reaction, user)=>{ if(reaction.message.partial) await reaction.message.fetch(); if(reaction.partial) await reaction.fetch(); if(user.bot) return; if(!reaction.message.guild) return; if(reaction.message.channel.id === "channel_id"){ if(reaction.emoji.id === "emoji_id"){ await reaction.message.guild.members.cache.get(user.id).roles.remove("role_id") } } })
Advertisement
Answer
To make your bot check if previous messages have been reacted upon you could use a code similar to this
let guildID = "xxx"; let channelID = "xxx"; let emojiID = "xxx"; let roleID = "xxx"; bot.on("ready", async () => { let guild = bot.guilds.cache.find(guild => guild.id == guildID); let channel = await guild.channels.cache.find(ch => ch.id == channelID) // You can set any limit you want, for performance I used a low number channel.messages.fetch({ limit: 10 }) .then(async messages => { messages.forEach(async message => { if (message.partial) await message.fetch(); if (!message.guild) return; for (let reactionObj of message.reactions.cache) { for (let reaction of reactionObj) { if (typeof reaction == "string") continue; if (reaction.emoji.id != emojiID) continue; reaction.users.fetch() .then(async users => { users.forEach(async user => { if (user.bot) return; console.log("Adding role") await reaction.message.guild.members.cache.get(user.id).roles.add(roleID) }) }) } } }); }) .catch(console.error); });
You might want to make some changes, but this works.
To break it down…
- Get messages in a specific channel (or multiple)
- Check if the message has reactions
- Check if any of the reactions match a specific emoji
- Add the role to the guild member
- Optionally check if the member already has the role before attempted to add it
Please note that this code might very well not be the most efficient, but it gets the job done. Also, it does NOT work with “non-custom” emojis, for that you’ll have to check for emoji.name instead of emoji.id.
As suggested by @michael.grigoryan it is very recommended to check out the documentation.
Edit: Removed previous answer, to remove confusion