Count reactions to a message after certain time has passed - discord.js

So I made a bot that has a vote command, where you ask it to say a votable thing and people can only react with tick, cross or N/A in discord.js
What I need to make work now, is a response (either by command or automated over-time, but preferably automated over the time period of 24hrs).
So far, I've tried many different methods and looked all over the Discord.js Docs, but nothing has quite worked out at all. Here's how the code ended up, although it doesn't work:
var textToEcho = args.join(" ");
Client.channels.cache.get('channel ID').send(textToEcho).then(async m => {
await m.react('✅');
await m.react('❎');
await m.react('801426534341541919');
});
message.channel.fetchMessage(textToEcho).then(msg => {
let downVoteCollection = msg.reactions.filter(rx => rx.emoji.name == '✅');
console.log(downVoteCollection.first().count);
}).catch(console.error);
Note: This ONLY checks for the tick response.

It appears that you're trying to get all of the reactions directly after the message has been sent, this will only return the bots reactions, if any at all.
To accurately get the reactions after a certain about of time you'll have to add a .setTimeout(...) function.
var textToEcho = args.join(" ");
Client.channels.cache.get('channel ID').send(textToEcho).then(async m => {
await m.react('✅');
await m.react('❎');
await m.react('801426534341541919');
});
setTimeout(() => {
message.channel.messages.fetch(message.id).then(msg => {
let downVoteCollection = msg.reactions.filter(rx => rx.emoji.name == '✅'); // Filter the reactions
msg.author.send(`You have received **${downVoteCollection.first().count}** votes on your latest poll!`); // Sends the poll owner how many votes they recieved
}).catch(console.error);
}, 86400000); // This will wait 24 hours after the message has been sent to count reactions

Related

Discord JS - If user sends DM to bot with specific string

The code below works and send a DM to the user when he/she reacts to a message.
The goal is then to add a role - or do something - if the user replies with the correct string.
if (reaction.emoji.name === theDoor) {
await reaction.message.guild.members.cache.get(user.id).roles.add(treasure);
const reactUser = await reaction.message.guild.members.cache.get(user.id);
reactUser.send('Enter the code. Hint: *Yumi Zouma*.');
} else {
return;
}
How can I make the bot handle DM from other users? Google seems to only provide how to send a DM to a user.
What you need to use then is a Message Collector.
Docs
For example,
const dm = await reactUser.send("Enter code")
const collector = dm.channel.createMessageCollector({filter, max: 5, time: 30000}); //We're creating the collector, allowing for a max of 5 messages or 30 seconds runtime.
collector.on('collect', m => {
console.log(m.content)
}
collector.on('end', (collected, reason) => {
await dm.channel.send({content: `Collector ended for reason: ${reason} reached! I collected ${collected.size} messages.`})
}

How do I get a users input and set it as a variable?

I am very new to Discord.js so please forgive me for any basic errors.
I am trying to create a command that will ask for a name, and then store the users input into a variable, however this is proving itself quite difficult.
After the program sends the message "What would you like to name your event?", I type "TEST", and then it sends another message saying "createevent", the command word.
client.on('message', async message => {
if (message.author.bot) return;
if (message.content.startsWith('createevent')) {
const filter = m => m.author.id === message.author.id;
message.channel.startTyping()
await sleep(500);
message.channel.stopTyping()
message.lineReply('What would you like to name your event?')
message.channel.awaitMessages(filter, {max: 1, time: 50000}).then(collected => {
const eventname = message.content;
message.channel.send(eventname);
})
}
});
First of all, you should stop the collector and, as you said you want to know the content that the user replies, the content in your case would be collected.content not message.content.

Discord js. Bot is not replying to messages

client.on("message", message =>{
if(message.channeltype = 'dm')
if (message.content === "confess")
message.channel.send("OOOOOOoooooo A SECRET??!?!?! WHAT IS IT?!??!")
message.channel.awaitMessages("response", message =>{
C = message.content
message.reply("Um.... theres two servers that this bot works on. 1: Loves in the snow or 2:🌙Moomins and Shep's Therapy Service🌙. Pick a number to send it to one of them")
client.on("message", message => { //////// SWITCH THIS LINE OUT FOR THE THING THAT WAITS FOR NEW MESSAGES
if (message.content === "2")
WDI = message.author
WDID = message.author.id
message.channel.get(WDIC2).send("Ok ok so who did it is" + WDI + "and their id is" + WDID)
message.channel.get(CC2).send(C)
if (message.content === "1")
WDI = message.author
WDID = message.author.id
message.channel.get(WDIC1).send("Ok ok so who did it is" + WDI + "and their id is" + WDID)
message.channel.get(CC1).send(C)
})
})})
Why does my bot not reply to my message?
I first put in confess then it would say the message but it doesnt detect that I continue and reply to that. WHat do I do?
Okay first off, try to be a lot more specific when asking questions there is a stackoverflow guide on how you should ask them effectively. Right now you are being unclear and I'm going to have to assume some stuff. Also, include a stack trace whenever possible, which there should have been as you provide some invalid properties, if you don't have one please include that there is not a stack trace in the question.
There is a lot of things wrong with this code. First off, the reason your bot isn't responding to you at all is because message.channeltype is not a property. Use message.channel.type instead. There is also something wrong with your message.channel.awaitMessages(). You are passing in a "response" string as a parameter, where there should be a filter. Since you don't need a filter since it is a dm channel you can just pass it in as null message.channel.awaitMessages(null, msg => { });. And awaitMessages is not the right call here. Await messages takes in messages in a certain time period, then resolving a promise with all of the collected messages. You should be using a discord.js collector. You should also not be using client.on("message") here. I'm assuming that you want to wait for messages in any channel after somebody "shared their secret". You can do that with a collector. If you want to collect messages all over the bot, or in just one discord server channel (using the filter which can be found on the docs) you can use a collector. This will wait for, in a number of milliseconds, for any event and filter out event triggers that aren't allowed. And when it gets it, it will run a lambda. Like this:
const filter = m => m.channel === message.channel && m.author = message.author); // The filter that will sort out the messages
const collector = message.channel.createMessageCollector(filter, { time: 30000 }); // creates a collector that will wait for 30 seconds
collector.on('collect', m => { // When somebody sends a message
// ...
if (message.content === '2') {
// ...
} else if (message.content === '1') {
// ...
} else {
message.reply('you need to say either 1 or 2. Please try again.');
return;
}
collector.stop(); // Makes sure that the collector no longer will receive anymore messages.
});
Final code (fill in the gaps I'm not going to code it all for you)
client.on("message", message => {
if(message.channel.type = 'dm')
if (message.content === "confess")
const filter = m => m.channel === message.channel && m.author = message.author; // The filter that will sort out the messages
const collector = message.channel.createMessageCollector(filter, {time: 30000})
collector.on('collect', message => {
const otherCollector = message.channel.createMessageCollector(filter, { time: 30000})
otherCollector.on('collect', message => {
if (message.content === '2') {
// ...
} else if (message.content === '1') {
// ...
} else {
message.reply('you need to say either 1 or 2. Please try again.');
return;
}
collector.stop(); // Makes sure that the collector no longer will receive anymore messages.
})
})
})
Also, before asking on any forum or discord server, always look up the documentation. It helps out 99% of cases, unless the docs is absolutely garbage.
Please read the docs. I'd say that the Discord.JS docs are a pretty handy reference.
For the first part, message.channeltype is not a real property, and do not use =. That is for setting variables, use == or === instead (What is the difference?). You can use message.channel.type or you can use instanceof as followed: message.channel instanceof Discord.DMChannel. Replace Discord with whatever your Discord.JS import variable is called.
Your ifs are missing some {}, they should be used as followed.:
if(message.channel instanceof Discord.DMChannel) {
//If the channel IS a DMChannel
} else return;
FYI, if you're planning to make multiple commands, I'd use a switch, and a way to convert message.content to arguments (string array).
message.channel.get is not a thing, use client.channels.cache.get. The variables C, and WDI / WDID need to have var before them.
Then you need to add a filter plus maximum messages, time limit, and minimum messages for your awaitMessages function. Plus you need then and catch, so now your code might look like this
if(message.channel instanceof Discord.DMChannel) {
if (message.content === "confess") {
message.channel.send("OOOOOOoooooo A SECRET??!?!?! WHAT IS IT?!??!")
message.reply("Um.... theres two servers that this bot works on. 1: Loves in the snow or 2:🌙Moomins and Shep's Therapy Service🌙. Pick a number to send it to one of them")
const filter = m => m.author == message.author;
message.channel.awaitMessages(filter, {/* whatever your parameters/limits are */})
.then(col => {
if (col.content === "2") {
/** Add in code */
} else if (col.content === "1") {
/** Add in code */
}
})
.catch(col => {/** Whatever you want to do if times up. */})
}
}
You may want to tweak the filter on this.

Discord.js Forward DM message to specific channel

So, I need a way to forward a message sent in the bot's dm to a specific channel in my server.
this is the code that I got so far:
execute(message, args) {
if(message.channel.type == "dm"){
let cf = args.join(' ')
const cfAdm = message.guild.channels.cache.get('767082831205367809')
let embed = new discord.MessageEmbed()
.setTitle('**CONFISSÃO**')
.setDescription(cf)
.setColor('#000000')
const filter = (reaction, user) => ['👍', '👎'].includes(reaction.emoji.name);
const reactOptions = {maxEmojis: 1};
cfAdm.send(embed)
.then(function (message) {
message.react('👍')
.then(() => message.react('👎'))
/**** start collecting reacts ****/
.then(() => message.awaitReactions(filter, reactOptions))
/**** collection finished! ****/
.then(collected => {
if (collected.first().emoji.name === '👍') {
const cfGnr = message.guild.channels.cache.get('766763882097672263')
cfGnr.send(embed)
}
})
});
}
else {
message.delete()
message.channel.send('Send me this in the dm so you can stay anon')
.then (message =>{
message.delete({timeout: 5000})
})
}
}
But for some reason that I can't seem to understand, it gives me this error:
TypeError: Cannot read property 'channels' of null
If anyone can help me, that would be greatly apreciated.
Thanks in advance and sorry for the bad english
The error here is that you are trying to call const cfAdm = message.guild.channels.cache.get('ID') on a message object from a Direct Message channel ( if(message.channel.type == "dm"){)
DMs don't have guilds, therefore message.guild is null and message.guild.channels does not exist.
You will need to first access the channel some other way. Luckily, Discord.js has a way to access all channels the bot can work with* (you don't need to muck around with guilds because all channels have unique IDs):
client.channels.fetch(ID) or client.channels.cache.get(ID)
(I have not tested this but it seems fairly straight forward)
*See the link for caveats that apply to bots in a large amount of servers.

Creating an invite in a GuildCreate event

So I was trying to make my bot send me a DM to every server it joins but I keep getting the API error: Unkown Channel
My code:
bot.on("guildCreate", async guild => {
guild.channels.first().createInvite().then(inv =>
bot.users.get(ownerID).send(`I have been added to **${guild.name}** | ${inv.url}`)
)
});
Okay, this is your problem. I have made the same mistake a few months ago, here's how to fix it.
Since you are using discord.js version 11, guild.channels is indeed a Collection, which you can use .first() on. In this case, you can't do that.
Here's my workaround:
bot.on("guildCreate", async guild => {
var channel;
guild.channels.forEach(c => {
if (c.type === "text" && !channel) channel = c;
});
channel.createInvite({ maxAge: 0 }).then(inv => bot.users.get(ownerID).send(`I have been added to **${guild.name}** | https://discord.gg/${inv.code}`));
});
This basically loops through each channel and finds a valid TextChannel to create an invite.
Hope this helps.

Resources