群发邮件最大的浪费不是没人打开,而是明明攒了订阅标签和行为数据,却对所有用户发同一封一样的文案。活跃用户觉得内容无聊逐渐冷淡,新订阅用户第一封就收到按老节奏写的旧话题,直接流失。手动分群、逐群写文案、A/B 测试又是三套重复劳动:导出名单、按标签筛、复制粘贴主题行、发完等两天看打开率、再换一版重发。一周写两封就把时间吃光,更别提打开率低于阈值后要人工判断"是主题行不行还是正文不行",全凭感觉,测完也没沉淀。
这个 n8n 工作流把"分群 -> 生成个性化邮件 -> A/B 发送 -> 追踪打开点击 -> 回写指标 -> 低打开率自动换文案重测"串成一条自动线:每周定时从 CRM 或飞书多维表格拉订阅者,按标签和近期行为自动分群;LLM 按每个分群生成 A/B 两个变体(主题行+正文),各发一半;邮件里嵌追踪链接,打开/点击通过 Webhook 回写指标;打开率低于阈值且样本足够时,自动触发 LLM 重新生成候选文案,进入下一轮 A/B。它和本站《客户线索自动收集打分通知工作流》(workflow-lead-crm-automation) 互补--线索工作流管获客,这个工作流管留存触达;邮件内容选题可接 RSS 聚合 AI 摘要内容选题工作流(workflow-rss-content-pipeline) 产出的高分话题,让邮件和站内发文同源,导流更顺。
合规提示:邮件营销须合规。只向已订阅/授权用户发送,每封必含一键退订(unsubscribe)链接,遵守 CAN-SPAM、GDPR、中国《电子商务法》等适用法规。个性化不等于滥用用户数据,避免基于种族、健康、收入、宗教等敏感属性做推断或差异化定价;发送频率与时间尊重用户,提供偏好设置入口。本工作流的分群仅基于订阅标签与公开行为(栏目偏好、近期打开)。具体合规要求以各地法规为准,发送前请核验。
工作流链路
Schedule 定时触发(每周二上午 10 点)-> HTTP Request 拉 CRM/飞书表格订阅者(带标签与行为字段)-> Code 按标签+行为分群 -> LLM 节点(HTTP Request 调 DeepSeek/Kimi)按分群生成 A/B 两版主题行+正文 -> Code 解析 JSON 并把分群名单对半切(A 发前一半、B 发后一半)-> Send Email(SMTP)逐变体发送(邮件内嵌追踪链接与退订链接)-> HTTP Request 回写发送记录到指标表 -> [Webhook 异步触发] 追踪打开/点击 -> HTTP Request 拉该变体发送数与打开数 -> Code 计算打开率 -> IF 打开率 < 阈值且样本 >= 50 -> HTTP Request 调 LLM 重新生成候选文案触发 A/B 重测。
下载模板
使用步骤
- 导入:n8n -> Workflows -> Import from File,选 workflow-email-marketing-automation.json
- Schedule 节点:设每周二上午 10 点触发(周一选题、周二发件,给文案生成留时间)。高频 newsletter 可改成每天
- 拉取订阅者节点:填 CRM 或飞书多维表格 API(飞书用 OpenAPI 拉 records,带"标签""近期打开""栏目偏好"字段;Mailchimp/ConvertKit 用官方 HTTP API)。只拉 status='subscribed' 的授权用户,退订用户在源头就排除
- 分群 Code 节点:按标签(如"AI工具实战""热点速递""教程订阅")和近期行为(30 天内有打开=活跃,否则=沉睡)分组。每个分群输出 segment / subscribers / count
- LLM 节点:填 API key(DeepSeek/Kimi/Qwen 都行),Prompt 要求输出 subjectA / bodyA / subjectB / bodyB 四字段(见下方配套 Prompt)。正文必须含 [姓名] 占位与 [[unsubscribe]] 退订链接占位
- 解析 Code 节点:把分群名单对半切,A 发前一半、B 发后一半,输出两个 items(variant / subject / body / recipients / segment)。n8n 会对两个 items 逐条执行下游节点
- Send Email 节点:配 SMTP 凭据(Gmail / 腾讯企业邮 / SendGrid 都行),fromEmail 用固定发件地址,toEmail 用表达式聚合 recipients 邮箱,subject/text 引用当前 item 的变体字段。正文末尾必带退订链接
- 回写发送记录节点:每发一个变体,POST 一条记录到指标表(variant / segment / sent / timestamp),这是后面算打开率的分母来源
- 追踪 Webhook 节点:path 设 email-track,邮件正文里的追踪像素/链接指向 https://你的n8n域名/email-track?variant=A&segment=xxx&event=open。打开和点击都走这个 Webhook
- 拉取计数节点:从指标表 GET 该变体的 sent 与 opened 累计计数
- 计算打开率 Code 节点:openRate = opened / sent * 100,输出 variant / sent / opened / openRate / segment
- IF 节点:双条件 AND--openRate < 20 且 sent >= 50(样本太少不触发,避免早期几个事件误判)。true 走换文案,false 结束
- 触发换文案节点:调 LLM 对低打开率变体重新生成 3 个候选主题行+正文(不同切入角度:利益/紧迫/好奇),写回文案库进入下一轮 A/B
- 试运行:手动触发 Schedule,查 A/B 是否各发一半;curl 模拟一次 Webhook 调用(带 variant=A&event=open),看指标是否回写;把 sent 手动设为 50、openRate 设为 10,看 IF 是否走换文案分支。确认退订链接可点击、只发授权用户后再开定时
配套 Prompt(LLM 按分群生成 A/B 个性化邮件)
你是邮件营销文案专家。读下面这个订阅者分群,生成 A/B 两个邮件变体,输出:
1. subjectA / subjectB:主题行,≤50 字,A 偏直白利益、B 偏好奇悬念
2. bodyA / bodyB:正文,纯文本,≤300 字,个性化称呼用 [姓名] 占位,文末必含退订链接 [[unsubscribe]]
约束:
- 只依据分群标签与公开行为(栏目偏好、近期打开)个性化,不推断种族/健康/收入/宗教等敏感属性
- 不编造产品功能与数据;优惠与数字须留占位由人工确认
- 语气与分群匹配(教程分群偏实操、热点分群偏时效)
输出 JSON:subjectA, bodyA, subjectB, bodyB。
分群标签:{{segment}}
分群人数:{{count}}进阶
- 分群细化:在分群 Code 节点叠加 RFM 维度--最近打开时间(R)、打开频率(F)、是否点击过链接(M)。把"沉睡高价值用户"单独成群,发唤醒邮件而非常规推送
- 发送时间优化:不同分群活跃时段不同。Send Email 前加一个 Wait 节点,按分群最佳时段延迟发送(教程党晚上 8 点、热点党早 7 点),打开率能拉开几个百分点
- 指标回写闭环:换文案节点后接一个 Send Email,把新候选文案自动发给该分群剩余未打开用户(注意同一用户短期内只重发一次,避免骚扰,这是合规与体验双重要求)
- 多分群并发:分群 Code 输出多条 items,LLM 和 Send Email 会逐群执行。注意 LLM 限流,加 Split in Batches 节点每批 1 群,控制并发
- 与内容站联动:把 RSS 聚合 AI 摘要内容选题工作流(workflow-rss-content-pipeline) 产出的本周高分选题灌进 LLM Prompt 的 context,邮件内容跟站内发文同源,导流效果更好
- 退订自动处理:Webhook 监听 unsubscribe 事件,接到后立刻 PATCH CRM 把该用户 status 改为 'unsubscribed',后续工作流拉名单时自动排除。这是合规硬要求,不是可选项
踩坑
- 打开率追踪不准:图片像素被邮件客户端默认拦截,打开数偏低。点击追踪比打开追踪更可靠,A/B 判断优先看点击率。Webhook 要对同一用户多次打开去重,否则打开率虚高
- Webhook 每次打开都触发换文案:打开率是动态值,早期几个事件会大幅拉高或拉低。IF 必须加 sent >= 50 的样本门槛;更稳的做法是改成每天定时跑一次评估,而非每次打开都跑
- LLM 漏退订链接:模型偶尔忘加 [[unsubscribe]]。解析 Code 节点加一步校验,body 里查不到 unsubscribe 就拦截报错,不进 Send Email
- SMTP 限频:腾讯企业邮 / Gmail 每日发件上限几百封。大列表加 Split in Batches 每批 50 封 + Wait 间隔,避免触发风控。大批量建议用 SendGrid / Mailgun 专用服务
- 分群名单对半切不均:count 为奇数时 half 向下取整,B 多一人。无伤大雅,但分群人数 < 100 时 A/B 样本量太小、统计不显著,不建议做 A/B,直接全量发一个变体
- 敏感属性推断:LLM 偶尔会基于姓名/地区推断性别或族裔做差异化文案。Prompt 里硬约束 + 解析 Code 检查 body 是否含敏感词,命中则丢弃重生成
- 退订链接失效:[[unsubscribe]] 占位没正确替换成真实链接就发出去了。Send Email 前加 Code 节点做占位替换,替换后校验链接可访问再发
参考来源
- n8n Schedule Trigger 官方文档:https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger/
- n8n Send Email 节点文档:https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.sendemail/
- n8n Webhook 节点文档:https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/
- n8n IF 节点文档:https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if/
- n8n Code 节点文档:https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/
- CAN-SPAM Act 合规指南(FTC):https://www.ftc.gov/business-guidance/resources/can-spam-act-compliance-guide-business
- GDPR 同意指引(EDPB Guidelines 05/2020):https://edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-052020-consent-under-regulation-2016679_en
- 飞书多维表格 OpenAPI:https://open.feishu.cn/document/server-docs/docs/bitable-v1/bitable-overview