I am making a tickets bot.
When I try click of any of the embeds, it will run the code and create a new channel, then continue to ping me in it like I wanted, but then shows this error.
DiscordAPIError: Invalid Form Body
components[0].components[1].emoji.name: Invalid emoji
at RequestHandler.execute (C:\Users\wrigh\Documents\Discord Bots\Practice Bot - Copy\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\wrigh\Documents\Discord Bots\Practice Bot - Copy\node_modules\discord.js\src\rest\RequestHandler.js:51:14)
at async TextChannel.send (C:\Users\wrigh\Documents\Discord Bots\Practice Bot - Copy\node_modules\discord.js\src\structures\interfaces\TextBasedChannel.js:175:15)
The full error is here (sorry for link wouldn't let me post full error) :
https://sourceb.in/dOCoUtAQVx
The code is here:
const { ButtonInteraction, MessageEmbed, MessageActionRow, MessageButton } = require("discord.js");
const DB = require("../../Structures/Handlers/Schemas/Ticket");
const { PARENTID, EVERYONEID } = require("../../Structures/config.json");
const Ticket = require("../../Structures/Handlers/Schemas/Ticket");
module.exports = {
name: "interactionCreate",
/**
*
* #param {ButtonInteraction} interaction
*/
async execute(interaction) {
if(!interaction.isButton()) return;
const { guild, member, customId } = interaction;
if (!["player", "bug", "other"].includes(customId)) return;
const ID = Math.floor(Math.random() * 90000) + 10000;
await guild.channels
.create(`${customId + "-" + ID}`, {
type: "GUILD_TEXT",
parent: PARENTID,
permissionOverwrites: [
{
id: member.id,
allow: ["SEND_MESSAGES", "VIEW_CHANNEL", "READ_MESSAGE_HISTORY"],
},
{
id: EVERYONEID,
deny: ["SEND_MESSAGES", "VIEW_CHANNEL", "READ_MESSAGE_HISTORY"],
},
],
})
.then(async (channel) => {
await DB.create({
GuildID: guild.id,
MemberID: member.id,
TicketID: ID,
ChannelID: channel.id,
Closed: false,
Locked: false,
type: customId,
});
const Embed = new MessageEmbed()
.setAuthor(
`${guild.name} | Ticket: ${ID}`,
guild.iconURL({ dynamic: true })
)
.setDescription(
"Please wait patiently for a response from the Staff team, in the mean while, describe your issue in as much detail."
)
.setFooter("The buttons below are staff only buttons.");
const Buttons = new MessageActionRow();
Buttons.addComponents(
new MessageButton()
.setCustomId("close")
.setLabel("Save and close")
.setStyle("PRIMARY")
.setEmoji("📂"),
new MessageButton()
.setCustomId("lock")
.setLabel("lock")
.setStyle("SECONDARY")
.setEmoji("'🔒"),
new MessageButton()
.setCustomId("unlock")
.setLabel("unlock")
.setStyle("SUCCESS")
.setEmoji("❤"),
);
channel.send({
embeds: [Embed],
components: [Buttons],
});
await channel
.send({ content: `${member} here is your ticket` })
.then((m) => {
setTimeout(() => {});
}, 1 * 5000);
})
interaction.reply({
content: `${member} your ticket has been created: ${channel}`,
});
},
};
```js
I'm still learning JavaScript so please bear with me if I don't get it straight away, I will try my best.
You have an extra character in your lock button. It should be .setEmoji("🔒"), not .setEmoji("'🔒"). That's what the error is telling you: "Invalid Emoji" (because '{lock} isn't an emoji)
Related
I am currently coding a bot discord.
I have an error about the buttons. The question has already been asked on the forum, but I haven't found a relevant answer...
When running the first command, everything works fine, when running the second command, this message appears...
==> Here is the code:
const Discord = require('discord.js');
const { MessageActionRow, MessageButton, MessageEmbed } = require('discord.js');
module.exports.run = async (client, message, args) => {
const row = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId('yes')
.setLabel('YES')
.setStyle('SUCCESS'),
new MessageButton()
.setCustomId('no')
.setLabel('NO')
.setStyle('DANGER'),
);
const embed = new MessageEmbed()
.setColor('#0099ff')
.setTitle('Some title')
await message.reply({ embeds: [embed], components: [row] });
client.on('interactionCreate', async interaction => {
if (interaction.customId == 'yes') {
await interaction.reply({ content: 'You click on YES !', ephemeral: true });
};
});
};
module.exports.info = {
names: ['t4', 'test4'],
};
==> Here is the error:
throw new DiscordAPIError(data, res.status, request);
^
DiscordAPIError: Interaction has already been acknowledged.
at RequestHandler.execute (C:\Users\famou\OneDrive\Bureau\RPG Bot\node_modules\discord.js\src\rest\RequestHandler.js:298:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RequestHandler.push (C:\Users\famou\OneDrive\Bureau\RPG Bot\node_modules\discord.js\src\rest\RequestHandler.js:50:14)
at async ButtonInteraction.reply (C:\Users\famou\OneDrive\Bureau\RPG Bot\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:99:5)
at async Client.<anonymous> (C:\Users\famou\OneDrive\Bureau\RPG Bot\commands\test4.js:45:13) {
method: 'post',
path: '/interactions/997619679268970577/aW50ZXJhY3Rpb246OTk3NjE5Njc5MjY4OTcwNTc3OjJsZmhuWlJWaVJYNnJlcnhJNkFtSXhhcEllM2Vhd0VQdVJOYTQwdzF0Y3IyakpGWVh1Vkd1a3BXeHZyc25aTFFOYk9uMVQ2QkNFTGJPQmFaVjdvWG90eTB3V1I3ckR3ZFd3TGd3YjdGejREajBZeGhKUWtRc3F3c3BMdlR2QW1a/callback',
code: 40060,
httpStatus: 400,
requestData: {
json: {
type: 4,
data: {
content: 'Ready! You closed the channel!',
tts: false,
nonce: undefined,
embeds: undefined,
components: undefined,
username: undefined,
avatar_url: undefined,
allowed_mentions: undefined,
flags: 64,
message_reference: undefined,
attachments: undefined,
sticker_ids: undefined
}
},
files: []
}
}
Thanks ^^
You are creating nested listeners. You are creating a listener whenever the command is run, doing no validation at all in the callback, making it take every interaction, even from a different command. A better option is to use collectors.
const msg = await message.reply({ embeds: [embed], components: [row] });
const collector = msg.createMessageComponentCollector({
componentType: "BUTTON",
time: 15_000 // how long you want it to collect for, in ms (this is 15 seconds)
})
collector.on('collect', async interaction => {
if (interaction.customId == 'yes') {
await interaction.reply({ content: 'You click on YES !', ephemeral: true });
};
});
Docs: Message#createMessageComponentCollector()
I am back again with a question :). I am building my own ticket function, and I just started but if I create a channel for a ticket, its only saying ticket-(Discord account ID) And thats also the case by the embed. Anyone who can look at it?
const discord = require("discord.js");
const { MessageEmbed, Collection, Permissions} = require('discord.js');
const { execute } = require("./ticket");
module.exports = {
name: 'create',
description: 'create your own ticket.',
execute(message, client, args){
if(message.guild.channels.cache.find(channel => channel.name === "Ticket from <#" + message.author + ">")) {
message.reply(`${message.member.user.toString()} **You have successfully created a ticket, Please click on ${channel} to view your ticket**`).then(m => m.delete({ timeout: 14000 }).catch(e => {}));
if(message.guild.channels.cache.find(channel => channel.name === `ticket-${message.author.id}`)) {
return message.reply('<a:no:784463793366761532> **You already have a ticket, please close your exsisting ticket first before opening a new one**');
}
message.delete();
message.guild.channels.create(`Ticket ${message.author}`, {
permissionOverwrites: [
{
id: message.author.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: message.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
type: 'text',
}).then(async channel => {
const embed = new MessageEmbed()
.setTitle("<#" + message.author + "> Ticket")
.setDescription(`**${message.author}, Welcome to your channel! Support will be arriving soon**\n**While you wait please tell us what your problem is**\n**If you want to close the ticket please type .close\`**`)
.setColor("BLUE")
channel.send({ embeds: [embed] })
});
}
}
}
I cleaned up the code a fair bit, less is more. Text channels do not have spaces in them so I replaced them with what Discord uses, hypens. The below code will check if a channel already exists and create one if it doesn't.
const {
MessageEmbed,
} = require('discord.js');
module.exports = {
name: 'create',
description: 'create your own ticket.',
async execute(message, client, args) {
const channelName = `ticket-${message.author.username}`
const existing = message.guild.channels.cache.find(channel => channel.name === channelName.toLowerCase());
if (existing) {
return message.reply({
content: `<a:no:784463793366761532> **You already have a ticket, please close your exsisting ticket first before opening a new one**\n${existing}.`,
}).then((m) => {
setTimeout(() => {
m.delete();
}, 14000);
})
}
message.delete();
message.guild.channels.create(channelName, {
type: 'GUILD_TEXT',
permissionOverwrites: [{
id: message.guild.id,
deny: ['VIEW_CHANNEL'],
}, {
id: message.author.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
}],
}).then(async channel => {
const embed = new MessageEmbed()
.setColor("BLUE")
.setTitle(`${message.author.username} Ticket`)
.setDescription(`**${message.author}, Welcome to your channel! Support will be arriving soon**\n**While you wait please tell us what your problem is**\n**If you want to close the ticket please type .close\`**`)
channel.send({
embeds: [embed]
})
});
}
}
When a person sends my command, a channel is created that only they have access to. Also, when creating a channel, a message is sent with the "accept" button, when another person clicks on the button, his rights in the created channel should be added. I can add rights, but when more than one message with a button arrives in a special channel, the person who clicked the button is added to all created channels
An example of how it works
let myreportChannel = ''
await interaction.guild.channels.create(channelNameMy, {
type: 'text', parent: `${categoryTiket}`, permissionOverwrites: [
{
id: `${permUser}`, // permUser - who sent the command
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY', 'ATTACH_FILES']
},
{
id: `${evryOneRolle}`,
deny: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY']
},
]
})
//Prvivate embed
.then(async reportChannel => {
const exampleEmbed = new MessageEmbed()
.setDescription(`Reported: <#${tagBan.id}>\nReason: ${reason}\ntiket: <#${reportChannel.id}>`)
.setColor("#2F3136")
.setImage(`${settings.reportgif}`)
myreportChannel = reportChannel.id // save new channel id
await interaction.reply({embeds: [exampleEmbed], ephemeral: true})
//Report embed
const reportEmbed = new MessageEmbed()
.setDescription(`Intruder: ${tagBan}\nReason: ${reason}`)
.setColor("#2F3136")
.setImage(`${settings.reportgif}`)
await client.channels.cache.get(`${reportChannel.id}`).send({
embeds: [reportEmbed]
})
})
client.on('interactionCreate', async interaction => {
if (interaction.isButton()) {
if (interaction.customId.includes(`acceptB`)) {
const editEmbRep = new MessageEmbed()
.setDescription(`Author: <#${interaction.user.id}>\nIntruder: <#${tagBan.id}>\nStatus: ${dmStatusAc}\nTiket: <#${myreportChannel}>`)
.setColor("#2F3136")
.setImage(`${settings.reportgif}`)
interaction.message.edit({
content: 'updated text',
embeds: [editEmbRep],
components: []
})
let channelx = interaction.guild.channels.cache.get(myreportChannel) // set channel by id
if (channelx) {
channelx.permissionOverwrites.edit(interaction.user.id, {
VIEW_CHANNEL: true,
SEND_MESSAGES: true,
ATTACH_FILES: true,
READ_MESSAGE_HISTORY: true
}) //edit permision channel. add the permission of the user who clicked on the "accept" button
}
So I adjusted the code above and made some notes along the way, but this should work as expected. I split the command from the button push.
const reportChannel = await interaction.guild.channels.create(channelNameMy, {
type: 'text',
parent: `${categoryTiket}`,
permissionOverwrites: [{
id: `${permUser}`, // permUser - who sent the command
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY', 'ATTACH_FILES']
},
{
id: `${evryOneRolle}`,
deny: ['VIEW_CHANNEL'] //denying view channel will stop all other ones from working too
},
]
})
//Prvivate embed
const exampleEmbed = new MessageEmbed()
.setDescription(`Reported: <#${tagBan.id}>\nReason: ${reason}\nticket: <#${reportChannel.id}>`)
.setColor("#2F3136")
.setImage(`${settings.reportgif}`)
interaction.reply({
embeds: [exampleEmbed],
ephemeral: true
})
//Report embed
const reportEmbed = new MessageEmbed()
.setDescription(`Intruder: ${tagBan}\nReason: ${reason}\nticket:<#${reportChannel.id}>`)
.setColor("#2F3136")
.setImage(`${settings.reportgif}`)
.setFooter({
text: `${reportChannel.id}` // I added the channel ID here again (critical part of the code to not change
})
// adds the new channel id to the footer to be used later when someone clicks the accept button
const acceptButton = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId(`acceptB`)
.setLabel('Accept')
.setStyle('SUCCESS')
.setEmoji('✅')
)
client.channels.cache.get(reportChannel.id).send({
embeds: [reportEmbed],
components: [acceptButton]
})
client.on('interactionCreate', async interaction => {
if (interaction.isButton()) {
if (interaction.customId.includes(`acceptB`)) {
// when someone clicks the accept button it grabs the embed
const oldEmbed = interaction.message.embeds[0]
// adds a line to that embed
const editEmbRep = new MessageEmbed()
.addField('Status:', `${dmStatusAc}`)
// updates the embed and removes the button
interaction.message.edit({
embeds: [editEmbRep],
components: []
})
// finds the channel using the channel id placed in the footer earlier
const channelx = interaction.guild.channels.cache.get(oldEmbed.footer.text)
channelx.permissionOverwrites.edit(interaction.user.id, {
VIEW_CHANNEL: true,
SEND_MESSAGES: true,
ATTACH_FILES: true,
READ_MESSAGE_HISTORY: true
}) // adds them to the channel
}
}
})
I need some help please,
When I click on the button Submit, it doesn't do what I want it to, it doesn't show up with any errors, and the bot doesn't crash so I'm not sure how to fix it.
This has never happened to me before so I'm just wondering I'm someone could point me in the right direction.
Suggest.js :
const { ButtonInteraction, MessageEmbed } = require("discord.js");
const DB = require('../Structures/Handlers/Schemas/SuggestDB');
const { APPLICATIONID } = require("../Structures/config.json")
const Embed1 = require('../Commands/Suggest/suggestion');
module.exports = {
name: "interactionCreate",
/**
*
* #param {ButtonInteraction} interaction
*/
async execute(interaction) {
if(!interaction.isButton()) return;
const { guildId, customId, message } = interaction;
DB.findOne({GuildID: guildId, MessageID: message.id}, async(err, data) => {
if(err) throw err;
if(!data) return interaction.reply({content: "No data was found in the database", ephemeral: true});
const Embed = message.embeds[0];
if(!Embed) return;
switch(customId) {
case "Submit" : {
await guild.channels.cache
.get(APPLICATIONID)
.send({ embeds: [Embed1] });
}
}
})
}
}
Suggestion.js
const { CommandInteraction, MessageEmbed, MessageActionRow, MessageButton, ButtonInteraction }
= require("discord.js");
const DB = require("../../Structures/Handlers/Schemas/SuggestDB");
module.exports = {
name:"suggest",
description: "Suggest",
options: [
{
name: "suggestion",
description: "Describe your suggestion",
type: "STRING",
required: true
}
],
/**
*
* #param {CommandInteraction} interaction
* #param {ButtonInteraction} interaction1
*/
async execute(interaction) {
const { options, guildId, member, user } = interaction;
const Suggestion = options.getString("suggestion");
const Embed1 = new MessageEmbed()
.setColor("AQUA")
.setAuthor(user.tag, user.displayAvatarURL({dynamic: true}))
.addFields(
{name: "Suggestion", value: Suggestion, inline: false}
)
.setTimestamp()
const row = new MessageActionRow();
row.addComponents(
new MessageButton()
.setCustomId("Submit")
.setLabel("Submit")
.setStyle("PRIMARY")
.setEmoji("📩"),
)
try {
const M = await interaction.reply({embeds: [Embed1], components: [row], fetchReply: true});
await DB.create({GuildID: guildId, MessageID: M.id, Details: [
{
MemberID: member.id,
Suggestion: Suggestion
}
]})
} catch (err) {
console.log(err)
}
},
};
Any help is appreciated.
If you need any more information / code files, just reply and I'll will add it straight away.
Hi can someone help me I have this error when I run my command lyrics: DiscordAPIError: Cannot send an empty message
(it's a music bot that uses a command handler)
you can contact me on discord : R Λ Z#9217
const { MessageEmbed } = require("discord.js");
const lyricsFinder = require("lyrics-finder");
module.exports = {
name: "lyrics",
aliases: ['ly'],
category: "Music",
description: "View the lyrics of a song",
args: false,
usage: "",
permission: [],
owner: false,
player: true,
inVoiceChannel: true,
sameVoiceChannel: true,
execute: async (message, args, client, prefix) => {
const player = message.client.manager.get(message.guild.id);
if (!player.queue.current) {
let thing = new MessageEmbed()
.setColor("RED")
.setDescription("There is no music playing.");
return message.channel.send(thing);
}
let lyrics = null;
const title = player.queue.current
try {
lyrics = await lyricsFinder(player.queue.current.title, "");
if (!lyrics) lyrics = `No lyrics found for ${title}.`, { title: title }
} catch (error) {
lyrics = `No lyrics found for ${title}.`, { title: title }
}
let lyricsEmbed = new MessageEmbed()
.setTitle(`${title} - Lyrics`, { title: title })
.setDescription(`${lyrics}`)
.setColor("#F8AA2A")
.setTimestamp();
if (lyricsEmbed.description.length >= 2048)
lyricsEmbed.description = `${lyricsEmbed.description.substr(0, 2045)}...`;
return message.channel.send(lyricsEmbed).catch(console.error);
}
};
Updating to v13 will cause a lot of errors because of breaking changes!
You can find them all listed in the guide right here.
But in your case, it was about how Discord.js handles parameters with the channel.send().
- channel.send(embed);
+ channel.send({ embeds: [embed, embed2] });
- channel.send('Hello!', { embed });
+ channel.send({ content: 'Hello!', embeds: [embed, embed2] });