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

Discord.JS 同按钮行内点击单个按钮切换样式的实现方案问询

Discord.js 按钮开关样式切换实现方案

核心实现逻辑

Discord.js 没有提供单独修改单个按钮的API,所有组件的更新都需要重新提交完整的组件数组,你可以直接复用原有消息的组件结构,只修改目标按钮的样式属性,就能保持其他按钮的位置和原有状态不变。

具体实现代码

首先定义customId和角色对象的映射,简化原有冗余的判断逻辑:

const roleMap = {
  rustUpdates: Rust,
  gmodUpdates: GarrysMod,
  minecraftUpdates: Minecraft,
  fivemUpdates: FiveM,
  arma3Updates: Arma3
}

修改后的interactionCreate事件代码:

client.on('interactionCreate', async (interaction) => {
  if (!interaction.isButton()) return
  // 过滤非角色选择类的按钮点击
  if (!Object.keys(roleMap).includes(interaction.customId)) return

  const targetRole = roleMap[interaction.customId]
  const hadRole = interaction.member.roles.cache.has(targetRole.id)
  
  // 处理角色加减逻辑
  if (hadRole) {
    await interaction.member.roles.remove(targetRole)
  } else {
    await interaction.member.roles.add(targetRole)
  }

  // 复用原有组件结构,仅修改目标按钮样式
  const updatedComponents = interaction.message.components.map(actionRow => {
    return {
      ...actionRow,
      components: actionRow.components.map(button => {
        if (button.customId === interaction.customId) {
          // 已订阅角色按钮变红,未订阅按钮变回绿色
          return {
            ...button,
            style: !hadRole ? 'DANGER' : 'SUCCESS'
          }
        }
        return button
      })
    }
  })

  // 提交更新后的组件
  await interaction.update({ components: updatedComponents })
})

注意事项

  • 如果你使用的是Discord.js v14版本,需要将MessageActionRow、MessageButton替换为v14对应的ActionRowBuilder、ButtonBuilder类,组件结构修改后需要调用.toJSON()方法再提交。
  • 如果该消息是公共频道的全局消息,按钮状态更新后会对所有可见用户同步,如果需要每个用户看到自己专属的按钮状态,建议发送仅用户可见的ephemeral类型消息承载按钮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:36:06