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

Discord.js反应角色Bot点击表情不分配角色 弃用警告问题求助

问题排查及修复方案

核心问题梳理

你遇到的问题根源如下:

  1. Client配置参数错误:Client构造函数仅接收1个配置对象,你错误将intents和partials分成两个对象传入,导致partials配置完全失效,且错误加入了不属于partial类型的MANAGE_ROLES项
  2. 缺少必要网关意图:监听服务器消息反应必须开启GUILD_MESSAGE_REACTIONS意图,你当前的intents配置没有包含该项,导致messageReactionAdd/messageReactionRemove事件根本不会触发
  3. 事件监听器重复注册风险:你把反应监听事件写在命令执行逻辑里,每次运行!reactionrole都会新增一组监听器,多次执行会出现重复分配、内存泄漏问题
  4. 你提到的弃用警告大概率是旧缓存/未清理的旧代码导致,你当前已经在使用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);
    }
}

第三步:额外权限检查

  1. 到Discord开发者平台的Bot设置页,确认已经开启Server Members Intent权限
  2. 进入你的Discord服务器,确认Bot的角色排序在所有需要分配的学生角色之上,且Bot角色拥有「管理角色」权限
  3. 确认你代码中写死的频道ID889233386781151232和你实际发送选角色消息的频道ID一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:48:02