AI PLAY玩法更新持续收录
← 回到更新流

2026-09-15 · 原文发布日

WhatsApp订座机器人:语音转写、查档与人工接管

面向工作室、诊所、场地等单门店预约业务的n8n模板:接收WhatsApp Business Cloud API的webhook消息后,先按手机号在Airtable查该会话是否处于人工模式,是则静默不回复。语音消息会拉取媒体文件用OpenAI转写成文字,文字消息直接解析。随后由OpenAI代理结合Airtable里的可约档期和商家信息回答咨询、创建待确认预订、按客户回复确认或取消,必要时升级人工。搭建需自备WhatsApp商业账号、开通计费的OpenAI key和含三张表的Airtable库。

原文要点

原模板面向单门店时段预约:接收WhatsApp Business Cloud API webhook,订阅请求回验证挑战,消息事件回EVENT_RECEIVED;无入站消息则忽略。按手机号查Airtable Conversations,人工模式即停止不回。语音先取WhatsApp媒体URL、HTTP下载音频、OpenAI转文字;文字直接从payload取正文和号码。之后OpenAI代理可查Airtable档期与商家信息,建待确认预订、确认、取消或升级人工;代理有回复且非无需回复时,经WhatsApp发回。需WhatsApp商业号、已计费OpenAI、Airtable三张表,媒体下载还要HTTP Header Auth。

这次做成什么

做成一个单门店订座机器人练习版:收到文字或语音WhatsApp消息后,先判断人工模式静默,再把输入统一成文本,让代理读Airtable可约档期和商家信息,输出待确认、确认、取消、FAQ或升级,最后只在需要时回WhatsApp。站内方案用三张Airtable表、一个webhook验证段、一个人工模式闸门、一个语音转写支路和OpenAI代理提示词完成,不假装提供原工作流下载。

准备什么

  • WhatsApp Business Cloud API测试号、Phone Number ID和可把webhook指到n8n的应用设置权限
  • 已开通计费的OpenAI API key,同时供聊天代理和音频转写节点使用
  • Airtable可编辑库,含Bookings、Business Info、Conversations三表及自增booking_id
  • n8n可公网访问的webhook地址,另建HTTP Header Auth凭证下载WhatsApp媒体

具体怎么做

  1. 建Airtable三表并放合成样例

    Conversations列表头:phone、human_mode、last_session、updated_at;Bookings列表头:booking_id用Autonumber,另加phone、customer_name、slot_date、slot_time、party_size、status、notes;Business Info列表头:key、value、language。导入下方合成CSV。把所有Airtable节点中的base/table占位ID替换为练习库ID,字段名与表头完全一致,避免代理工具找不到列。

  2. 完成webhook验证与消息闸门

    Webhook节点接收WhatsApp GET验证:当query含hub.mode=subscribe与hub.verify_token时返回hub.challenge;POST消息立即回EVENT_RECEIVED。Switch节点过滤无messages数组或statuses回执的事件,只保留入站消息。再接Airtable Conversations按phone查询;IF条件human_mode=true直接NoOp结束,不发任何自动回复。字段映射:phone={{$json.entry[0].changes[0].value.messages[0].from}},msg_type={{$json...messages[0].type}}。

  3. 语音支路转文字,文字支路直取正文

    IF按msg_type分流。text分支Set:customer_text=messages[0].text.body。audio分支先用WhatsApp节点按messages[0].audio.id取media URL,再用HTTP Request下载,URL={{$json.media_url}},认证选HTTP Header Auth,头名Authorization,值填Bearer 你的隔离token;响应设binary。接OpenAI Transcribe,file取二进制,输出text写回customer_text。两支路合并为统一{phone,customer_text,message_id}。

  4. 接OpenAI代理并挂Airtable工具

    Agent节点系统提示词用下方订座代理全文,模型选已具备凭证的聊天模型,不新增作者未提模型名。工具只配置三项:Airtable Search读Business Info与Bookings空档,Airtable Create在Bookings写status=pending,Airtable Update按phone+booking_id把pending改confirmed或cancelled。升级人工不调用真实外呼,只Update Conversations.human_mode=true并返回固定提示。代理输出JSON字段:reply、action、booking_id、no_response_needed。

  5. 回复发送与静默控制

    Agent后接Code解析JSON;若no_response_needed=true或action=human_handoff且human_mode已为真,则不发送。否则WhatsApp Send节点选同一Phone Number ID,to=phone,text=reply。确认码练习沿用原文提到的2/3:客户回2把最新pending改confirmed,回3改cancelled;如要按钮需自行核对你账号是否支持。每次发送后更新Conversations.last_session与updated_at。

  6. 用合成事件跑三种结局

    先在Meta开发者面板把webhook指向n8n测试URL并完成验证。用下方example.input发文字预约,期待Bookings新增pending;再发内容为2的消息,期待同一booking_id变confirmed;把Conversations中该phone改human_mode=true,再发任意消息,执行日志应停在闸门且无WhatsApp发送记录。语音测试用本地假media URL走HTTP节点,不要把真实客户音频拉进练习库。

可直接复制的材料

Airtable三表合成CSV

本站合成练习数据;booking_id在Airtable应为Autonumber,CSV仅演示字段,导入后可删编号由Airtable自增。

Conversations.csv
phone,human_mode,last_session,updated_at
8613800001111,FALSE,sess-wa-demo-01,2026-09-15 09:00
8613900002222,TRUE,sess-wa-demo-02,2026-09-15 09:05

Bookings.csv
booking_id,phone,customer_name,slot_date,slot_time,party_size,status,notes
1,8613800001111,测试甲,2026-09-20,19:00,2,pending,靠窗
2,8613900002222,测试乙,2026-09-21,12:30,4,cancelled,人工处理

Business Info.csv
key,value,language
hours,周二至周日 11:30-22:00,zh
address,滨河路88号一层,zh
policy,预订保留15分钟;取消需提前2小时,zh

OpenAI订座代理系统提示词

本站独立编写;确认码2/3来自原文描述,若换交互按钮需自行核对账号能力。

你是单门店时段预约助手,只处理一个地点。可用事实仅来自Airtable的Business Info与Bookings;查不到就说无法确认,不编造营业时间、地址、价格或空档。
输入:phone={{phone}},customer_text={{customer_text}}。
任务:1)咨询:用Business Info回答;2)预约:缺slot_date、slot_time、party_size就追问,齐了在Bookings创建status=pending;3)客户只回2:把该phone最新pending改为confirmed;只回3:改为cancelled;4)客户要求投诉、退款、人工、开发票或连续两次无法理解:action=human_handoff并把Conversations.human_mode置true;5)已是人工模式时不要回复。
输出严格JSON:{"reply":"中文短句","action":"faq|create_pending|confirm|cancel|human_handoff|none","booking_id":null,"no_response_needed":false}。reply不超过120字;需要静默时reply为空且no_response_needed=true。

统一消息字段映射配置

路径按常见Cloud API结构写成练习映射;具体节点字段需以你导入模板或面板显示为准,未声称已实测。

Webhook解析:phone=$json.entry[0].changes[0].value.messages[0].from;msg_type=$json.entry[0].changes[0].value.messages[0].type;message_id=$json.entry[0].changes[0].value.messages[0].id;text_body=$json.entry[0].changes[0].value.messages[0].text.body;audio_id=$json.entry[0].changes[0].value.messages[0].audio.id。Conversations查询:filterByFormula={phone}='{{phone}}'。闸门:human_mode=true时Stop。语音:media_url来自WhatsApp媒体读取;HTTP Request Method=GET,Authentication=Header Auth,Header Name=Authorization,Header Value=Bearer <隔离媒体token>,Response=File。合并后字段固定为phone、customer_text、message_id、source=text|audio。

代理工具调用边界数据

本站设计的护栏,不是原模板文件;用于限制工具只碰预约相关列。

工具白名单JSON:{"tools":[{"name":"airtable_search_business","allowed_tables":["Business Info"],"max_records":10},{"name":"airtable_search_bookings","allowed_tables":["Bookings"],"filters":["slot_date","status"],"max_records":20},{"name":"airtable_create_booking","allowed_fields":["phone","customer_name","slot_date","slot_time","party_size","status","notes"],"fixed_status":"pending"},{"name":"airtable_update_booking","allowed_fields":["status","notes"],"require_match":"phone+latest_pending"},{"name":"set_human_mode","allowed_fields":["human_mode","updated_at"],"fixed_value":true}]}。禁止代理读写payment、身份证、银行卡字段;本练习不放这些列。

POST消息隔离测试事件

虚构号码与WABA ID;验证GET请用Meta面板下发,不要把此JSON当验证请求。

{"object":"whatsapp_business_account","entry":[{"id":"WABA_DEMO","changes":[{"value":{"messaging_product":"whatsapp","metadata":{"phone_number_id":"PNID_DEMO"},"messages":[{"from":"8613800001111","id":"wamid.demo1","timestamp":"1757900000","type":"text","text":{"body":"你好,9月20日晚上7点两个人还有位吗?想订靠窗。"}}]},"field":"messages"}]}]}

输入与输出示例

本站虚构演示,未真实调用WhatsApp/OpenAI/Airtable;数字与字段均对应上述合成输入。

输入

上一条POST事件:来自8613800001111,文字“你好,9月20日晚上7点两个人还有位吗?想订靠窗。”;Conversations中human_mode=FALSE;Bookings里2026-09-20 19:00尚无confirmed冲突。

对应输出

闸门结果human_mode=false继续;source=text,customer_text=原句。代理查询Business Info得hours与policy,查Bookings发现19:00可约,创建booking_id=3:phone=8613800001111,slot_date=2026-09-20,slot_time=19:00,party_size=2,status=pending,notes=靠窗。代理JSON:{"reply":"已为你预留9月20日19:00两位,备注靠窗;保留15分钟。回复2确认,回复3取消。","action":"create_pending","booking_id":3,"no_response_needed":false}。WhatsApp Send到8613800001111发送该reply;客户回2后同一booking_id改confirmed。

做完检查这些

  • GET验证返回hub.challenge,POST无message或仅statuses时只确认不进入代理
  • Conversations.human_mode=true时执行停止,Airtable不新增、WhatsApp不发送
  • 语音audio支路能把二进制交给转写节点,最终与text支路合并成同一customer_text字段
  • 预约信息齐全才创建pending,缺日期时间人数时reply只追问不建单
  • 客户回2或回3只影响该phone最新pending,确认后Conversations.updated_at被刷新

容易卡住的地方

  • WhatsApp回执statuses被当成入站消息,会导致空文本进入代理,必须先过滤
  • media下载缺Authorization头会401,练习用隔离token,不指导复用真实客户凭据
  • OpenAI key未开计费或模型无权限时聊天与转写会失败,勿承诺免费可用
  • Airtable占位base/table ID未替换,代理会读写错库或找不到booking_id
  • 原文说单门店;多门店必须自己加location字段并改提示词,不能宣称模板已支持
  • 人工模式字段若是文本TRUE而非布尔,IF判断会失效,需统一勾选字段类型

原文与作者资料 ↗

本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。

原文标题
Handle WhatsApp booking requests with OpenAI and Airtable
原作者
Eshal Naveed
原始发布日期
2026-09-15T13:10:14.078Z
来源
https://n8n.io/workflows/19631