Discord.js如何实现bot等待用户回复后再发送下一条问题
核心问题
你现有代码无法实现顺序等待的根本原因:
client.on("messageCreate")是注册全局永久事件监听器,注册动作本身不会阻塞代码执行,所以发完第一个问题后程序会立刻往下跑,直接发送第二个问题,根本不会等用户输入- 每次调用提问函数都会新增一个全局监听器,后续全服所有频道的消息都会触发这个监听器,不仅会出现重复执行逻辑的bug,还会造成内存泄漏
正确实现方式
用discord.js频道对象自带的awaitMessages方法做一次性消息收集即可,这个方法会返回Promise,等到符合条件的用户消息后才会继续往下执行,天然适配顺序问答的流程。
修正后的完整代码如下:
const { MessageEmbed } = require("discord.js"); const clearMessages = require("./clearMessages"); const askEventQuestions = async (client, channelId, targetUserId) => { const edonoChannel = client.channels.cache.get(channelId); const answers = []; // 所有问题按提问顺序存在数组中,后续新增问题直接往数组里加Embed即可 const questionEmbeds = [ new MessageEmbed() .setColor("AQUA") .setDescription("What Type of Event would you like to donate for?"), new MessageEmbed() .setColor("AQUA") .setDescription("What are the amounts of DMC/Items that you are donating?") ]; // 消息过滤规则:只接收触发问答的目标用户发送的非bot消息,避免其他用户发言干扰流程 const messageFilter = (msg) => !msg.author.bot && msg.author.id === targetUserId; // 循环逐个提问 for (const embed of questionEmbeds) { await edonoChannel.send({ embeds: [embed] }); try { // 等待用户回复,最多收集1条符合规则的消息,设置5分钟超时 const collectedMsg = await edonoChannel.awaitMessages({ filter: messageFilter, max: 1, time: 300000, errors: ["time"] }); const userReply = collectedMsg.first(); answers.push(userReply.content); // 删除问题消息和用户回复共2条 await clearMessages(2, userReply); } catch (e) { // 超时未收到回复的处理逻辑 await edonoChannel.send("问答超时,流程已结束"); return; } } // 所有问题收集完成后,可从answers数组按顺序拿到所有用户回复,做后续业务处理 console.log("收集到的答案列表:", answers); };
注意事项
- 函数新增了
targetUserId参数,调用时需要传入触发问答流程的用户ID,确保只有该用户的回复会被收集,不会被频道其他人的消息打断 - 如果你不需要限制回复用户,把
messageFilter里的&& msg.author.id === targetUserId删掉即可 awaitMessages是一次性收集,流程执行完不会残留全局监听器,没有内存泄漏风险- 超时时间可自行调整,
time字段单位为毫秒,当前设置的300000毫秒即5分钟
内容的提问来源于stack exchange,提问作者Ramy Hazem
相关产品推荐
相关产品推荐

