如何基于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
相关产品推荐
相关产品推荐

