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

如何基于JSON文件实现Discord Bot的Reaction Roles增删功能?

优化Discord反应角色的JSON配置实现

问题背景

通过JSON文件配置Discord反应角色,实现用户点击表情时自动添加/移除对应关联角色,现有代码可正常运行但结构冗余,以下是原实现代码与JSON配置:

原JavaScript代码

const Discord = require('discord.js');
const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
const { token }  = require('./config.json');
const Roles = require('/roles.json');

client.on("ready", () => {
    console.log("Bot opérationnel");
});

client.on('message', message => {
    if (message.content === 'Choisir un rôle :') {
        const reactionEmoji1 = message.guild.emojis.cache.find(emoji => emoji.name === 'FR');
        const reactionEmoji2 = message.guild.emojis.cache.find(emoji => emoji.name === 'UK');
        message.react(reactionEmoji1);
        message.react(reactionEmoji2);
    }
});


client.on("messageReactionAdd", (reaction, user) => {
    if(user.bot) return;

    console.log("Réaction ajoutée");

    if(reaction.message.id === "1037314191163412573"){
        if(reaction.emoji.name === "FR"){
            var member =  reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur 
            member.roles.add("1036583426620399647").then (mbr => { // Assigne le role
            console.log("Role attribué avec succès pour" + mbr.displayName);
        })
        .catch(err => {
            console.log("Le role n'a pas pu etre attribué :" + err);
        });
        }
        if(reaction.emoji.name === "UK"){
            var member =  reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur 
            member.roles.add("1036583684247134208").then (mbr => { // Assigne le role
            console.log("Role attribué avec succès pour" + mbr.displayName);
        })
        .catch(err => {
            console.log("Le role n'a pas pu etre attribué :" + err);
        });
        }
    }
});

client.on("messageReactionRemove", (reaction, user) => {
    if(user.bot) return;

    console.log("Réaction supprimée");

    if(reaction.message.id === "1037314191163412573"){
        if(reaction.emoji.name === "FR"){
            var member =  reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur 
            member.roles.remove("1036583426620399647").then (mbr => { // Assigne le role
            console.log("Role supprimé avec succès pour" + mbr.displayName);
        }).catch(err => {
            console.log("Le role n'a pas pu etre attribué :" + err);
        });
        }
        if(reaction.emoji.name === "UK"){
            var member =  reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur 
            member.roles.remove("1036583684247134208").then (mbr => { // Assigne le role
            console.log("Role supprimé avec succès pour" + mbr.displayName);
        }).catch(err => {
            console.log("Le role n'a pas pu etre attribué :" + err);
        });
        }
    }
});

client.login(token);

原JSON配置文件(roles.json)

{
    "message": "1037314191163412573",
    "channel": "1037311658416152616",
    "reactions": [
        {
            "emoji": "FR",
            "role": "1036583426620399647"               
        },
        {
            "emoji": "UK",
            "role": "1036583684247134208"
        }
    ]
 }  

优化后的实现

以下是简化后的代码,完全基于JSON配置动态处理,消除冗余逻辑:

优化后的JavaScript代码

const Discord = require('discord.js');
const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
const { token } = require('./config.json');
const roleConfig = require('./roles.json');

client.on("ready", () => {
    console.log("Bot已启动");
});

// 自动给指定消息添加反应
client.on('message', async message => {
    if (message.content === 'Choisir un rôle :') {
        // 遍历配置中的表情,批量添加反应
        for (const reactionItem of roleConfig.reactions) {
            const emoji = message.guild.emojis.cache.find(e => e.name === reactionItem.emoji);
            if (emoji) await message.react(emoji);
        }
    }
});

// 统一处理反应添加/移除逻辑
async function handleReaction(reaction, user, isAdding) {
    if (user.bot || reaction.message.id !== roleConfig.message) return;

    // 找到当前反应对应的角色配置
    const reactionConfig = roleConfig.reactions.find(item => item.emoji === reaction.emoji.name);
    if (!reactionConfig) return;

    try {
        // 获取成员(缓存不存在时从API拉取)
        const member = await reaction.message.guild.members.fetch(user.id);
        // 执行添加或移除角色操作
        if (isAdding) {
            await member.roles.add(reactionConfig.role);
            console.log(`成功为${member.displayName}添加角色`);
        } else {
            await member.roles.remove(reactionConfig.role);
            console.log(`成功为${member.displayName}移除角色`);
        }
    } catch (err) {
        console.log(`角色操作失败: ${err}`);
    }
}

client.on("messageReactionAdd", (reaction, user) => handleReaction(reaction, user, true));
client.on("messageReactionRemove", (reaction, user) => handleReaction(reaction, user, false));

client.login(token);

优化说明

  • 完全依赖JSON配置:所有表情、角色ID、目标消息ID都从配置文件读取,新增/修改反应角色无需改动代码
  • 消除重复逻辑:将添加和移除反应的处理合并为一个函数,避免代码冗余
  • 更可靠的成员获取:使用fetch方法确保能获取到成员(缓存不存在时会从API拉取)
  • 批量处理反应添加:遍历配置自动添加所有需要的表情,不用逐个硬编码
  • 统一错误处理:集中处理角色操作的异常,日志输出更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:50:37