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

Discord.js V14按钮交互异常:首次点击失败、Bot偶发崩溃

Discord.js V14 机器人按钮交互异常问题

我基于Discord.js V14开发了一款Discord机器人,创建了文本触发指令:用户发送test后,机器人会发送带按钮的消息,点击按钮时消息需更新为“button was clicked”。但实际运行中出现以下问题:

  • 按钮可正常发送,但首次点击提示“interaction failed”,二次点击才正常生效
  • 再次执行指令时,机器人有时直接崩溃,有时发送按钮后崩溃

原代码

client.on('messageCreate', (message) => {
  if (message.author.bot) return;
  if (message.content === 'test') {
    let row = new ActionRowBuilder()
      .addComponents(
        new ButtonBuilder()
        .setCustomId('test')
        .setLabel('testing')
        .setStyle(ButtonStyle.Primary),
      );

    message.channel.send({
      content: 'hey there!',
      components: [row]
    });
  }

  client.on('interactionCreate', (interaction) => {
    if (!interaction.isButton()) {
      message.channel.send('hello gringo');
    };
    if (interaction.customId)
      console.log(interaction);

    const filter = i => i.customId === 'test' && i.user.id === '877466540679786536';

    const collector = interaction.channel.createMessageComponentCollector({
      filter,
      time: 15000
    });

    collector.on('collect', async i => {
      await i.update({
        content: 'Button was clicked!',
        components: []
      });
    });

    collector.on('end', collected => console.log(`Collected ${collected.size} items`));
  })
});

报错信息

rawError: {
    message: 'Interaction has already been acknowledged.',
    code: 40060
  },
  code: 40060,
  status: 400,
  method: 'POST',
  url: 'https://discord.com/api/v10/interactions/1064212307045003315/aW50ZXJhY3Rpb246MTA2NDIxMjMwNzA0NTAwMzMxNTpJOGxpUEttZ2U3ZERIaW9iRXg4VkxiN2ZpREZJN2RRV2d6WW9uMUE3dXR2RFpNckI4SnliMEpCZGFEWm9qUVg0R2duS3ZTWk1UVkMyM015SWlKYk94cjU0Q3FWMVhCUFA5UDQzeWJVTzZPU09YNmZBR2NwS3MxZjRXeGgzOVAzSA/callback'
}

问题根源

  1. 重复绑定interactionCreate事件:每次触发messageCreate(比如用户发test),都会新增一个interactionCreate监听器。触发次数越多,监听器堆积越多,同一个交互会被多次处理,直接引发“交互已被响应”的错误,甚至导致机器人崩溃。
  2. 错误的非按钮交互处理:当收到非按钮交互时,直接调用message.channel.send,这里的message是上一次messageCreate的上下文,会导致逻辑混乱,且未对交互做正确响应。
  3. 冗余的消息组件收集器:仅需处理单次按钮点击,不需要使用收集器,收集器会和直接处理逻辑冲突,增加不必要的复杂度。

修复后的代码

const { Client, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
const client = new Client({ intents: [/* 请确保启用必要的权限,如Guilds、GuildMessages、MessageContent */] });

// 仅绑定一次interactionCreate事件,放在messageCreate外部
client.on('interactionCreate', async (interaction) => {
  // 非按钮交互直接返回,避免无效处理
  if (!interaction.isButton()) return;

  // 校验按钮ID和用户ID
  if (interaction.customId === 'test' && interaction.user.id === '877466540679786536') {
    try {
      // 更新消息内容并移除按钮
      await interaction.update({
        content: 'Button was clicked!',
        components: []
      });
    } catch (error) {
      console.error('按钮交互处理失败:', error);
    }
  }
});

client.on('messageCreate', (message) => {
  if (message.author.bot) return;
  if (message.content === 'test') {
    const row = new ActionRowBuilder()
      .addComponents(
        new ButtonBuilder()
          .setCustomId('test')
          .setLabel('testing')
          .setStyle(ButtonStyle.Primary)
      );

    // 增加错误捕获,防止发送消息失败导致崩溃
    message.channel.send({
      content: 'hey there!',
      components: [row]
    }).catch(error => console.error('消息发送失败:', error));
  }
});

// 登录机器人
client.login('你的机器人令牌');

核心修复点

  • 将interactionCreate监听器移至messageCreate外部,确保仅绑定一次,避免重复处理交互
  • 移除冗余的消息组件收集器,直接在interactionCreate中处理按钮点击逻辑
  • 修正非按钮交互的处理逻辑,直接返回而非错误发送消息
  • 添加错误捕获,避免异常导致机器人崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:55:21