Discord.js 函数内调用.then提示未定义及反应监听、消息发送异常
代码问题排查与修复方案
核心错误点
- 未定义变量引用:filter回调中使用了不存在的
message变量(当前作用域的消息对象命名为msg),直接触发ReferenceError,导致反应收集流程立即中断。 - 自定义emoji匹配逻辑错误:自定义服务器emoji的唯一标识是ID,不能通过
reaction.emoji.name匹配,需改用reaction.emoji.id判断。 - 消息取值错误:embed配置中写的
msg.author.content逻辑错误,消息正文的属性是msg.content,msg.author是发送者用户对象,无content属性,会导致embed描述为空或触发报错。 catch语法无效:当前写法中逗号分隔的第二个字符串参数属于无效入参,Promise的catch仅接收1个回调函数参数,无法输出预期的成功日志。- 异步执行顺序错误:放在
awaitReactions外部的console.log会立即执行,不会等待反应收集完成,因此出现“流程直接走完”的现象。 - 废弃事件监听:discord.js v14+ 已将原
message事件更名为messageCreate,沿用旧事件名会导致消息监听根本不触发。 - 意图未开启(v14+必现):客户端初始化时未开启
GuildMessageReactions对应意图,无法接收反应相关事件,即使监听到消息也收不到反应数据。
修复后完整代码
// v14+ 客户端初始化需引入意图枚举 const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions // 必须开启才能接收反应事件 ] }); // v14+ 消息事件更名为 messageCreate client.on('messageCreate', async msg => { // 排除机器人自身消息,避免触发死循环 if (msg.author.bot) return; // 反应匹配规则 const filter = (reaction, user) => { // 匹配指定自定义emoji + 仅校验消息发送者的反应(需统计全服反应可删除user判断) return reaction.emoji.id === '703033480090484756' && user.id === msg.author.id; }; try { // 等待收集指定数量的反应,max参数即为需要的反应数 await msg.awaitReactions({ filter, max: 1, time: 30000, errors: ['time'] }); const starboard = new Discord.MessageEmbed() .setColor(0xFF0000) .setAuthor(`${msg.author.username}`, msg.author.avatarURL()) .setDescription(msg.content); // 发送内容到指定频道 await client.channels.cache.get('714842643766444122').send(starboard); console.log('Passed! Added to starboard.'); } catch (err) { // 等待超时或其他错误时的处理 if (err.errors?.includes('time')) { console.log('等待反应超时,未添加到星板'); } else { console.log('执行错误:', err); } } });
补充说明
- 若需求为统计所有用户的反应数量,直接删除filter中
&& user.id === msg.author.id的判断,同时将awaitReactions的max参数值改为你需要的指定反应数即可。 - 需确保机器人拥有目标频道的发送消息、嵌入链接权限,以及读取频道历史消息的权限,否则会出现发送静默失败的情况。
- 若使用discord.js v12及更早版本,无需使用
GatewayIntentBits枚举,可在客户端初始化时通过intents配置项传入对应意图的数字值,或直接启用全部非特权意图。
内容的提问来源于stack exchange,提问作者Exonent
相关产品推荐
相关产品推荐

