Discord.js v14 - DiscordAPIError [40060]:交互已被确认

问题描述 投票:0回答:0

我正在尝试在我的 discord 机器人上实施票务系统,我不明白为什么当我去点击票务开放表情符号时,我得到以下信息: 这是我在 discord.js v14 中的代码。他存储在:../Clippy/events/buttonResponse.js

const { ChannelType, PermissionFlagsBits, ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, AttachmentBuilder, Attachment } = require('discord.js');
const fs = require('fs');

module.exports = {
    name: 'interactionCreate',
    once: false,

    async execute(interaction, client) {
        if (!interaction.isButton()) return;
        const button = interaction.customId;

        if (button === 'open-ticket') {
            await interaction.deferReply({ ephemeral: true });
            const ticketData = JSON.parse(fs.readFileSync('../Clippy/ticket.json', 'utf-8')); // Leggi i dati dal file.
            const supportRole = interaction.guild.roles.cache.get(ticketData.supportRoleID); // Ottieni il ruolo di supporto dai dati.
            const openCategory = interaction.guild.channels.cache.get(ticketData.openCategoryID); // Ottieni la categoria di apertura dai dati.
            const closeCategory = interaction.guild.channels.cache.get(ticketData.closeCategoryID); // Ottieni la categoria di chiusura dai dati.
            if (!supportRole) return interaction.editReply({ embeds: [client.config.embeds.E('Il ruolo di supporto non esiste!')] });
            if (!openCategory) return interaction.editReply({ embeds: [client.config.embeds.E('La categoria di apertura non esiste!')] });
            if (!closeCategory) return interaction.editReply({ embeds: [client.config.embeds.E('La categoria di chiusura non esiste!')] });
        
        const createdChannel = await interaction.guild.channels.create({
            name: `ticket-${interaction.user.username}`,
            type: ChannelType.GuildText,
            parent: openCategory,
            permissionOverwrites: [
                {
                    id: interaction.guild.id,
                    deny: PermissionFlagsBits.ViewChannel // Negare il permesso di visualizzazione del canale a tutti i ruoli.
                },
                {
                    id: interaction.user.id,
                    allow: PermissionFlagsBits.ViewChannel // Consentire il permesso di visualizzazione del canale all'utente che ha fatto clic sul pulsante.
                },
                {
                    id: supportRole.id,
                    allow: PermissionFlagsBits.ViewChannel // Consentire il permesso di visualizzazione del canale al ruolo di supporto.
                }
            ],
            topic: `🎫 Ticket creato da ${interaction.user.tag}! - ${interaction.user.id}` // Impostare il topic del canale.
        });
        
            const createdEmbed = new EmbedBuilder()
                .setTitle('🎫 Ticket System')
                .setDescription(`Ciao ${interaction.user}👋, benvenuto nel tuo ticket!\nPerfavore spiega dettagliatamente il tuo problema.\n <@&${supportRole.id}> ti risponderò a breve!`)
                .setColor(client.config.colors.info)
                .setTimestamp();

            const createdRow = new ActionRowBuilder()
                .addComponents(
                    new ButtonBuilder()
                        .setCustomId('close-ticket')
                        .setLabel('Chiudi Ticket')
                        .setStyle(ButtonStyle.Danger)
                );

            await createdChannel.send({ embeds: [createdEmbed], components: [createdRow] });
            await interaction.editReply({ embeds: [client.config.embeds.S(`Il tuo ticket è stato creato! ${createdChannel}`)] }); 
        } else if (button === 'close-ticket') {
            const ticketEmbed = new EmbedBuilder()
                .setTitle('🎫 Ticket System')
                .setDescription(`Stai per chiudere il tuo ticket!\nSicuro di voler procedere?`)
                .setColor(client.config.colors.error)
                .setTimestamp();

            const ticketRow = new ActionRowBuilder()
                .addComponents(
                    new ButtonBuilder()
                        .setCustomId('confirm-close-ticket')
                        .setLabel('Conferma chiusura Ticket')
                        .setStyle(ButtonStyle.Danger),
                    new ButtonBuilder()
                        .setCustomId('cancel-close-ticket')
                        .setLabel('Annulla chiusura Ticket')
                        .setStyle(ButtonStyle.Success)
                );

            await interaction.reply({ embeds: [ticketEmbed], components: [ticketRow], ephemeral: true });
        } else if (button === 'confirm-close-ticket') {
            const ticketData = JSON.parse(fs.readFileSync('ticket.json', 'utf-8')); // Read the data from the file.

            const closeCategory = interaction.guild.channels.cache.get(ticketData.closeCategoryID); // Get the close category from the data.

            if (!closeCategory) return interaction.editReply({ embeds: [client.config.embeds.E('La categoria chiusa non esiste!')] });

            const closedRow = new ActionRowBuilder()
                .addComponents(
                    new ButtonBuilder()
                        .setCustomId('delete-ticket')
                        .setLabel('Elimina Ticket')
                        .setStyle(ButtonStyle.Danger),
                    new ButtonBuilder()
                        .setCustomId('reopen-ticket')
                        .setLabel('Riapri Ticket')
                        .setStyle(ButtonStyle.Success),
                    new ButtonBuilder()
                        .setCustomId('transcript-ticket')
                        .setLabel('Trascrivi Ticket')
                        .setStyle(ButtonStyle.Primary)
                );

            await interaction.update({ embeds: [client.config.embeds.S('Il tuo ticket è stato chiuso!')], components: [] });

            await interaction.channel.send({ embeds: [client.config.embeds.S(`\🎫 : ${interaction.user} ha chiuso questo ticket!`)], components: [closedRow] }); 
            
            // Change the parent of the channel.
            await interaction.channel.setParent(closeCategory);
        } else if (button === 'cancel-close-ticket') {
            await interaction.update({ embeds: [client.config.embeds.S('Il tuo ticket non è stato chiuso!')], components: [] });
        } else if (button === 'delete-ticket') {
            await interaction.reply({ embeds: [client.config.embeds.S(`Ticket eliminato! \`${interaction.channel.name}\` Questo canale verrà eliminato tra 5 secondi!`)], ephemeral: true });
            setTimeout(() => interaction.channel.delete(), 5000);
        } else if (button === 'reopen-ticket') {
            const ticketData = JSON.parse(fs.readFileSync('ticket.json', 'utf-8')); // Read the data from the file.

            const openCategory = interaction.guild.channels.cache.get(ticketData.openCategoryID); // Get the open category from the data.

            if (!openCategory) return interaction.reply({ embeds: [client.config.embeds.E('La categoria aperta non esiste!')] });
            
            // Change the parent of the channel.
            await interaction.channel.setParent(openCategory);

            await interaction.update({ embeds: [client.config.embeds.S(`${interaction.user} ha riaperto questo ticket!`)], components: [] });
        } else if (button === 'transcript-ticket') {
            await interaction.deferReply({ ephemeral: true });

            const transcript = await interaction.channel.messages.fetch({ limit: 100 }); // Fetch the last 100 messages from the channel.

            const transcriptText = transcript.map(m => `[${m.createdAt.toDateString()}] [${m.createdAt.toTimeString().split(' ')[0]}] [${m.author.tag}]: ${m.content}`).join('\n'); // Map the messages and join them with a new line.
            const transcriptData = `🎫 Transcript for #${interaction.channel.name}\n\n${transcriptText}`; // Create the transcript data.

            const transcriptFile = new AttachmentBuilder()
                .setName(`transcript-${interaction.channel.name}.txt`) // Set the name of the file.
                .setFile(Buffer.from(transcriptData)); // Set the file data.

            await interaction.editReply({ files: [transcriptFile] });
        }
    }
}

当我点击一个按钮:“open-ticket”我有这个错误:

node:events:491
      throw er; // Unhandled 'error' event
      ^

DiscordAPIError[40060]: Interaction has already been acknowledged.
    at SequentialHandler.runRequest (/home/enigma/opt/progetti/Clippy/node_modules/@discordjs/rest/dist/index.js:667:15)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async SequentialHandler.queueRequest (/home/enigma/opt/progetti/Clippy/node_modules/@discordjs/rest/dist/index.js:464:14)
    at async REST.request (/home/enigma/opt/progetti/Clippy/node_modules/@discordjs/rest/dist/index.js:910:22)
    at async ButtonInteraction.reply (/home/enigma/opt/progetti/Clippy/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:111:5)
Emitted 'error' event on Client instance at:
    at emitUnhandledRejectionOrErr (node:events:394:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:84:21) {
  requestBody: {
    files: [],
    json: {
      type: 4,
      data: {
        content: 'Ruolo non trovato',
        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,
        thread_name: undefined
      }
    }
  },
  rawError: {
    message: 'Interaction has already been acknowledged.',
    code: 40060
  },
  code: 40060,
  status: 400,
  method: 'POST',
  url: 'https://discord.com/api/v10/interactions/1087867648693522442/aW50ZXJhY3Rpb246MTA4Nzg2NzY0ODY5MzUyMjQ0MjplVW41eXBCNXJJYnlBNEUwYjNjYlQ1WUhTMFQ4M0pmNVdyT3FpNm5kRFNWWTVqNGE3ZnJ6UHJjRlIzSjIybzJ4YmY1NUhZZ0tJZnBrbVVENTlmc3dDaFhteFBseU1EMW90Y3g4RWpaZ2FsQm5WNXhRQ0JCVEhFdWZWNURpVzhVbQ/callback'
}

Node.js v18.14.2

我什么都试过了,但我无法修复它,你能帮帮我吗?问候,达拉

javascript discord.js bots
© www.soinside.com 2019 - 2024. All rights reserved.