discord.js v14.7.1 反应监听功能失效求助
Discord.js v14 反应无响应问题修复
问题场景
使用discord.js v14.7.1在Replit开发Discord机器人,执行!classes命令时,机器人可正常发送嵌入消息并添加🇦、🇧反应,但触发反应后无任何响应,反应也不会被取消。
问题根源
awaitReactions未设置超时时间,若用户未操作会进入无限等待状态,且无任何提示- 反应收集后的错误处理范围不全,
awaitReactions本身的异常未被捕获 - 未移除用户触发的反应,导致反应残留
- 重复代码冗余,增加了出错概率
修正后的代码
const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.MessageContent, ] }); client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); // 提取复用的作业收集函数 async function collectHomework(channel, author, className) { await channel.send(`Please enter your homework for ${className}:`); const homeworkMsg = await channel.awaitMessages({ filter: m => m.author.id === author.id, max: 1, time: 60000, // 1分钟超时 errors: ['time'] }); const homework = homeworkMsg.first().content; await channel.send('Please enter the due date for your homework (e.g. "Tomorrow at 3pm"):'); const dateMsg = await channel.awaitMessages({ filter: m => m.author.id === author.id, max: 1, time: 60000, errors: ['time'] }); const dueDate = dateMsg.first().content; return { homework, dueDate }; } client.on('messageCreate', async message => { if (!message.content.startsWith('!classes')) return; const embed = new EmbedBuilder() .setTitle('Classes') .addFields( { name: 'Class 1', value: 'Description of Class 1' }, { name: 'Class 2', value: 'Description of Class 2' } ); try { const sentMessage = await message.channel.send({ content: 'Here are the available classes:', embeds: [embed] }); await sentMessage.react('🇦'); await sentMessage.react('🇧'); const filter = (reaction, user) => ['🇦', '🇧'].includes(reaction.emoji.name) && user.id === message.author.id; const collected = await sentMessage.awaitReactions({ filter, max: 1, time: 60000, // 1分钟超时 errors: ['time'] }); const reaction = collected.first(); // 移除用户的反应 await reaction.users.remove(message.author.id); let className, homeworkData; if (reaction.emoji.name === '🇦') { className = 'Class 1'; homeworkData = await collectHomework(message.channel, message.author, className); } else if (reaction.emoji.name === '🇧') { className = 'Class 2'; homeworkData = await collectHomework(message.channel, message.author, className); } else { await message.channel.send('Invalid reaction added. Please try again.'); return; } // 替换为实际的频道ID const homeworkChannel = client.channels.cache.get('YOUR_ACTUAL_CHANNEL_ID'); if (!homeworkChannel) { await message.channel.send('Homework channel not found!'); return; } await homeworkChannel.send(`Homework for ${className}: ${homeworkData.homework}\nDue date: ${homeworkData.dueDate}`); await message.channel.send('Homework submitted successfully!'); } catch (error) { console.error(error); if (error.name === 'CollectingTimeoutError') { await message.channel.send('Operation timed out. Please try again later.'); } else { await message.channel.send('An error occurred while processing your request.'); } } }); client.login('YOUR_BOT_TOKEN');
关键修复点
- 为所有
awaitMessages和awaitReactions添加time超时参数(1分钟),并处理超时错误 - 将反应收集和作业收集的逻辑包裹在
try-catch中,捕获所有异常并给出用户提示 - 收集到反应后立即移除用户的反应,解决反应残留问题
- 提取复用的作业收集函数,减少代码冗余,提升可维护性
- 增加频道存在性检查,避免因频道ID错误导致的崩溃
内容的提问来源于stack exchange,提问作者Coralap
相关产品推荐
相关产品推荐

