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

Discord TS机器人点击按钮后禁用双按钮的实现问题

在TypeScript的Discord机器人中点击任意按钮后禁用所有按钮的实现方法

问题原因

你之前尝试的interaction.component.disabled;只是读取组件的禁用状态,并非修改操作。而且Discord组件的状态变更不能直接修改本地引用,必须通过更新消息的组件结构同步到Discord服务器端,所以这个语句不会生效。

解决思路

不管点击两个按钮中的哪一个,都需要执行以下步骤:

  • 获取当前消息中的所有组件行(ActionRow)
  • 遍历每个组件,将所有按钮类型的组件设置为disabled: true
  • 调用interaction.update()方法,把修改后的组件重新应用到消息上

具体实现代码

1. 按钮创建(warn.ts)

确保创建按钮时设置唯一的自定义ID,方便后续路由处理:

import { ButtonBuilder, ButtonStyle, ActionRowBuilder, SlashCommandBuilder, CommandInteraction } from 'discord.js';

export async function execute(interaction: CommandInteraction) {
  // 创建确认警告按钮
  const confirmBtn = new ButtonBuilder()
    .setCustomId('warn_confirm')
    .setLabel('确认警告')
    .setStyle(ButtonStyle.Danger);

  // 创建取消按钮
  const cancelBtn = new ButtonBuilder()
    .setCustomId('warn_cancel')
    .setLabel('取消')
    .setStyle(ButtonStyle.Secondary);

  // 组装成组件行
  const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents(confirmBtn, cancelBtn);

  // 发送带按钮的回复
  await interaction.reply({
    content: '确定要对该用户执行警告操作吗?',
    components: [buttonRow],
    ephemeral: true
  });
}

export const data = new SlashCommandBuilder()
  .setName('warn')
  .setDescription('警告指定用户');

2. 取消按钮处理(cancel.ts)

在取消按钮的处理函数中实现禁用所有按钮的逻辑:

import { ButtonInteraction, ComponentType } from 'discord.js';

export async function handleCancelBtn(interaction: ButtonInteraction) {
  // 获取当前消息的所有组件
  const originalComponents = interaction.message.components;

  // 遍历组件,禁用所有按钮
  const updatedComponents = originalComponents.map(row => {
    return {
      ...row.toJSON(),
      components: row.components.map(component => {
        // 只处理按钮类型的组件
        if (component.type === ComponentType.Button) {
          return {
            ...component.toJSON(),
            disabled: true
          };
        }
        return component.toJSON();
      })
    };
  });

  // 更新消息,应用禁用后的组件
  await interaction.update({ components: updatedComponents });

  // 发送操作提示(可选)
  await interaction.followUp({ content: '操作已取消,所有按钮已禁用', ephemeral: true });
}

3. 确认按钮处理(可单独创建文件或整合到warn相关逻辑中)

在确认按钮的处理逻辑中,同样执行禁用所有按钮的操作:

import { ButtonInteraction, ComponentType } from 'discord.js';

export async function handleConfirmBtn(interaction: ButtonInteraction) {
  // 先禁用所有按钮
  const originalComponents = interaction.message.components;
  const updatedComponents = originalComponents.map(row => {
    return {
      ...row.toJSON(),
      components: row.components.map(component => {
        if (component.type === ComponentType.Button) {
          return { ...component.toJSON(), disabled: true };
        }
        return component.toJSON();
      })
    };
  });
  await interaction.update({ components: updatedComponents });

  // 执行你的警告逻辑(比如添加警告记录、发送提示等)
  await interaction.followUp({ content: '已成功警告该用户', ephemeral: true });
}

4. 交互路由(interactionCreate.ts)

在主交互处理文件中,根据按钮自定义ID分发到对应处理函数:

import { Client, Interaction } from 'discord.js';
import { handleCancelBtn } from './cancel';
import { handleConfirmBtn } from './warn-confirm';

export function setupInteractionHandlers(client: Client) {
  client.on('interactionCreate', async (interaction: Interaction) => {
    // 只处理按钮交互
    if (!interaction.isButton()) return;

    switch (interaction.customId) {
      case 'warn_cancel':
        await handleCancelBtn(interaction);
        break;
      case 'warn_confirm':
        await handleConfirmBtn(interaction);
        break;
      // 其他按钮的处理逻辑可添加在这里
    }
  });
}

关键说明

  • 必须使用interaction.update()更新消息组件,而非直接修改本地组件对象,因为Discord的组件状态由服务器维护,本地修改无法同步过去。
  • 如果是通过interaction.followUp()发送的消息,需要改用interaction.editReply()来更新组件,具体需根据消息发送方式调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 03:46:27