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

2026-09-21 · 原文发布日

Supabase任务队列驱动短信与语音外呼

免费n8n模板(三部分系列的第二部分):每15分钟从Supabase认领到期外呼任务,按候选人所在时区的静默时段和周末规则判断,生成短信内容或Retell通话上下文及幂等键;短信走Twilio、语音走Retell,按发送结果分类(成功、临时失败、永久失败)并带回退重试,运营商级退订单独标记,全部写回Supabase,可选发Slack摘要。支持演示和测试模式。

原文要点

原模板是免费n8n工作流,作者标注为候选人引擎三部曲第二部分。定时器每15分钟触发,从Supabase的due-queue视图认领到期外呼任务(未配置Supabase时用内置示例队列),按候选人本地时区的静默时段和周末规则决定短信或语音,生成短信正文或Retell通话上下文与幂等键。发送结果分为sent/transient/permanent三类,带退避与抖动重试,Twilio返回的运营商级退订单独写入opt_outs,全部回写contact_attempts与enrollments,可选Slack摘要。DEMO_MODE/TEST_RUN控制预览与测试手机路由。

这次做成什么

搭好一个能每15分钟自动认领外呼任务、按渠道分流、按结果分类回写的n8n外呼流水线;先在本站设计的演示模式下用内置样例队列跑通分流与分类逻辑,再接真实Supabase与服务商。

准备什么

  • 一个n8n实例(云端或自托管均可)及模板导入权限
  • Supabase项目URL与service role密钥,或先用内置示例队列
  • Twilio账号SID、Auth Token与发送号码或Messaging Service SID(仅短信)
  • Retell API密钥、agent ID与外呼号码(仅语音,可选)
  • 可选:Slack incoming webhook地址用于运行摘要

具体怎么做

  1. 导入模板并先开演示模式

    在n8n的Templates页搜索工作流19776导入。在配置节点中找到DEMO_MODE与TEST_RUN开关,先把两者都设为开启:此时不连Supabase也能用内置示例队列,且所有外呼只路由到测试手机号,不会打扰真实候选人。

  2. 建Supabase表结构与视图

    在Supabase SQL编辑器按模板要求建enrollments、contact_attempts、opt_outs三张表和一个due-queue视图(视图逻辑:next_attempt_at早于当前时间且状态为active)。再建模板引用的RPC函数用于原子认领任务,避免两个执行实例抢同一批。字段映射:enrollments需含候选人时区、渠道偏好、当前序列步数;contact_attempts记录幂等键、渠道、结果分类。

  3. 填运行时配置与凭据

    在工作流配置节点填入Supabase URL、service role key、静默时段起止时间(如21:00至08:00)、每轮发送上限。分别创建Twilio(Header Auth或内置凭据)与Retell(Bearer Token)凭据并绑定到对应发送节点;没配哪个服务商,该渠道任务会被标记为transient而不是报错中断。

  4. 核对分流与分类逻辑

    打开判断节点确认分支:候选人本地时间在静默时段或周末→顺延到下一允许窗口;渠道为sms→Twilio节点,为voice→Retell节点并附通话上下文;发送后按返回分类sent/transient/permanent,transient按退避加随机抖动计算下次尝试时间,Twilio回调含退订关键字→写入opt_outs并停止后续触达。

  5. 跑测试数据再切正式

    手动触发一次,确认示例队列被认领、分类正确、Slack摘要出现。然后在Supabase插入一条next_attempt_at为过去时间的测试enrollment,再触发一次确认它被认领并回写contact_attempts。全部通过后关闭DEMO_MODE,把TEST_RUN的测试手机号改为正式路由。

可直接复制的材料

Supabase测试enrollment数据

本站虚构的练习用单行数据,插入enrollments表前请按你实际建的列名调整;手机号是占位测试号,不要用真实候选人号码。

{"candidate_name":"测试候选人甲","phone_e164":"+8613800000000","timezone":"Asia/Shanghai","channel":"sms","sequence_step":1,"next_attempt_at":"2026-09-21T01:00:00Z","status":"active"}

结果分类与退避核对提示词

本站独立编写的分类练习提示词,用于人工核对模板分类逻辑是否一致;示例日志返回码仅为演示,正式规则以你Twilio账号的错误码文档为准。

你是外呼系统运维助手。我给你一条外呼发送日志(含渠道、服务商返回码、错误描述),请输出JSON:{"classification":"sent|transient|permanent","reason":"一句中文说明","next_action":"retry_with_backoff|skip_until_window|stop_and_flag_optout"}。规则:号码无效、已退订、被运营商永久拦截算permanent;限流、超时、服务商5xx算transient;成功提交算sent。日志如下:渠道=sms,返回码=30034,错误描述=US A2P unregistered number。

输入与输出示例

本站虚构演示输出,未实际运行模板;具体时间计算以你配置的静默时段与周末规则为准。

输入

enrollment:候选人乙,时区Asia/Shanghai,渠道voice,next_attempt_at为2小时前,当前为上海时间周六14:00

对应输出

判断节点输出{"action":"defer","reason":"weekend_rule","next_attempt_at":"下周一09:00(上海)"};另一条周三14:00的sms任务输出{"action":"send","idempotency_key":"enr_1042_step1","classification":"sent"}

做完检查这些

  • 手动触发后内置示例队列被认领,且每条任务都有渠道判断输出
  • 静默时段或周末内的任务被顺延而非直接发送,顺延时间在允许窗口内
  • 未配置Twilio时短信任务被标记为transient而不是工作流报错
  • Supabase中contact_attempts出现与任务对应的幂等键和结果分类记录
  • 测试退订回复后opt_outs表新增一行且该候选人不再被认领

容易卡住的地方

  • Supabase表、视图与RPC缺失或字段名不符会让认领步骤直接失败,需先按模板要求建全
  • service role密钥权限很高,只放在n8n凭据里,不要写进节点明文参数
  • 两次执行间隔内若运行耗时超过15分钟可能重叠执行,认领RPC必须原子化
  • Twilio与Retell为付费服务且按量计费,具体资费以其官网为准,模板本身免费
  • 运营商退订判定依赖Twilio返回内容,其他服务商需自行调整识别规则

原文与作者资料 ↗

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

原文标题
Send scheduled SMS and voice outreach from Supabase via Twilio and Retell
原作者
Atharva Ashtekar
原始发布日期
2026-09-21T05:50:41.500Z
来源
https://n8n.io/workflows/19776