Discord.js slash commands with embeds - discord

I am trying to build an embed with slash commands. This is an error I am getting and for the life of me I cannot figure out what is wrong. I know this embed itself works as I had it in the old bot and it ran fine, however as soon as I update the command handler it has stopped working. It seems that it is unable to find the embeds description yet I have one set so I am really unsure why it is not reading it
node_modules\discord.js\src\rest\RequestHandler.js:350
throw new DiscordAPIError(data, res.status, request);
^
DiscordAPIError: Invalid Form Body
data.embeds[0].description: This field is required
at RequestHandler.execute (node_modules\discord.js\src\rest\RequestHandler.js:350:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RequestHandler.push (node_modules\discord.js\src\rest\RequestHandler.js:51:14) {
method: 'post',
path: '/interactions/987187176422907954/aW50ZXJhY3Rpb246OTg3MTg3MTc2NDIyOTA3OTU0OnBuWmNoTmVoOXltU0pydG9WOXpJenUzeTRPSDBybllDZEZSME9RandlOExpYlFFckRteG1sa1RVV2NycmhQbmpsenpRb1ZBdzhLQ3hGV09WR0dKcHI2QlQ2bjZMWFZWVVU3Q3pzN0tVT24xV1F6S1psVG41UGhWVHZYUzl4alZ4/callback',
code: 50035,
httpStatus: 400,
requestData: {
json: {
type: 4,
data: {
content: undefined,
tts: false,
nonce: undefined,
embed: {
title: null,
type: 'rich',
description: null,
url: null,
timestamp: null,
color: null,
fields: [],
thumbnail: null,
image: null,
author: null,
footer: null
},
embeds: [
{
title: null,
type: 'rich',
description: null,
url: null,
timestamp: null,
color: null,
fields: [],
thumbnail: null,
image: null,
author: null,
footer: null
}
],
username: undefined,
avatar_url: undefined,
allowed_mentions: undefined,
flags: undefined,
files: []
}
},
files: []
}
}
And this is the code in question
const { Client, MessageEmbed } = require("discord.js");
const config = require("../settings/config")
module.exports = {
slash: true,
testOnly: true,
description: "Gives latency of the bot",
/**
*
* #param {CommandInteration} interaction
* #param {Client} client
*/
callback: async (interaction, client) => {
const Build = new MessageEmbed()
.setColor(config.settings.EmbedColour)
.setTitle('**Ping / API Latency:**')
.setDescription(`🏓 ${Date.now() - interaction.createdTimestamp}ms.`)
.setFooter({ text: `${interaction.guild.name} | Made By WildFyr#0008`, iconURL: interaction.guild.iconURL({ dynamic: true }) })
return ({embeds: [Build]})
}
}
Does anyone know why I am getting this error and how to fix it?
Here is the Config.js, I removed all tokens and IDs and what not
const config = {
settings: {
Token: 'BOT TOKEN', //Visit https://discord.com/developers/applications and get your bots token
LicenseKey: 'LICENSE KEY', //Visist https://license.wildfyr.net to get your keys
BotApplicationID: 'BOT USER ID', //Bot's user ID
BotOwnerID: 'USER ID', //Your user ID, used for Owner only commands
GuildID: 'GUILD ID', //The ID for your Server
EmbedColour: '#fc6a03', //The colour you want the side bar of the embeds to be
botActivity: {
status: 'online', //Online, idle, dnd, offline
activity: {
name: 'Whatever you want', //The name of the game the bot is playing
type: 'PLAYING', //Playing, Watching, Streaming, Listening
}
},
deleteCommands: 'TRUE', //Deletes the command after a set ammount of time, reduces chat spam
ShowTriggeredEvents: 'FALSE', //Used for De-Bugging, prints in console everytime someone runs a command
}
}
module.exports = config;
#新Acesyyy
This is what I get after changing that.
commands\ping.js:15
.setColor(config.settings[0].EmbedColour)
^
TypeError: Cannot read properties of undefined (reading 'EmbedColour')
at Command.callback [as _callback] (commands\ping.js:15:38)
at SlashCommands.<anonymous> (node_modules\wokcommands\dist\SlashCommands.js:177:54)
at step (node_modules\wokcommands\dist\SlashCommands.js:44:23)
at Object.next (node_modules\wokcommands\dist\SlashCommands.js:25:53)
at node_modules\wokcommands\dist\SlashCommands.js:19:71
at new Promise (<anonymous>)
at __awaiter (node_modules\wokcommands\dist\SlashCommands.js:15:12)
at SlashCommands.invokeCommand (node_modules\wokcommands\dist\SlashCommands.js:168:16)
at SlashCommands.<anonymous> (node_modules\wokcommands\dist\SlashCommands.js:67:26)
at step (node_modules\wokcommands\dist\SlashCommands.js:44:23)
at Object.next (node_modules\wokcommands\dist\SlashCommands.js:25:53)
at node_modules\wokcommands\dist\SlashCommands.js:19:71
at new Promise (<anonymous>)
at __awaiter (node_modules\wokcommands\dist\SlashCommands.js:15:12)
at WebSocketManager.<anonymous> (node_modules\wokcommands\dist\SlashCommands.js:58:86)
at WebSocketManager.emit (node:events:390:28)

Your error message is showing that you're trying to access config.settings[0].EmbedColour which will return the first index object in the array.
However, it appears that config.settings is the only item in the config object.
config.settings.EmbedColour is the property you want to access.

Maybe Instead of returning the embed, try replying to the interaction
interaction.reply({embeds: [Build]})

Related

Discord.js does not recognise the description of an embed

I've been making a custom bot for a server I'm in, and all was going well until I encountered this runtime error in code that was seemingly working fine. Any tips?
Error:
throw new DiscordAPIError(data, res.status, request);
^
DiscordAPIError: Invalid Form Body
embeds[0].description: This field is required
at RequestHandler.execute (C:\Users\arinb\node_modules\discord.js\src\rest\RequestHandler.js:350:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RequestHandler.push (C:\Users\arinb\node_modules\discord.js\src\rest\RequestHandler.js:51:14)
at async TextChannel.send (C:\Users\arinb\node_modules\discord.js\src\structures\interfaces\TextBasedChannel.js:175:15) {
method: 'post',
path: '/channels/949653134551154718/messages',
code: 50035,
httpStatus: 400,
requestData: {
json: {
content: undefined,
tts: false,
nonce: undefined,
embeds: [
{
title: null,
type: 'rich',
description: null,
url: null,
timestamp: null,
color: null,
fields: [],
thumbnail: null,
image: null,
author: null,
footer: null
}
],
components: undefined,
username: undefined,
avatar_url: undefined,
allowed_mentions: undefined,
flags: undefined,
message_reference: undefined,
attachments: undefined,
sticker_ids: undefined
},
files: []
}
}
code:
client.on('interactionCreate', (interaction) => {
let target = client.channels.cache.get(baseChannel) // gets channel 'general'
let waitTrue = setWaitTime()
if (!waitTrue) {
console.log("sending success message")
await interaction.reply({embeds: [
new MessageEmbed()
.setColor("DARK_BUT_NOT_BLACK")
.setTitle("Current Status")
.setDescription("OFF")
]})
target.send({components: [defaultMessage(serverState)] })
} else {
interaction.reply({embeds : [waitTrue]})
}
}
function setWaitTime() {
state = serverState
let retValue = false
if (state.minecraft.players + state.hlServer.players != 0 ){
retValue = {embeds: [
new MessageEmbed()
.setColor("LUMINOUS_VIVID_PINK")
.setDescription(`People are currently using the ${(state.minecraft.on) ? "minecraft": (state.hlServer.on) ? "TF2" : "ERROR"} server, try again later`)
.setTitle("Queued your selection")
]
}
}
console.log(retValue)
return retValue
I'm not sure why discord.js has not recognised the .setDescription(...) that has been applied to the embed, especially as this function was not changed since it worked...
After executing the setWaitTime() function, the value of the retValue variable is an object with an embed key and the value being the MessageEmbed so when you try to send retValue, what is actually happening is something like this:
interaction.reply({
embeds: {
embeds: {
new MessageEmbed()
// ...
}
}
})
which is why this particular error is happening. So to fix it, instead of sending retValue as the embed property, just send it by itself like this:
interaction.reply(retValue)

Trying to add a warning system to my mongodb, it works but says application didn't respond

const {Client, CommandInteraction, MessageEmbed} = require("discord.js");
const db = require("../../Structures/Schemas/InfractionDB");
module.exports = {
name: "warnings",
description: "Give a warning",
permission: "ADMINISTRATOR",
options: [
{
name: "target",
description: "Select a target.",
type: "USER",
required: true
},
{
name: "reason",
description: "Provide a reason.",
type: "STRING",
required: true
},
{
name: "evidence",
description: "Provide evidence.",
type: "STRING",
required: false
},
],
/**
*
* #param {CommandInteraction} interaction
* #param {Client} client
*/
execute(interaction, client) {
const{guild, member, options} = interaction
const Target = options.getMember("target");
const Reason = options.getString("reason");
const Evidence = options.getString("evidence") || "None provided";
const Response = new MessageEmbed()
.setColor("RED")
.setAuthor({name: "MOD BOT", iconURL: guild.iconURL()});
db.findOne({GuildID: guild.id, UserID: Target.id}, async (err,data)=> {
if(err) throw err;
if(!data || !data.WarnData) {
data = new db({
GuildID: guild.id,
UserID: Target.id,
WarnData: [
{
ExecuterID: member.id,
ExecuterTag: member.user.tag,
TargetID: Target.id,
TargetTag: Target.user.tag,
Reason: Reason,
Evidence: Evidence,
Date: parseInt(interaction.createdTimestamp / 1000)
}
],
})
} else {
const WarnDataObject ={
ExecuterID: member.id,
ExecuterTag: member.user.tag,
TargetID: Target.id,
TargetTag: Target.user.tag,
Reason: Reason,
Evidence: Evidence,
Date: parseInt(interaction.createdTimestamp / 1000)
}
data.WarnData.push(WarnDataObject)
}
data.save()
});
Response.setDescription(`Warning Added: ${Target.user.tag} | ||${Target.id}||\n**Reason**: ${Reason}\n**Evidence**:${Evidence}`);
guild.channels.cache.get("946217387336818699").send({embeds:[Response]});
}}
originally this was routed to a different collection in my db. I've tried to convert it so I can see everything in one place. but it's taken me hours and don't seem to be getting anywhere. Like I said, the data is being stored on the db, but the Response is failing. Any ideas how to fix this? There are no errors in terminal
The error i think is that your application is taking too long to respond.
you have only 3 seconds to respose.
for this i would suggest that you execute you interaction as a async function
and you should use await before trying to find it in the database. because it can take some time to find the data in the database.
The data is store in database because it has no concern with the response time but the discord api wants a reply in 3 seconds or it will fail.
I have read your code. it seems okay.
i would suggest you to use the easier way instead of using the object or json form to create the commands.
SlashCommandBuilder from #discordjs/builders
its easy to use and simple.
here is an example of how easy it is if you use SlashCommandBuilder
const { SlashCommandBuilder } = require('#discordjs/builders');
const data = new SlashCommandBuilder()
.setName('gif')
.setDescription('Sends a random gif!')
.addStringOption(option =>
option.setName('category')
.setDescription('The gif category')
.setRequired(true)
.addChoice('Funny', 'gif_funny')
.addChoice('Meme', 'gif_meme')
.addChoice('Movie', 'gif_movie'));
you can install all the dependencies using
npm install discord.js #discordjs/rest discord-api-types

interaction.options.getMember is not a function

first time posting here. I hope I've posted this correctly, but basically getting the error message "interaction.options.getMember is not a function" I've tried using getUser as well (someone suggested this) and it doesnt seem to fix the problem. I'm pretty new to all this so please go easy on me. as far as I can see everything has been defined correctly and I'm pretty sure the issue is from here somewhere as the rest of the commands work absolutely fine. Any help greatly appreciated!!
const { Client, CommandInteraction, MessageEmbed } = require("discord.js");
module.exports = {
name: "ban",
description: "Bans the target member",
permission: "ADMINISTRATOR",
options: [
{
name: 'target',
description: "Select a target to ban",
type: "USER",
required: true,
},
{
name: 'reason',
description: "Provide a reason for the ban",
type: "STRING",
required: true,
},
{
name: 'messages',
description: "Choose one of the choices",
type: "STRING",
required: true,
choices: [
{
name: "Don't delete any",
value: "0"
},
{
name: "Previous 7 days",
value: "7"
}
]
},
],
/**
*
* #param {Client} client
* #param {CommandInteraction} interaction
*/
execute(client, interaction) {
//ERROR IS LINE BELOW//
const Target = interaction.options.getMember('target');
if (Target.id === interaction.member.id)
return interaction.followUp({embeds: [new MessageEmbed().setColor("RED").setDescription(`⛔ You can't ban yourself.`)]})
if (Target.permissions.has("ADMINISTRATOR"))
return interaction.followUp({embeds: [new MessageEmbed().setColor("RED").setDescription(`⛔ You can't ban an administrator.`)]})
const Reason = interaction.options.getString('reason');
if (Reason.length > 512)
return interaction.followUp({embeds: [new MessageEmbed().setColor("RED").setDescription(`⛔ The reason cannot exceed 512 characters`)]})
const Amount = interaction.options.getString('messages')
Target.ban({days: Amount, reason: Reason})
interaction.followUp({embeds: [new MessageEmbed().setColor("GREEN").setDescription(`✅ **${Target.user.username}** has been banned!`)]})
}
}
According to your code, and per Discord API, you have your member (actually user) here:
name: 'target',
description: "Select a target to ban",
type: "USER",
required: true,
so that line should read
const Target = interaction.options.getUser('target');
You need to get the member by using the below code
const targetMember = interaction.guild.members.cache.find(member => member.id === Target)
The rest needs to change Target to targetMember or simplify with example below:
if (targetMember.permissions.has(Permissions.FLAGS.BAN_MEMBERS) || targetMember.user.bot || targetMember.user.id === interaction.user.id) {
return interaction.reply({
content: 'You are not authorized to ban this member or yourself.',
ephemeral: true
})
I actually managed to fix the issue before I went sleep at 4am. Essentially the problem was actually caused by the execute (client, interaction). In my other file, these parameters are (interaction, client). I also changed all instances of "followUp" with "reply" and it started working as intended.
Thanks for helping out though!

How to put emoji icon into embed thumbnail when emojiCreated

When someone adds an emoji to the server, the bot will log it. I'm trying to make it where it will but the emoji in the thumbnail of the log embed. Whenever it trys to log, I get the error..
[15:55:28] [UTC June:10:2021] [ERROR] (node:11176) UnhandledPromiseRejectionWarning: DiscordAPIError: Invalid Form Body embed.thumbnail.url: Scheme "undefined" is not supported. Scheme must be one of ('http', 'https'). embeds[0].thumbnail.url: Scheme "undefined" is not supported. Scheme must be one of ('http', 'https').
I'm guessing that the code for the thumbnail is returned undefined and you can't put that into a thumbnail. My code is
const Discord = require("discord.js")
exports.run = async(client) => {
client.on("emojiCreate", function(emoji){
console.log(emoji)
const Embedf = new Discord.MessageEmbed()
.setColor("#1CDEA3")
.setTitle('New Emoji Created')
.addFields(
{ name: 'Emoji Name:', value: emoji.name, inline: false },
{ name: 'Emoji ID:', value: emoji.id, inline: false },
{ name: 'Nitro Emote?', value: emoji.animated, inline: false })
.setThumbnail(`${emoji.icon}`)
.setFooter(`${emoji.guild.name}`)
.setTimestamp()
client.channels.cache.find(channel => channel.id == "851987273837969408").send(Embedf)
})
}
How can I fix this? Thanks
A GuildEmoji does not have an icon property.
You may have meant to use the url property.
const Embedf = new Discord.MessageEmbed()
.setColor("#1CDEA3")
.setTitle('New Emoji Created')
.addFields(
{ name: 'Emoji Name:', value: emoji.name, inline: false },
{ name: 'Emoji ID:', value: emoji.id, inline: false },
{ name: 'Nitro Emote?', value: emoji.animated, inline: false })
.setThumbnail(emoji.url) // use URL instead of icon
.setFooter(emoji.guild.name)
.setTimestamp()

On saving entity PrimaryGeneratedColumn value not generated, gives NOT NULL constraint error

Typeorm 0.2.8
I'm building an Ionic app for both mobile use and browser (PWA) use. Below is some shortened code from my project. I create a simple entity with a PrimaryGeneratedColumn and try to insert one instance. This generates an error about the primary column being NULL. Doesn't the word 'generated' mean the column value gets generated?
Is this a bug? Something specific to the sqljs driver? Or something obvious and simple I missed?
Entity
#Entity()
export class MyEntity {
#PrimaryGeneratedColumn()
id:number;
#Column()
name:string;
#CreateDateColumn()
createdAt:string;
}
Migration
export class Migration20181022133900 implements MigrationInterface {
async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.createTable(new Table({
name: 'my_entity',
columns: [
{
name: 'id',
type: 'int',
isPrimary: true,
isGenerated: true
},
{
name: 'name',
type: 'varchar'
},
{
name: 'createdAt',
type: 'timestamp',
'default': 'now()'
}
]
}), true);
}
async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.dropTable('my_entity');
}
}
Database provider
const DATABASE_SHARED_OPTIONS:Partial<ConnectionOptions> = {
entities: [
MyEntity
],
logging: 'all',
logger: new DatabaseLogger(),
migrationsRun: true,
migrations: [
Migration20181022133900
]
};
#Injectable()
export class Database {
constructor(public platform:Platform) {}
setup(): Promise<Connection> {
let options: CordovaConnectionOptions | SqljsConnectionOptions;
// Mobile app
if (this.platform.is('cordova')) {
options = {
type: 'cordova',
database: 'my_project.db',
location: 'default',
};
options = Object.assign(options, DATABASE_SHARED_OPTIONS);
}
// Browser PWA app
else {
options = {
type: 'sqljs',
autoSave: true,
location: 'my_project',
};
options = Object.assign(options, DATABASE_SHARED_OPTIONS);
}
return createConnection(options);
}
}
App component
export class MyApp {
constructor(
platform: Platform,
database: Database
) {
platform.ready().then(() => {
database.setup()
.then((connection) => {
this.insertTest();
});
});
}
insertTest() {
const myEntity= new MyEntity();
myEntity.name = 'foo';
getRepository(MyEntity).save(myEntity)
.then((data) => {
console.log(data); // never reached due to error
});
}
}
The database log show the following query (with parameters ["foo"]):
INSERT INTO "my_entity"("name", "createdAt") VALUES (?, datetime('now'))
The following error shows up in my console:
ERROR Error: Uncaught (in promise): QueryFailedError: NOT NULL constraint failed: my_entity.id
Update 1
It only seems to give the error when using migrations. Removing the migrations and using synchronize: true on the database setting works and generates an id for the entity. So is there something wrong with my column definition in the migration code?
{
name: 'id',
type: 'int',
isPrimary: true,
isGenerated: true
}
Update 2
Okay, I fixed it. The migration configuration for a #PrimaryGeneratedColumn seems to be very specific. For anyone else facing this issue, this fixed it for me:
{
name: 'id',
type: 'integer', // instead of 'int', required for the increment strategy
isPrimary: true,
isGenerated: true,
generationStrategy: 'increment' // thought this was the default
}
Okay, I fixed it. The migration configuration for a #PrimaryGeneratedColumn seems to be very specific. For anyone else facing this issue, this fixed it for me:
{
name: 'id',
type: 'integer', // instead of 'int', required for the increment strategy
isPrimary: true,
isGenerated: true,
generationStrategy: 'increment' // thought this was the default
}

Resources