How to add roles when user reacts to specific message - discord.js

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.

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.

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().

Related

Roles from reaction

So when bot sends a certain message, it reacts to it too. Now m tryin to check a user who reacted to that reaction has a certain role or not but so far I haven't been able to do so.
bot.on('messageReactionAdd', (reaction, user) => {
//var member = reaction.message.guild.members.cache.find(member => member.id = user.id);
//if(message.member.roles.cache.some(role => role.name === 'Bronze')) return(message.channel.send("you dont have role."));
if (reaction.message.members.roles.cache.has('729452091168260188')) return(message.channel.send("you have the role"));
else { console.log("you dont have role"); }
})
You made a mistake in the following line of code:
reaction.message.members.roles.cache.has('729452091168260188')
The Message object has no property members, it should be member:
reaction.message.member.roles.cache.has('729452091168260188')

Discord.js - How do you move a user that reacts to an embed?

I am new to Discord js and I am trying to make my bot move all users that react to an embed into a certain voice channel. Currently, it takes whoever wrote the message and moves them to the specified voice channel.I tried many combinations of user.id, guild.member, etc. What would I put before the .setVoiceChannel? I am confused as to what message.member is other than the person that wrote the message. Thank you!
collector.on('collect', (reaction, user) => {
if (reaction.emoji.name == reactionControls.VOID) {
const channel = message.guild.channels.find('name', 'Void 1');
message.member.setVoiceChannel(channel);
}
});
message.member does refer to the user who execute the command, if you want the member who reacted you will have to convert user using <GuildMember>.fetchMember, the only issue now is that the collect event doesn't give the parameter of user in v11.5.1 so you will need to just use collector.users.last() to get the last reactor
collector.on('collect', async (reaction) => {
if (reaction.emoji.name == reactionControls.VOID) {
const channel = message.guild.channels.find('name', 'Void 1');
const user = collector.users.last();
const member = await message.guild.fetchMember(user);
member.setVoiceChannel(channel);
}
});

Add roles to users in specific guild through DM

When I try
message.member.roles.add('695699359634817094');
I get the following error:
TypeError: Cannot read property 'add' of undefined
Is there a specific way to add my guild ID and update their role to that specific server through DM?
My function works within the guild by calling the command, however, through DM it doesn't.
You could do this by using message.author.id to get the user's ID and then using guild.get(guild_ID).members.fetch(user_ID) to access the GuildMember of that user.
You also mentioned that you give users the ability to run that command either in DM or a text channel in your guild.
If that is the case I would suggest adding a check to see if the command is being sent to a text channel or dm channel.
if (message.channel.type === "dm") {
const member = await client.guilds.get(guild_ID).members.fetch(message.author.id);
member.roles.add(role_ID);
} else {
message.member.roles.add('695699359634817094');
}
Ignore the if statement if you intend on having the command only run from dm.
By using the info given from Syntle and tipakA this is the solution.
if (message.channel.type === "dm") {
client.guilds.get('[SeverId]').members.fetch(message.author.id).then(async () => {
await client.guilds.get('[ServerId]').members.fetch(message.author.id).then((memberid) => {
memberid.roles.add('[roleid]');
}).catch((err) => {
console.log("ERROR");
});
});
}
else
{
message.member.roles.add('[roleid]');
}

Discord.js support channel

I want to create an if variable which checks if a user joins a certain channel, if they do then I'll keep doing my program.
What I have tried so far is different things like:
client.on('channel', async channel => {
if (channel.member.join(channel => channel.id === `672920107457970177`)) {
working.send("did it work??")
}
})
But I am pretty sure that my whole script is wrong; I only started using discord.js a few weeks ago.
You can use Client's voiceStateUpdate event. It will return 2 GuildMember values. The old one and the updated one.
Client.on("voiceStateUpdate", (oldMember, newMember) => {
if (!oldMember.voiceChannel && newMember.voiceChannel) {
console.log("oldMember channel doesn't exist. newMember channel exist. User joined a voice channel.")
} else if (!newMember.voiceChannel) {
console.log("newMember voice channel doesn't exist. User left a voice channel.")
}
})
You need to do these checks because voiceStatusUpdate is fired whenever the voice status updates (e.g. defean, mute, channel move etc.)
To check if the user joined a certain channel, just check the ID:
Client.on("voiceStateUpdate", (oldMember, newMember) => {
if (!oldMember.voiceChannel && newMember.voiceChannel && newMember.voiceChannelID == "CHANNEL ID") {
console.log(`User joined ${newMember.voiceChannel.name}!`)
}
})

Add a role to people that react with a certain emoji in a certain channel

I'm trying to make a discord.js bot for my server I made for people in my school. I'm trying to make a #classes channel and if you react to certain messages it gives you a role (which gives you access to the text channel for that class).
client.on('messageReactionAdd', (reaction, user) => {
console.log("client.on completed.")
if (message.channel.name === 'classes') {
console.log("if(message) completed.")
if (reaction.emoji.name === "reminder_ribbon") {
console.log("emoji test completed.")
const guildMember = reaction.message.guild.members.get(user.id);
const role = reaction.message.guild.roles.find(role => role.name === "FACS");
guildMember.addRole(role);
}
}
});
This is what I have tried so far, however, it does not give me/the other people reacted to it the role nor does it return an error message.
P.S. Also, how would I be able to make it so when they unreact it removes the role?
Edit: It seems it only gets reactions from cached messages/messages sent after bot startup. Also, message is not defined on the first if(message.channel.id) message.
Try to use the following code:
client.on('messageReactionAdd', (reaction, user) => {
if (reaction.message.channel.id === '552708152232116224') {
if (reaction.emoji.name === "reminder_ribbon") {
const guildMember = reaction.message.guild.members.get(user.id);
const role = reaction.message.guild.roles.get('552709290427940875');
guildMember.addRole(role);
}
}
});
First of all, reaction.users is an Object with all the users that reacted on the message, so you first have to define to which user you want to assign the role. I fixed this fetching the guildMember with user.id.
The second mistake was that you tried to assign a role ID to a guildMember although you first have to fetch the role and then assign the role Object to the guildMember.

Resources