Discord.js反应角色Bot点击表情不分配角色 弃用警告问题求助
问题排查及修复方案
核心问题梳理
你遇到的问题根源如下:
- Client配置参数错误:
Client构造函数仅接收1个配置对象,你错误将intents和partials分成两个对象传入,导致partials配置完全失效,且错误加入了不属于partial类型的MANAGE_ROLES项 - 缺少必要网关意图:监听服务器消息反应必须开启
GUILD_MESSAGE_REACTIONS意图,你当前的intents配置没有包含该项,导致messageReactionAdd/messageReactionRemove事件根本不会触发 - 事件监听器重复注册风险:你把反应监听事件写在命令执行逻辑里,每次运行
!reactionrole都会新增一组监听器,多次执行会出现重复分配、内存泄漏问题 - 你提到的弃用警告大概率是旧缓存/未清理的旧代码导致,你当前已经在使用
messageCreate事件,修复配置后警告会自动消失
修复步骤
第一步:修复index.js配置
const Discord = require("discord.js"); // 修正配置结构、新增反应意图、清理无效partial项 const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_MESSAGE_REACTIONS"], partials: ["MESSAGE", "CHANNEL", "REACTION", "USER"] }) require("dotenv").config(); const prefix = "!"; const fs = require("fs"); client.commands = new Discord.Collection(); // 全局存储反应角色映射,避免重复注册监听器 client.reactionRoles = { channelId: "889233386781151232", // 对应你写死的频道ID roleMap: new Map() }; const commandFiles = fs.readdirSync("./commands/").filter(file => file.endsWith('.js')); for (const file of commandFiles) { const command = require(`./commands/${file}`); client.commands.set(command.name, command); } client.on("ready", () => { console.log("bot online"); }); // 全局注册反应添加监听器,只注册一次 client.on('messageReactionAdd', async(reaction, user) => { if (reaction.message.partial) await reaction.message.fetch(); if (reaction.partial) await reaction.fetch(); if (user.bot || !reaction.message.guild) return; if (reaction.message.channel.id === client.reactionRoles.channelId) { const targetRole = client.reactionRoles.roleMap.get(reaction.emoji.name); if (targetRole) { await reaction.message.guild.members.cache.get(user.id).roles.add(targetRole).catch(err => console.log("添加角色失败:", err)); } } }); // 全局注册反应移除监听器,只注册一次 client.on("messageReactionRemove", async(reaction, user) => { if (reaction.message.partial) await reaction.message.fetch(); if (reaction.partial) await reaction.fetch(); if (user.bot || !reaction.message.guild) return; if (reaction.message.channel.id === client.reactionRoles.channelId) { const targetRole = client.reactionRoles.roleMap.get(reaction.emoji.name); if (targetRole) { await reaction.message.guild.members.cache.get(user.id).roles.remove(targetRole).catch(err => console.log("移除角色失败:", err)); } } }); client.on("messageCreate", message => { if(!message.content.startsWith(prefix) || message.author.bot) return; const args = message.content.slice(prefix.length).split(/ +/); const command = args.shift().toLowerCase(); if (command === "reactionrole") { client.commands.get("reactionrole").execute(message, args, Discord, client); } }); client.login(process.env.BOT_TOKEN);
第二步:修复reactionrole.js逻辑,移除内部的重复监听器
module.exports = { name: 'reactionrole', description: "Sets up a reaction role message", async execute(message, args, Discord, client) { const maths = message.guild.roles.cache.find(role => role.name === "Maths"); const mathsExpertes = message.guild.roles.cache.find(role => role.name === "Maths expertes"); const nsi = message.guild.roles.cache.find(role => role.name === "NSI"); const physique = message.guild.roles.cache.find(role => role.name === "Physique"); const svt = message.guild.roles.cache.find(role => role.name === "SVT"); const artsPlastique = message.guild.roles.cache.find(role => role.name === "Arts Plastiques"); const mathsEmoji = '📐'; const mathsExpertesEmoji = '🧠'; const nsiEmoji = '💻'; const physiqueEmoji = '🧪'; const svtEmoji = '🧬'; const artsPlastiquesEmoji = '🎨'; // 写入全局角色映射 client.reactionRoles.roleMap.clear(); client.reactionRoles.roleMap.set(mathsEmoji, maths); client.reactionRoles.roleMap.set(mathsExpertesEmoji, mathsExpertes); client.reactionRoles.roleMap.set(nsiEmoji, nsi); client.reactionRoles.roleMap.set(physiqueEmoji, physique); client.reactionRoles.roleMap.set(svtEmoji, svt); client.reactionRoles.roleMap.set(artsPlastiquesEmoji, artsPlastique); let embed = new Discord.MessageEmbed() .setColor("#e42643") .setTitle("Selection des matière") .setDescription("Choisis tes matières en cliquant sur la reaction qui correspond\n\n" + `${mathsEmoji} : Maths\n` + `${mathsExpertesEmoji} : Maths Expertes\n` + `${nsiEmoji} : NSI\n` + `${physiqueEmoji} : Physique\n` + `${svtEmoji} : SVT\n` + `${artsPlastiquesEmoji} : Arts Plastiques\n`); let messageEmbed = await message.channel.send({embeds: [embed]}); await messageEmbed.react(mathsEmoji); await messageEmbed.react(mathsExpertesEmoji); await messageEmbed.react(nsiEmoji); await messageEmbed.react(physiqueEmoji); await messageEmbed.react(svtEmoji); await messageEmbed.react(artsPlastiquesEmoji); } }
第三步:额外权限检查
- 到Discord开发者平台的Bot设置页,确认已经开启
Server Members Intent权限 - 进入你的Discord服务器,确认Bot的角色排序在所有需要分配的学生角色之上,且Bot角色拥有「管理角色」权限
- 确认你代码中写死的频道ID
889233386781151232和你实际发送选角色消息的频道ID一致
内容的提问来源于stack exchange,提问作者deoxys
相关产品推荐
相关产品推荐

