Reaction event discord.js - javascript

I'm trying to make a starboard code with my bot, and everything else is working good. But I'm trying to make it to where the bot ignores reactions from the author of the actual message.
This is my current code:
client.on('messageReactionAdd', (reaction_orig, message, user) => {
if (message.author.id === reaction_orig.users.id) return
manageBoard(reaction_orig)
})
It returns the following error:
if (message.author.id === reaction_orig.users.id) return;
^
TypeError: Cannot read property 'id' of undefined

The problem is that messageReactionAdd takes two parameters; the message reaction as the first one, and the user that applied the emoji as the second one. When you write reaction_orig, message, user, reaction_orig is the reaction (which is correct), but message is the user who reacted as it's the second parameter. The user variable will be undefined.
Another issue is that reaction_orig.users returns a ReactionUserManager that doesn't have an id property. Luckily, the user is already passed down to your callback so you can use its ID.
Also, reaction_orig has a message property, the original message that this reaction refers to so you can get its authors' ID from it.
You can change your code to this to work:
client.on('messageReactionAdd', (reaction_orig, user) => {
if (reaction_orig.message.author.id === user.id) {
// the reaction is coming from the same user who posted the message
return;
}
manageBoard(reaction_orig);
});
However, the code above only works on cached messages, ones posted after the bot is connected. Reacting on older messages won't fire the messageReactionAdd event. If you also want to listen to reactions on old messages you need to enable partial structures for MESSAGE, CHANNEL and REACTION when instantiating your client, like this:
const client = new Discord.Client({
partials: ['MESSAGE', 'CHANNEL', 'REACTION'],
});
You can check if the message is cached by e.g. checking if its author property is not null. If it's null, you can fetch the message. Now, you have both the message author and the user who reacted, so you can compare their IDs:
// make sure it's an async function
client.on('messageReactionAdd', async (reaction_orig, user) => {
// fetch the message if it's not cached
const message = !reaction_orig.message.author
? await reaction_orig.message.fetch()
: reaction_orig.message;
if (message.author.id === user.id) {
// the reaction is coming from the same user who posted the message
return;
}
// the reaction is coming from a different user
manageBoard(reaction_orig);
});

Try doing this :
client.on('messageReactionAdd', (reaction, user) => {
if (!reaction.message.author.id === user.id){
//Do whatever you like with it
console.log(reaction.name)
}
});
Note: The message must be cached. For that you'll need to do this
Client.channels.cache.get("ChannelID").messages.fetch("MessageID");
I'm guessing you're using discord.js v12

Related

Discord.JS Message Edit

I want to edit the message over and over again.
So I made variable
this.msgRef = await channel.send({ embeds: [embedMessage] });
If I want to edit I use
this.msgRef.edit(...)
If the bot for some reason disconnects, he will lose msgReference.
Because of that, I saved it to DB.
How to create a message again because Message (object) in Discord.JS have a private constructor?
If you want to get the message again, you can simply fetch the channel's messages every time you bot connects (on the ready event for example) like so
client.on('ready', () =>{
const messages = await channel.messages.fetch()
client.msgRef = messages.find(msg => msg.author.id === client.user.id
&& msg.embeds[0]
// Etc.. Add as many conditions to make sure you choose the right message
);
})
This way, use client.msgRef.edit(...) whenever you want.

Discordjs - lastMessageId always null event after fetching

Introduction :
I'm pretty new at creating discord BOT and I'm currently trying to make like a ticket bot.
In order to do that, I need to check if the user that add the reaction is allow to do it or not.
Code :
I already checked this (successfully) when the user is using a command thanks to this (isAllow is a custom function that works when passing member object in params) :
if (Common.isAllow(message.member)) { /* code ... */ }
But I also want to check for the roles of the user that is reacting to a message, in order to create a new channel if the user is allowed to do it.
The problem is that when I get the user object, the lastMessageId is null, so I cannot get member object and check its roles.
The code that is checking for reaction is this one :
client.on("messageReactionAdd", async (reaction, user) => {
// When a reaction is received, check if the structure is partial
if (reaction.partial) {
// If the message this reaction belongs to was removed, the fetching might result in an API error which should be handled
try {
await reaction.fetch();
} catch (error) {
console.error('Something went wrong when fetching the message: ', error);
// Return as `reaction.message.author` may be undefined/null
return;
}
}
switch (reaction.message.channel.id) {
// Check if the message has been sent into the lawyer contact channel
case Config.CHANNELS.LAWYER_CONTACT:
case Config.CHANNELS.CONFIG:
checkForLawyerChannelReaction(reaction, user);
break;
default:
break;
}
});
If the reaction has been made in the good channel (LAWYER_CONTACT) or in the config channel (CONFIG), it will call this function, which is the one trying to check for permission :
function checkForLawyerChannelReaction(reaction, user) {
console.log('checkForLawyerChanelReaction');
console.log(user);
if (Common.isAllow( /* member object */ ) { /* code ... */ }
The response I get for console.log(user) is :
Result
I already tried to fetch user data like this, and it doesn't change a thing :
console.log(await client.users.fetch('123456789123456789'));
(ID has been changed, of course)
Note that the BOT has joined (again) yesterday with administrator permissions, and message has been sent by the user since yesterday.
Does somebody has a fix for this or information that I may not have yet ?
Thank you for your time.
You can get the GuildMember object by passing the user as an argument into the Guild.member(user) method.
const guildMember = reaction.message.guild.member(user);

Problem defining typingStart to a specific channel

I am trying to get my discord bot to send this message only if the user starts typing in the defined channel, and not other text channels. I don't get any errors, the bot just doesn't send a message. What am I doing wrong here? Can typingStart be defined to a specific channel?
const Join2_channel = "972135774921247676"
bot.on("typingStart", (message , channel) => {
if (channel.id === Join2_channel) {
message.send('Type !join');
}
});
The typingStart event takes two parameters; channel (the channel the user started typing in) and user (that started typing), in this order.
In your current code you're checking if the user.id is 972135774921247676 and as that's a channel's snowflake, it won't match. You need to update your callback function:
bot.on("typingStart", (channel, user) => {
if (channel.id === Join2_channel) {
channel.send('Type !join');
}
});

How to make discord.js bots check if the channel is NSFW and reply?

I want to make my discord bot send different messages when anyone types a command in a normal channel or NSFW channels.
I followed the documentation, which I didn't quite get it. I wrote the testing commands below:
client.on('message', message => {
if (command === 'testnsfw') {
if (this.nsfw = Boolean(true.nsfw)) {
return message.channel.send('yes NSFW');
} else return message.channel.send('no NSFW');
}
})
I think it is not working. The bot only responds "no NSFW" on both channels.
You cannot refer to the TextChannel using this in the anonymous function. (Also, this is always undefined in an arrow function) You can access the TextChannel using the Message class, stored in the message variable.
client.on("message", message => {
// Making the sure the author of the message is not a bot.
// Without this line, the code will create an infinite loop of messages, because even if a message is sent by a bot account, the client will emit the message event.
if (message.author.bot) return false;
// message.content is a String, containing the entire content of the message.
// Before checking if it equals to "testnsfw", I would suggest to transform it to lowercase first.
// So "testNSFW", "testnsfw", "TeStNsFw", etc.. will pass the if statement.
if (message.content.toLowerCase() == "testnsfw") {
// You can get the Channel class (which contains the nsfw property) using the Message class.
if (message.channel.nsfw) {
message.channel.send("This channel is NSFW.");
} else {
message.channel.send("This channel is SFW.");
}
}
});
What I encourage you to read:
Message
TextChannel
now you can just do this instead
if(!message.channel.nsfw) return message.channel.send('a message to send to channel')
this is using
discord.js verson 13.6.0

Emotions and discord reactions

I want it when I add emoji as a reaction it sends a private message to who added.
Exemple:
https://youtu.be/tcBhXB4Kmqk
You can use client.on('messageReactionAdd', listener) to listen to the reactions.
Inside the listener function, you can check the message id & then send the message.
Here's a sample:
// let's say that the message ID is stored in my_id
client.on('messageReactionAdd', (reaction, user) => {
// this is to avoid the bot sending messages to everyone that reacts anywhere
if (reaction.message.id == my_id) user.send('Your message.');
});
You can also send different messages depending on which reaction was added: you can use ReactionEmoji.name to check that.
To get the Unicode value of a built-in emoji, type the emoji with a backward slash (E.g.: \:joy: will result in 😂).
if (reaction.message.id == my_id) {
if (reaction.name == '😂') user.send('Ayy lmao!11!!');
else user.send('This is another emoji.');
}

Categories