I am unable to collect a DM in discord.js when i try to use discord message collector
i have tried changing "message.channel" to message.author but it won't work
const collector = new discord.MessageCollector(message.channel, m => m.author.id === message.author.id, { time: 30000 });
collector.on('collect', message => {
if (message.content == strng) {
message.channel.send(`Successfully Verified User: <#${message.author.id}>`).then(m => {
m.delete(30000)
message.member.addRole('470615991555063808')
}).catch(err => console.log(err));
}
})
expected: user DMs bot with correct string and it verifies them
actual: user has to put the string in the same channel as the user originally said !verify
The user has to put the string in the same channel because you're collecting messages in said channel with message.channel as the first MessageCollector argument.
Instead, what you could do is open a DMChannel with the user and return it with .then() like so:
message.author.createDM().then(dmchannel => {
const collector = new discord.MessageCollector(dmchannel, m => m.author.id === message.author.id, { time: 30000 });
collector.on('collect', m => {
if (m.content == strng) {
message.channel.send(`Successfully Verified User: <#${message.author.id}>`)
.then(m => {
m.delete(30000)
message.member.addRole('470615991555063808')}).catch(err => console.log(err))}
})
})
i have worked it out...
i used
message.author.createDM().then(c => {
var verified = new discord.RichEmbed()
.setTitle("Verification Started")
.addField("**User**", `${message.author}`, false)
.setFooter("Goriko Bot")
.setColor(0xfffb00)
.setTimestamp();
message.guild.channels.get('470619175547830315').send(verified).catch(err => console.log(err));
console.log("DM Created")
c.send(verifyEmbed)
console.log(`Embed Sent to ${message.author.tag}`)
const filter = m => m.content.includes("~");
const collector = c.createMessageCollector(filter, { time: 30000 })
console.log("Collector Created")
collector.on('collect', m => {
console.log('Reply Collected')
if (m.content === strng) {
console.log('Success')
c.send("Successfully Verified")
if (message.channel.type == "dm") return;
message.member.addRole('470615991555063808').catch(err => console.log(err));
var successEmbed = new discord.RichEmbed()
.setTitle("Verification Successful")
.addField("**User**", `${message.author}`, true)
.addField("**String**", `\`\`${strng}\`\``, true)
.setFooter("Goriko Bot")
.setColor(0x00ff00)
.setTimestamp();
message.guild.channels.get('470619175547830315').send(successEmbed).catch(err => console.log(err));
} else {
var failEmbed = new discord.RichEmbed()
.setTitle("Verification Failed")
.addField("**User:**", `${message.author}`, true)
.addField("**Correct Token:**", `${strng}`, true)
.addField("**Token Given:**", `${m.content}`, true)
.setColor(0xff0000)
.setFooter("Goriko Bot")
.setTimestamp();
message.guild.channels.get('470619175547830315').send(failEmbed).catch(err => console.log(err));
m.reply("Invalid Token! Please Try Again")
}
})
})
Related
I'm pretty trash at coding so I need a little bit of help. I'm trying to code my discord bot to delete someone's messages for one minute after they click a react emoji. It sounds simple but for my tiny pea brain, it's not. This is what I have got so far. It deletes all messages from different users and guilds it's in, forever. I want it so it only delete messages in one channel for one minute.
client.once('message', async userMessage => {
if (userMessage.content.startsWith(''))
{
botMessage = await userMessage.channel.send('Who here likes goats?')
await botMessage.react("👍")
await botMessage.react("👎")
const filter = (reaction, user) => {
return (
["👍", "👎"].includes(reaction.emoji.name) && user.id === userMessage.author.id
);
};
botMessage
.awaitReactions(filter, { max: 1, time: 60000, errors: ["time"] })
.then((collected) => {
const reaction = collected.first();
if (reaction.emoji.name === "👎") {
userMessage.channel.send(`${userMessage.author}, how dare you. I guess no on here likes me. Hmmm, because of that I shall now eat all your messages! BAAAAAHAHAHHAHAHA!`)
setTimeout(() => {
client.on("message", async msg => {
if (author.msg.content.startsWith("")) {
userMessage.channel = await msg.delete();
}
});
}, 2000);
} else {
userMessage.reply("Thanks!");
}
})
.catch((_collected) => {
userMessage.channel.send("Hehe")
});
}
});
Btw, the code is in discord.js!
Your problem is this chunk of code
setTimeout(() => {
client.on("message", async msg => {
if (author.msg.content.startsWith("")) {
userMessage.channel = await msg.delete();
}
});
}, 2000);
This is not how you use events.
A) Your message event is nested within another which could cause memory leaks.
B) To get the content you need to use msg.content, author.msg Is not a thing.
C) I assume your intention here: msg.content.startsWith("") is to always fire the if statement, in that case why not do if (true).
Here's how I would do it:
Create a Set in the namespace which will hold id's of users who's messages should be deleted
const toDelete = new Set();
If they react with a 👎 add them to the set.
if (reaction.emoji.name === "👎") {
userMessage.channel.send('Your message here');
if (!toDelete.has(userMessage.author.id)) {
toDelete.add(userMessage.author.id);
}
}
On each message event check if the author of the message has their id in the set, If so delete their message
client.once('message', async userMessage => {
if (toDelete.has(userMessage.author.id)) {
return userMessage.delete()
.catch(console.error);
}
if (userMessage.content.startsWith('')) {
// Rest of your code
I think your problem in understanding how everything works.
I took everything from discord.js documentation.
Type reaction command to see how it works.
const Discord = require("discord.js");
require("dotenv").config();
const TOKEN = process.env.TOKEN||"YOUR TOKEN";
const PREFIX = process.env.PREFIX||"YOUR PREFIX";
const bot = new Discord.Client();
bot.on("ready", async function(e) {
console.log("Loaded!");
})
bot.on("message", async function(message) {
if (message.author.bot) return;
if (!message.content.startsWith(PREFIX)) return;
let args = message.content.slice(PREFIX.length).trim().split(/\s+/);
let command = args.splice(0, 1).toString().toLowerCase();
if (command == "reaction") {
message.delete();
let msg = await message.channel.send("Click on the reaction");
await msg.react("👍");
await msg.react("👎");
let filter = (reaction, user) => {
return ["👍", "👎"].includes(reaction.emoji.name) && user.id == message.author.id;
}
msg.awaitReactions(filter, {max: 1, time: 10000, errors: ["time"]}).then(collected => {
let reaction = collected.first();
if (reaction.emoji.name == "👎") {
return message.channel.send("downvote");
}
return message.channel.send("upvote");
}).catch(e => {
message.channel.send("user didn't vote");
})
}
})
bot.login(TOKEN);
I am trying to make emoji reaction for my discord bot , everything is okay until I click "❌" emoji but when i click "❌" emoji i am getting this error: TypeError: Cannot read property 'emoji' of undefined
and the error shows this line : if (reaction.emoji.name === '❌')
const Discord = require("discord.js");
const ayarlar = require("../ayarlar.json");
module.exports.run = async (bot, message, args) => {
let gonderenKisi = message.author;
let mesaj = args.slice(0).join(" ");
if(!mesaj) return message.reply("**➤ Mesaj Atabilmek İçin Bir Mesaj Yazmalısın!**").then(message => {
message.delete({ timeout: 5000 });
});
const filter = (reaction, user) => {
return ['❌'].includes(reaction.emoji.name) && user.id === message.author.id;
};
const sEmbed = new Discord.MessageEmbed()
.setDescription(`➤ ` + mesaj)
.setAuthor(`➤ Yeni Bir Fotoğraf Paylaşıldı !`)
.setThumbnail(message.guild.iconURL())
.setColor('RANDOM')
.setFooter(`➤ Fotoğraf Atan: ${message.author.username}`, message.author.displayAvatarURL())
.setTimestamp(message.createdAt)
message.delete();
message.channel.send(sEmbed).then(e =>
e.react("❤️")).then(e =>
e.message.react("❌")).catch(e => {
console.error('Emojiler De Sorun Var.');
});
message.awaitReactions(filter, { max: 1 })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '❌') {
collected.on('collect', () => {
message.delete();
var s2Embed = new Discord.MessageEmbed()
.setTitle(`${message.author.username} Mesajın Silindi.`)
.setColor('RANDOM')
.setDescription(`Mesajı Silen : ${message.author.username}`, message.author.displayAvatarURL())
message.channel.send(s2Embed)
});
}
}).catch(e => {
console.error(e)
})
};
module.exports.config = {
name: 'instagram',
aliases: ['i']
}
The actual cause of the error is this line:
const reaction = collected.first();
Here the value of reaction is undefined so you are getting the error.You are trying to read the emoji property of an undefined value.You can change the condition to:
if (reaction && reaction.emoji && reaction.emoji.name){
////logic
}
Also I can see there is some issue in the discord version probably which is giving you an undefined value. Check this thread it may help you.
https://github.com/discordjs/discord.js/issues/3868
someone can help?
5️⃣ = 5️⃣
var embed1 = new Discord.RichEmbed()
.setTitle("hjgsadgv")
message.channel.send(embed9)
.then(function (message) {
message.react("5️⃣")
.then(() => message.react("4️⃣"))
.then(() => message.react("3️⃣"))
.then(() => message.react("2️⃣"))
.then(() => message.react("1️⃣"))
const filter = (reaction, user) => {
return ['5️⃣', '4️⃣', '3️⃣', '2️⃣', '1️⃣'].includes(reaction.emoji.name) && user.id === message.author.id;
}
message.awaitReactions(filter, { max: 1, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '5️⃣') {
message.reply('123');
}
else {
message.reply('321');
}
var embed2 = new Discord.RichEmbed()
.setTitle("uysygadk")
message.channel.send(embed10)
})
})
Bot responds to its own reactions
You can ignore bots by changing your filter to this:
const filter = (reaction, user) => {
return ['5️⃣', '4️⃣', '3️⃣', '2️⃣', '1️⃣'].includes(reaction.emoji.name) && user.id === message.author.id && !user.bot;
}
It basically checks the bot property of user and if it's true then the filter blocks it.
I am making my first Discord Bot, using Discord.js - I can make it read a command !makeraid and the bot will ask the first question, and store the response into an array.
I want to be able to ask multiple questions like raid name, description, date, and time. I have not yet got this far, after the first question is asked, as a test i want the bot to create the embed message.
However, i cannot make it trigger/fire the next question.
client.on('message', message => {
if (message.content.toLowerCase().startsWith("!makeraid")) {
const filter = m => m.author.id === message.author.id;
var raid = {};
var color = ((1 << 24) * Math.random() | 0).toString(16);
var raidImages = {'DDS':'https://i.imgur.com/izsm8ri.jpg','GR':'https://i.imgur.com/4S9NKtF.jpg','CR':'https://i.imgur.com/EnYiWka.jpg','OR':'https://i.imgur.com/VOYDUlO.jpg'};
message.reply('Raid Name?').then(r => r.delete(10000));
message.channel.awaitMessages(filter, {
max: 1,
time: 10000,
errors: ['time'],
})
.then((collected) => {
raid.title = collected.first().content;
console.log(raid);
collected.first().delete(5000);
})
.catch(() => {
message.channel.send('Raid Cancelled - Too Slow!').then(r => r.delete(5000));
});
while ( Object.keys(raid).length > 0 ) {
message.reply('Do you want to create the raid? Yes or No.').then(r => r.delete(10000));
message.channel.awaitMessages(filter, {
max: 1,
time: 10000,
errors: ['time'],
})
.then((collected) => {
if (collected.first().content.toLowerCase() === "yes") {
collected.first().delete();
var raidEmbed = new Discord.RichEmbed()
.setColor('#'+color)
.setAuthor('Raid Bot', client.user.avatarURL)
.setTitle(':star::star: '+raid.title+' :star::star:')
.setThumbnail(client.user.avatarURL)
.setDescription('Some description here')
.addField('Date', 'Some value here', true)
.addField('Time', 'Some value here', true)
.setTimestamp()
.setFooter('Raid created by: '+ message.member.user.tag, message.member.user.avatarURL);
message.channel.send(raidEmbed).then(async embedMessage => {
await embedMessage.react('✅');
await embedMessage.react('❓');
await embedMessage.react('🇽');
});
} else {
collected.first().delete();
message.channel.send('Raid Cancelled').then(r => r.delete(5000));
}
})
.catch(() => {
message.channel.send('Raid Cancelled - Too Slow! (Make)').then(r => r.delete(5000));
});
}
message.delete();
} else if (message.content.toLowerCase().startsWith("!help")) {
message.reply('You Suck 😃').then(r => r.delete(10000));
message.delete();
}
});
No errors are coming up in the terminal, it just does nothing after the first response has been collected and push into the array.
I send messages to users when they connect to my server, and I want to continue authorization by clicking on reactions.
How can I create this? I'm using the following code:
robot.on("guildMemberAdd", (gMembAdd) =>
{
gMembAdd.send(`Hi ${gMembAdd.toString()} welcome to the server Test`).then(msg => {
msg.react('✅')
.then(() => msg.react('❎'));
//--------------------Developmend-------------------------------------
let filter = (reaction, user) => reaction.emoji.name === '✅' || reaction.emoji.name === '❎';
let col = msg.createReactionCollector(filter);
col.on('collect', r =>
{
if (r.users.last().id !== msg.author.id)
{
gMembAdd.addRole(gMembAdd.guild.roles.find("name", "Autorize")).catch(console.error)
r.remove(r.users.last().id);
console.log(` ${gMembAdd.user.id} и ${gMembAdd.user.username} and ${r.emoji}`);
}
});
//--------------------------------------------------------------------
});
I need a reaction check and role assignment if the response is positive and kick if not. I don't understand how to continue.
Will this code be used correctly?
To check the reaction you can use MesssageReaction.emoji.name, as you did above.
For the other thing, you can use GuildMember.addRole() & GuildMember.kick().
Here's a sample you can check out:
robot.on('guildMemberAdd', async member => {
let msg = await member.send(`Hi ${member} welcome to the server Test`);
await msg.react('✅');
await msg.react('❎');
msg.createReactionCollection(r => ['✅', '❎'].includes(r.emoji.name))
.on('collect', r => {
if (r.emoji.name == '✅')
member.addRole(member.guild.roles.find("name", "Authorize"))
.then(() => { console.log(`Added ${member.user.username} (${member.id}).`); })
.catch(console.error);
else if (r.emoji.name == '❎') member.kick("You got rejected.");
r.remove(r.users.last());
});
});
You can also use Message.awaitReactions(), which is better because it doesn't go on after the reaction is added:
robot.on('guildMemberAdd', async member => {
let msg = await member.send(`Hi ${member} welcome to the server Test`);
await msg.react('✅');
await msg.react('❎');
msg.awaitReactions(r => ['✅', '❎'].includes(r.emoji.name), {max: 1})
.then(collected => {
let r = collected.first();
if (r.emoji.name == '✅')
member.addRole(member.guild.roles.find("name", "Authorize"))
.then(() => { console.log(`Added ${member.user.username} (${member.id}).`); })
.catch(console.error);
else if (r.emoji.name == '❎') member.kick("You got rejected.");
r.remove(r.users.last())
});
});