基于node-telegram-bot-api的花店Bot:如何处理键盘与自定义回复?
处理Telegram Bot自定义回复的解决方案
要处理用户的自定义回复(姓名、电话、地址等),核心是跟踪用户的对话状态——明确用户当前处于哪个提问环节,才能正确识别回复对应的信息并推进流程。以下是具体实现步骤:
1. 管理用户对话状态
用一个对象(生产环境建议用Redis或数据库)存储每个用户的当前对话阶段,避免内存重启丢失数据:
// 内存存储用户状态(仅示例,生产环境请用数据库) const userStates = {}; // 定义状态常量,避免拼写错误 const STATES = { AWAITING_NAME: 'awaiting_name', AWAITING_PHONE: 'awaiting_phone', AWAITING_ADDRESS: 'awaiting_address' };
2. 发送提问时更新状态
在键盘回复处理完成后,发送下一个自定义问题,并同步更新用户的对话状态:
// 处理"Add a card"回复,切换到等待姓名状态 bot.onText(new RegExp('Add a card'), msg => { const chatId = msg.chat.id; userStates[chatId] = STATES.AWAITING_NAME; bot.sendMessage(chatId, '请输入您的姓名:'); }); // 处理配送时间选择,切换到等待电话状态(示例) bot.onText(new RegExp('(今日配送|明日配送)'), msg => { const chatId = msg.chat.id; // 先保存用户选择的配送时间(可存入订单对象) const deliveryDate = msg.text; userStates[chatId] = STATES.AWAITING_PHONE; bot.sendMessage(chatId, '请输入您的联系电话:'); });
3. 监听所有消息,按状态处理自定义回复
通过bot.on('message')监听所有文本消息,根据用户当前状态识别回复、验证内容并推进流程:
// 监听所有文本消息,处理自定义回复 bot.on('message', msg => { const chatId = msg.chat.id; const userInput = msg.text.trim(); const currentState = userStates[chatId]; // 用户未处于待收集状态时,忽略(可额外处理/start等初始命令) if (!currentState) return; // 按当前状态处理回复 switch (currentState) { case STATES.AWAITING_NAME: // 验证姓名:非空且长度≥2 if (userInput.length < 2) { bot.sendMessage(chatId, '姓名长度不能少于2位,请重新输入:'); return; } // 保存姓名(示例,生产环境存入数据库或订单对象) const userName = userInput; // 推进到下一步:等待电话 userStates[chatId] = STATES.AWAITING_PHONE; bot.sendMessage(chatId, '请输入您的联系电话:'); break; case STATES.AWAITING_PHONE: // 验证手机号格式(适配国内号码,可根据需求调整正则) const phoneRegex = /^1[3-9]\d{9}$/; if (!phoneRegex.test(userInput)) { bot.sendMessage(chatId, '请输入有效的手机号格式:'); return; } const userPhone = userInput; // 推进到下一步:等待地址 userStates[chatId] = STATES.AWAITING_ADDRESS; bot.sendMessage(chatId, '请输入您的配送地址:'); break; case STATES.AWAITING_ADDRESS: // 验证地址:非空且信息足够详细 if (userInput.length < 5) { bot.sendMessage(chatId, '地址信息不够详细,请重新输入:'); return; } const userAddress = userInput; // 所有信息收集完成,重置状态 delete userStates[chatId]; // 发送订单确认消息 bot.sendMessage(chatId, `订单信息确认:\n姓名:${userName}\n电话:${userPhone}\n地址:${userAddress}\n我们会尽快安排配送!`); break; } });
额外优化建议
- 生产环境不要用内存对象存储状态,改用Redis或数据库,避免重启丢失用户对话进度。
- 可以给每个用户维护一个订单对象,统一存储收集到的所有信息(姓名、电话、地址、配送时间等)。
- 添加取消命令(如
/cancel),允许用户中途终止流程并重置状态。 - 验证逻辑可根据业务需求调整,比如支持国际手机号、地址格式校验等。
内容的提问来源于stack exchange,提问作者katrin_melody
相关产品推荐
相关产品推荐

