"This interaction failed"
I'm trying to make buttons with discord.js, everything is good and the buttons work well, but even though it gives the error message "This interaction failed".
(This is the code)
Everyone talk about the "defer", and I don't understand.
I hope for some help :)
interactionCreate.js:
let hastebin = require('hastebin');
module.exports = {
name: 'interactionCreate',
async execute(interaction, client) {
if (!interaction.isButton()) return;
if (interaction.customId == "open-ticket") {
if (client.guilds.cache.get(interaction.guildId).channels.cache.find(c => c.topic == interaction.user.id)) {
return interaction.reply({
content: 'you have already a Ticket created!',
ephemeral: true
});
};
interaction.guild.channels.create(`ticket-${interaction.user.username}`, {
parent: client.config.parentOpened,
topic: interaction.user.id,
permissionOverwrites: [{
id: interaction.user.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL', 'READ_MESSAGE_HISTORY'],
},
{
id: client.config.roleSupport,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL', 'READ_MESSAGE_HISTORY'],
},
{
id: interaction.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
type: 'text',
}).then(async c => {
interaction.reply({
content: `Ticket has ben created! <#${c.id}>`,
ephemeral: true
});
const embed = new client.discord.MessageEmbed()
.setColor('ff9600')
.setAuthor('Reason', ' ')
.setDescription('choose a reason why you open a ticket')
.setFooter('Ticket System', ' ')
.setTimestamp();
const row = new client.discord.MessageActionRow()
.addComponents(
new client.discord.MessageSelectMenu()
.setCustomId('category')
.setPlaceholder('choose a reason why you open a ticket')
.addOptions([{
label: 'Apply',
value: 'Apply',
emoji: { name: 'π' }
},
{
label: 'Support',
value: 'Support',
emoji: { name: 'β' }
},
{
label: 'Complaint',
value: 'Complaint',
emoji: { name: 'π‘' }
},
{
label: 'Hosting',
value: 'Hosting',
emoji: { name: 'π' }
},
{
label: 'Partnership',
value: 'Partnership',
emoji: { name: 'π₯' }
},
]),
);
msg = await c.send({
content: `<#!${interaction.user.id}>`,
embeds: [embed],
components: [row]
});
const collector = msg.createMessageComponentCollector({
componentType: 'SELECT_MENU',
time: 20000
});
collector.on('collect', i => {
if (i.user.id === interaction.user.id) {
if (msg.deletable) {
msg.delete().then(async () => {
const embed = new client.discord.MessageEmbed()
.setColor('ff9600')
.setAuthor('Ticket', ' ')
.setDescription(`<#!${interaction.user.id}> has create a **Ticket** with the reasonγ» ${i.values[0]}`)
.setFooter('Ticket System', ' ')
.setTimestamp();
const row = new client.discord.MessageActionRow()
.addComponents(
new client.discord.MessageButton()
.setCustomId('close-ticket')
.setLabel('close ticket')
.setEmoji('899745362137477181')
.setStyle('DANGER'),
);
const opened = await c.send({
content: `<#&${client.config.roleSupport}>`,
embeds: [embed],
components: [row]
});
opened.pin().then(() => {
opened.channel.bulkDelete(1);
});
});
};
if (i.values[0] == 'Apply') {
c.edit({
parent: client.config.parentApply
});
};
if (i.values[0] == 'Support') {
c.edit({
parent: client.config.parentSupport
});
};
if (i.values[0] == 'Complaint') {
c.edit({
parent: client.config.parentComplaint
});
};
if (i.values[0] == 'Hosting') {
c.edit({
parent: client.config.parentHosting
});
};
if (i.values[0] == 'Partnership') {
c.edit({
parent: client.config.parentPartnership
});
};
};
});
collector.on('end', collected => {
if (collected.size < 1) {
c.send(`There was no reason, the ticket will be closed.`).then(() => {
setTimeout(() => {
if (c.deletable) {
c.delete();
};
}, 5000);
});
};
});
});
};
if (interaction.customId == "close-ticket") {
const guild = client.guilds.cache.get(interaction.guildId);
const chan = guild.channels.cache.get(interaction.channelId);
const row = new client.discord.MessageActionRow()
.addComponents(
new client.discord.MessageButton()
.setCustomId('confirm-close')
.setLabel('Ticket close')
.setStyle('DANGER'),
new client.discord.MessageButton()
.setCustomId('no')
.setLabel('close cancel')
.setStyle('SECONDARY'),
);
const verif = await interaction.reply({
content: 'Are you sure you want to close the ticket?',
components: [row]
});
const collector = interaction.channel.createMessageComponentCollector({
componentType: 'BUTTON',
time: 10000
});
collector.on('collect', i => {
if (i.customId == 'confirm-close') {
interaction.editReply({
content: `The ticket has been closed by <#!${interaction.user.id}>`,
components: []
});
chan.edit({
name: `closed-${chan.name}`,
permissionOverwrites: [
{
id: client.users.cache.get(chan.topic),
deny: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: client.config.roleSupport,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: interaction.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
})
.then(async () => {
const embed = new client.discord.MessageEmbed()
.setColor('ff9600')
.setAuthor('Ticket', ' ')
.setDescription('```Ticket saving```')
.setFooter('Ticket System', ' ')
.setTimestamp();
const row = new client.discord.MessageActionRow()
.addComponents(
new client.discord.MessageButton()
.setCustomId('delete-ticket')
.setLabel('Ticket delete')
.setEmoji('ποΈ')
.setStyle('DANGER'),
);
chan.send({
embeds: [embed],
components: [row]
});
});
collector.stop();
};
if (i.customId == 'no') {
interaction.editReply({
content: 'Close ticket cancelled!',
components: []
});
collector.stop();
};
});
collector.on('end', (i) => {
if (i.size < 1) {
interaction.editReply({
content: 'Ticket closure cancelled!',
components: []
});
};
});
};
if (interaction.customId == "delete-ticket") {
const guild = client.guilds.cache.get(interaction.guildId);
const chan = guild.channels.cache.get(interaction.channelId);
interaction.reply({
content: 'ticket saving...'
});
chan.messages.fetch().then(async (messages) => {
let a = messages.filter(m => m.author.bot !== true).map(m =>
`${new Date(m.createdTimestamp).toLocaleString('de-DE')} - ${m.author.username}#${m.author.discriminator}: ${m.attachments.size > 0 ? m.attachments.first().proxyURL : m.content}`
).reverse().join('\n');
if (a.length < 1) a = "It was not written in the ticket"
hastebin.createPaste(a, {
contentType: 'text/plain',
server: 'https://www.toptal.com/developers/hastebin/documents'
}, {})
.then(function (urlToPaste) {
const embed = new client.discord.MessageEmbed()
.setAuthor('Logs Ticket', ' ')
.setDescription(`π° Ticket-Logs \`${chan.id}\` created by <#!${chan.topic}> and deleted by <#!${interaction.user.id}>\n\nLogs: [**Click here to see the logs**](${urlToPaste})`)
.setColor('2f3136')
.setTimestamp();
const embed2 = new client.discord.MessageEmbed()
.setAuthor('Logs Ticket', ' ')
.setDescription(`π° Logs of your ticket \`${chan.id}\`: [**Click here to see the logsn**](${urlToPaste})`)
.setColor('2f3136')
.setTimestamp();
client.channels.cache.get(client.config.logsTicket).send({
embeds: [embed]
});
client.users.cache.get(chan.topic).send({
embeds: [embed2]
}).catch(() => {console.log('I cant send it DM')});
chan.send('Delete channel.');
setTimeout(() => {
chan.delete();
}, 5000);
});
});
};
},
}; ```
Try adding i.deferUpdate(); in your collector.
collector.on('collect', i => {
i.deferUpdate();
// code here
})
Related
hi please i need some help the bot is giving an error which is yourid , productownerid , productname is not defined in last steps i tried many codes but no one worked for me if anyone can help me please and thank you
if(interaction.customId == 'evv'){
let yourid = interaction.fields.getTextInputValue('ask_1')
let productownerid = interaction.fields.getTextInputValue('ask_2')
let productname = interaction.fields.getTextInputValue('ask_3')
let evalmsg = interaction.fields.getTextInputValue('ask_4')
const exampleEmbed = new MessageEmbed()
.setColor("RANDOM")
.setFields(
{ name: '**Buyer-Name**', value: `<#${yourid}>`}
{ name: '**Owner Of The Product**', value:`**<#${productownerid}>**`}
{ name: '**Product**', value:`**${productname}**`}
{ name: '**Message**', value: `**${evalmsg}**`}
)
.setFooter(`Requested By ${interaction.user.tag} , ${new Date()}`)
let button25 = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId('1')
.setLabel("ΨͺΩΩΩΩ
")
.setStyle('PRIMARY')
.setEmoji("π")
)
await interaction.guild.channels.cache.get("1048414164932108289").send({embeds: [exampleEmbed],components:[button25]})
}
the error is from here :
if (interaction.customId == '1'){
const exampleEmbed2 = new MessageEmbed()
.setColor("RANDOM")
.setFields(
{ name: '**Buyer-Name**', value: `<#${yourid}>`}
{ name: '**Owner Of The Product**', value:`**<#${productownerid}>**`}
{ name: '**Product**', value:`**${productname}**`}
{ name: '**Message**', value: `**${evalmsg}**`}
{ name: '**Evaluation**', value: `**π**`}
)
.setFooter(`Requested By ${interaction.user.tag} , ${new Date()}`)
interaction.guild.channels.cache.get("1048414164932108289").send({embeds: [exampleEmbed2],components:[]})
}
})```
Instead of using <#${yourid}>, you can use userMention(yourid) but i don't think it's the problem.
I think the probleme is the .setFooter for the date you don't have to do ${new Date()} there is a command for this : .setTimestamp().
Or another problem you can't put "RANDOM" in .setColor
And I use new EmbedBuilder() instead of messageEmbed()
You also have to put "," at the end of a field like this :
.setFields(
{ name: '**Buyer-Name**', value: `<#${yourid}>`},
{ name: '**Owner Of The Product**', value:`**<#${productownerid}>**`},
{ name: '**Product**', value:`**${productname}**`},
{ name: '**Message**', value: `**${evalmsg}**`},
{ name: '**Evaluation**', value: `**π**`},
)
You also have to set a Title with .setTitle('title')
The last error i saw is for search a channel I use interaction.guild.channels.fetch('id')
So i propose you this correction :
if (interaction.customId == '1'){
const exampleEmbed2 = new EmbedBuilder()
.setTitle('title')
.setColor(15548997)
.addFields(
{ name: '**Buyer-Name**', value: userMention(yourid)},
{ name: '**Owner Of The Product**', value: '**' + userMention(productownerid) + '**'},
{ name: '**Product**', value:`**${productname}**`},
{ name: '**Message**', value: `**${evalmsg}**`},
{ name: '**Evaluation**', value: `**π**`},
)
.setFooter(`Requested By ${interaction.user.tag}`)
.setTimestamp()
interaction.guild.channels.fetch("1048414164932108289").send({embeds: [exampleEmbed2]})
}
exports.run = async (client, message, args) => {
let data = await cs.leaderboard(message.guild.id);
if (data.length < 1) return message.reply("Nobody's in leaderboard yet.");
const msg = new Discord.MessageEmbed();
let pos = 0;
// This is to get First 10 Users )
data.slice(0, 10).map(e => {
if (!client.users.cache.get(e.userID)) return;
pos++
msg.setColor('#0099ff')
msg.setTitle('Leaderboard')
msg.setAuthor({ name: 'Arkbuddies UK', iconURL: 'https://i.imgur.com/yHgaVv2.png', url: 'https://discord.js.org' })
msg.setThumbnail('https://i.imgur.com/yHgaVv2.png')
msg.addFields(
{ name: `${pos}\u200B\n`, value: `**${client.users.cache.get(e.userID).username}**`, inline: true },
{ name: `Wallet:`, value: `**${e.wallet}** <:Wishbone:939942552809902150>'s`, inline: true },
{ name: `Bank:`, value: `**${e.bank}** <:Wishbone:939942552809902150>'s`, inline: true},
)
msg.setTimestamp()
msg.setFooter({ text: 'Arkbuddies UK', iconURL: 'https://i.imgur.com/yHgaVv2.png' });
});
message.reply({
embeds: [msg]
}).catch();
}
exports.help = {
name: "leaderboard",
data: {
name: 'leaderboard',
description: "show's guild leaderboard.",
options: []
}
}
exports.conf = {
aliases: ["lb"],
cooldown: 5
}
I have an issue with discord.js slash commands.
As you can see in my code I am setting the name to "Name" and "Age" so I don't understand what the issues are.
This is my error:
error: (node:16004) UnhandledPromiseRejectionWarning: DiscordAPIError: Invalid Form Body
options[0].name: Command name is invalid
And this is my code:
const Discord = require('discord.js');
require("dotenv").config();
const client = new Discord.Client();
client.on('ready', async () => {
console.log(`Logged in as ${client.user.tag}!`);
const getApp = (guildid) => {
const app = client.api.applications(client.user.id);
if(guildid){
app.guilds(guildid);
}
return app;
}
await getApp("842486032842358784").commands.post({
data: {
name: 'embed',
description: 'Displays embed',
options: [
{
name: 'Name',
description: 'Your Name',
required: true,
type: 3
},
{
name: 'Age',
description: 'Your Age',
required: false,
type: 4
}
]
},
})
client.ws.on('INTERACTION_CREATE', async(interaction) => {
const command = interaction.data.name.toLowerCase();
const { name, options } = interaction.data;
console.log(options);
if(command === "embed"){
reply(interaction, 'hi');
}
})
const reply = (interaction, response) => {
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: response,
}
}
})
}
});
client.login(process.env.TOKEN);
The option names should be all lowercased, in your case, substitute "Name" with "name" and "Age" with "age". That should work. The code is below:
const Discord = require('discord.js');
require("dotenv").config();
const client = new Discord.Client();
client.on('ready', async() => {
console.log(`Logged in as ${client.user.tag}!`);
const getApp = (guildid) => {
const app = client.api.applications(client.user.id);
if (guildid) {
app.guilds(guildid);
}
return app;
}
await getApp("842486032842358784").commands.post({
data: {
name: 'embed',
description: 'Displays embed',
options: [{
name: 'name',
description: 'Your Name',
required: true,
type: 3
},
{
name: 'age',
description: 'Your Age',
required: false,
type: 4
}
]
},
})
client.ws.on('INTERACTION_CREATE', async(interaction) => {
const command = interaction.data.name.toLowerCase();
const {
name,
options
} = interaction.data;
console.log(options);
if (command === "embed") {
reply(interaction, 'hi');
}
})
const reply = (interaction, response) => {
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: response,
}
}
})
}
});
client.login(process.env.TOKEN);
I have a MongoDB model:
const userSchema = new Schema = ({
name: { type: String },
company: [
companyId: {
type: String,
},
movies: [
{
genre: {
type: String,
enum: [
'horror',
'comedy',
'action',
'romance',
],
},
ratings: { type: String }
},
]
],
})
In my query, I have an endpoint that pushes a genre to the movies array but I want to check if there is an existing genre with the name already, if it exists, I want to show a message that says it already exists, otherwise, push the new items to the movies array
const result = await UserProfile.updateOne(
{
_id: id,
'company.companyId{ $eq: req.params.companyId},
'company.movies.$.genre': {
$eq: { genre: req.body.genre},
},
}
},
{
$push: {
'company.$.movies': {
...model,
},
},
},
{ new: true, runValidators: true }
).catch((err) => handleErrorThrow(err));
if (result.nModified === 0)
throw new CustomError(409, 'Movie exists already');
And if I want to remove the array based on another endpoint, I tried the same thing it doesn't work
const result = await UserProfile.updateOne(
{
_id: id
}
},
{
$pull: {
company: {
$elemMatch: {
companyId: req.params.companyId,
"movies.genre": {
$ne: req.body.genre
}
}
}
},
{ new: true, runValidators: true }
)
.catch((err) => handleErrorThrow(err));
if (result.nModified === 0)
throw new CustomError(409, 'Not exist');
It returned Not exist'
use $elemMatch for nested array condition, and $ne for genre should not exists before push into movies,
const result = await UserProfile.updateOne(
{
_id: id,
company: {
$elemMatch: {
companyId: req.params.companyId,
"movies.genre": {
$ne: req.body.genre
}
}
}
},
{
$push: {
"company.$.movies": model
}
},
{ runValidators: true }
)
.catch((err) => handleErrorThrow(err));
if (result.nModified === 0) {
throw new CustomError(409, 'Movie exists already');
}
And if I want to remove the array based on another endpoint
const result = await UserProfile.updateOne(
{
_id: id,
company: {
$elemMatch: {
companyId: req.params.companyId,
"movies.genre": req.body.genre
}
}
},
{
$pull: {
"company.$.movies": {
genre: req.body.genre
}
}
},
{ runValidators: true }
).catch((err) => handleErrorThrow(err));
if (result.nModified === 0) {
throw new CustomError(409, 'Not exist');
}
I'm looping an array of objects taken from MongoDB and attempting to insert a property into one of them, without success.
The array of objects would be:
[
{
_id: [String],
customerInformation: [ [Object] ],
purchasedBanners: [ [Object] ],
statusOfPurchase: 'new',
createdAt: 2021-02-24T15:04:42.074Z,
updatedAt: 2021-02-24T15:04:42.074Z,
__v: 0
}
...
]
I've tried:
return PurchasesModel.schemaForPurchases.find({
statusOfPurchase: args.statusOfPurchase
})
.limit(10)
.then(purchases => {
purchases.forEach(purchase => {
NotesModel.schemaForNotes.countDocuments({ purchaseId: purchase._id })
.then(numberOfNotes => {
Object.defineProperty(purchase, 'numberOfNotes', {
value: numberOfNotes
})
})
})
return purchases
})
But then I found that the forEach method is synchronous, so I tried:
return PurchasesModel.schemaForPurchases.find({
statusOfPurchase: args.statusOfPurchase
})
.limit(10)
.then(purchases => {
for (let i = 0; i < purchases.length; i++) {
let numberOfNotes = 0
numberOfNotes = NotesModel.schemaForNotes.countDocuments({ purchaseId: purchases[i]._id })
.then(numberOfNotes => {
return numberOfNotes
})
Object.defineProperty(purchases[i], 'numberOfNotes', {
value: numberOfNotes.then(numberOfNotes => {
return numberOfNotes
})
})
}
return purchases
})
In each case (including several other approaches), the objects aren't appended.
I'm new to MongoDB, so I assume I'm either doing something wrong, or perhaps the objects are somehow protected?
Thoughts welcome.
In the end, there wasn't a shortcut! Or at least I'm not aware of it.
const GET_ALL_PURCHASES_QUERY = (statusOfPurchase) => {
return gql`
query {
getAllPurchases(statusOfPurchase: "${statusOfPurchase}") {
id
customerInformation {
customerName
customerEmailAddress
}
purchasedBanners {
nameOfBanner
costOfBanner
numberOfBannersToPrint
nameOfChosenComponent
targetPDF
previewImage
dataToExport
}
numberOfNotes {
count
}
createdAt
updatedAt
}
}
... and then:
const NotesCountForPurchaseType = new GraphQLObjectType({
name: 'NotesCountForPurchase',
fields: () => ({
count: {
type: GraphQLInt
}
})
})
const PurchaseType = new GraphQLObjectType({
name: 'Purchase',
fields: () => ({
id: {
type: GraphQLID
},
customerInformation: {
type: GraphQLList(PurchaseCustomerInformationType)
},
purchasedBanners: {
type: GraphQLList(PurchaseBannerType)
},
statusOfPurchase: {
type: GraphQLString
},
createdAt: {
type: GraphQLDateTime
},
updatedAt: {
type: GraphQLDateTime
},
numberOfNotes: {
type: NotesCountForPurchaseType,
resolve(parent, args) {
return NotesModel.schemaForNotes.countDocuments({
purchaseId: parent.id
})
.then(numberOfNotes => {
console.log('Schema:numberOfNotes()', numberOfNotes)
return { count: numberOfNotes }
})
}
}
})
})
Extra work, but working.