如何在Discord机器人Bingo命令中监听新消息并校验message.content?
解决Discord Bingo命令的消息监听与校验问题
核心问题修正
原代码里的while(!founded)循环会阻塞Node.js事件循环,导致机器人完全卡死,绝对不能这么用。正确的做法是用Discord.js提供的**消息收集器(MessageCollector)**来监听频道消息,它能在不阻塞事件循环的前提下,过滤并处理符合条件的消息。
另外,原随机数生成逻辑有错误,生成的数字范围不对,需要修正为正确的min到max区间随机数。
完整实现代码
client.on("interactionCreate", async interaction => { if (!interaction.isCommand()) return; if (interaction.commandName !== "bingo") return; const min = interaction.options.getInteger("min"); const max = interaction.options.getInteger("max"); // 修正随机数生成逻辑:生成min到max之间(包含两端)的随机整数 const targetNumber = Math.floor(Math.random() * (max - min + 1)) + min; let founded = false; const firstEmbed = new Discord.EmbedBuilder() .setTitle("Bingo 游戏开始") .setDescription(`目标是猜出 ${Discord.bold(min)} 到 ${Discord.bold(max)} 之间的随机数字!`) .setFooter({ text: interaction.guild.name, iconURL: interaction.guild.iconURL() }); await interaction.reply({ embeds: [firstEmbed] }); // 创建消息收集器,监听当前交互频道的消息 const filter = m => { // 过滤条件:不是机器人发送的消息,内容是有效数字,且在指定区间内 const num = parseInt(m.content); return !m.author.bot && !isNaN(num) && num >= min && num <= max; }; // 设置收集器参数:过滤函数,可选项(比如超时时间) const collector = interaction.channel.createMessageCollector({ filter, time: 60000 }); // 60秒超时 // 监听符合条件的消息 collector.on("collect", async m => { const guessedNumber = parseInt(m.content); if (guessedNumber === targetNumber) { founded = true; collector.stop("bingo"); // 结束收集器,标记为bingo成功 const successEmbed = new Discord.EmbedBuilder() .setTitle("🎉 Bingo!") .setDescription(`${m.author} 猜对了!目标数字就是 ${Discord.bold(targetNumber)}`) .setColor("Green") .setFooter({ text: interaction.guild.name, iconURL: interaction.guild.iconURL() }); await interaction.followUp({ embeds: [successEmbed] }); } else { // 猜错了,给出提示 const hint = guessedNumber > targetNumber ? "猜大了!" : "猜小了!"; await m.reply({ content: hint, ephemeral: true }); // ephemeral只让发送者看到提示 } }); // 监听收集器结束事件 collector.on("end", (collected, reason) => { if (reason !== "bingo") { const timeoutEmbed = new Discord.EmbedBuilder() .setTitle("⏰ 游戏结束") .setDescription(`时间到了,没人猜对!目标数字是 ${Discord.bold(targetNumber)}`) .setColor("Red") .setFooter({ text: interaction.guild.name, iconURL: interaction.guild.iconURL() }); interaction.followUp({ embeds: [timeoutEmbed] }); } }); });
关键部分说明
- 消息收集器(MessageCollector):通过
channel.createMessageCollector()创建,自带过滤和事件监听机制,不会阻塞机器人的其他逻辑。 - 过滤函数:确保只处理用户发送的有效数字消息,排除机器人自己的消息和无效输入。
- 超时设置:给游戏设置时间限制(示例是60秒),避免收集器一直运行。
- 交互回复:用
followUp()发送后续消息,保持和初始命令回复的关联。
内容的提问来源于stack exchange,提问作者pierrepapierciseaux Lafontaine
相关产品推荐
相关产品推荐

