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

discord.js v14 messageReactionAdd事件触发后无限发送消息问题排查

问题

使用discord.js v14开发的机器人,在messageReactionAdd事件中实现了点击指定表情后向目标频道发送通知消息的功能。该功能初期运行正常,但一段时间后,用户点击一次表情就会触发机器人无限重复发送消息。相关代码如下:

const { MessageReaction, Events, GatewayIntentBits, Partials } = require("discord.js");

const reactionConfig = {
    channelID: "1078339846172573778",
    targetChannelID: "972616312952070144",
    messageID: "1078355581435379723",
    firstEmoji: "926995541596962919",
    staffRoleID: "886867243076567071",
    normalRoleID: "886869696752803890",
}

module.exports = {
    name: "messageReactionAdd",

    /**
     * 
     * @param {MessageReaction} reaction
     */

    async execute(reaction) {
        const client = reaction.client;

        if (reaction.partial) {
            try {
                await reaction.fetch();
            } catch (error) {
                console.error('Something went wrong when fetching the message:', error);
                return;
            }
        }

        const channel = client.channels.cache.get(reactionConfig.channelID)
        const msg = await channel.messages.fetch(reactionConfig.messageID)

        if(msg){
        const collector = msg.createReactionCollector( 'time: 10000ms');

            collector.on('collect', async (reaction, user) => {
                switch (reaction.emoji.id){
                    case reactionConfig.firstEmoji: {
                    await client.channels.cache.get(reactionConfig.targetChannelID).send(`<@&${reactionConfig.staffRoleID}> - ${user} want to get Wookiee role. Please take action and check requirements!`)
                collector.stop();
                    break;
                }
            }
        })

    }
}
问题原因与解决方案
  • 重复创建ReactionCollector导致资源堆积:每次触发messageReactionAdd事件,代码都会为目标消息创建一个新的反应收集器。随着时间推移,大量活跃的收集器会积累下来,当用户点击表情时,所有收集器都会同时触发collect事件,导致重复发送消息。
  • 未排除机器人自身反应:如果机器人对目标消息有操作(比如添加初始表情),可能会触发事件进入循环,这是潜在的触发重复的诱因。
  • 冗余的消息获取逻辑:每次事件触发都重新获取目标消息,既浪费资源又没必要,直接通过reaction.message即可判断是否为目标消息。

修正后的代码:

const { MessageReaction, Events } = require("discord.js");

const reactionConfig = {
    channelID: "1078339846172573778",
    targetChannelID: "972616312952070144",
    messageID: "1078355581435379723",
    firstEmoji: "926995541596962919",
    staffRoleID: "886867243076567071",
    normalRoleID: "886869696752803890",
};

module.exports = {
    name: Events.MessageReactionAdd,

    /**
     * @param {MessageReaction} reaction
     * @param {import('discord.js').User} user
     */
    async execute(reaction, user) {
        const client = reaction.client;

        // 排除机器人自身反应,避免循环触发
        if (user.bot) return;

        // 处理部分反应对象,获取完整数据
        if (reaction.partial) {
            try {
                await reaction.fetch();
            } catch (error) {
                console.error('获取消息时出错:', error);
                return;
            }
        }

        // 校验当前反应是否属于目标频道和目标消息
        if (reaction.message.channel.id !== reactionConfig.channelID || reaction.message.id !== reactionConfig.messageID) {
            return;
        }

        // 校验是否为目标表情,发送通知
        if (reaction.emoji.id === reactionConfig.firstEmoji) {
            try {
                await client.channels.cache.get(reactionConfig.targetChannelID).send(`<@&${reactionConfig.staffRoleID}> - ${user} 想要获取 Wookiee 角色,请处理并检查要求!`);
            } catch (error) {
                console.error('发送通知消息时出错:', error);
            }
        }
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:40:17