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
相关产品推荐
相关产品推荐

