JS开发Discord Bot的Reaction Roles如何实现单次仅选一个身份
解决方案
核心修改逻辑如下:
- 把颜色表情和对应身份组整理成映射表,减少重复判断代码,后续新增颜色直接补全映射即可
- 用户添加新的颜色反应时,先自动移除该用户所有其他颜色的反应和对应身份组,再添加新选中的身份组
- 增加消息ID校验,避免误处理同频道其他消息的反应,同时新增重复监听移除逻辑,避免多次执行命令导致事件重复触发
修改后完整代码
module.exports = { name: 'reactioncolor', description: "Sets up a reaction role message!", async execute(client, message, args, Discord) { const channel = '865154605356285962'; // 颜色表情-身份组映射表 const colorRoles = { '🔴': message.guild.roles.cache.find(role => role.name === "Red"), '🟠': message.guild.roles.cache.find(role => role.name === "Orange"), '🟡': message.guild.roles.cache.find(role => role.name === "Yellow"), '🔵': message.guild.roles.cache.find(role => role.name === "Blue"), } const colorEmojis = Object.keys(colorRoles); let embed = new Discord.MessageEmbed() .setColor('#e42643') .setTitle('Choose your colour!') .setDescription('\n\n' + `🔴 ➜ <@&865163260500377602>\n` + `🟠 ➜ <@&865163175091503104>\n` + `🟡 ➜ <@&865163103469961226>\n` + `🔵 ➜ <@&866988159162515527>\n`); let messageEmbed = await message.channel.send(embed); // 批量添加表情 for (const emoji of colorEmojis) { await messageEmbed.react(emoji); } // 移除之前的重复监听,避免事件多次触发 client.removeAllListeners('messageReactionAdd'); client.removeAllListeners('messageReactionRemove'); client.on('messageReactionAdd', async (reaction, user) => { if (reaction.message.partial) await reaction.message.fetch(); if (reaction.partial) await reaction.fetch(); if (user.bot) return; if (!reaction.message.guild) return; // 仅处理当前命令生成的颜色选择消息的反应 if (reaction.message.channel.id !== channel || reaction.message.id !== messageEmbed.id) return; const selectedEmoji = reaction.emoji.name; if (!colorEmojis.includes(selectedEmoji)) return; const member = reaction.message.guild.members.cache.get(user.id); // 遍历移除其他所有颜色的反应和对应身份组 for (const emoji of colorEmojis) { if (emoji !== selectedEmoji) { const otherReaction = reaction.message.reactions.cache.get(emoji); if (otherReaction) await otherReaction.users.remove(user.id); const role = colorRoles[emoji]; if (role) await member.roles.remove(role); } } // 添加当前选中的身份组 await member.roles.add(colorRoles[selectedEmoji]); }); client.on('messageReactionRemove', async (reaction, user) => { if (reaction.message.partial) await reaction.message.fetch(); if (reaction.partial) await reaction.fetch(); if (user.bot) return; if (!reaction.message.guild) return; if (reaction.message.channel.id !== channel || reaction.message.id !== messageEmbed.id) return; const removedEmoji = reaction.emoji.name; if (!colorEmojis.includes(removedEmoji)) return; const member = reaction.message.guild.members.cache.get(user.id); await member.roles.remove(colorRoles[removedEmoji]); }); } }
内容的提问来源于stack exchange,提问作者Immix
相关产品推荐
相关产品推荐

