2026-09-28 · 原文发布日
n8n模板:语音AI牙科前台管理预约
这个n8n工作流接收来自ElevenLabs语音客服的POST webhook,按intent字段把请求路由到预约、改期或取消分支:预约时OpenAI代理查Google Sheets现有记录、追加或更新行并经Gmail发确认邮件;改期时查找匹配预约更新时间;取消时删除对应行,结果通过webhook响应回传给语音客服转告患者。搭建需配置webhook地址、OpenAI与Google Sheets凭据(表格含姓名、电话、邮箱、期望日期时间等列),作者提醒按姓名匹配可能撞名,建议改用唯一标识。
原文要点
这个免费n8n工作流从语音客服(示例为ElevenLabs agent)收POST webhook,JSON里至少要有intent与患者资料;按intent路由到booking、rescheduling、cancellation。预约分支由OpenAI代理查Google Sheets现有预约,追加或更新行,并可经Gmail发确认邮件;改期查找匹配预约后更新时间;取消搜索匹配行并删除。结果通过webhook response回传给语音客服转告患者。作者提醒按Full Name匹配可能撞名,建议改唯一标识;它只是牙科前台起点,不含完整患者管理系统。
这次做成什么
做一个安全的语音牙科前台练习:用三条webhook JSON分别演练预约、改期、取消,强制intent白名单、必填字段校验、唯一patient_id匹配、Sheet行变更与webhook响应一致;先用测试Sheet和手动POST,不接真实ElevenLabs。
准备什么
- n8n实例可开Webhook节点并返回响应,测试用Manual Trigger或curl到测试URL
- OpenAI凭据用于三个分支代理,练习可先用规则判读替代再换模型
- Google Sheets测试表,列含Full Name、Phone Number、Email、Preferred Date、Preferred Time、Reason,并新增patient_id与status
- Gmail凭据仅用于向测试邮箱发确认,不发真实患者
- ElevenLabs账号只在联调时需要,字段名必须按语音agent实际发送核对
具体怎么做
定义webhook契约与测试Sheet
Webhook只接受POST JSON,字段为intent、full_name、phone_number、email、preferred_date、preferred_time、reason、patient_id、request_id。Sheet列完全同名并加status(booked|rescheduled|cancelled)、updated_at。request_id先查重,重复请求直接返回原结果,避免语音端重试造成双预约。
按intent白名单路由
Switch只放行booking、rescheduling、cancellation,其余返回ok=false与code=unsupported_intent。每个入口先校验必填:booking需全部基本字段;rescheduling需patient_id、新preferred_date/time;cancellation需patient_id或request_id。缺字段不写Sheet,直接回code=missing_fields并列出缺失。
预约查重后追加或更新
booking分支先按patient_id查Sheet,存在status=booked且同日期时间的行则返回已存在;存在旧记录则更新该行并status=booked;不存在追加新行。成功后Gmail发测试确认,收件人只用email字段中的测试地址,主题含诊所名与日期,正文不写诊断承诺。
改期取消用唯一标识
rescheduling与cancellation绝不只用Full Name;按patient_id定位,若多行再要求request_id或电话尾号人工复核。改期只更新Preferred Date/Time、status=rescheduled、updated_at;取消把status改为cancelled而不是物理删行,练习环境保留审计。语音端收到ok=true才向患者播报成功。
统一webhook响应给语音客服
所有分支返回JSON:ok、code、message_to_patient、appointment、request_id。失败也回HTTP 200携带ok=false,避免语音平台只判网络层;message_to_patient用自然中文,例如已收到待确认,不谎称医生已批准。记录每次分支、耗时与输入摘要到测试日志。
可直接复制的材料
webhook请求JSON契约
本站练习契约;ElevenLabs实际字段名、OpenAI模型与节点参数需在原模板和语音agent后台核对。
{"accepted_fields":["intent","full_name","phone_number","email","preferred_date","preferred_time","reason","patient_id","request_id"],"intents":["booking","rescheduling","cancellation"],"required":{"booking":["intent","full_name","phone_number","email","preferred_date","preferred_time","patient_id","request_id"],"rescheduling":["intent","patient_id","preferred_date","preferred_time","request_id"],"cancellation":["intent","patient_id","request_id"]},"matching":"patient_id_only","cancel_mode":"soft_delete_status_cancelled","response_codes":["ok","duplicate","missing_fields","not_found","unsupported_intent","conflict"] }三个分支共用系统提示词
本站独立提示词;原模板称使用OpenAI代理,未给出此提示词,接入时需替换为实际节点配置。
你是牙科前台预约代理。只能处理传入JSON和APPOINTMENTS_ROWS,不诊断、不承诺疗效、不创造患者。输出单个JSON:{"ok":true|false,"code":"ok|duplicate|missing_fields|not_found|unsupported_intent|conflict","action":"append|update|none","row_key":"patient_id或空","changes":{"列名":"新值"},"message_to_patient":"不超过60字中文"}。规则:intent不在白名单返回unsupported_intent;缺必填返回missing_fields;预约冲突或同名不同patient_id返回conflict;取消只用soft delete,changes把status设为cancelled;不要删除整行。INPUT={{webhook_json}} ROWS={{sheet_rows}}测试Sheet行与请求
虚构同名两患者用于证明不能只按Full Name;电话邮箱均为测试值。
{"sheet_rows":[{"patient_id":"p-1001","Full Name":"林岚","Phone Number":"13900001111","Email":"linlan@example.test","Preferred Date":"2026-10-03","Preferred Time":"15:00","Reason":"洁牙","status":"booked"},{"patient_id":"p-1002","Full Name":"林岚","Phone Number":"13800002222","Email":"another@example.test","Preferred Date":"2026-10-04","Preferred Time":"10:00","Reason":"复诊","status":"booked"}],"request":{"intent":"rescheduling","patient_id":"p-1001","preferred_date":"2026-10-05","preferred_time":"16:30","request_id":"req-55"}}输入与输出示例
本站虚构演示,未运行OpenAI/Sheets/Gmail;输出只更新p-1001,呼应同名风险。
输入
req-55要求把patient_id=p-1001从2026-10-03 15:00改到2026-10-05 16:30;Sheet中有两个都叫林岚但patient_id不同。对应输出
{"ok":true,"code":"ok","action":"update","row_key":"p-1001","changes":{"Preferred Date":"2026-10-05","Preferred Time":"16:30","status":"rescheduled"},"message_to_patient":"已为您登记改期到10月5日16:30,诊所确认后生效。"} webhook响应同此JSON,p-1002不受影响。做完检查这些
- 重复request_id返回duplicate且不追加第二行
- 非法intent返回unsupported_intent,Sheet无任何变化
- booking缺email或preferred_time时返回missing_fields并逐条列出
- 同名患者存在时只按patient_id命中,Full Name相同不造成conflict误改
- cancellation练习采用status=cancelled软删除,保留原行审计
容易卡住的地方
- 作者明确按Full Name匹配可能撞名;本站改为patient_id是练习方案,接入原模板要同步改匹配列
- ElevenLabs字段名若与预期不一致,webhook入口会先缺字段,不要先在Sheet层补救
- OpenAI代理可能误判日期时间,写入Sheet前必须用契约校验日期格式与必填
- Gmail确认只发测试邮箱;真实患者邮件涉及隐私与送达,不应在练习环境开启
- 预约结果回传只是转告患者,不能表述成医生已确认或已锁定号源,除非另有系统
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Manage dental appointments via ElevenLabs voice, OpenAI and Google Sheets
- 原作者
- Abu Bakar
- 原始发布日期
- 2026-09-28T08:53:52.793Z
- 来源
- https://n8n.io/workflows/20035