I'm trying to make a help embed command with reactions, but I keep getting this error
I'm trying to make a help embed with reactions, but when I do !help, it doesnt send the embed???
I'm trying to make a help embed command with reactions, but I keep getting this error I'm trying to make a help embed with reactions, but when I do !help, it doesnt send the embed???
This is my code:
const Discord = require('discord.js')
module.exports = {
name: 'help',
description: "Help command",
execute(message, args){
async function helpEmbed(message, args) {
const helpEmbed = new Discord.MessageEmbed()
.setTitle('Help!')
.setDescription(`**React with one of the circles to get help with a category!**`)
.addFields(
{ name: 'Moderation', value: ':blue_circle:'},
{ name: 'Fun', value: ':green_circle:'},
{ name: 'Misc', value: ':purple_circle:'},
)
.setColor(4627199)
message.channel.send({embed: helpEmbed}).then(embedMessage => {
embedMessage.react('🔵')
embedMessage.react('🟢')
embedMessage.react('🟣')
})
const msg = await sendReact()
const userReactions = message.reactions.cache.filter(reaction => reaction.users.cache.has(userId));
const filter = (reaction, user) =>{
return ['🔵', '🟢', '🟣'].includes(reaction.emoji.name) && user.id === message.author.id;
}
msg.awaitReactions(filter, { max: 1, time: 10000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '🔵') {
try {
for (const reaction of userReactions.values()) {
reaction.users.remove(userId)
}
} catch (error) {
console.error('Failed to remove reactions.')
}
message.channel.send('Moderation');
} else if (reaction.emoji.name === '🟢') {
try {
for (const reaction of userReactions.values()) {
reaction.users.remove(userId)
}
} catch (error) {
console.error('Failed to remove reactions.')
}
message.channel.send('Fun');
} else if (reaction.emoji.name === '🟣') {
try {
for (const reaction of userReactions.values()) {
reaction.users.remove(userId)
}
} catch (error) {
console.error('Failed to remove reactions.')
}
message.channel.send('Misc')
}
})
.catch(collected => {
message.reply('you reacted with neither a thumbs up, nor a thumbs down.');
});
}
}
}
You defined helpEmbed funcion but not called it.
try writing "helpEmbed()" after "execute(message, args){"
if still doesn't work:
Check bot's permission
Bot needs SEND_EMBED_LINKS Permission in that channel.
Related
Desired outcome: Assign role to a user who reacts to message in channel. On bot restart the message if not in cache, therefore user is not assigned role.
Issue: Code stops responding after guildID = client.guilds.get(packet.d.guild_id);
client has been defined at the start of the script.
Expected output: Returns guildID and adds the role to the user who reacted.
Followed this guide
client.on('raw', packet => {
if (!['MESSAGE_REACTION_ADD', 'MESSAGE_REACTION_REMOVE'].includes(packet.t)) return;
if (!(packet.d.channel_id === '<CHANNEL_ID>')) return;
//console.log(packet);
guildID = client.guilds.get(packet.d.guild_id);
if (packet.t === 'MESSAGE_REACTION_ADD') {
console.log("ADDED");
if (packet.d.emoji.name === '⭐') {
try {
guildID.members.cache.get(packet.d.user_id).roles.add('<ROLE_ID>').catch()
} catch (error) {
console.log(error);
}
}
}
if (packet.t === 'MESSAGE_REACTION_REMOVE') {
console.log("REMOVED");
}
});
Try to using these alternative way to use
And guildID = client.guilds.get(packet.d.guild_id); this wrong way to get guild since discord.js v12 updated it will be guildID = client.guilds.cache.get(packet.d.guild_id);
client.on('messageReactionAdd', (reaction, user) => {
console.log('a reaction has been added');
});
client.on('messageReactionRemove', (reaction, user) => {
console.log('a reaction has been removed');
});
Solved it with this
client.on('raw', async (packet) => {
if (!['MESSAGE_REACTION_ADD', 'MESSAGE_REACTION_REMOVE'].includes(packet.t)) return;
if (!(packet.d.channel_id === '800423226294796320')) return;
guild = client.guilds.cache.get(packet.d.guild_id);
if (packet.t === 'MESSAGE_REACTION_ADD') {
console.log("ADDED");
if (packet.d.emoji.name === '⭐') {
try {
member = await guild.members.fetch(packet.d.user_id);
role = await guild.roles.cache.find(role => role.name === 'star');
member.roles.add(role);
} catch (error) {
console.log(error);
}
}
}
if (packet.t === 'MESSAGE_REACTION_REMOVE') {
console.log("REMOVED");
if (packet.d.emoji.name === '⭐') {
try {
member = await guild.members.fetch(packet.d.user_id);
role = await guild.roles.cache.find(role => role.name === 'star');
member.roles.remove(role);
} catch (error) {
console.log(error);
}
}
}
});
I'm trying to create a dynamic help command, in the sense that the users can decide what "page" they would like to go to simply by reacting to the message. I have tried doing this, however, with my code it only detects the first reaction. I have tried setting the max for the awaitReactions method to more than 1, however once I do that it doesn't detect any reaction. Here is my code:
const Discord = require('discord.js');
const fs = require('fs');
module.exports = {
name: 'help',
aliases: ('cmds'),
description: 'Shows you the list of commands.',
usage: 'help',
example: 'help',
async execute(client, message, args, prefix, footer, color, invite, dev, devID, successEmbed, errorEmbed, usageEmbed) {
const helpEmbed = new Discord.MessageEmbed()
.setColor(color)
.setAuthor(`${client.user.username} Discord Bot\n`)
.setDescription('• 📍 Prefix: ``' + prefix + '``\n' +
`• 🔧 Developer: ${dev}\n\n⚙️ - **Panel**\n👮 - **Moderation**\n❔ - **Other**`);
const moderationEmbed = new Discord.MessageEmbed()
.setColor(color)
.setAuthor(`Config\n`)
.setDescription('To get more information about a certain command, use ``' + prefix +
'help [command]``.\n\n•``test``, ``test2``, ``test3``.');
try {
const filter = (reaction, user) => {
return (reaction.emoji.name === '⚙️' || '👮' || '❔') && user.id === message.author.id;
};
message.delete();
message.channel.send(helpEmbed).then(embedMsg => {
embedMsg.react("⚙️")
.then(embedMsg.react("👮"))
.then(embedMsg.react("❔"))
embedMsg.awaitReactions(filter, { max: 1, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '⚙️') {
embedMsg.edit(helpEmbed);
} else if (reaction.emoji.name === '👮') {
embedMsg.edit(moderationEmbed);
} else if (reaction.emoji.name === '❔') {
message.reply('test.');
}
})
.catch(collected => {
message.reply('didnt work.');
});
});
} catch (e) {
console.log(e.stack);
}
}
}
Used a collector.
const collector = embedMsg.createReactionCollector(filter);
collector.on('collect', (reaction, user) => {
reaction.users.remove(user.id); // remove the reaction
if (reaction.emoji.name === '⚙️') {
embedMsg.edit(helpEmbed);
} else if (reaction.emoji.name === '🛠️') {
embedMsg.edit(utilityEmbed);
} else if (reaction.emoji.name === '👮') {
embedMsg.edit(moderationEmbed);
}
});
I use ${reaction.message.author} so the bot mentions the person who clicked on the reaction after it. But the bot is mentioning itself.
How to make the bot to mention the user who clicked on the reaction after the bot?
===Code===
client.on('message', (message) => {
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (message.content.startsWith(prefix + 'Interpol')) {
const response = args.join(' ');
message.channel
.send({
content: '<#&776034311245660200>',
embed: {
color: 3447003,
title: 'Новый вызов',
timestamp: new Date(),
},
})
.then((sentMessage) => {
sentMessage.react('1️⃣');
message.delete({ timeout: 100 });
const filter = (reaction, user) => {
return ['1️⃣'].includes(reaction.emoji.name);
};
sentMessage
.awaitReactions(filter, {
max: 2,
time: 60000,
errors: ['time'],
})
.then((collected) => {
const reaction = collected.first();
if (reaction.emoji.name === '1️⃣') {
console.log(reaction.message.author);
message.author.send({
embed: {
color: 3447003,
title: 'Вызов принят',
description: `**Сотрудник:** ${reaction.message.author}`,
timestamp: new Date(),
},
});
}
});
});
}
});
You can update your filter to filter out reactions if the user is a bot. This way the first reaction will be from a member:
const filter = (reaction, user) => {
return ['1️⃣'].includes(reaction.emoji.name) && !user.bot;
};
Update: So, you want to find the first member who reacted to the message and is not a bot. The problem is that you send a DM with reaction.message.author. reaction.message is the message that this reaction refers to, so the sentMessage in your case and the author of this message is the bot itself.
You can .find() the first member who reacted to the message by checking the reaction.users.cache. reaction.users is manager of the users that have given this reaction (including the bot). By using .find(), you can return a single member:
message.channel
.send({
content: '<#&776034311245660200>',
embed: {
color: 3447003,
title: 'Новый вызов',
timestamp: new Date(),
},
})
.then((sentMessage) => {
sentMessage.react('1️⃣');
message.delete({ timeout: 100 });
const filter = (reaction, user) => {
return !user.bot && ['1️⃣'].includes(reaction.emoji.name);
};
sentMessage
.awaitReactions(filter, {
max: 1,
time: 60000,
// errors: ['time'],
})
.then((collected) => {
const reaction = collected.first();
if (reaction.emoji.name === '1️⃣') {
// find the first member who reacted and is not a bot
const member = reaction.users.cache.find((user) => !user.bot);
message.author.send({
embed: {
color: 3447003,
title: 'Вызов принят',
description: `**Сотрудник:** ${member}`,
timestamp: new Date(),
},
});
}
})
.catch(console.log);
});
You're just missing a filter, if I'm not mistaken. This is a common occurrence when trying to collect something, the bot picks its own message/reactions to itself.
To correct this, all you have to add onto your filter function. && user.id === message.author.id;
So:
return ['1️⃣'].includes(reaction.emoji.name) && user.id === message.author.id;
This basically checks if the user who reacted was also the sender of the message, who I'm assuming is the bot. Else not, then you could just make it !user.bot to check if it's not a bot who responded like Zsolt said.
So i think i quite forgot some .then's beause the bot sends the B emoji message instanntly without a reaction from the user and even when i would provide a "suggestion" then it wouldnt send it to the specific channel, but idk where i have to put the missing .then's. Can someone help me please? I tried to figure it out myself and tested some but it didn't make anything better.
execute(message, client, args) {
const Discord = require('discord.js');
let Embed = new Discord.MessageEmbed()
.setColor('0x0099ff')
.setDescription(`Suggestion categories`)
.addField(`For what you want to suggest something?`, `\nA: I want to suggest something for the Website/Servers/Discord Server\nB: I want to suggest something for the CloudX Bot \n\nPlease react to this message with A or B`)
message.channel.send(Embed).then(function (message) {
message.react("🇦").then(() => {
message.react("🇧")
const filter = (reaction, user) => {
return ['🇦', '🇧'].includes(reaction.emoji.name) && user.id;
}
message.awaitReactions(filter, { max: 1 })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '🇦') {
const filter = m => m.author.id === message.author.id;
message.channel.send(`Please provide a suggestion for the Website/Servers/Discord Server or cancel this command with "cancel"!`).then(() => {
message.channel.awaitMessages(filter, { max: 1, })
.then(async (collected) => {
if (collected.first().content.toLowerCase() === 'cancel') {
message.reply("Your suggestion has been cancelled.")
}
else {
let embed1 = new Discord.MessageEmbed()
.setColor('0x0099ff')
.setAuthor(message.author.tag)
.addField(`New Suggestion:`, `${collected.first().content}`)
.setFooter(client.user.username, "attachment://CloudX.png")
.setTimestamp();
const channel = await client.channels.fetch("705781201469964308").then(() => {
channel.send({embed: embed1, files: [{
attachment:'CloudX.png',
name:'CloudX.png'
}]})
message.channel.send(`Your suggestion has been filled to the staff team. Thank you!`)
})
}
})
})
}
if (reaction.emoji.name === '🇧') {
const filter = m => m.author.id === message.author.id;
message.channel.send(`Please provide a suggestion for the CloudX Bot or cancel this command with "cancel"!`).then(() => {
message.channel.awaitMessages(filter, { max: 1, })
.then(async (collected) => {
if (collected.first().content.toLowerCase() === 'cancel') {
message.reply("Your suggestion has been cancelled.")
}
else {
let embed2 = new Discord.MessageEmbed()
.setColor('0x0099ff')
.setAuthor(message.author.tag)
.addField(`New Suggestion:`, `${collected.first().content}`)
.setFooter(client.user.username, "attachment://CloudX.png")
.setTimestamp();
const channel = await client.channels.fetch("702825446248808519").then(() => {
channel.send({embed: embed2, files: [{
attachment:'CloudX.png',
name:'CloudX.png'
}]})
message.channel.send(`Your suggestion has been filled to the staff team. Thank you!`)
})
}
})
})
}
})
})
})
},
I would suggest learning await/async functions.
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
This will clean up your code and keep things steady without five thousand .then()
async execute(message, client, args) {
const { MessageEmbed } = require('discord.js');
const embed = new MessageEmbed()
.setColor('#0099ff')
.setDescription(`Suggestion categories`)
.addField(`For what you want to suggest something?`, `\nA: I want to suggest something for the Website/Servers/Discord Server\nB: I want to suggest something for the CloudX Bot \n\nPlease react to this message with A or B`)
const question = message.channel.send(embed)
await question.react("🇦")
await question.react("🇧")
const filter = (reaction, user) => {
return ['🇦', '🇧'].includes(reaction.emoji.name) && user.id;
}
This is just part of it but you should be able to get the gist...
I am getting this error UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'username' of undefined which is caused by client.user.username in embed's .setFooter().
module.exports = {
name: 'suggest',
aliases: ['sug', 'suggestion'],
description: 'Suggest something for the Bot',
execute(message, client, args) {
const Discord = require('discord.js');
const filter = m => m.author.id === message.author.id;
message.channel.send(`Please provide a suggestion for the Bot or cancel this command with "cancel"!`)
message.channel.awaitMessages(filter, { max: 1, })
.then(async (collected) => {
if (collected.first().content.toLowerCase() === 'cancel') {
message.reply("Your suggestion has been cancelled.")
}
else {
let embed = new Discord.MessageEmbed()
.setFooter(client.user.username, client.user.displayAvatarURL)
.setTimestamp()
.addField(`New Suggestion from:`, `**${message.author.tag}**`)
.addField(`New Suggestion:`, `${collected.first().content}`)
.setColor('0x0099ff');
client.channels.fetch("702825446248808519").send(embed)
message.channel.send(`Your suggestion has been filled to the staff team. Thank you!`)
}
})
},
catch(err) {
console.log(err)
}
};
According to your comment here
try { command.execute(message, args); } catch (error) { console.error(error); message.reply('There was an error trying to execute that command!'); } });
You are not passing client into execute(), you need to do that.
You also need to use await on channels.fetch() since it returns a promise so replace client.channels.fetch("702825446248808519").send(embed) with:
const channel = await client.channels.fetch("702825446248808519")
channel.send(embed)