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

discord.js按钮交互问题:点击按钮变绿及testMsg.edit报错解决

问题解决:按钮变色与testMsg.edit is not a function报错修复

报错原因分析

msg.reply()是异步方法,返回的是Promise对象而非直接的Message实例。你未用await等待异步操作完成,导致testMsg实际是Promise,自然没有edit方法。另外testMsg作为局部变量,按钮交互触发时已被销毁,无法跨事件访问。

修复方案与完整代码

核心解决思路

  1. 存储消息实例:用全局Map存储消息ID对应的消息对象,避免局部变量失效,同时支持多用户使用。
  2. 等待异步操作:用await获取msg.reply()返回的Message实例。
  3. 按钮变色逻辑:点击按钮时,复制原消息组件,找到对应ID的按钮修改样式为绿色(Success),再编辑消息更新组件。

完整代码如下:

const { ButtonBuilder, ActionRowBuilder, ButtonStyle } = require('discord.js');

// 存储消息实例,key为消息ID,value为Message对象
const messageMap = new Map();

client.on('interactionCreate', async (msg) => {
    // 简化按钮创建逻辑
    const createButton = (id, label, style) => 
        new ButtonBuilder().setCustomId(id).setLabel(label).setStyle(style);

    // 处理/test指令
    if (msg.isChatInputCommand() && msg.commandName === 'test') {
        const btns = [];
        for (let i = 0; i < 25; i++) {
            btns.push(createButton(`test${i}`, String(i).padStart(2, '0'), ButtonStyle.Secondary));
        }

        const rows = [];
        for (let i = 0; i < 25; i += 5) {
            const row = new ActionRowBuilder();
            for (let j = i; j < i + 5 && j < 25; j++) {
                row.addComponents(btns[j]);
            }
            rows.push(row);
        }

        // 用await获取消息实例并存入Map
        const testMsg = await msg.reply({ content: "test", components: rows });
        messageMap.set(testMsg.id, testMsg);
    }

    // 处理按钮点击
    if (msg.isButton()) {
        // 过滤非测试按钮
        if (!msg.customId.startsWith('test')) return;

        // 获取对应的消息实例
        const targetMsg = messageMap.get(msg.message.id);
        if (!targetMsg) return;

        // 复制原组件,避免修改原数据
        const newComponents = [...targetMsg.components];

        // 遍历找到目标按钮并修改样式
        newComponents.forEach(row => {
            row.components.forEach(btn => {
                if (btn.customId === msg.customId) {
                    btn.setStyle(ButtonStyle.Success);
                }
            });
        });

        // 更新消息组件,同时回复交互避免超时
        await targetMsg.edit({ components: newComponents });
        await msg.deferUpdate();
    }
});

关键修改点说明

  • await msg.reply()确保拿到真实的Message实例,彻底解决edit is not a function报错。
  • messageMap实现跨事件的消息实例访问,支持多用户同时使用功能。
  • 复制原组件后修改目标按钮样式,保证其他按钮状态不受影响。
  • msg.deferUpdate()回复按钮交互,避免Discord判定操作超时。
  • 移除不必要的btn类,简化按钮创建逻辑,让代码更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:40:24