2026-09-22 · 原文发布日
WhatsApp 自动追问缺勤原因
每天 10:30 读 Google Sheets 考勤表,筛出已缺勤但还没有原因的学生,经 WhatsApp Business Cloud API 发消息给家长并写入 Redis 聊天记录。收到回复后过滤非文本,用 Redis 去重 webhook、把同一号码 5 分钟内多条消息缓冲合并并加锁;按家长手机号查学生,交 Gemini 结合 Redis 记忆判断是否给出有效原因,有效则回写 Sheets 并确认,无效继续追问。注意这是付费模板。
原文要点
这是n8n.io上的付费模板(工作流19812,附YouTube讲解)。流程:每天10:30定时读Google Sheets考勤表,筛出已缺勤但无原因记录的学生,经WhatsApp Business Cloud API给家长发消息并把外发消息存入Redis聊天记录;收到回复时过滤非文本(回警告),用Redis做webhook去重、把同一号码5分钟内多条消息缓冲合并并加短锁,再按家长手机号查学生,交Google Gemini(配合Redis聊天记忆)判断是否给出有效缺勤原因,有效则回写Sheets并确认,无效则继续追问,最后释放锁。要求表含ParentPhoneNumber、ParentName、StudentName、Reason、got_reason字段。
这次做成什么
理解这套定时追问+防重缓冲+AI判定的架构后,先用本站设计的合成考勤表和三段虚构对话,在不购买模板、不接真实WhatsApp的前提下,手工推演每个分支的输入输出;确有需要再购买原模板并按其真实节点配置。
准备什么
- 一个n8n实例(云端或自托管),以及可访问的Redis实例(去重键、缓冲、锁、聊天记忆都依赖它)
- WhatsApp Business Cloud API凭据与phone number ID(Meta平台,发送消息可能按会话计费)
- Google Service Account(读写考勤表)和Google Gemini(PaLM)API凭据
- 一张含ParentPhoneNumber、ParentName、StudentName、Reason、got_reason列的测试考勤表,勿用含真实学生信息的生产表演练
- 原模板为付费商品,本站不提供其文件;以下节点描述基于作者公开说明,具体参数以购买后的模板为准
具体怎么做
搭建合成考勤表
新建一张Google Sheet,按下方artifacts的CSV建表头并写入两条虚构缺勤记录(got_reason为空)。演练时不启用定时器,用Manual Trigger代替10:30的Schedule Trigger。
推演筛选与外发分支
按作者说明,流程先筛「缺勤且Reason为空、got_reason为否」的行,对这些行的ParentPhoneNumber发追问消息,并把外发内容写入Redis聊天历史。用合成表手工核对:应恰好筛出两行,且第二遍运行时若got_reason已置为是则不再外发。
推演去重、缓冲与锁
模拟同一家长号码在5分钟内连发三条文本回复:第一条到达时获取该号码的Redis锁并开缓冲窗口,后续消息并入缓冲,窗口结束合并为一段文本送Gemini,处理完清空缓冲并释放锁。重复的webhook投递(同一message id)应被去重键直接丢弃。非文本消息(图片/语音)应收到警告回复,不进入判定。
用判定提示词验证有效/无效分支
把合并后的家长消息逐条贴入下方判定提示词(可先用任意大模型手工跑),确认「孩子发烧39度在家休息」判为valid并给出要回写的Reason,「好的知道了」判为invalid并生成追问语。有效分支应回写Sheets的Reason与got_reason=是,并发确认消息。
决定购买后再接真实服务
若推演符合需求,再购买原模板(本站示例并非原工作流文件),在其真实节点上配置WhatsApp、Sheets、Redis、Gemini凭据与phone number ID;未购买前不要编造可导入的工作流JSON。
可直接复制的材料
缺勤原因有效性判定提示词(本站独立编写)
本站独立编写,用于演练;原模板内agent的实际提示词与模型选择需以购买后的模板为准。
你是学校考勤助手。根据家长的WhatsApp回复,判断其中是否包含有效的学生缺勤原因。只输出JSON:{"valid":true或false,"reason":"用不超过30字概括缺勤原因,无则填空字符串","followup":"若valid为false,给家长的一句礼貌追问,否则填空字符串"}。规则:1) 明确说明病因、事假、交通等具体事由视为有效;2) 仅回复收到、好的、表情或答非所问视为无效;3) 时间含糊(如『明天再说』)视为无效并追问具体原因。合成考勤表 attendance_test.csv
全部为虚构号码与姓名;第三行已有原因,用于验证筛选时会被跳过。正式使用请替换为真实表并注意个人信息保护。
ParentPhoneNumber,ParentName,StudentName,Reason,got_reason
+8613800000001,陈家长,陈小明,,否
+8613800000002,林家长,林小雨,,否
+8613800000003,周家长,周子涵,家中有事,是Redis键设计示例(演练用)
本站设计的键名与参考TTL,仅说明去重/5分钟缓冲/短锁/聊天记忆四种用途;原模板的具体键结构未公开,以购买后实际节点为准。
{"dedup_key":"wa:dedup:{message_id}","dedup_ttl_seconds":86400,"buffer_key":"wa:buffer:{parent_phone}","buffer_window_seconds":300,"lock_key":"wa:lock:{parent_phone}","lock_ttl_seconds":120,"memory_key":"wa:memory:{parent_phone}"}输入与输出示例
本站虚构演示,未运行原模板;分支行为按作者公开说明推演,非作者实测结果。
输入
合成表中陈小明、林小雨缺勤无原因。10:30外发后,家长陈(+8613800000001)在5分钟内连发『孩子今天发烧』『39度』『在家休息一天』;家长林回复『好的』;另有一条重复投递的同一message id webhook和一张图片消息。对应输出
陈家长三条消息被缓冲合并为「孩子今天发烧 39度 在家休息一天」,Gemini判定{"valid":true,"reason":"发烧39度在家休息一天"},回写该行Reason并置got_reason=是,WhatsApp收到确认语;重复webhook被去重丢弃;图片消息收到『请用文字回复』警告;林家长收到『好的』判定valid=false,收到追问『请问孩子缺勤的具体原因是什么?』,行记录不变。做完检查这些
- 定时/手动运行只筛出缺勤且got_reason=否的行,已有原因的行被跳过
- 同一号码5分钟内多条消息被合并为一段送判定,且处理期间该号码持有锁
- 同一message id的重复webhook不产生第二次外发或回写
- 非文本消息走警告分支,不进入Gemini判定
- valid=true时Sheets的Reason与got_reason被回写,valid=false时表数据不变且发出追问
容易卡住的地方
- 原模板需付费购买,本站示例不是原工作流文件,节点参数以购买后为准
- Redis不可用时去重、缓冲、锁和聊天记忆会同时失效,是单点依赖
- 缓冲窗口(作者设定为5分钟)内家长持续发消息会推迟处理,紧急场景需另行考虑
- WhatsApp Business Cloud API按会话计费且需Meta审核号码,Gemini调用另计费,免费额度不保证
- 锁TTL过短可能处理未完锁已释放,过长则家长后续消息被阻塞,需按实际处理耗时调整
- 考勤表含未成年人信息,演练务必用合成数据,勿把真实学生电话写入测试环境
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Collect student absence reasons via WhatsApp, Google Sheets, Gemini, and Redis
- 原作者
- iamvaar
- 原始发布日期
- 2026-09-22T09:10:21.237Z
- 来源
- https://n8n.io/workflows/19812