0
votes

I need it so that a bot will send a message and if anyone on the server reacts to that message with a reaction it will give them a role.

I Have already tried multiple times, different code samples which allow reactions anywhere in the guild but i want it specific to one channel.

client.on("messageReactionAdd", (reaction, user) => {
  if (user.bot) return;
  const member = reaction.message.member
   switch (reaction.name) {
     case "????":
     member.addRole("597011179545690121").then((res) => {
       reaction.message.channel.send(`You've been given the \`${res.name}\` role!`)
     }).catch(console.error);
     break;
     case "????":
     member.addRole("597011179545690121").then((res) => {
       reaction.message.channel.send(`You've been given the \`${res.name}\` role!`)
     }).catch(console.error);
  };
})

client.on("messageReactionRemove", (reaction, user) => {
  if (user.bot) return;
  const member = reaction.message.member
  switch (reaction.name) {
case "emoji_name_1":
member.removeRole("roleID").then((res) => 
  reaction.message.channel.send(`You've been removed from the \`${res.name}\` role!`)
    }).catch(console.error);
    break;
    case "emoji_name_2":
    member.removeRole("someOtherRole").then((res) => {
      reaction.message.channel.send(`You've been removed from the \`${res.name}\` role!`)
    }).catch(console.error);
  };
})

I Want the outcome to be that the person reacts with say a smiley face and they get a certain role but they have to react to a certain message sent by the bot in its own dedicated channel same as pre-made bots such as Reaction Roles bot.

2
Please do not vandalize your posts. Once you have submitted a post, you have licensed the content to the Stack Overflow community at large (under the CC BY-SA license). By SE policy, any vandalism will be reverted.NobodyNada

2 Answers

0
votes

First we have to fetch our Message.

let channel_id = "ChanelID of message"; 
let message_id = "ID of message";



client.on("ready", (reaction, user) => {

client.channels.get(channel_id).fetchMessage(message_id).then(m => {
        console.log("Cached reaction message.");
    }).catch(e => {
    console.error("Error loading message.");
    console.error(e);
    });

Then we'll check if someone reacted to our message and give them the appropriate Role

client.on("messageReactionAdd", (reaction, user) => {
    if(reaction.emoji.id == "EMOJI ID HERE" && reaction.message.id === message_id) 
        {
            guild.fetchMember(user) // fetch the user that reacted
                .then((member) => 
                {
                    let role = (member.guild.roles.find(role => role.name === "YOUR ROLE NAME HERE"));
                    member.addRole(role)
                    .then(() => 
                    {
                        console.log(`Added the role to ${member.displayName}`);
                    }
                    );
                });
        }
}

I advise against using this code for multiple Roles at once as that would be rather inefficient.

0
votes
const member = reaction.message.member

Problem: This is defining member as the GuildMember that sent the message, not the one that added the reaction.

Solution: Use the Guild.member() method, for example...

const member = reaction.message.guild.member(user);

switch (reaction.name) {...}

Problem: name is a not a valid property of a MessageReaction.

Solution: What you're looking for is ReactionEmoji.name, accessed via reaction.emoji.name.


...[the users] have to react to a certain message...

Problem: Your current code isn't checking anything about the message that's been reacted to. Therefore, it's triggered for any reaction.

Solution: Check the message ID to make sure it's the exact one you want. If you'd like to allow reactions on any message within a certain channel, check the message's channel ID.

Consider these examples:

if (reaction.message.id !== "insert message ID here") return;
if (reaction.message.channel.id !== "insert channel ID here") return;

Problem: The messageReactionAdd event is not emitted for reactions on uncached messages.

Solution: Use the raw event to fetch the required information and emit the event yourself, as shown here. Alternatively, use Caltrop's solution and fetch the message when the client is ready via TextChannel.fetchMessage().