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

Discord.js消息反应监听异常:仅响应机器人自身操作

解决Discord机器人消息反应监听无响应问题

核心问题诊断

  1. 缺失必要的Intents:Discord.js v13及以上版本中,监听消息反应事件必须启用GUILD_MESSAGE_REACTIONS意图,当前代码未配置该权限。
  2. 未处理Partial对象:如果监听的消息是机器人启动前已存在的,或不在客户端缓存中,反应事件触发时会返回Partial对象,需启用Partial支持并处理完整数据。

具体修改步骤

1. 补充Intents并启用Partial支持(修改index.js)

修改客户端初始化代码,添加缺失的意图并开启消息、反应、用户的Partial支持:

const { Client, Intents } = require('discord.js');
const roleClaim = require('./role-claim')

const client = new Client({ 
  intents: [
    Intents.FLAGS.GUILDS, 
    Intents.FLAGS.GUILD_MESSAGES,
    Intents.FLAGS.GUILD_MESSAGE_REACTIONS // 新增:监听消息反应的必要意图
  ],
  partials: ['MESSAGE', 'REACTION', 'USER'] // 新增:处理缓存外的Partial对象
});

client.login("你的机器人Token"); 
const config = require("./config.json");

client.on("ready", () => {
  client.user.setActivity("altV: Multiplayer on FreeZone", { type: "PLAYING" })
  console.log("1000-7");
  roleClaim(client);
})

2. 处理Partial事件并过滤机器人操作(修改role-claim.js)

在反应事件监听中先获取完整对象,并排除机器人自身的反应操作:

const firstMessage = require('./first-message')

module.exports = (client) => {
  const channelId = '813819563703271484'

  const getEmoji = (emojiName) => client.emojis.cache.find((emoji) => emoji.name === emojiName)

  const emojis = {
    mercedes: 'Mercedes',
    ferrari: 'FERRARI',
    renault: 'RENAULT'
  }

  const reactions = []

  let emojiText = 'Pick any team \n\n'
  for (const key in emojis) {
    const emoji = getEmoji(key)
    reactions.push(emoji)
    const role = emojis[key]
    emojiText += `${emoji} = ${role} \n` 
  }

  firstMessage(client, channelId, emojiText, reactions);

  // 修改添加反应监听,处理Partial对象
  client.on('messageReactionAdd', async (reaction, user) => {
    // 若为Partial对象,先获取完整数据
    if (reaction.partial) {
      try { await reaction.fetch(); } 
      catch (err) { console.error('获取反应数据失败:', err); return; }
    }
    if (user.partial) {
      try { await user.fetch(); } 
      catch (err) { console.error('获取用户数据失败:', err); return; }
    }
    // 跳过机器人自身的反应
    if (user.bot) return;
    console.log("用户添加了反应");
    // 此处可添加角色分配逻辑
  })

  // 修改移除反应监听,处理Partial对象
  client.on('messageReactionRemove', async (reaction, user) => {
    if (reaction.partial) {
      try { await reaction.fetch(); } 
      catch (err) { console.error('获取反应数据失败:', err); return; }
    }
    if (user.partial) {
      try { await user.fetch(); } 
      catch (err) { console.error('获取用户数据失败:', err); return; }
    }
    if (user.bot) return;
    console.log("用户移除了反应");
    // 此处可添加角色移除逻辑
  })
}

3. 优化消息处理逻辑(修改first-message.js)

原代码遍历频道所有消息并编辑,建议只处理目标消息,避免不必要的操作:

function addReactions(message, reactions) {
  message.react(reactions[0])
  reactions.shift()
  if (reactions.length > 0) {
    setTimeout(() => addReactions(message, reactions), 750)
  }
}

module.exports = async (client, id, text, reactions = []) => {
  const channel = await client.channels.fetch(id)
  const messages = await channel.messages.fetch();

  if (messages.size === 0) {
    channel.send(text).then(message => addReactions(message, reactions))
  } else {
    // 仅处理频道内第一条消息,可根据需求调整
    const targetMessage = messages.first();
    await targetMessage.edit(text);
    // 清除现有反应后重新添加
    await targetMessage.reactions.removeAll();
    addReactions(targetMessage, reactions);
  }
}

关键说明

  • Intents权限:Discord API要求机器人明确声明所需权限,GUILD_MESSAGE_REACTIONS是接收反应事件的必要条件。
  • Partial对象:当消息/反应不在本地缓存时,需通过fetch()获取完整数据才能正常操作。
  • 过滤机器人:添加user.bot判断可避免机器人自身的反应触发业务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:48:18