如何在Discord.js中检测用户对消息内嵌表情的反应并向其发送私信
问题排查与修复方案
你当前代码无法检测到反应是因为存在属性调用错误、缺少必要的事件监听与权限配置,修复方案如下:
- 首先确认你使用的Discord.js版本为v13及以上,该版本开始强制要求配置网关意图,才能接收反应相关事件
- 原代码存在两处属性错误:反应对象的消息ID属性为
reaction.message.id而非reaction.msg.id,触发反应的用户是事件返回的user参数,不存在reaction.author属性 - Discord.js默认不会缓存机器人启动前就已发送的旧消息,要监听旧消息的反应需要主动将目标消息抓取到缓存中
- 需要过滤机器人触发的反应,避免第三方机器人自身的操作触发你的逻辑
- 要等第三方机器人完成角色分配,可以加合理的延时触发私信逻辑
1. 前置意图配置
初始化客户端时必须开启消息反应相关的意图,示例代码如下:
const { Client, IntentsBitField } = require('discord.js'); const client = new Client({ intents: [ IntentsBitField.Flags.Guilds, IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.GuildMessages, IntentsBitField.Flags.GuildMessageReactions // 必须开启该意图才能接收反应事件 ] });
同时需要前往Discord开发者后台的Bot设置页,把「Privileged Gateway Intents」下的Server Members Intent开关打开。
2. 目标消息预缓存配置
如果你的目标消息是机器人启动前就已发送到频道的,需要在机器人就绪后主动抓取该消息存入缓存:
client.on('ready', async () => { console.log(`已登录为 ${client.user.tag}`); // 替换为目标消息所在的频道ID const targetChannelId = '替换为你的实际频道ID'; const targetMessageId = '910907568459759617'; try { const channel = await client.channels.fetch(targetChannelId); await channel.messages.fetch(targetMessageId); console.log('目标消息已缓存,可正常监听反应'); } catch (err) { console.error('抓取目标消息失败:', err); } });
3. 反应事件监听完整代码
client.on('messageReactionAdd', async (reaction, user) => { // 过滤所有机器人触发的反应 if (user.bot) return; // 处理部分缓存的反应数据 if (reaction.partial) { try { await reaction.fetch(); } catch (error) { console.error('拉取反应完整数据失败:', error); return; } } const targetMessageId = '910907568459759617'; const targetEmoji = '🧰'; // 如果是自定义表情,可替换为表情ID // 匹配目标消息和指定表情 if (reaction.message.id === targetMessageId && reaction.emoji.name === targetEmoji) { console.log("检测到目标反应,准备发送私信"); // 等待2秒让第三方机器人完成角色分配,时长可根据实际情况调整 setTimeout(async () => { try { await user.send("你好,可以提供一下你的邮箱地址吗?"); } catch (err) { console.error(`给用户${user.id}发送私信失败,可能是用户关闭了服务器私信权限:`, err); } }, 2000); } });
内容的提问来源于stack exchange,提问作者COdeingNinja
相关产品推荐
相关产品推荐

