MessageEmbed field values may not be empty. Discord.js - discord.js

I am working on a code that sends a random picture from a subreddit, from the weekly top.
But I receive the following error when I am trying to use the command:
(node:25) UnhandledPromiseRejectionWarning: RangeError [EMBED_FIELD_VALUE]: MessageEmbed field values may not be empty.
Code:
client.on("message", async message => {
if (message.content.toLowerCase() === "!foto") {
const snekfetch = require('snekfetch');
try {
const {
body
} = await snekfetch
.get('https://www.reddit.com/r/gtavcustoms.json?sort=top&t=week')
.query({
limit: 10
});
const allowed = message.channel.nsfw ? body.data.children : body.data.children.filter(post => !post.data.over_18);
if (!allowed.length) return message.channel.send('Het lijkt erop dat de nieuwe fotos op zijn, probeer het later nog eens!');
const randomnumber = Math.floor(Math.random() * allowed.length)
const embed = new Discord.MessageEmbed()
.setColor(0x00A2E8)
.setTitle(allowed[randomnumber].data.title)
.setDescription("Gepost door: " + allowed[randomnumber].data.author)
.setImage(allowed[randomnumber].data.url)
.addField("Overige informatie:", "Likes: " + allowed[randomnumber].data.ups + " / Comments: " + allowed[randomnumber].data.num_comments)
.setFooter("DaddyCoolNL Official Discord Server")
message.channel.send(embed)
} catch (err) {
return console.log(err);
}
}
});

This may be a simple fix, but may not work. What you can try is putting it in backticks.
.addField("Overige informatie:", `Likes: ${allowed[randomnumber].data.ups + " / Comments: " + allowed[randomnumber].data.num_comments)}`
It also may be due to the allowed array not being complete, or something is off with it.

Related

MessageEmbed description must be a string

This is my code and im getting this error: RangeError [EMBED_DESCRIPTION]: MessageEmbed description must be a string can can someone help me please? I updated from v12 to v13 and now this error happens, haven't found a solution yet.
const { MessageEmbed } = require('discord.js');
const Command = require('../../Structures/Command');
module.exports = class extends Command {
constructor(...args) {
super(...args, {
aliases: ['halp'],
description: 'Displays all the commands in the bot',
category: 'Utilities',
usage: '[command]'
});
}
async run(message, [command]) {
const embed = new MessageEmbed()
.setColor('BLUE')
.setAuthor(`${message.guild.name} Help Menu`, message.guild.iconURL({ dynamic: true }))
.setThumbnail(this.client.user.displayAvatarURL())
.setFooter(`Requested by ${message.author.username}`, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp();
if (command) {
const cmd = this.client.commands.get(command) || this.client.commands.get(this.client.aliases.get(command));
if (!cmd) return message.channel.send(`Invalid Command named. \`${command}\``);
embed.setAuthor(`${this.client.utils.capitalise(cmd.name)} Command Help`, this.client.user.displayAvatarURL());
embed.setDescription([
`**❯ Aliases:** ${cmd.aliases.length ? cmd.aliases.map(alias => `\`${alias}\``).join(' ') : 'No Aliases'}`,
`**❯ Description:** ${cmd.description}`,
`**❯ Category:** ${cmd.category}`,
`**❯ Usage:** ${cmd.usage}`
]);
return message.channel.send(embed);
} else {
embed.setDescription([
`These are the available commands for ${message.guild.name}`,
`The bot's prefix is: ${this.client.prefix}`,
`Command Parameters: \`<>\` is strict & \`[]\` is optional`
]);
let categories;
if (!this.client.owners.includes(message.author.id)) {
categories = this.client.utils.removeDuplicates(this.client.commands.filter(cmd => cmd.category !== 'Owner').map(cmd => cmd.category));
} else {
categories = this.client.utils.removeDuplicates(this.client.commands.map(cmd => cmd.category));
}
for (const category of categories) {
embed.addField(`**${this.client.utils.capitalise(category)}**`, this.client.commands.filter(cmd =>
cmd.category === category).map(cmd => `\`${cmd.name}\``).join(' '));
}
return message.channel.send(embed);
}
}
};
Since you updated discord.js to v13, <MessageEmbed>.setDescription no longer accepts arrays, you need to put a string or use <Array>.join like this:
embed.setDescription([
`These are the available commands for ${message.guild.name}`,
`The bot's prefix is: ${this.client.prefix}`,
`Command Parameters: \`<>\` is strict & \`[]\` is optional`
].join('\n'));
Discord.js is expecting a string but you give it an array.
I would remove the array brackets [ ] and the commas from the setDescriptions

Bot readout for who used a command

Wanting to have a readout channel for my bot to keep track of what happens, just like a second console log. Want to be able to have it read out in the message the username of the person who used the command. Any ideas? Also, in a similar note, is there a way to copy the console readout and possibly just paste that instead?
var Scraper = require('images-scraper');
const google = new Scraper({
puppeteer: {
headless: true
},
})
module.exports = {
name: 'image',
description: 'Google image scraper',
async execute(message, args){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const image_query = args.join(' ');
if(!image_query) return message.channel.send('Please enter a valid image search.');
const image_results = await google.scrape(image_query, 1);
message.channel.send(image_results[0].url);
readout.send('Image sent');
}
}
I think you want
message.author.username (It gives username who sent the message)
or message.member (it gives user as a guildmember)
Just access the author property of the message object and include it via a template string into the message:
readout.send(`Image sent to ${message.author.username}`);
Ended up doing an embed system in a separate channel on my discord.
const Discord = require('discord.js');
module.exports = {
name: 'suggestionlog',
description: 'logs suggestion',
execute(message){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const embed = new Discord.MessageEmbed()
.setColor('FADF2E')
.setTitle(message.channel.name)
.setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
.setDescription(message);
readout.send(embed)
.catch((err)=>{
throw err;
});
}
}

How to check a users permissions in a certain server

So I am making a DM command and I want to make it so when the user uses the command it will check the users permissions in a certain server. This is my current code:
bot.on("message", async msg => {
if(msg.channel.type === "dm") {
if(msg.content.startsWith(";announce")) {
if(msg.author.guilds.cache.has("396085313618837526").hasPermission("BAN_MEMBERS")) {
if(!msg.content.split(" ").slice(1).join(" ")) {
msg.reply("I cannot send an announcement without `args`. Please type the command like this: `;announce [MESSAGE]`.")
} else {
let Question1 = new Discord.MessageEmbed()
.setDescription("What channel do you want me to send this in? Please give me the Channel ID (# coming soon).")
msg3 = await msg.channel.send(Question1)
const filter = (m) => m.author.id === msg.author.id
msg.channel.awaitMessages(filter, { max: 1, time: 30000 })
.then(async collected => {
const msg2 = collected.first()
if (!msg2.content) {
msg.reply("You need to give me args. Please retry the command.")
msg2.delete()
} else {
let SendAnnouncement = new Discord.MessageEmbed()
.setTitle("New announcement!")
.setDescription(msg.content.split(" ").slice(1).join(" "))
.setFooter("This announcement has flown in from: " + msg.author.tag)
bot.channels.cache.get(msg2.content).send(SendAnnouncement)
let SuccessfullySent = new Discord.MessageEmbed()
.setDescription("Successfully sent the announcement to <#" + msg2.content + ">!")
msg3.edit(SuccessfullySent)
msg2.delete()
}
})
}
} else {
let error = new Discord.MessageEmbed()
.setDescription("You must have a certain permission to do this. If your roles have just been changed, please type `retry` now so I can check again.")
ERRMSG = await msg.channel.send(error)
const filter = (m) => m.author.id === msg.author.id
msg.channel.awaitMessages(filter, { max: 1, time: 30000 })
.then(async collected => {
const msg2 = collected.first()
if(msg2.content === "retry") {
if(msg.member.hasPermission("BAN_MEMBERS")) {
if(!msg.content.split(" ").slice(1).join(" ")) {
msg.reply("I cannot send an announcement without `args`. Please type the command like this: `;announce [MESSAGE]`.")
} else {
let Question1 = new Discord.MessageEmbed()
.setDescription("What channel do you want me to send this in? Please give me the Channel ID (# coming soon).")
msg3 = await ERRMSG.edit(Question1)
msg2.delete()
const filter = (m) => m.author.id === msg.author.id
msg.channel.awaitMessages(filter, { max: 1, time: 30000 })
.then(async collected => {
const msg2 = collected.first()
if (!msg2.content) {
msg.reply("You need to give me args. Please retry the command.")
msg2.delete()
} else {
let SendAnnouncement = new Discord.MessageEmbed()
.setTitle("New announcement!")
.setDescription(msg.content.split(" ").slice(1).join(" "))
.setFooter("This announcement has flown in from: " + msg.author.tag)
bot.channels.cache.get(msg2.content).send(SendAnnouncement)
let SuccessfullySent = new Discord.MessageEmbed()
.setDescription("Successfully sent the announcement to <#" + msg2.content + ">!")
msg3.edit(SuccessfullySent)
msg2.delete()
}
})
}
} else {
let error2 = new Discord.MessageEmbed()
.setDescription("I still could not find your permissions. Please retry when you have the correct permissions.")
ERRMSG.edit(error2)
msg2.delete()
}
}
})
}
}
}
})
This gives me the error:
(node:347) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'cache' of undefined
(node:347) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:347) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
This just throws this error but I am not sure how I can check the actual permissions in this discord server. How can I manipulate this feature into my Discord Bot?
Well, first of all, you would want to get the guild object of the guild you're referring to, and obviously check if that guild even exists. something that could be done using:
const guildObject = client.guilds.cache.get('place guild id here'); // gets the guild object of the id provided
if (!guildObject) return console.log('Guild could not be found!'); // Would console log in the case that the guild you've provided does not exist.
From there on, we could use the guild object we've found to check if the message author actually exists in this guild, which can be done using
const memberObject = guildObject.member(message.author.id)
if (!memberObject) return console.log('User could not be found in the provided guild!');
Finally, we could determine whether or not the user has the wanted permissions using:
if (!memberObject.hasPermission('Permission here')) return console.log('User does not have the corresponding permissions needed!')
The error you get comes from this line:
if(msg.author.guilds.cache.has("396085313618837526").hasPermission("BAN_MEMBERS"))
What are you checking with this line of code? If the author has permission?
You can check if the author has permission by doing:
if(msg.guild.member(msg.author).hasPermission("BAN_MEMBERS"))

client.on('messageUpdate' ....) not working properly?

I'm trying to log when a user edits a message.
Its not really working....
Here is my code:
client.on('messageUpdate', (oldMessage, newMessage) => {
logMessageEdit(oldMessage, newMessage);
});
function logMessageEdit(oldMessage, newMessage) {
if (!newMessage.guild.channels.find('name', "logs")) return;
logChannel = newMessage.guild.channels.find('name', "logs");
let logEmbed = new Discord.RichEmbed()
.setAuthor(newMessage.author.tag, newMessage.author.avatarURL)
.setDescription(`💬 | Meddelande redigerat i ${oldMessage.channel}.`)
.addField("Innan", "test" + oldMessage.content)
.addField("Efter", "test" + newMessage.content)
.setTimestamp()
.setFooter(newMessage.id)
.setColor(greenColor);
logChannel.send(logEmbed)
}
And here is what it results in:
not too familiar with the client.on('messageUpdate') method but the bot is logging its own message sends, not just your messages. try updating your client.on('messageUpdate') method
client.on('messageUpdate', (oldMessage, newMessage) => {
if(newMessage.author.id === client.user.id) return;
logMessageEdit(oldMessage, newMessage);
});
if this doesn't work check for other calls of logMessageEdit such as in the client.on('message') event

How to retrieve all members of a guild by user object?

I have the following code setup, but it often doesn't find members on my server.
How can I solve this problem?
BOT.on('message', function(message) {
if (!message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).split(' ');
const command = args.shift().toLowerCase();
const chan = message.channel;
if (command == "grabreacts" && chan.name == "the-purge") {
var role = message.guild.roles.find(role => role.name === "2019 Purge Survivor");
if (!role) return message.channel.send(`**${message.author.username}**, role not found`);
//console.log(role);
chan.fetchMessage(args)
.then(function(value) {
const react = value.reactions.filter(r => r.emoji == "👍").first();
var reacts = react.count;
react.fetchUsers()
.then(function(users) {
var fetchedMemebers = users.size;
users.map(async user => {
console.log(user.tag);
message.guild.fetchMember(user, false)
.then((memeber) => {
member.addRole(role)
.then((mem) => {
react.remove(user)
.catch((err) => console.log("Cannot remove user: " + user.tag + ". ex: " + ex + "!"));
})
.catch(ex => {
console.log(ex);
});
})
.catch((err) => {
console.log("Cannot find member object for: " + user.tag + "!");
});
});
var assignedusers = role.members.size;
message.reply("Reacts found: " + reacts + "; users fetched: " + fetchedMemebers + "; roles assigned: " + assignedusers);
})
.catch(err => message.reply("Cannot fetch users for react: '" + reacts + "', err: " + err + "!"));
})
.catch(err => message.reply("Cannot fetch message: '" + args + "', err: " + err + "!"));
}
});
It works fine, up until message.guild.fetchMember(user, false), where I fall into the catch block and print many "Cannot find member object for: ******#****!" messages.
I am not getting back any actual exception blocks, and the code worked for the first 62 or 788 reacts. It seems like if the bot doesn't have the user info cached, even using a false in message.guild.fetchMember(user, boolean) doesn't work.
The user object for that member, however is defined. I need the member object to use member.addRole().
Can someone help me figure out how to get this to work, please? Or what I am doing wrong?
I am running node v11.6.0 with "discord.js": "^11.4.2" as a dependency.
Thanks!
I found that the guild object from BOT.guilds.first() has:
members: 656,
memberCount: 2470
So, if I do:
BOT.guilds.first().fetchMembers().then((guild) => {
...
}
That fixes my issue, as the fetchMembers() returns a Promise<Guild> that I can see in the .then() clause, and that Guild object has all members fetched inside of it.
Hope this helps others out!

Resources