You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遭遇DiscordAPIError 40060错误,请求技术协助排查修复

解决DiscordAPIError 40060: "Interaction has already been acknowledged"错误

这个错误的核心原因是同一个Discord交互被多次调用确认方法(如reply()/deferReply())。你的代码存在两个关键问题:

  1. 命令执行的错误处理逻辑中,未检查交互是否已被回复,直接再次调用interaction.reply(),导致重复确认。
  2. 拆分的两个InteractionCreate监听器虽然通过类型判断过滤,但代码结构不够严谨,存在潜在的重复处理风险。

修复后的代码

index.js

const fs = require('node:fs');
const path = require('node:path');
const { Events, Collection, ActivityType } = require('discord.js');

const client = require('./client.js');
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));

for (const file of commandFiles) {
    const filePath = path.join(commandsPath, file);
    const command = require(filePath);
    if ('data' in command && 'execute' in command) {
        client.commands.set(command.data.name, command);
    } else {
        console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
    }
}

// 合并所有交互处理逻辑到单个监听器
client.on(Events.InteractionCreate, async interaction => {
    // 处理模态框提交
    if (interaction.isModalSubmit()) {
        if (interaction.customId === 'myModal') {
            try {
                await interaction.reply({ content: 'Your submission was received successfully!' });
                const good = interaction.fields.getTextInputValue('good');
                const bot = interaction.fields.getTextInputValue('bot');
                
                // 先获取用户再发送,避免缓存不存在的情况
                const targetUser = await client.users.fetch('821682594830614578');
                await targetUser.send(`good: "${good}"\nbot: "${bot}" from ${interaction.user.username}`);
            } catch (error) {
                console.error(error);
                // 检查交互状态,避免重复确认
                if (interaction.replied || interaction.deferred) {
                    await interaction.followUp({ content: '提交处理时发生错误!', ephemeral: true });
                } else {
                    await interaction.reply({ content: '提交处理时发生错误!', ephemeral: true });
                }
            }
        }
        return;
    }

    // 处理斜杠命令
    if (!interaction.isChatInputCommand()) return;
    
    const command = interaction.client.commands.get(interaction.commandName);
    if (!command) {
        console.error(`No command matching ${interaction.commandName} was found.`);
        if (!interaction.replied && !interaction.deferred) {
            await interaction.reply({ content: '未找到匹配的命令!', ephemeral: true });
        }
        return;
    }

    try {
        await command.execute(interaction);
    } catch (error) {
        console.error(error);
        // 关键:根据交互状态选择回复方式
        if (interaction.replied || interaction.deferred) {
            await interaction.followUp({ content: '执行命令时发生错误!', ephemeral: true });
        } else {
            await interaction.reply({ content: '执行命令时发生错误!', ephemeral: true });
        }
    }
});

client.once(Events.ClientReady, c => {
    client.user.setActivity('you or i have no food', { type: ActivityType.Watching });
    console.log(`Logged in as ${c.user.tag}`);
});

client.login(process.env.token);

ping.js(优化往返延迟计算)

const { SlashCommandBuilder } = require('discord.js');
const client = require('./../client.js');

module.exports = {
    data: new SlashCommandBuilder()
        .setName('ping')
        .setDescription('Ping! Pong!'),
    async execute(interaction) {
        // 获取回复消息时间戳,计算准确往返延迟
        const sent = await interaction.reply({ 
            content: `Websocket heartbeat: ${client.ws.ping} ms.`, 
            fetchReply: true 
        });
        await interaction.editReply(`Websocket heartbeat: ${client.ws.ping} ms. 
Roundtrip latency: ${sent.createdTimestamp - interaction.createdTimestamp} ms.`);
    },
};

关键修改说明

  1. 合并交互监听器:将模态框和斜杠命令的处理逻辑整合到同一个监听器,避免多个监听器同时处理交互的潜在冲突。
  2. 检查交互状态:在所有可能回复的逻辑中,先判断interaction.replied或interaction.deferred,已确认的交互使用followUp()替代reply(),彻底避免重复确认。
  3. 优化用户消息发送:使用client.users.fetch()确保目标用户存在(即使不在缓存中),同时添加异常捕获,避免发送消息失败影响交互回复。
  4. 完善ping命令功能:修复原代码中往返延迟为NaN的问题,通过fetchReply获取回复时间戳计算真实延迟。

内容的提问来源于stack exchange,提问作者realguystuff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:45:37