This block of code listens for member's first message to be yes. However if member's first message isn't yes the collection stops collecting messages and ends. How can I have this block wait for member to say yes even if other messages before did not. I've tried using collected.content instead of collected.first().content However that doesn't seem to work.
const filter = m => m.author.id === member.id
message.channel.send(message).then(() => {
message.channel.awaitMessages(filter, { max: 10, time: 15000, errors: ['time'] })
.then(collected => {
if (collected.first().content == 'yes') return console.log('A yes was found')
}).catch(error => {
return console.log('A yes was not found')
})
})
You can replace the if statement inside your then callback to these lines instead :
const yes = collected.find(c => c.content === 'yes');
if (yes) return console.log('A yes was found');
This will attempt to find a message which's content is 'yes' from your collection,
Hope this helps :)
What about replacing your filter with this one :
const filter = m => { return m.author.id === member.id && m.content === 'yes' };
Related
Why is it not waiting for a response? it just runs the whole code
Someone told me filter is part of v13 collector options, is there anyway to do this then?
const target = message.mentions.users.first();
if (!target) return message.reply("you have to mention somebody");
await message.reply(
`you proposed to ${target}! Is it **YES** or **NO**?`
);
const filter = (m) =>
m.content.toLowerCase().startsWith("yes") &&
!m.author.bot &&
m.author.target;
const main = message.guild.channels.resolve("706263571562102835");
main.awaitMessages(filter, {
errors: ["time"],
max: 1,
time: 900000,
});
await message.reply(
`You e ${target} are now married!`
);
},
};
message.author.target does not exist. I believe what you meant to do is
const filter = (m) =>
m.content.toLowerCase().startsWith("yes") &&
!m.author.bot &&
m.author.id == target.id
This means that the filter will only detect messages which: begin with "yes", when the author is not a bot, and when the author's ID the same as the target's ID.
I'm trying to make a collector which will collect the mentioned user's message. But even with filter my bot respond to it's own message and other peoples messages! Here is my test.js file code:
const mentioned = message.mentions.users.first();
const filter1 = (msg) => {
return msg.author.id === mentioned.id
}
const collector1 = await message.channel.createMessageCollector({ filter1, max: 1, time: 120000 })
collector1.on('collect', message => {
console.log(message.content)
})
collector1.on('end', (collected) => {
if (collected.size === 0) return message.channel.send("Mentioned user did not respond in time!")
collected.forEach((message) => {
if (message.content.toLowerCase() == 'accept') {
message.channel.send(`${mentioned} accepted!`)
}
if (message.content.toLowerCase() == 'cancel') return message.channel.send(`${mentioned} declined!`)
})
})
I was changing my filter many times, but I still can't fix this problem, so what am I doing wrong?
Also I use djs v13
The problem is you're trying to use Short-Hand Property Assignment to assign the filter option. However, you pass in "filter1" which results in {filter1: filter1}. Since this does not resolve to a filter option for TextChannel#createMessageCollector() the method disregards the unknown option and therefor your collector has no filter.
Change your filter1 variable to filter
const filter = (msg) => {
return msg.author.id === mentioned.id
}
const collector1 = await message.channel.createMessageCollector({ filter, max: 1, time: 120000 })
This question already has an answer here:
How to use awaitReactions in guildMemberAdd
(1 answer)
Closed 1 year ago.
I'm trying to create a calendar and depending on the emoji which one we react something happens but I don't find the good function . I try to find in another post but nothing helped me.
Thanks for your help.
This is the code :
if (message.content.startsWith('!agenda')){
var embed = new Discord.MessageEmbed()
.setColor('YELLOW')
.setTitle('Matter')
.addFields(
{name : 'Math :', value: '📏'},
)
var Msg = await message.channel.send(embed);
Msg.react("📏");
var emoji = await Msg.awaitReactions;
if (emoji === '📏'){
message.channel.send('test')
}
}
})
Here is what you are looking for:
message.channel.send(embed).then((m) => {
m.react('📏'); //reacts with 📏
const filter = (reaction, user) => {
return user.id != 'put bot id here' || user.id === message.author.id && reaction.emoji.name === '📏';
};
//this filter is to make sure only the user that called the command can react, and the only emoji collected is 📏
m.awaitReactions(filter, { max: 1, time: 15000, errors: ['time'] })
.then(collected => {
if (collected.first().emoji.name === '📏') {
m.channel.send(`:white_check_mark: you reacted with "📏"`).then(m => m.delete({ timeout: 3000 }));
//when the user reacts with 📏 - this code is executed
} else {
//if the user reacts with any other emoji - remove if you dont want this
m.channel.send(":x: Command cancelled").then(m => m.delete({ timeout: 3000 }));
};
})
.catch(collected => {
//if the user does not react in time
m.channel.send(":x: Command cancelled").then(m => m.delete({ timeout: 3000 }));
});
});
please ask questions if you're confused about any part.
I was thinking of code like this to get the number of reactions a message has received after a set time:
if (message.content == "test") {
message.channel.send("Hi").then(msg => {
msg.react('🏠').then(r => {
const react = (reaction, user) => reaction.emoji.name === '🏠'
const collector = msg.createReactionCollector(react)
collector.on('collect', (r, u) => {
setTimeout(() => u.send(r.length), 60000 * 5);
})
})
})
}
});
But rightly .lenght is not the correct method to obtain the number of reactions, consequently the error is that the "r.length" message is empty and the bot cannot send it.
The goal is to send a message, as soon as you react to that message, a setTimeOut starts and at the end of the time it returns (in this case in private) the number of reactions that that message has received.
collected.size is the right way of getting the number of collected reactions a message has.
You can read about reaction collectors here
Here is a basic reaction collector that uses collected.size:
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) => {
console.log(`Collected ${reaction.emoji.name} from ${user.tag}`);
});
collector.on('end', collected => {
console.log(`Collected ${collected.size} items`);
});
I want the user to answer a "yes or no" question using reactions. However, there is a bug in which when the tagged user reacts to the question, the bot is not sending a message on whether or not the tagged user wants to negotiate. Here is my code below.
const yesEmoji = '✅';
const noEmoji = '❌';
client.on('message', (negotiate) => {
const listen = negotiate.content;
const userID = negotiate.author.id;
var prefix = '!';
var negotiating = false;
let mention = negotiate.mentions.users.first();
if(listen.toUpperCase().startsWith(prefix + 'negotiate with '.toUpperCase()) && (mention)) {
negotiate.channel.send(`<#${mention.id}>, do you want to negotiate with ` + `<#${userID}>`)
.then(async (m) => {
await m.react(yesEmoji);
await m.react(noEmoji);
//get an answer from the mentioned user
const filter = (reaction, user) => user.id === mention.id;
const collector = negotiate.createReactionCollector(filter);
collector.on('collect', (reaction) => {
if (reaction.emoji.name === yesEmoji) {
negotiate.channel.send('The mentioned user is okay to negotiate with you!');
}
else {
negotiate.channel.send('The mentioned user is not okay to negotiate with you...')
}
})
})
negotiating = true;
}
})
So far, the code displays the reaction but it does not make the bot send a message whether the tagged user is ok or not ok to negotiate with the user that tagged them.
UPDATE:
I managed to get the bot to send a message whether the tagged user is ok or not ok to negotiate with the user that tagged them. Now there is an error in which is shown after 10 seconds (specified time). Here is the updated code below:
const yesEmoji = '✅';
const noEmoji = '❌';
client.on("message", async negotiate => {
const listen = negotiate.content;
let mention = negotiate.mentions.users.first();
if(listen.toUpperCase().startsWith(prefix + 'negotiate with '.toUpperCase()) && (mention)) {
let mention = negotiate.mentions.users.first();
let msg = await negotiate.channel.send(`${mention} do you want to negotiate with ${negotiate.author}`);
var negotiating = false;
await msg.react(yesEmoji);
await msg.react(noEmoji);
const filter = (reaction, member) => {
return reaction.emoji.name === yesEmoji || reaction.emoji.name === noEmoji && member.id === mention.id;
};
msg.awaitReactions(filter, { max: 1, time: 10000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === yesEmoji) {
negotiating = true;
negotiate.reply('The mentioned user agreed to negotiate with you!');
}
else return negotiate.reply('The mentioned user did not agree to negotiate with you.')
})
}
})
I have a much easier solution to your problem:
const yesEmoji = '✅';
const noEmoji = '❌';
let mention = negotiate.mentions.users.first();
if(mention.id === negotiate.author.id) return message.channel.send("You cannot tag yourself!");
let msg = await negotiate.channel.send(`${mention} do you want to negotiate with ${negotiate.author}`);
var negotiating = false;
await msg.react(yesEmoji);
await msg.react(noEmoji);
const filter = (reaction, member) => {
return (member.id === mention.id && reaction.emoji.name === yesEmoji) || (member.id === mention.id && reaction.emoji.name === noEmoji);
};
msg.awaitReactions(filter, { max: 1, time: 10000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === yesEmoji) {
negotiating = true;
negotiate.channel.send('The mentioned user is okay to negotiate with you!');
}
else if (reaction.emoji.name === noEmoji) return negotiate.channel.send('The mentioned user is not okay to negotiate with you...')
}).catch(err => {
if(err) return message.channel.send(`${mention} did not react within the 10 seconds!`);
})
So first we got the two emojis, we want the user to react with. mention is our mentioned user, msg is the "yes or no" question and negotiating is set to false by default. At first we react to the question with our emojis. In this example I am using awaitReactions, because it is very simple to use. For this we need a filter. In this case I named the variable also filter. filter checks if the reaction wether is yesEmoji or noEmoji and if the user who reacted is mention (our mentioned user). Then in awaitReactions we want only 1 reaction (yes or no), and I set the time to 10 seconds, but you can change it if you want. After awaitReactions is set up we want to collect our reaction. This is done in .then(). collected gives us the reactions, and we only want the first one, so we store collected.first() in reaction. Now we have a really simple if-else statement. If the reacted emoji is yesEmoji, negotiating will be set to true and a message gets sent into the channel, otherwise it will only sent a message and return.
It is important to set negotiating only to true if the user reacted with yesEmoji. In your code it is true even if nothing happens, because as you run the command everything in that command code will be executed. and your last line there was negotiating = true;. And I think that is not what you wanted to do.