Facebook Messenger Webhook用户信息收集:问答关联存储问题咨询
关联Messenger提问与用户回答并存储的解决方案
我之前做过类似的Messenger机器人信息收集功能,刚好能给你一些实用的思路。核心在于用sender_id跟踪用户的当前提问状态,结合数据库来存储每一步的回答,下面是具体的实现步骤:
1. 设计用户状态与数据存储结构
首先你需要在数据库里创建一张用户表(比如messenger_users),至少包含这些字段:
sender_id:Facebook用户唯一标识(主键,用来关联所有操作)current_step:标记用户当前处于哪个提问环节(比如ask_name、ask_email、ask_phone,或者用数字1/2/3)- 你需要收集的基础信息字段:
full_name、email、phone_number等 created_at/updated_at:可选,记录时间
如果用MongoDB的话,文档结构大概是这样:
{ _id: ObjectId("..."), sender_id: "123456789", // Facebook返回的sender_id current_step: "ask_email", full_name: "John Doe", email: "", phone_number: "", created_at: ISODate("2024-05-20T10:00:00Z") }
2. Webhook核心逻辑:根据状态处理用户消息
当你的Webhook收到用户消息时,流程应该是这样的:
- 从请求中提取
sender_id和用户输入的message_text - 根据
sender_id查询数据库,获取该用户的current_step - 根据当前步骤,把用户的回答对应存储到数据库的字段中
- 更新用户的
current_step为下一个提问环节,或者如果是最后一步就标记为完成 - 发送下一个问题给用户(或者结束提示)
举个Node.js + Express的代码示例:
const express = require('express'); const mongoose = require('mongoose'); const app = express(); // 连接MongoDB(假设你已经配置好) mongoose.connect('mongodb://localhost:27017/messenger_bot', { useNewUrlParser: true }); // 定义用户模型 const User = mongoose.model('User', { sender_id: { type: String, unique: true, required: true }, current_step: { type: String, default: 'ask_name' }, full_name: String, email: String, phone_number: String }); // Webhook接收消息的路由 app.post('/webhook', async (req, res) => { const messagingEvent = req.body.entry[0].messaging[0]; const sender_id = messagingEvent.sender.id; const message_text = messagingEvent.message.text; try { // 查找用户,不存在则创建新用户(第一次对话) let user = await User.findOne({ sender_id }); if (!user) { user = new User({ sender_id }); await user.save(); // 第一次对话,发送第一个问题 sendMessengerMessage(sender_id, "您好!请问您的全名是?"); return res.sendStatus(200); } // 根据当前步骤处理回答 switch(user.current_step) { case 'ask_name': // 存储姓名 user.full_name = message_text; // 更新步骤为问邮箱 user.current_step = 'ask_email'; await user.save(); // 发送下一个问题 sendMessengerMessage(sender_id, "感谢您的告知!请问您的邮箱地址是?"); break; case 'ask_email': user.email = message_text; user.current_step = 'ask_phone'; await user.save(); sendMessengerMessage(sender_id, "好的!最后请问您的联系电话是?"); break; case 'ask_phone': user.phone_number = message_text; user.current_step = 'completed'; await user.save(); sendMessengerMessage(sender_id, "信息收集完成!感谢您的配合😊"); break; default: // 用户已完成收集,发送默认回复 sendMessengerMessage(sender_id, "您的信息已经收集完成啦,如果有其他需求请告诉我~"); } res.sendStatus(200); } catch (err) { console.error("处理用户消息出错:", err); res.sendStatus(500); } }); // 封装发送Messenger消息的函数(你已经有基础的回复逻辑,这里简化示例) function sendMessengerMessage(senderId, text) { // 调用Facebook Graph API发送消息的逻辑,这里省略具体实现 console.log(`发送消息给${senderId}: ${text}`); } app.listen(3000, () => console.log("Webhook服务启动在3000端口"));
3. 额外注意事项
- 状态持久化:如果用户长时间不回复,状态要保留,所以数据库比缓存更可靠,当然你也可以用Redis做短期缓存+数据库持久化的组合
- 输入验证:比如收集邮箱时要校验格式,不符合的话可以提示用户重新输入,同时不更新状态
- 异常处理:比如数据库连接失败、Facebook API调用失败,要做好日志记录和容错
- 多线程/分布式场景:如果你的Webhook是多实例部署,要注意状态更新的原子性(比如用数据库的事务或者乐观锁)
这样就能把每一个问题和用户的回答准确关联起来,并且完整存储到数据库里啦!
内容的提问来源于stack exchange,提问作者Hardik Kalathiya
相关产品推荐
相关产品推荐

