You need to enable JavaScript to run this app. JS开发Discord Bot的Reaction Roles如何实现单次仅选一个身份
优惠活动
大模型
产品
解决方案
定价
更多

JS开发Discord Bot的Reaction Roles如何实现单次仅选一个身份

解决方案

核心修改逻辑如下:

  1. 把颜色表情和对应身份组整理成映射表,减少重复判断代码,后续新增颜色直接补全映射即可
  2. 用户添加新的颜色反应时,先自动移除该用户所有其他颜色的反应和对应身份组,再添加新选中的身份组
  3. 增加消息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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 13:45:01