使用node-telegram-bot-api如何让机器人等待用户输入响应?
解决node-telegram-bot-api等待用户输入的问题
你的核心问题是没有跟踪用户的交互状态,点击"Food"后直接用当前文本(即"Food")调用了add函数,自然不会等待后续输入。要实现点击选项后等待输入的逻辑,需要给每个用户维护一个交互状态,区分当前是选择类别还是输入金额。
完整实现代码
const TelegramBot = require('node-telegram-bot-api'); const token = '你的机器人Token'; const bot = new TelegramBot(token, { polling: true }); // 存储每个用户的消费数据,key为chatId const personalData = {}; // 存储用户当前的交互状态:key为chatId,value为等待输入的类别(如'food') const userStates = {}; // 处理用户消息(包括键盘点击的文本) bot.on('message', (msg) => { const chatId = msg.chat.id; const text = msg.text.trim(); // 初始化当前用户的消费数据(首次交互时创建) if (!personalData[chatId]) { personalData[chatId] = { food: 0 }; } // 优先处理用户处于等待输入金额的状态 if (userStates[chatId]) { const targetCategory = userStates[chatId]; const inputAmount = parseFloat(text); // 验证输入是否为有效正数 if (!isNaN(inputAmount) && inputAmount > 0) { personalData[chatId][targetCategory] += inputAmount; bot.sendMessage(chatId, `餐饮消费已更新:${personalData[chatId][targetCategory]}`); } else { bot.sendMessage(chatId, '请输入有效的正数金额,重新输入吧'); // 不重置状态,让用户继续输入 return; } // 完成输入后重置用户状态 delete userStates[chatId]; return; } // 处理类别选择(如点击Food按钮) if (text === 'Food') { bot.sendMessage(chatId, '请输入餐饮消费的金额'); // 设置用户状态为等待输入food类别的金额 userStates[chatId] = 'food'; } // 可扩展其他类别,比如: // if (text === 'Transport') { // bot.sendMessage(chatId, '请输入交通消费金额'); // userStates[chatId] = 'transport'; // personalData[chatId].transport = personalData[chatId].transport || 0; // } });
关键逻辑说明
- 状态管理:
userStates对象记录每个用户的当前操作阶段,用户点击"Food"后,状态被设为'food',下一次用户发送消息时,程序就知道这是要输入该类别的金额。 - 多用户支持:
personalData以chatId为key存储每个用户的独立数据,避免不同用户的数据互相干扰。 - 输入验证:加入了数字有效性检查,防止用户输入非数字内容导致数据错误。
- 流程控制:先判断用户是否处于等待输入状态,再处理类别选择,确保交互流程的顺序性。
原代码问题分析
你原来的代码在用户发送"Food"时,直接执行add('food', text),这里的text是字符串"Food",转成数字后是NaN,加到personalData.food会导致值变为NaN,而且完全没有等待用户后续输入金额的逻辑,自然达不到预期效果。
内容的提问来源于stack exchange,提问作者Voltfex
相关产品推荐
相关产品推荐

