I want the bot to delete it's message after a user reacts to the message with a specific emoji. When I tried this with the code below, nothing happens. No errors whatsoever. I also don't want a time limit, just do a thing when it gets one reaction. Current code:
const filter = (reaction, user) => {
return ['🗑'].includes(reaction.emoji.name) && user.id === message.author.id;
};
message.awaitReactions(filter, { max: 1})
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '🗑') {
sentMessage.delete(1000)
} else {
message.reply('you reacted with a thumbs down.');
}
})
.catch(collected => {
console.log(`After a minute, only ${collected.size} out of 4 reacted.`);
message.reply('you reacted with neither a thumbs up, nor a thumbs down.');
what does your filter look like? We con't see the first line of it. Your problem is that you try to check the emote twice. Once in the filter and then again in the function. Only use the filter here, or use the function if you want multiple emotes (i wouldn't recommend it).
my solution would look like this:
var message = msg.channel.send("test message");
const filter = (reaction, user) => reaction.emoji.name === ':ok_hand:' //whatever emote you want to use, beware that .await.Reactions can only check a singel emote
message.then(m=>{m.awaitReactions(filter, { max: 1})
.then(collected => {
console.log("do what ever");
m.delete();//such as this
})
.catch(console.error);
});
This works for me. Keep in mind that #awaitReactions isn't very versatile. If you want multiple ways of interacting with a message, you may want to look at #createReactionCollector which works the same way, but is triggered on every emote change instead.
I hope I helped.
Related
I'm making my first discord bot and I'm trying to make it send a message after I react to one of its emojis, problem is, when I click the thumbs up emoji, the bot simply does not send the message, it's been a few hours now and I can't find the problem, I'm sorry if this has been solved somewhere else, I couldn't find anything that works.
if (command === "ping") {
const attachment = new MessageAttachment('https://cdn.mcr.ea.com/3/images/ac394369-2801-4e09-87eb-82ca54e26254/1588018258-0x0-0-0.jpg');
const sentMessage = await message.channel.send({files: [attachment] })
sentMessage.react('👍');
//sentMessage.react('👎');
const filter = (reaction, user) => {
return reaction.emoji.name === '👍' && user.id === message.author.id;
};
const collector = sentMessage.createReactionCollector(filter, { time: 15000 });
collector.on('collect', (reaction, user) => {
message.channel.send(`Collected ${reaction.emoji.name} from ${user.tag}`);
});
collector.on('end', collected => {
message.channel.send(`Collected ${collected.size} items`);
console.log(`Collected ${collected.size} items`);
});
EDIT
I found that I was missing the "GUILD_MESSAGE_REACTIONS" intent, now i have these 3 "GUILDS", "GUILD_MESSAGES", "GUILD_MESSAGE_REACTIONS", still not working sadly!
Here's the full code:
https://pastebin.com/Q0eZ6VSz
Hi, this code is working except a small thing...
sentMessage.createReactionCollector(filter, { time: 15000 });
change this to:
sentMessage.createReactionCollector({filter, time: 15000 });
also I suggest you to add max: 1 option too.
so final code:
...
sentMessage.createReactionCollector({filter, max: 1, time: 15000 });
in this situation only gets first react by you.
I'm trying to make a bot where a user makes a poll and if a certain emoji that the bot has reacted with reaches a number, say 10, then it does other actions. However, that is not my issue. My issue is collecting the amount of reactions itself from that emoji.
My Code:
const embedSend = await message.channel.send({ embeds: [suggestionEmbed] }).then(async sEmbed => {
await sEmbed.react('⬆️');
await sEmbed.react('⬇️');
const filter = (reaction, user) => {
return ['⬆️', '⬇️'].includes(reaction.emoji.name) && user.id === message.author.id;
};
sEmbed.awaitReactions({ filter, max: 20, time: 50000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '⬆️') {
console.log('up');
} else if (reaction.emoji.name === '⬇️') {
console.log('down');
}
})
.catch(collected => {
console.log("didnt reach 20 reacts");
});
});
I tried using the previous method above. However, it doesn't seem to actually print up or down for every reaction after reaching 20 reacts but instead it prints nothing or just up or just down. I've tried using the line of code below to count the emojis but no luck either:
console.log(sEmbed.reactions.find(reaction => reaction.emoji.name === '⬆️').count)
Placed this inside of the .then statement with the awaitReactions right under the If-else block of code and got no output.
embedSend.reactions.cache.get('⬆️').count;
This I've placed after the embedSend and it returns me this error:
TypeError: Cannot read property 'reactions' of undefined
and if i place it within the block of code tiehr the embedSend or awaitReactions and change it to sEmbed it returns nothing.
I wanted to make a command that sends a message when someone reacts on a message with their name, I can't make it get the name of the person that reacted.
if (reaction.emoji.name === firstEmoji) {
await reaction.message.channel.send(`${reaction.message.author.username} reacted!`);
}
This will just say the bot's name and reacted!
Firstly you should provide full code for an accurate answer
Now, once the message is sent and if the bot is reacting to it before the user of course the bot would return itself.
Also for a better approach you can try using reaction collectors
const filter = (reaction, user) => {
return reaction.emoji.name === '👍' && user.id === message.author.id;
};
const collector = message.createReactionCollector(filter, { time: 15000 });
collector.on('collect', (reaction, user) => {
reaction.channel.send(`Collected ${reaction.emoji.name} from ${user.tag}`);
});
I am making a battle command for my discord bot where people can fight each other.
This is my current code :
//rng battl command (my whole life has lead up to this and bela cant stop me)
if(message.content.startsWith(`k!battle`)) {
var opponent = message.content.split(' ').slice(1).join(' ')
if(!opponent) return message.reply('Wait, who were you going to battle again?\nProper command useage: **k!battle <#username>**')
message.channel.send('Mentioned user, you have been challenged to a battle! Do you accept?')
message.channel.send(opponent)
//battle accept/deny
message.react('👍').then(() => message.react('👎'));
const filter = (reaction, user) => {
return reaction.emoji.name === '👍' && user.id === message.author.id;
};
message.awaitReactions(filter, { max: 3, time: 30000, errors: ['time'] })
.then(collected => message.channel.send('Let the battle commence! :KirbyPopcorn:'))
.catch(collected => {
message.channel.send(`Battle Expired.`);
});
}
Whenever the two users react to the message, nothing happens, but after the 30 seconds, the Battle Expired text shows up.
Please let me know if you spotted my mistake !
As #Sean said in the comments, your filter is misconfigured.
You're only allowing the command's author reactions to get through your collector, so you should replace your filter with this one:
const filter = (reaction, user) => { return reaction.emoji.name === '👍' && !user.bot; };
This one will allow anyone, except bots, to play the game!
I hope this fixes your issue!
PS: You should also lower the collector's max to 2 ;)
It's about one month that i'm actively developing a Discord bot but I have a problem about grabbing users from a reaction with the ReactionCollector
I know that you can catch this with this example :
bot.on('messageReactionAdd',(reaction,user)=>{
console.log(user); //Return the user
console.log(reaction); //Return the Reaction
});
But I want to create a complex system and I don't know if it's possible or not to grab the user with the ReactionCollect to do something that would look like this :
let reactionCollector = new Discord.ReactionCollector(messagefilteroptions);
reactionCollector.on('collect', (reactions,user,collector)=>{
console.log(user); //Return the User
console.log(reaction); //Return the Reaction
console.log(collector); //Return the Collector
});
How do I solve the problem?
Answer for V11
for v12, see tipakA answer
A ReactionCollector is used to wait for a specific condition about reactions on a messages (a number of reactions, a certain time, ...). You have access to the reactions after the collector has collected the reactions.
You have an example here:
const filter = (reaction, user) => {
return reaction.emoji.name === '👌' && user.id === message.author.id;
};
const collector = message.createReactionCollector(filter, { time: 15000 });
collector.on('collect', (reaction, reactionCollector) => {
console.log(`Collected ${reaction.emoji.name}`);
});
collector.on('end', collected => {
console.log(`Collected ${collected.size} items`);
});
The collector will collect all 👌 reactions. For every reactions, it will log the name of the emoji, and after 15 secondes, it will log how many reactions were added.
However, we can't access the user who reacted during the collect because the reaction is a MessageReaction. This type has a property which list all the users who reacted, because it's linked to the message and not the event which was fired when someone clicked.
note: you can access the last user by browsing the users Collection. Since it extend the Map, it remembers the original insertion order of the keys. But it will work only for one reaction.
However, the filter function has a user and a reaction. The filter function is used to filter what type of reaction you want to collect (for example, only from people with a specific role, or only one type of reaction, ...).
Here, if you want to log the user, you can do something like this:
const filter = (reaction, user) => {
console.log(user);
return reaction.emoji.name === '👌' && user.id === message.author.id;
};
However, if you want to do something with the users who reacted, you can do it after the collector has finished collecting the reactions:
collector.on('end', collected => {
console.log(collected.forEach((reaction => reaction.users.forEach(console.log))));
});
Depending on what type of reactions you're waiting, you will maybe have to verify the users hasn't already reacted to another reactions on the message (to avoid using it twice).
Use the ReactionCollector if you have to wait reactions on a particular messages. If you want to use it for every messages, use bot.on('messageReactionAdd',...)
Previous answers are outdated by now, as they are for version 11 of Discord.js.
Version 12 was released since then, and as it brings multiple changes, Collectors also got a "refresh".
Now, the collect event on ReactionCollector instead of giving reaction and collector itself, gives reaction and user objects.
const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === message.author.id;
const collector = message.createReactionCollector(filter, { time: 10000 });
collector.on('collect', (reaction, user) => {
console.log(`${user.tag} reacted with ${reaction.emoji.name}.`);
});
This is a bit late, but you could put your code in the filter and use that instead of on collect
const filter = (reaction, user) => {
console.log(user);
if(return reaction.emoji.name === '👌' && user.id === message.author.id) {
// Your code :)
}
return reaction.emoji.name === '👌' && user.id === message.author.id;
};