0
votes

I am currently creating a reaction role event where people can interact with a message and get a role assigned to themselves after clicking a certain emoji, however for some reason the event will not trigger and no role is assigned to the user.

Below is my reaction.js event file:

module.exports = 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) {
    if (reaction.emoji.name === 'pinkEmoji') {
      await reaction.message.guild.members.cache.get(user.id).roles.add(pink);
    }
    if (reaction.emoji.name === 'yellowEmoji') {
      await reaction.message.guild.members.cache.get(user.id).roles.add(yellow);
    }
    if (reaction.emoji.name === 'purpleEmoji') {
      await reaction.message.guild.members.cache.get(user.id).roles.add(purple);
    }
  } else {
    return;
  }

  if (reaction.message.channel.id == channel) {
    if (reaction.emoji.name === 'pinkEmoji') {
      await reaction.message.guild.members.cache.get(user.id).roles.remove(pink);
    }
    if (reaction.emoji.name === 'yellowEmoji') {
      await reaction.message.guild.members.cache.get(user.id).roles.remove(yellow);
    }
    if (reaction.emoji.name === 'purpleEmoji') {
      await reaction.message.guild.members.cache.get(user.id).roles.remove(purple);
    }
  } else {
    return;
  }
}

I'm also using a command to let the bot know it has to send the message after typing in the command.

Here is my reactionrole.js command file if it helps:

module.exports = {
  name: 'reactionrole',
  description: 'sets up a reaction role message!',
  permissions: ["MANAGE_ROLES"],
  cooldown: 10,
  async execute(message, args, cmd, client, Discord) {
    const channel = process.env.WELCOME;

    const pink = message.guild.roles.cache.find(role => role.name === "Pink");
    const yellow = message.guild.roles.cache.find(role => role.name === "Yellow");
    const purple = message.guild.roles.cache.find(role => role.name === "Purple");

    const pinkEmoji = '????';
    const yellowEmoji = '????';
    const purpleEmoji = '????';

    let embed = new Discord.MessageEmbed()
    .setColor('#e42643')
    .setTitle('Choose your own **Color Role**!')
    .setDescription('Choosing a color role will give you a coloured name!\n\n'
        + `${pinkEmoji} for pink color\n`
        + `${yellowEmoji} for yellow color\n`
        + `${purpleEmoji} for purple color`);
    
    let messageEmbed = await message.channel.send(embed);
    messageEmbed.react(pinkEmoji);
    messageEmbed.react(yellowEmoji);
    messageEmbed.react(purpleEmoji);
  }
}

Below is the event handler I am using:

const fs = require('fs');

module.exports = (client, Discord) => {
  const load_dir = (dirs) => {
    const event_files = fs.readdirSync(`./events/${dirs}`).filter(file => file.endsWith('.js'));

    for (const file of event_files) {
      const event = require(`../events/${dirs}/${file}`);
      const event_name = file.split('.')[0];
      client.on(event_name, event.bind(null, Discord, client));
    }
  }
  ['client', 'guild'].forEach(e => load_dir(e));
}

I have been stuck on this for quite a while now and I don't know where the problem lies because it's not throwing any errors.

2

2 Answers

1
votes

I'm not sure where or when the module from the reaction.js file is executed but if I check your event handler, it seems you want to listen to the reaction event. The problem is there is no reaction event. I think what you're looking for is the messageReactionAdd event instead, so you should rename reaction.js to messageReactionAdd.js.

Still, roles like pink, yellow, etc. won't be available in this file if you're declaring them in reactionrole.js. You need to define them in this file instead.

// messageReactionAdd.js
module.exports = async (reaction, user) => {
  if (user.bot) return;
  if (reaction.message.partial) await reaction.message.fetch();
  if (reaction.partial) await reaction.fetch();

  const channel = process.env.WELCOME;
  const { message } = reaction;
  const { guild } = message;

  if (!guild || message.channel.id !== channel) return;

  const pinkEmoji = '🍑';
  const yellowEmoji = '🍋';
  const purpleEmoji = '🍇';

  const member = guild.members.cache.get(user.id);
  const pink = guild.roles.cache.find((role) => role.name === 'Pink');
  const yellow = guild.roles.cache.find((role) => role.name === 'Yellow');
  const purple = guild.roles.cache.find((role) => role.name === 'Purple');

  if (reaction.emoji.name === pinkEmoji) {
    await member.roles.add(pink);
  }
  if (reaction.emoji.name === yellowEmoji) {
    await member.roles.add(yellow);
  }
  if (reaction.emoji.name === purpleEmoji) {
    await member.roles.add(purple);
  }
};
// reactionrole.js
module.exports = {
  name: 'reactionrole',
  description: 'sets up a reaction role message!',
  permissions: ['MANAGE_ROLES'],
  cooldown: 10,
  async execute(message, args, cmd, client, Discord) {
    const pinkEmoji = '🍑';
    const yellowEmoji = '🍋';
    const purpleEmoji = '🍇';

    let embed = new Discord.MessageEmbed()
      .setColor('#e42643')
      .setTitle('Choose your own **Color Role**!')
      .setDescription(
        'Choosing a color role will give you a coloured name!\n\n' +
          `${pinkEmoji} for pink color\n` +
          `${yellowEmoji} for yellow color\n` +
          `${purpleEmoji} for purple color`,
      );

    let messageEmbed = await message.channel.send(embed);
    messageEmbed.react(pinkEmoji);
    messageEmbed.react(yellowEmoji);
    messageEmbed.react(purpleEmoji);
  },
};
-1
votes

I think you need to get ID message when user type reactionrole . Then in file reaction.js event you write a collector , collection all reaction from message id and give role for you click it.