📧 Marketing Automation 执行流程

Feature: 018-marketing-automation + 047-experiment-config

系统概览

Marketing Automation 系统支持两种消息发送方式:

发送方式触发条件处理时机使用场景
手动发送 用户点击"发送"按钮 立即发送 一次性营销活动、促销通知
自动触发 业务事件(生日、服务完成等) 每 5 分钟批量处理 自动化营销、客户关怀

核心组件

graph TB subgraph "前端 Frontend" A[Campaign 管理页面
promotion/page.tsx] end subgraph "后端 API" B[Marketing API
api/marketing.js] end subgraph "核心服务" C[MessagingService
services/messaging/index.js] D[TriggerEngine
services/automation/trigger-engine.js] E[ExecutionProcessor
services/automation/execution-processor.js] end subgraph "定时任务" F[AutomationExecutionJob
jobs/automationExecutionJob.js] G[JobScheduler
jobs/index.js] end subgraph "外部服务" H[AWS SES / Resend] I[Twilio / Telnyx] end subgraph "数据库" J[(marketing_campaigns)] K[(automation_executions)] L[(email_templates)] M[(sms_templates)] end A -->|POST /campaigns/:id/send| B B -->|手动发送| C B -->|读取| J B -->|读取| L B -->|读取| M D -->|调度执行| K G -->|每5分钟| F F -->|处理待发送| E E -->|发送消息| C E -->|读取| K C -->|Email| H C -->|SMS| I

手动发送流程

流程图

sequenceDiagram participant U as 用户 participant F as 前端 participant A as Marketing API participant M as MessagingService participant DB as 数据库 participant SES as AWS SES participant SMS as Twilio U->>F: 点击"发送 Campaign" F->>A: POST /api/marketing/campaigns/:id/send A->>DB: 获取 Campaign 详情 A->>DB: 获取目标受众列表 A->>DB: 获取模板内容 loop 每个收件人 alt Email Campaign A->>M: sendEmail(recipient, content) M->>SES: 发送邮件 SES-->>M: 发送结果 else SMS Campaign A->>M: sendSMS(recipient, message) M->>SMS: 发送短信 SMS-->>M: 发送结果 end A->>DB: 记录发送历史 end A->>DB: 更新 Campaign 统计 A-->>F: 返回发送结果 F-->>U: 显示发送结果

API 端点

POST /api/marketing/campaigns/:id/send

Request Body:
{
  "testMode": false,      // 可选,测试模式只发给自己
  "testEmail": "...",     // 测试模式时的邮箱
  "testPhone": "..."      // 测试模式时的手机号
}

Response:
{
  "success": true,
  "message": "Campaign sent successfully",
  "stats": {
    "total": 100,
    "sent": 98,
    "failed": 2,
    "skipped": 0
  }
}

自动触发流程

流程图

sequenceDiagram participant E as 业务事件 participant T as TriggerEngine participant DB as automation_executions participant J as JobScheduler participant P as ExecutionProcessor participant M as MessagingService participant EXT as 外部服务 Note over E,T: 第一阶段:事件触发 E->>T: 业务事件发生
(生日/服务完成/etc) T->>T: 匹配触发器规则 T->>DB: 创建执行记录
(status=pending) Note over J,P: 第二阶段:定时处理 (每5分钟) J->>P: cron: */5 * * * * P->>DB: 获取待处理执行
(status=pending) loop 每个执行任务 P->>DB: 更新状态 = executing P->>DB: 获取模板内容 P->>M: 发送消息 M->>EXT: AWS SES / Twilio EXT-->>M: 结果 alt 发送成功 P->>DB: 更新状态 = completed else 发送失败 P->>DB: 更新状态 = failed end end

触发器事件类型

事件类型说明触发时机
service_completed服务完成预约状态变为 completed
birthday生日客户生日当天
last_visit最后访问超过 N 天未到店
membership_expiring会员到期会员即将到期
points_expiring积分到期积分即将过期
new_customer新客户首次预约完成

执行状态

状态说明
pending等待处理
executing正在执行
completed执行成功
failed执行失败
skipped跳过(无联系方式等)

关键文件

文件职责
backend/api/marketing.js Marketing API 路由,包含手动发送端点
backend/services/messaging/index.js 统一消息服务,封装 Email 和 SMS 发送
backend/services/automation/trigger-engine.js 触发器引擎,处理业务事件并调度执行
backend/services/automation/execution-processor.js 执行处理器,批量处理待发送消息
backend/jobs/automationExecutionJob.js 定时任务,每 5 分钟调用执行处理器
backend/jobs/index.js 任务调度中心,注册所有定时任务
frontend/.../promotion/page.tsx Campaign 管理页面

数据库表结构

marketing_campaigns

marketing_campaigns
├── id                    VARCHAR(50) PK
├── name                  VARCHAR(255)
├── type                  VARCHAR(20)    -- 'email' | 'sms'
├── status                VARCHAR(20)    -- 'draft' | 'active' | 'paused'
├── content_source        VARCHAR(20)    -- 'template' | 'custom'
├── template_id           INTEGER        -- email/sms_templates.id
├── trigger_template_ids  UUID[]         -- 关联的触发器模板
├── subject               VARCHAR(500)   -- Email 主题
├── content               TEXT           -- 自定义内容
├── audience_type         VARCHAR(50)    -- 受众类型
├── target_tags           VARCHAR[]      -- 目标标签
├── last_manual_send_at   TIMESTAMPTZ    -- 最后手动发送时间
├── manual_send_count     INTEGER        -- 手动发送次数
└── ...
    

automation_executions

automation_executions
├── id                UUID PK
├── rule_id           UUID FK          -- trigger_templates.id
├── customer_id       UUID FK          -- guests.id
├── channel           VARCHAR(20)      -- 'email' | 'sms' | 'both'
├── email_template_id INTEGER          -- email_templates.id
├── sms_template_id   INTEGER          -- sms_templates.id
├── status            VARCHAR(20)      -- pending/executing/completed/failed
├── scheduled_for     TIMESTAMPTZ      -- 计划执行时间
├── executed_at       TIMESTAMPTZ      -- 实际执行时间
├── error_message     TEXT             -- 错误信息
└── metadata          JSONB            -- 扩展数据
    

配置说明

定时任务配置

Automation Execution Job 默认每 5 分钟执行一次:

cron.schedule('*/5 * * * *', async () => {
  await this.jobs.automationExecution.run();
}, { timezone: 'America/New_York' });
批处理配置
参数默认值说明
batchSize50每批处理的执行数量
maxExecutions500单次运行最大处理数量
外部服务配置

消息发送依赖以下环境变量:

# Email (AWS SES)
AWS_SES_ACCESS_KEY_ID=xxx
AWS_SES_SECRET_ACCESS_KEY=xxx
AWS_SES_REGION=us-east-1
AWS_SES_FROM_EMAIL=noreply@celoria.ai

# Email (Resend - 备选)
RESEND_API_KEY=xxx

# SMS (Twilio)
TWILIO_ACCOUNT_SID=xxx
TWILIO_AUTH_TOKEN=xxx
TWILIO_FROM_NUMBER=+1xxxxxxxxxx

# SMS (Telnyx - 备选)
TELNYX_API_KEY=xxx
      

调试与监控

查看任务状态

# 查看定时任务日志
pm2 logs celoria-api --lines 100 | grep "automation-execution"

# 查看待处理执行
SELECT * FROM automation_executions
WHERE status = 'pending'
ORDER BY scheduled_for;

# 查看失败的执行
SELECT * FROM automation_executions
WHERE status = 'failed'
ORDER BY executed_at DESC
LIMIT 20;
    

手动触发执行

# 通过 API 获取 Job 状态
GET /api/dev/jobs/status

# 手动运行 automation-execution job
POST /api/dev/jobs/run/automationExecution
    

更新日期: 2026-02-04