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

Discord.js V14按钮点击后Embed编辑失败且机器人崩溃问题

解决Discord.js V14 /suggest指令按钮崩溃与持久化问题

一、修复按钮点击崩溃(TypeError: Cannot read properties of undefined (reading 'find'))

这个报错的核心是调用find方法的对象为undefined,本质是获取Embed或字段时未做存在性校验,按以下步骤修正:

  1. 确保获取到目标Embed
    在按钮交互处理代码中,先校验消息内的Embed是否存在:

    // 按钮交互逻辑内
    if (!interaction.message.embeds[0]) {
      return interaction.reply({ content: "找不到对应的建议Embed", ephemeral: true });
    }
    // 用EmbedBuilder克隆原Embed,避免直接修改不可变对象
    const newEmbed = new EmbedBuilder(interaction.message.embeds[0]);
    
  2. 安全获取并更新字段数值
    假设Embed字段格式为✅ 同意: 0、❌ 反对: 0,添加数值解析的校验:

    // 处理同意按钮
    const agreeField = newEmbed.data.fields.find(field => field.name === "✅ 同意");
    if (!agreeField) {
      return interaction.reply({ content: "同意字段不存在", ephemeral: true });
    }
    const agreeCount = parseInt(agreeField.value.split(": ")[1]);
    if (isNaN(agreeCount)) {
      return interaction.reply({ content: "无法解析同意数", ephemeral: true });
    }
    agreeField.value = `✅ 同意: ${agreeCount + 1}`;
    
    // 同理处理反对按钮
    const disagreeField = newEmbed.data.fields.find(field => field.name === "❌ 反对");
    if (!disagreeField) {
      return interaction.reply({ content: "反对字段不存在", ephemeral: true });
    }
    const disagreeCount = parseInt(disagreeField.value.split(": ")[1]);
    if (isNaN(disagreeCount)) {
      return interaction.reply({ content: "无法解析反对数", ephemeral: true });
    }
    disagreeField.value = `❌ 反对: ${disagreeCount + 1}`;
    
  3. 更新消息并响应交互
    修改完成后更新消息,用deferUpdate避免交互超时:

    await interaction.message.edit({ embeds: [newEmbed] });
    await interaction.deferUpdate();
    

二、实现按钮重启后仍可用(解决与interactionCreate冲突)

冲突原因是同时在指令内使用临时collector和全局interactionCreate事件处理按钮,需统一用全局事件处理:

  1. 给按钮设置带标识的自定义ID
    在/suggest指令创建按钮时,将消息ID作为自定义ID的一部分,用于识别对应建议:

    // /suggest指令内创建按钮与消息
    const suggestEmbed = new EmbedBuilder()
      .setTitle("新建议")
      .setDescription(interaction.options.getString('content'))
      .addFields(
        { name: "✅ 同意", value: "0", inline: true },
        { name: "❌ 反对", value: "0", inline: true }
      );
    
    const actionRow = new ActionRowBuilder().addComponents(
      new ButtonBuilder()
        .setCustomId(`suggest_agree_temp`)
        .setLabel("Agree")
        .setStyle(ButtonStyle.Success),
      new ButtonBuilder()
        .setCustomId(`suggest_disagree_temp`)
        .setLabel("Disagree")
        .setStyle(ButtonStyle.Danger)
    );
    
    const suggestMessage = await interaction.channel.send({
      embeds: [suggestEmbed],
      components: [actionRow]
    });
    
    // 发送后更新按钮ID,绑定消息ID
    const updatedRow = new ActionRowBuilder().addComponents(
      new ButtonBuilder()
        .setCustomId(`suggest_agree_${suggestMessage.id}`)
        .setLabel("Agree")
        .setStyle(ButtonStyle.Success),
      new ButtonBuilder()
        .setCustomId(`suggest_disagree_${suggestMessage.id}`)
        .setLabel("Disagree")
        .setStyle(ButtonStyle.Danger)
    );
    await suggestMessage.edit({ components: [updatedRow] });
    
  2. 在interactionCreate.js内统一处理按钮
    移除指令内的collector代码,全局监听按钮交互:

    // interactionCreate.js
    module.exports = {
      name: 'interactionCreate',
      async execute(interaction) {
        if (!interaction.isButton()) return;
    
        // 处理同意按钮
        if (interaction.customId.startsWith('suggest_agree_')) {
          if (!interaction.message.embeds[0]) {
            return interaction.reply({ content: "无效的建议消息", ephemeral: true });
          }
          const newEmbed = new EmbedBuilder(interaction.message.embeds[0]);
          const agreeField = newEmbed.data.fields.find(f => f.name === "✅ 同意");
          if (!agreeField || isNaN(parseInt(agreeField.value.split(": ")[1]))) {
            return interaction.reply({ content: "字段解析失败", ephemeral: true });
          }
          const count = parseInt(agreeField.value.split(": ")[1]) + 1;
          agreeField.value = `✅ 同意: ${count}`;
          await interaction.message.edit({ embeds: [newEmbed] });
          await interaction.deferUpdate();
        }
    
        // 处理反对按钮
        else if (interaction.customId.startsWith('suggest_disagree_')) {
          if (!interaction.message.embeds[0]) {
            return interaction.reply({ content: "无效的建议消息", ephemeral: true });
          }
          const newEmbed = new EmbedBuilder(interaction.message.embeds[0]);
          const disagreeField = newEmbed.data.fields.find(f => f.name === "❌ 反对");
          if (!disagreeField || isNaN(parseInt(disagreeField.value.split(": ")[1]))) {
            return interaction.reply({ content: "字段解析失败", ephemeral: true });
          }
          const count = parseInt(disagreeField.value.split(": ")[1]) + 1;
          disagreeField.value = `❌ 反对: ${count}`;
          await interaction.message.edit({ embeds: [newEmbed] });
          await interaction.deferUpdate();
        }
      }
    };
    
  3. 移除指令内的临时Collector
    删掉/suggest指令中类似message.createMessageComponentCollector()的代码,避免与全局事件冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:12:30