Epic Boomer Moments
Epic Boomer Moments

Reputation: 21

How to add a reaction role function with custom emojis?

Hello members of the Stack Overflow community,

I have been working on a function that activates when a moderator approves a user using Auttaja's gatekeeper. Basically, the new user gets to choose between two server emoji reactions, which will give him/her the roles. But I have been having difficulties with the role and emoji constants.

Here's my code:

 const ApprovalEmbed = new Discord.MessageEmbed()
.setColor('RED')
.setTitle('Hi there new user!')
.setDescription('Please react to this message with either one of the emojis in order to get a role.')
.addFields(
  { name: '\u200B', value: '\u200B' },
  { name: 'The Boomer emoji gives you the "Les boomers normaux" role, and the rat emoji gives you the "The normal Rat Haven dwellers" role.'},
   { name: '\u200B', value: '\u200B' },
  { name: 'Selecting the Boomer emoji will give you access to only the Boomer Haven compartment, and the rat emoji will give you access to the Rat Haven compartment. '},
  { name: '\u200B', value: '\u200B' },
  {name: 'To get access to both of these compartments, please consider using the command "^AccessToBoth" to receive the "Access to both compartments" role.'},
  )
  .setTimestamp()
  .setFooter('Time to pick a role!');
  const roleOne = guild.roles.cache.find((role) => role.name === "The normal Rat Haven dwellers")
  const roleTwo = guild.roles.cache.find((role) => role.name === "Les boomers normaux")
  const BoomerEmoji = message.guild.emojis.cache.find(emoji => emoji.name === 'boomer');
  const RatEmoji = message.guild.emojis.cache.find(emoji => emoji.name === 'robincutmoment');



client.on('message', async message => {
  let AdminRole = message.member.roles.cache.find(role => role.name === "Server Moderators")
  let RulerRole = message.member.roles.cache.find(role => role.name === "The Supreme Boomers")
  let RatRole = message.member.roles.cache.find(role => role.name === "Rat Majesty Robin")
  if (message.member.roles.cache.has(AdminRole)) {
  } else if (message.member.roles.cache.has(RulerRole)) {
  } else if (message.member.roles.cache.has(RatRole)) {}
  if (message.content === `-approve`) {
    message.channel.send(BoomerEmoji)
    const reactionMessage = await message.channel.send(ApprovalEmbed);
    message.channel.send(ApprovalEmbed).then(reactionMessage.react(BoomerEmoji), reactionMessage.react(RatEmoji))
      
    
  }
  const filter = (reaction, user) => {
      return [(BoomerEmoji), (RatEmoji)].includes(reaction.emoji.name) && user.id === message.author.id;
  };
  message.awaitReactions(filter, { max: 1, time: 60000, errors: ['time'] })
    .then(collected => {
      const reaction = collected.first();
      
      if (reaction.emoji.name === (BoomerEmoji)) {
        message.member.roles.add(roleOne)
      } else if (reaction.emoji.name === (RatEmoji)) {
              message.member.roles.add(roleTwo)
      }
  })

});

Upvotes: 0

Views: 953

Answers (1)

Lioness100
Lioness100

Reputation: 8402

Your first problem is occurring in this snippet:

if (message.member.roles.cache.has(AdminRole)) {
 // ...
} else if (message.member.roles.cache.has(RulerRole)) {
 // ...
} else if (message.member.roles.cache.has(RatRole)) {
 // ...
}

Collection.prototype.has() checks if an element exists in the collection. It takes one parameter: the key of the element you wish to check the existence of. Since roles are mapped by snowflakes, you should be passing the role ID, not the entire object.

// `Collection.prototype.has()` is identical to `Map.prototype.has()`
// here's how it works:
const map = new Map();

// 'foo' is the key,
// 'bar' is the value
map.set('foo', 'bar');

console.log(map.has('foo')); // true
console.log(map.has('bar')); // 'bar' is not the key; false

if (message.member.roles.cache.has(AdminRole.id)) {
 // ...
} else if (message.member.roles.cache.has(RulerRole.id)) {
 // ...
} else if (message.member.roles.cache.has(RatRole.id)) {
 // ...
}

If you'd like to be fancy, you could use Collection.prototype.findKey() instead of the normal Collection.prototype.find(). This method is almost the same, except it returns the key of the found element instead of the value. Again, it makes almost no difference; just another option.

let AdminRole = message.member.roles.cache.findKey(
 (role) => role.name === 'Server Moderators'
);
let RulerRole = message.member.roles.cache.findKey(
 (role) => role.name === 'The Supreme Boomers'
);
let RatRole = message.member.roles.cache.findKey(
 (role) => role.name === 'Rat Majesty Robin'
);
if (message.member.roles.cache.has(AdminRole)) {
 // ...
} else if (message.member.roles.cache.has(RulerRole)) {
 // ...
} else if (message.member.roles.cache.has(RatRole)) {
 // ...
}

Your second problem is somewhat along the same lines. BoomerEmoji and RatEmoji are complete GuildEmoji objects. However, in this line:

return (
 [BoomerEmoji, RatEmoji].includes(reaction.emoji.name) &&
 user.id === message.author.id
);

And these lines:

if (reaction.emoji.name === BoomerEmoji) {
 message.member.roles.add(roleOne);
} else if (reaction.emoji.name === RatEmoji) {
 message.member.roles.add(roleTwo);
}

You're comparing it to the name property of another emoji. This fix is fairly simple, just clarify you only need the name properties when declaring each variable:

const BoomerEmoji = message.guild.emojis.cache.find(
 (emoji) => emoji.name === 'boomer'
).name;
const RatEmoji = message.guild.emojis.cache.find(
 (emoji) => emoji.name === 'robincutmoment'
).name;

Upvotes: 1

Related Questions