Send message to users who reacted to a message discrod js - javascript

I want to create a command to send DM to users who reacted (all reactions) to a message from ID. I want to filter the bots and don't send two messages for one user if they reacted twice.
if (command === 'gopv') {
message.channel.messages.fetch("806866144597770280").then((reactionMessage) => {
console.log(
reactionMessage.reactions.cache
.each(async(reaction) => await reaction.users.fetch())
.map((reaction) => reaction.users.cache.filter((user) => !user.bot))
.flat()
);
});
}

I would probably create a dmSent object with the user IDs as keys, so I could easily check if a DM was already sent to them. When you loop over the users reacted to the message, you can check if the ID already exists or if the user is a bot. If the user is not found in the dmSent object, you can send a message and add the user ID to the object.
I've just checked it, the following sends only one message to each user who reacted at least to the message:
if (command === 'gopv') {
const dmSent = {};
try {
const { reactions } = await message.channel.messages.fetch('806866144597770280');
reactions.cache.each(async (reaction) => {
const usersReacted = await reaction.users.fetch();
usersReacted.each((user) => {
if (dmSent[user.id] || user.bot) return;
dmSent[user.id] = true;
user.send('You sent at least one reaction, so here is a DM.');
});
});
} catch (err) {
console.log(err);
}
}

Related

Check if someone sent the message twice

On my server, we have a channel for just one word, "Oi".
If someone sends something other than the word "Oi", it gets deleted. But now I need a code that deletes the message if someone sends it twice in a row. They have to wait for someone else to send if they want to send.
This is my current code if you want to check it out for some reason:
if (message.channel.id === "ChannelIdWhichImNotGonnaTell") {
if (message.content === "Oi") {
let log = client.channels.cache.get("ChannelIdWhichImNotGonnaTell")
log.send(`New Oi By ${message.author.tag}`)
} else {
message.delete()
}
}
You can fetch() the last two messages by using the limit option and the last() in the returned collection will be the second last message in the channel (the one before the last one triggered your code).
Then you can compare the author's IDs; if they are the same, you can delete the message:
if (message.channel.id === oiChannelID) {
if (message.content === 'Oi') {
// fetch the last two messages
// this includes this one and the previous one too
let lastMessages = await message.channel.messages.fetch({ limit: 2 });
// this is the message sent before the one triggered this command
let previousMessage = lastMessages.last();
if (previousMessage.author.id === message.author.id) {
console.log('No two Ois, mate');
message.delete();
// don't execute the rest of the code
return;
}
let log = client.channels.cache.get(logChannelID);
log.send(`New Oi By ${message.author.tag}`);
} else {
message.delete();
}
}
There's some several work around for this. But I found this is the efficient way to do that.
As you said 'They have to wait for someone else to send oi' then you should fetch the "old message" before "the new message" that sent. and try to get the User ID. Then compare it with the new message one.
Here is the Example code :
if (message.content === 'Oi') {
message.channel.messages.fetch({limit: 2})
.then(map => {
let messages = Array.from(map.values());
let msg = messages[1];
if (msg.author.id === message.author.id){
message.delete();
// do something
} else {
let log = client.channels.cache.get("ChannelID")
log.send(`New Oi By ${message.author.tag}`)
}}).catch(error => console.log("Error fetching messages in channel"));
}
It will compare the "old messages" author UserID with the "new messages" author UserID. If it's match. Then it will be deleted.

!unban id with spaces discord.js

I'm new to this platform and desperately running in circles to unban a player on discord.
Its id has spaces, and I always run into 400 or 404 errors ...
Do you have any idea to solve my problem ?
I tested a lot of codes, and the last one I have is this :
if (message.content.startsWith('!unban')) {
let args = message.content.split(/ +/g);
let user = message.guild.members.cache.get(args[1]);
if (!user) return message.channel.send('Please specify a user ID');
user.unban().then(() => message.channel.send('Success'));
}
I am currently receiving the message 'Please specify a user ID'.
For information, I am not using the async function :
const Discord = require('discord.js');const client = new Discord.Client();client.on('message', message => {}
Thanks for your help !
Since the user is banned he's not in the guild, and you're trying to get the user from the guild members and this returns undefined so the bot keeps sending the error message.
To unban a user you need to use the GuildMemberManager#unban method.
Here's an example:
if (message.content.startsWith('!unban')) {
let args = message.content.split(/ +/g);
let user = args[1];
if (!user) return message.channel.send('Please specify a user ID');
message.guild.members.unban(user).then((u) => {
message.channel.send(`Successfully unbanned ${u.tag}`);
}).catch((err) => {
console.log(err);
message.channel.send("I couldn't unban this user, please check if i have the required permissions and if the user id is correct");
});
}
if I understand you correctly, you want to use a command like !unban idBeforeSpace afterSpace.
In that case, your code runs like this:
if (message.content.startsWith('!unban')) {
let args = message.content.split(/ +/g); //args = ["!unban", "idBeforeSpace", "afterSpace"]
let user = message.guild.members.cache.get(args[1]); //args[1] = "idBeforeSpace"; user = null
if (!user) return message.channel.send('Please specify a user ID');
user.unban().then(() => message.channel.send('Success'));
}
but instead you wanted this:
args = ["!unban", "idBeforeSpace afterSpace"]
You split your arglist on every whitespace you find. Instead of splitting at every occurence of the regex, just split after the first.

How can I check if a user reacted to the bot's message and then send a message if he didn't or if he did ( all in DM's )

So I'm not too sure how I would do this. I'm trying to make it so if someone says a command (already finished this part), the bot would send that member a DM saying something like this, "please react with any emoji to continue, (also finished this part), so know I have to make it check if the member reacted or if he didn't (with a time limit of 12 seconds).
Here's what I've already got:
bot.on('message', message => {
let args = message.content.slice(PREFIX.length).split(" ");
switch (args[0]) {
case "SpamDM":
message.react('✔️');
const SpamEmbed = new Discord.MessageEmbed()
.setTitle("Command: DMTest ")
.setDescription("Please go to DM's");
message.channel.send(SpamEmbed);
message.author.send("Please react with any message to continue.");
break;
}
});
bot.login(token);
You can use a Message#createReactionCollector to do this.
const filter = (reaction, user) => {
return reaction.emoji.name === '✔️' && user.id === message.author.id;
};
const collector = message.createReactionCollector(filter, { time: 12000 });
collector.on('collect', (reaction, user) => {
console.log(`Collected ${reaction.emoji.name} from ${user.tag}`);
// The user (who sent the command) has now reacted
});
The collect event will only fire if the person who sent the command has reacted to it, because of the filter that has been setup. The time is currently set to 12000ms which is 12 seconds.
There is also an end event emitted, which you could use to see if the user did or didn't react to the message, for example:
collector.on('end', collected => {
console.log(`Collected ${collected.size} items`);
});

Remove a specific reaction emote on any message (Discord.js)

I want to make a "banned reaction". I got the following code working, but it only removes reactions for messages the bot sends.
client.on('messageReactionAdd', async (reaction, user) => {
console.log(reaction);
if(reaction.emoji.name === 'pinkphallicobject')
reaction.remove();
});
How can I get it to remove a specific reaction for all messages from anyone?
For the messageReactionAddevent to fire on old messages you will need to cache the old messages in the server when the ready event is fired you can do it like this:
client.once('ready', () => {
var guild = client.guilds.cache.first();// you can find the server you want it to work on in a different way or do this for all servers
guild.channels.cache.forEach(channel => {
if(channel.type == 'text'){//do this for text channels only
channel.messages.fetch({limit: 100}).then(() => {
console.log('cached 100 or less messages from the: ' + channel.name + 'text channel.');
});
}
});
}

Discord JS // Trying to add role by reacting to the message

bot.on('messageReactionAdd', async (reaction, user) => {
// Define the emoji user add
let role = message.guild.roles.find(role => role.name === 'Alerts');
if (message.channel.name !== 'alerts') return message.reply(':x: You must go to the channel #alerts');
message.member.addRole(role);
});
Thats the part of my bot.js. I want the user to react in a certain channel and receive role Alerts
You haven't really stated what the problem is, what works and what doesn't work but I'll take a wild stab at some parts which catch my eye.
For starters you are calling properties on the variable message whilst in the code you supplied, you didn't create/set a variable named message. My guess is that you want the message to which a reaction has been added. To do that you have to use the MessageReaction parameter which is supplied in the messageReactionAdd event as reaction.
From there you can replace message.<something> with reaction.message.<something> everywhere in the code you supplied.
Something also to note is that you add the role Alerts to message.member. This won't work how you want it to, since it will give the Alerts role to the author of the original message.
What (I think) you want to do, is fetch the user who just reacted with the emoji and assign them the Alerts role. You'll have to find the member in the guild first and then assign them the Alerts role. To do this you'll have to use the User parameter and find the correct Member because you can't add a role to a User object but you can to a Member object. Below is some code which should hopefully put you on the right track.
// Fetch and store the guild (the server) in which the message was send.
const guild = reaction.message.guild;
const memberWhoReacted = guild.members.find(member => member.id === user.id);
memberWhoReacted.addRole(role);
You are using message.member variable despite not defining message.
Any of these methods won't really work in v12 so I updated it for someone else searching.
If you find any mistakes be sure to make me aware of it.
const Discord = require('discord.js');
const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] }); //partials arent really needed but I woudld reccomend using them because not every reaction is stored in the cache (it's new in v12)
const prefix = "-";
client.on('messageReactionAdd', async (reaction, user) => {
if (reaction.partial) { //this whole section just checks if the reaction is partial
try {
await reaction.fetch(); //fetches reaction because not every reaction is stored in the cache
} catch (error) {
console.error('Fetching message failed: ', error);
return;
}
}
if (!user.bot) {
if (reaction.emoji.id == yourEmojID) { //if the user reacted with the right emoji
const role = reaction.message.guild.roles.cache.find(r => r.id === yourRoleID); //finds role you want to assign (you could also user .name instead of .id)
const { guild } = reaction.message //store the guild of the reaction in variable
const member = guild.members.cache.find(member => member.id === user.id); //find the member who reacted (because user and member are seperate things)
member.roles.add(role); //assign selected role to member
}
}
})
Here's a quick answer, though way too late. So I'll be updating the answer with Discord.js v.12.x (or the same as Discord.js Master)
bot.on('messageReactionAdd', async (reaction, user) => {
//Filter the reaction
if (reaction.id === '<The ID of the Reaction>') {
// Define the emoji user add
let role = message.guild.roles.cache.find((role) => role.name === 'Alerts');
if (message.channel.name !== 'alerts') {
message.reply(':x: You must go to the channel #alerts');
} else {
message.member.addRole(role.id);
}
}
});

Categories