cannot send an empty message error while running a eval command - discord.js

I'm trying to make an eval command for my discord.js project but it's doing what it's supposed to do but it says Cannot send an empty message.
here's my command code:
case 'eval':
const result = eval(message.content.replace('>eval ', ''));
message.channel.send(result);
break;

Let's look at your eval statement in the situation in which you use the command >eval message.channel.send('hello'). It would be running message.channel.send('hello'), and setting result to the result of that code.
But the method message.channel.send() does not return a value, so your statement message.channel.send(result) will give you the "cannot send an empty message" error because you would be trying to send an empty string.
So in other words, when you run that eval command, this is what's happening:
const result = message.channel.send('hello');
And if you were to console.log(result) at this point, you would find that result is undefined. This is why the next line, message.channel.send(result), gives you the "empty message" error.
To fix this, try something like:
if (result && result != "") message.channel.send(result)
This will only attempt to send result if it exists and is a non-empty string. Even if that doesn't work in all cases, you just need to adjust the if statement to check if the result exists.
This way, if you do >eval message.author.id it will send you a message containing the author's ID, but if you do >eval message.channel.send('hello') it will not try to send an empty string in addition to sending "hello".

Related

Discord.js checking for mention in args

Hey so I am making a discord bot and when I use this to check for mention: message.mentions.members.first(); it will look for mention in whole message user has sent. I am trying to work this out because if user send message ?ban bla bla bla #user it will work. I want to check for mention only in args[0]. Is that possible? I am using discord v12. Thanks!
this is what i found to work...
if(args[0].slice(2).slice(0, -1) !== message.mentions.users.first()?.id) {
return message.reply("Please start with a user...")
}
the args[0].slice(2).slice(0, -1) if a mention... will be the id of the first mention... and if the mention is the first arg, it will also be the first mention. So what I did was took ID of the first mention and compared it to the sliced args[0] to see if they match, else it will return telling them to please start with a user... Make sure to keep the ? in message.mentions.users.first()?.id just in the case of no mention in the message, it will not cause an error to the process and will also return the please start with a user message.
Mentions
USERS_PATTERN uses RegEx for checking if string mentions about a User. If string matches with the pattern it returns true, otherwise returns false.
const { MessageMentions: { USERS_PATTERN } } = require('discord.js');
...
if (!args[0].match(USERS_PATTERN)) return message.channel.send("Please mention a user");
...

Is it possible to print out an IndexError from a discord bot?

I want to print out and IndexError("List index out of range") from my Discord bot into a channel if something is incorrectly executed. However my method, which I also used for AttributeErrors, does not work. Where is the mistake I made?
try:
message = await channel.fetch_message(id_)
except IndexError:
return await ctx.send('The ID that was entered was incorrect, make sure you have entered the correct giveaway message ID.')
Messageable.fetch_message never raises IndexError, it raises the following:
discord.Notfound - if the message was not found
discord.Forbidden - if you don't have the required permissions
discord.HTTPException - when retrieving the message failed
Answering your question - you can simply except discord.NotFound error
try:
message = await channel.fetch_message(message_id)
except discord.NotFound:
await ctx.send("The ID that was entered is incorrect, make sure you have entered the correct giveaway message ID.")

Command Restrictions

I'm trying to make a command won't work if it's not in a certain channel. When I run my code, I get this error: SyntaxError: Unexpected token '!'
module.exports = {
name: "kill",
desciprtion: "idk",
if (!message.channel.id === '794303555975643136') return;
const { member } = message;
member.roles.add('794308638125981726')
}
In JavaScript and most other languages, you could refer to ! in functions as not.
For example, let's take message.member.hasPermission().
If we add ! at the start, giving us:
if (!message.member.hasPermission('ADMINISTRATOR') return
We're basically telling the client, if the message member does **not** have the administrator permission, return the command.
Now, let's take your if statement, saying if (!message.channel.id === 'id') return, you're basically telling the client if not message id equals to id return the command, which let's face it makes totally no sense.
When we want to compare a variable with a certain value, we would want to tell the client if the variable is **not** equal to value, return the command.
Hence why, you should fix your if statement into saying:
if (message.channel.id !== '794303555975643136') return;
Sorry for the pretty long answer, felt like giving a little lesson to someone :p

Can Command B only be Executed if command A is executed succesfully

I am trying to make a smart questions bot, and I was wondering if there is a way for allowing command B to be executed if command A was executed first
} else if(message.content.match(/Discord/gi)){
const Embed = new Discord.MessageEmbed()
}
This looks for messages that contains Discord (lowercase or uppercase)
I don't want the bot to look for every message that contains Discord.
I was hoping that It would only execute if the preceding command was executed first, and then after that it would also be disabled, sounds complicated but possible
Assuming I understood your intentions correctly, you want to only look for command B after command A is called, and then once command B is executed, you want to stop looking for it. This can be achieved using a message collector that searches for command B. Here is some sample code (works in the latest version):
if (message.content.match("Command A")) {
//Execute your command A code
message.channel.send("Did some command A stuff");
//After command A code is executed, do the following:
var filter = m => m.author.id == message.author.id;
//Creates a message collector, to collect messages sent by the same user
//When max is 1, only 1 message will be collected and then the collector dies
const collector = new Discord.MessageCollector(message.channel, filter, {max: 1});
collector.on("collect", msg => {
//msg is the new message that the user just sent, so check if it contains Discord
if(msg.content.match(/Discord/gi)){
//Do your command B stuff:
const Embed = new Discord.MessageEmbed()
}
});
}
This code checks for Command A, and executes the Command A code. Then it creates a message collector. The message collector will wait until the user that just executed Command A sends another message. Once the user sends another message, it will run the code listening for the collect event. So we take the collected message, in this case msg, and we check if it matches "Discord". From there, you can do your Command B functionality.
Note that immediately after the user sends a message after executing Command A, the collector ends. That means if the user does not enter a message containing "Discord" within 1 attempt, the collector ends and the user must execute Command A once again in order to attempt to execute Command B again. If you want to allow the user to make more attempts to execute Command B, or if you want the user to be able to execute Command B more than once in a row after executing Command A, then you'll need to increase the value of max.

Discord js TypeError: Cannot read property members

Hello i have this code,
user = message.guild.members.fetch(id2).then((use,err)
And i have this error
TypeError: Cannot read property 'members' of null
Please can yuo help me ?
Thank you
message.guild is not initialized. You could check if it is null before use eg
if(message.guild){
user = message.guild.members.fetch(id2).then((use,err) ...
}else{
//do something when it is not initialized
}
Your error occurs because the message object refers to a message that was received as a DM. Because of how DMs work, there is no guild or member property for such message (they are left as nulls).
To avoid that, you should handle direct messages slightly differently. The easiest and most commonly used way is to completely stop direct messages from running your message event code. This can be done by adding
if (message.channel.type === 'dm') return;
at the very top of your event.
As that makes it impossible to initiate commands in DMs, even if they don't need to be executed in a guild to work (like ping command for example), this might be not what you want. In such case, you should implement a way to determine if command someone tried to run in DM is "allowed" to be executed there. Implementations for that vary depending on command handling implementation, but snippet below is basic princinple.
client.on('message', message => {
if (message.author.bot || !message.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).split(/ /g);
const command = args.shift().toLowerCase();
if (command === 'memberinfo') {
if (message.channel.type === 'dm') return message.reply('this command cannot be run in DMs.');
// Actual command code
}
});

Resources