Discord.js Embed error Cannot send an empty message - javascript

so I'm trying to make a help command with list of commands showed in embed. My code kinda works but it throws an error "DiscordAPIError: Cannot send an empty message" and I've tried already everything I know and what I've found but I can't fix it.
Here's the code
const Discord = require('discord.js');
const { prefix } = require('../config.json');
module.exports = {
name: 'help',
description: 'List all of my commands or info about a specific command.',
aliases: ['commands', 'cmds'],
usage: '[command name]',
cooldown: 5,
execute(msg, args) {
const data = [];
const { commands } = msg.client;
if (!args.length) {
const helpEmbed = new Discord.MessageEmbed()
.setColor('YELLOW')
.setTitle('Here\'s a list of all my commands:')
.setDescription(commands.map(cmd => cmd.name).join('\n'))
.setTimestamp()
.setFooter(`You can send \`${prefix}help [command name]\` to get info on a specific command!`);
msg.author.send(helpEmbed);
return msg.author.send(data, { split: true })
.then(() => {
if (msg.channel.type === 'dm') return;
msg.reply('I\'ve sent you a DM with all my commands!');
})
.catch(error => {
console.error(`Could not send help DM to ${msg.author.tag}.\n`, error);
msg.reply('it seems like I can\'t DM you! Do you have DMs disabled?');
});
}
const name = args[0].toLowerCase();
const command = commands.get(name) || commands.find(c => c.aliases && c.aliases.includes(name));
if (!command) {
return msg.reply('that\'s not a valid command!');
}
data.push(`**Name:** ${command.name}`);
if (command.aliases) data.push(`**Aliases:** ${command.aliases.join(', ')}`);
if (command.description) data.push(`**Description:** ${command.description}`);
if (command.usage) data.push(`**Usage:** ${prefix}${command.name} ${command.usage}`);
data.push(`**Cooldown:** ${command.cooldown || 3} second(s)`);
msg.channel.send(data, { split: true });
},
};

You should try replace this line :
msg.channel.send(data, { split: true });
with
msg.channel.send(data.join(' '), { split: true }); since your data variable is an array and not a string

The problem is as the error states. You are trying to send an empty message somewhere.
You can try replacing msg.channel.send(data) with msg.channel.send(data.join('\n')), since the data variable is an array.
I don't see why sending an array doesn't work though.

Related

TypeError: Cannot read property 'mentions' of undefined

first time poster looking for some help, struggling to get this to work. I'm wanting to create a command which followed by a channel mention and Raw JSON will then post an embed in the mention channel. The code itself throws up no errors, until the point I initiate the command, where I get "TypeError: Cannot read property 'mentions' of undefined". Any ideas where I've gone wrong?
const DiscordJS = require('discord.js')
const WOKCommands = require('wokcommands')
require('dotenv').config();
module.exports = {
name: "embedjson",
category: "info",
description: "post embed from json data",
minArgs: 2,
expectedArgs: '<Channel mention> <JSON>',
run: async ({client, message, args, level }) => {
// get the target channel
const targetChannel = message.mentions.channels.first()
if (!targetChannel) {
message.reply('Please specify a channel to send the embed in')
return
}
// removes the channel mention
args.shift()
try {
// get the JSON data
const json = JSON.parse(args.join(' '))
const { text = '' } = json
// send the embed
targetChannel.send(text, {
embed: json,
})
} catch (error) {
message.reply(`Invalid JSON ${error.message}`)
}
},
}

Getting UUID’s by providing only the crypto coins name/ticker

I’m building a Discord bot using the Discord.JS module, and using NodeJS. I’m trying to add a simple crypto-price feature to my bot.
For now, I’m using the following code:
const unirest = require("unirest");
const req = unirest("GET", "https://coinranking1.p.rapidapi.com/coin/Qwsogvtv82FCd/price");
req.query({
"referenceCurrencyUuid": "yhjMzLPhuIDl"
});
req.headers({
"X-RapidAPI-Host": "coinranking1.p.rapidapi.com",
"X-RapidAPI-Key": "X",
"useQueryString": true
});
req.end(function (res) {
if (res.error) throw new Error(res.error);
console.log(res.body);
});
So basically, you have to provide the UUID of the desired crypto coin to request information, but I want my users to be able to do (for example) !price bitcoin or !price btc, but this requires the command to be like !price Qwsogvtv82FCd.
How do I resolve this issue?
If you check the API documentation, you can see that instead of using the coin price endpoint, you could use the search suggestion (https://coinranking1.p.rapidapi.com/search-suggestions), where you can search for a coin by its name or symbol. It returns an object like the one below. If you check the objects in data.coins, they have keys like uuid, name, symbol, and price:
{
"status":"success",
"data":{
"coins":[
{
"uuid":"Qwsogvtv82FCd",
"iconUrl":"https://cdn.coinranking.com/gNsKAuE-W/bitcoin_btc.svg",
"name":"Bitcoin",
"symbol":"BTC",
"price":"65955.43592725793773050345"
},
{...}
],
"exchanges":[
{...},
{...}
],
"markets":[...]
}
}
Your current code doesn't really do anything and it doesn't even have discord.js code. Here is a sample code with some explanation:
const { Client, Intents } = require('discord.js');
// I'm using node-fetch instead of unirest
// make sure you install it using npm i node-fetch
const fetch = require('node-fetch');
const RAPID_API_KEY = 'YOUR RAPID API KEY';
const TOKEN = 'YOUR DISCORD API TOKEN';
const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
});
const prefix = '!';
client.on('messageCreate', async (message) => {
if (message.author.bot || !message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command !== 'price') return;
if (!args[0]) return message.reply('Please provide a coin!');
try {
// get the search query
let query = args[0].toLowerCase();
// call the API
let coins = await searchCoin(query);
// if there is no search result, or something went wrong, exit w/ a message
if (!coins || coins.length === 0)
return message.reply(`No result for \`"${query}"\``);
// check the first result only
let coin = coins[0];
// if there is an exact match, send the price returned from the API
if (
coin.name.toLowerCase() === query ||
coin.symbol.toLowerCase() === query
)
return message.reply(
`The current price of **${coin.name} (${coin.symbol})** is **${coin.price} USD**`,
);
// if there is no exact match, just send the coin name and symbol in a message
message.reply(
`No exact result found. Did you mean **${coin.name} (${coin.symbol})**?`,
);
} catch (err) {
console.error(err);
message.reply('Oops, there was an error. Please try again later.');
}
});
client.once('ready', () => {
console.log('Bot is connected...');
});
client.login(TOKEN);
async function searchCoin(query) {
const url = `https://coinranking1.p.rapidapi.com/search-suggestions?query=${query}`;
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Host': 'coinranking1.p.rapidapi.com',
'X-RapidAPI-Key': RAPID_API_KEY,
},
};
try {
const response = await fetch(url, options);
const json = await response.json();
return json.status === 'success' ? json.data?.coins : null;
} catch (err) {
console.error(err);
return null;
}
}
And here is the result:

Check if first argument is a mention

I'm coding a discord bot and I'm trying to make a kick command right now. I managed to find how to check if there's any mention in the command message with message.mentions.members.first() but I couldn't find anything to check if a specific argument is a mention.
Code I have so far:
module.exports = {
name: "kick",
category: "moderation",
permissions: ["KICK_MEMBERS"],
devOnly: false,
run: async ({client, message, args}) => {
if (args[0]){
if(message.mentions.members.first())
message.reply("yes ping thing")
else message.reply("``" + args[0] + "`` isn't a mention. Please mention someone to kick.")
}
else
message.reply("Please specify who you want to kick: g!kick #user123")
}
}
I looked at the DJS guide but couldn't find how.
MessageMentions has a USERS_PATTERN property that contains the regular expression that matches the user mentions (like <#!813230572179619871>). You can use it with String#match, or RegExp#test() to check if your argument matches the pattern.
Here is an example using String#match:
// make sure to import MessageMentions
const { MessageMentions } = require('discord.js')
module.exports = {
name: 'kick',
category: 'moderation',
permissions: ['KICK_MEMBERS'],
devOnly: false,
run: async ({ client, message, args }) => {
if (!args[0])
return message.reply('Please specify who you want to kick: `g!kick #user123`')
// returns null if args[0] is not a mention, an array otherwise
let isMention = args[0].match(MessageMentions.USERS_PATTERN)
if (!isMention)
return message.reply(`First argument (_\`${args[0]}\`_) needs to be a member: \`g!kick #user123\``)
// kick the member
let member = message.mentions.members.first()
if (!member.kickable)
return message.reply(`You can't kick ${member}`)
try {
await member.kick()
message.reply('yes ping thing')
} catch (err) {
console.log(err)
message.reply('There was an error')
}
}
}

How do I create a slash command in discord using discord.js

I am trying to create a slash command for my discord bot, but I don't know how to execute code when the command is exuted
The code I want to use will send a message to a different channel (Args: Message)
Here is the code I want to use
const channel = client.channels.cache.find(c => c.id == "834457788846833734")
channel.send(Message)
You need to listen for an event interactionCreate or INTERACTION_CREATE. See the code below, haven't tested anything, hope it works.
For discord.js v12:
client.ws.on("INTERACTION_CREATE", (interaction) => {
// Access command properties
const commandId = interaction.data.id;
const commandName = interaction.data.name;
// Do your stuff
const channel = client.channels.cache.find(c => c.id == "834457788846833734");
channel.send("your message goes here");
// Reply to an interaction
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "Reply message"
}
}
});
});
For discord.js v13:
client.on("interactionCreate", (interaction) => {
if (interaction.isCommand()) {
// Access command properties
const commandId = interaction.commandId;
const commandName = interaction.commandName;
// Do your stuff
const channel = client.channels.cache.find(c => c.id == "834457788846833734")
channel.send("your message goes here");
// Reply to an interaction
interaction.reply("Reply message");
}
});

Having some trouble with weather-js and args

I have a command in my bot, called weather, it works fine, but i want to send an error message if the user writes it without any arguments.
It works if the arguments are not a place, but if you write it without any args, it doesnt reply anything
Here's the code (Updated with entire code)
const Discord = require('discord.js');
const weather = require('weather-js');
exports.run = async (client, message, args) => {
weather.find({search: args[0], degreeType: "C"}, function(err, result){
if (err) message.channel.send(err);
const noargs = new Discord.RichEmbed()
.setDescription(`Input a valid location, please`)
.setColor(0xfd5454)
if(!result.length) {
message.channel.send(noargs);
return;
}
var current = result[0].current;
var location = result[0].location;
It works if you write ",weather nonexistingcity" but if you write ",weather" without any args, it doesnt work.
PD: noargs is a discord embed, is declared but not included in this post.
const weather = require('weather-js');
const Discord = require('discord.js');
module.exports = {
name: "weather",
description: "Checks a weather forecast",
async execute(client, message, cmd, args, Discord){
weather.find({search: args.join(" "), degreeType: 'F'}, function (error, result){
// 'C' can be changed to 'F' for farneheit results
if(error) return message.channel.send(error);
if(!args[0]) return message.channel.send('Please specify a location')
if(result === undefined || result.length === 0) return message.channel.send('**Invalid** location');
var current = result[0].current;
var location = result[0].location;
const weatherinfo = new Discord.MessageEmbed()
.setDescription(`**${current.skytext}**`)
.setAuthor(`Weather forecast for ${current.observationpoint}`)
.setThumbnail(current.imageUrl)
.setColor(0x111111)
.addField('Timezone', `UTC${location.timezone}`, true)
.addField('Degree Type', 'Celsius', true)
.addField('Temperature', `${current.temperature}°`, true)
.addField('Wind', current.winddisplay, true)
.addField('Feels like', `${current.feelslike}°`, true)
.addField('Humidity', `${current.humidity}%`, true)
message.channel.send(weatherinfo)
})
}
}
If you want to check if no args where provoided you can do :
if(args.length == 0) return message.channel.send('You need to provide a city');
...weather-js is programmed to answer the user if he didn't provide args with a default message. I want to know how to change that message.
If you really want to change this message instead of checking your arguments yourself like #PLASMA chicken has suggested, the message is located on line 31 of weather-js/index.js.

Categories