Files
Fulfilled-Knowledge/wishfulfilled-wiki/05_需求文档/通用EDM业务流程说明.md
2026-05-29 14:33:56 +08:00

16 KiB
Raw Permalink Blame History

通用 EDM 业务流程说明

更新时间2026-05-26

1. 文档目标

本文用于新的 EDM 子系统设计或重构,目标是在功能保持一致的前提下,将现有 EDM 业务抽象成通用流程,便于后续拆分服务、设计数据模型、规划 Kafka 消费链路、接入邮件发送通道和处理邮件客服工单。

2. 业务范围

通用 EDM 子系统建议分为三条业务线:

业务线 说明
批量营销邮件 管理后台创建邮件任务,按标签、站点、产品、用户状态筛选目标用户,生成待发送邮件记录,通过队列异步发送
自动 / 实时策略邮件 根据用户注册、访问、在线、站点、产品、行为、无消息等规则自动筛选用户,并生成策略邮件
邮件工单 用户来信、表单提交或外部收信服务进入后台后,生成或更新邮件工单,由客服处理、回复、转发、关闭

如果新系统还需要普通邮箱功能,可以作为独立模块处理。普通邮箱收发不一定进入 EDM 工单链路,是否合并需要单独确认。

3. 总体架构

flowchart TD
    A["管理后台"] --> B["EDM 任务服务"]
    B --> C["目标用户筛选服务"]
    C --> D["邮件记录生成服务"]
    D --> E["Kafka / 队列"]
    E --> F["邮件发送消费者"]
    F --> G["外部发送通道"]
    G --> H["AWS SES / SMTP / Gmail / Microsoft"]
    H --> I["事件回调"]
    I --> J["事件处理服务"]
    J --> K["统计与黑名单"]

    L["用户来信 / 表单提交"] --> M["入站接收服务"]
    M --> N["Kafka / 入站队列"]
    N --> O["EDM 工单服务"]
    O --> P["客服工作台"]
    P --> E

核心组件职责:

组件 职责
管理后台 创建邮件任务、审核任务、查看统计、处理邮件工单
任务服务 保存任务配置、正文、模板、发送时间、审核状态
用户筛选服务 根据标签、站点、产品、黑名单、订阅状态、发送频率等规则筛选目标用户
邮件记录服务 按用户生成单封待发送邮件记录和正文快照
Kafka / 队列 解耦任务生成、邮件发送、入站消息、事件统计
发送消费者 消费待发送邮件,调用外部发送通道,并保存发送结果
入站接收服务 接收表单、用户来信或外部邮件服务回调,写入入站队列
工单服务 根据来信生成或更新邮件工单,维护状态、负责人、未读数和处理记录
事件处理服务 处理送达、打开、点击、退信、投诉、拒信等邮件事件
Redis / 缓存 保存并发锁、游标、限流计数、近期任务统计、临时筛选集合

4. 核心数据模型

新子系统建议至少抽象以下对象:

对象 说明
邮件任务 EmailTask 批量营销或策略邮件任务,保存任务名称、类型、发送时间、审核状态、目标条件
邮件内容 EmailContent 任务级正文、标题、模板、发件人、回复地址、附件配置
目标用户 TaskRecipient 任务命中的用户关系,便于统计和去重
单封邮件 EmailMessage 最终发送或接收的一封邮件记录包含方向、收件人、发件人、状态、message_id、工单 ID
邮件正文 EmailBody 单封邮件正文快照,避免模板后续变化影响历史邮件
工单 EmailTicket 用户来信或客服主动发起的一次处理过程
分配记录 Assignment 工单分配、移交、释放、代班等操作记录
节点日志 NodeLog 创建、分配、首次回复、关闭、未解决、转化中等关键节点
发送事件 EmailEvent 送达、打开、点击、退信、投诉、拒信、渲染失败等事件
黑名单 / 退订名单 Suppression 退信、投诉、退订、风险用户等不可发送或需谨慎发送的人群

5. 批量营销邮件流程

flowchart TD
    A["后台创建邮件任务"] --> B["校验任务配置"]
    B --> C["写入任务、内容、标签条件"]
    C --> D["进入待审核"]
    D --> E{"审核结果"}
    E -->|通过| F["进入待执行"]
    E -->|驳回| G["记录驳回原因并结束"]
    F --> H["到达发送时间"]
    H --> I["筛选目标用户"]
    I --> J["生成单封待发送邮件记录"]
    J --> K["投递 Kafka"]
    K --> L["发送消费者调用外部邮件通道"]
    L --> M["更新发送状态和 message_id"]

创建任务时建议校验:

  1. 任务名称不能重复。
  2. 邮件模板或正文必须存在。
  3. 发件邮箱必须存在并可用。
  4. 发件域名必须在允许范围内。
  5. 必须选择目标人群或策略条件。
  6. 发送时间必须符合业务规则。
  7. 如果绑定活动,发送时间需要满足活动时间约束。
  8. 目标人数需要预估,避免误发全量用户。

目标用户筛选建议包含:

  1. 标签包含和标签排除。
  2. 站点、产品、品牌、语言、地区。
  3. 订阅状态、退订状态、黑名单、投诉用户、永久退信用户。
  4. 近期发送频率限制,避免短时间重复触达。
  5. 任务级去重,避免同一用户重复生成同一任务邮件。

6. 自动 / 实时策略邮件流程

flowchart TD
    A["策略配置"] --> B["定时任务生成当日策略任务"]
    B --> C["实时策略扫描"]
    C --> D["按用户行为和条件筛选"]
    D --> E["应用黑名单、退订、频率控制"]
    E --> F["生成待发送邮件"]
    F --> G["投递发送队列"]
    G --> H["发送消费者调用邮件通道"]
    H --> I["事件回调更新统计"]

策略邮件与批量邮件的区别:

  1. 批量邮件通常由运营手动创建,发送时间明确。
  2. 策略邮件通常由系统按规则自动生成,可能按分钟或按天扫描。
  3. 策略邮件更依赖幂等和频率控制,避免同一用户在同一策略下反复触发。
  4. 策略邮件应记录策略 ID、触发原因、触发时间便于归因。

建议策略执行时做并发锁,避免多个任务实例重复生成邮件。

7. 邮件发送链路

通用发送链路:

flowchart TD
    A["待发送邮件记录"] --> B["写入 Kafka"]
    B --> C["发送消费者"]
    C --> D["读取发件通道配置"]
    D --> E{"发送通道"}
    E -->|批量营销| F["AWS SES 或批量发送通道"]
    E -->|客服回复| G["SMTP / Gmail / Microsoft"]
    F --> H["保存发送结果"]
    G --> H
    H --> I["通知前端或更新统计"]

发送消费者需要处理:

  1. 队列消息反序列化。
  2. 邮件正文、标题、收件人、发件人、回复地址、附件组装。
  3. 发送通道选择。
  4. 调用外部服务。
  5. 成功后保存 message_id、发送时间和成功状态。
  6. 失败后保存错误信息、失败状态和重试次数。

发送通道建议按场景区分:

场景 推荐处理
批量营销邮件 走支持批量和事件回调的邮件服务,例如 AWS SES
策略邮件 可复用批量发送通道,但必须做频率和幂等控制
工单客服回复 按发件邮箱配置选择 SMTP、Gmail API 或 Microsoft Graph
普通邮箱回复 可独立于工单链路,同步或异步发送均可

8. 邮件事件回调与统计

邮件发送后,外部服务会产生事件。通用事件包括:

事件 处理建议
Delivery / 送达 标记邮件已送达,记录送达时间和发送 IP
Bounce / 退信 区分永久退信和临时退信,更新任务统计;永久退信可加入黑名单
Open / 打开 标记打开时间,更新任务打开统计
Click / 点击 记录点击链接和点击时间,更新点击统计
Complaint / 投诉 记录投诉,加入抑制名单或黑名单
Subscription / 订阅变更 更新订阅或退订状态
Reject / 拒信 记录拒信原因,更新失败统计
Rendering Failure / 渲染失败 记录模板或内容渲染失败
DeliveryDelay / 延迟 可记录延迟事件,是否统计需业务确认

事件处理要点:

  1. 事件必须通过 message_id 或自定义追踪 ID 关联到本地邮件记录。
  2. 同一事件可能重复回调,需要幂等处理。
  3. 打开和点击事件存在图片加载、隐私保护、客户端屏蔽等不确定性,统计只能作为参考指标。
  4. 投诉、退订、永久退信应优先进入发送抑制规则。

9. 入站邮件 / 表单进入工单流程

入站来源可以有多种:

  1. 网站表单提交。
  2. 用户真实邮件来信。
  3. 外部收信服务回调。
  4. IM 或其他渠道转入邮件客服。

通用流程:

flowchart TD
    A["用户来信或表单提交"] --> B["入站接收服务"]
    B --> C["写入 Kafka 入站队列"]
    C --> D["EDM 工单消费者"]
    D --> E["保存入站邮件和正文"]
    E --> F{"是否存在未关闭工单"}
    F -->|否| G["创建新工单"]
    F -->|是| H["绑定到原工单并更新未读数"]
    G --> I["写入节点日志"]
    H --> I
    I --> J["通知客服工作台"]

创建或更新工单时建议:

  1. 以发件邮箱、收件邮箱、业务用户 ID、会话标识等组合判断是否复用未关闭工单。
  2. 新工单记录来源、用户邮箱、发件邮箱、团队、状态、未读数、最后来信时间。
  3. 已有工单更新最后来信时间、未读数、用户来信数。
  4. 如果当前客服离线,可以释放负责人,让工单重新进入分配池。
  5. 入站正文应保存原始内容和清洗后的展示内容。

10. 工单客服处理流程

10.1 工单状态

通用状态建议:

状态 说明
待处理 新入站邮件或表单生成工单,等待客服处理
服务中 客服已接手并正在处理
未解决 客服标记暂未解决,需要后续跟进
转化中 进入销售或转化跟进阶段
已关闭 本次邮件工单处理结束

状态值可以由新系统自行定义,但需要保证列表筛选、统计、自动关闭和权限校验口径统一。

10.2 自动分配

自动分配建议流程:

  1. 找到待处理且未分配的工单。
  2. 根据收件邮箱、团队、站点、语言或业务线确定可服务团队。
  3. 获取在线客服。
  4. 按接单上限、当前处理数、最近分配时间选择客服。
  5. 更新工单负责人。
  6. 写入分配记录和节点日志。
  7. 通知客服工作台。

10.3 客服回复

flowchart TD
    A["客服点击发送"] --> B["校验客服在线、权限、工单状态"]
    B --> C["写入待发送邮件记录和正文"]
    C --> D["更新工单未读数、首次响应、回复耗时"]
    D --> E["投递客服回复队列"]
    E --> F["发送消费者选择 SMTP / Gmail / Microsoft"]
    F --> G["保存发送成功或失败结果"]
    G --> H["通知客服工作台"]

发送前建议校验:

  1. 客服必须在线。
  2. 工单必须存在且未关闭。
  3. 当前客服必须是工单处理人,或具备接手权限。
  4. 工单必须属于当前客服可处理团队。
  5. 主题、正文、收件人、回复地址必须合法。
  6. 附件大小、类型、数量需要符合业务规则和发送通道限制。

10.4 转发和主动开工单

转发:

  1. 需要填写新的收件人。
  2. 转发邮件可以不绑定到原工单作为普通回复。
  3. 原邮件和转发邮件需要建立关联,方便追溯。
  4. 发送链路仍可复用客服回复队列。

主动开工单:

  1. 客服选择发件邮箱和目标用户邮箱。
  2. 系统校验发件邮箱归属团队。
  3. 如果同一发件邮箱和用户邮箱已有未关闭工单,应拒绝重复创建或要求接手原工单。
  4. 创建服务中工单,负责人为当前客服。
  5. 写入节点日志和分配记录。
  6. 发送第一封邮件。

11. 工单辅助任务

新子系统可按需要保留以下后台任务:

任务 说明
自动分配 将未分配待处理工单分配给在线客服
自动移交 当前负责人离线且有新来信时,按代班或团队规则重新分配
DDL 释放 工单分配后超过配置时间未处理,释放为未分配
未回复提醒 用户新来信超过配置时间未回复,提醒负责人
自动关闭 服务中工单超过配置时间无新用户来信时自动关闭
未分配告警 未分配工单数量超过阈值时通知团队管理员
统计同步 定时刷新任务发送数、回复数、打开数、点击数等统计

具体调度频率和启用范围需要按新系统 SLA 确认。

12. 通用限制与风控点

12.1 任务和发送限制

建议配置化管理:

  1. 单任务最大目标人数。
  2. 单轮投递队列数量。
  3. 单发件邮箱每分钟、每小时、每天发送上限。
  4. 单用户每天或一段时间内最大触达次数。
  5. 单域名发送上限。
  6. 批量邮件和客服回复是否共享额度。

12.2 内容限制

建议校验:

  1. 邮件主题最大长度。
  2. 正文最小和最大长度。
  3. 附件大小、类型、数量。
  4. 发件邮箱和回复邮箱格式。
  5. 链接合法性和追踪参数。
  6. 必要的退订入口和合规声明。

12.3 人群抑制

发送前应排除:

  1. 退订用户。
  2. 投诉用户。
  3. 永久退信用户。
  4. 风险用户。
  5. 明确不允许触达的用户。
  6. 已达到频率上限的用户。

12.4 幂等和重试

需要幂等的场景:

  1. 任务生成邮件记录。
  2. 邮件记录投递 Kafka。
  3. Kafka 消费发送。
  4. 外部事件回调。
  5. 入站邮件生成工单。

失败重试建议区分:

  1. 可重试:网络超时、临时服务不可用、临时退信、限流。
  2. 不可重试:邮箱格式错误、发件权限错误、账号不存在、永久退信、投诉抑制。

13. 可观测性

建议至少记录以下指标:

指标 说明
任务创建数 按类型、状态统计
目标用户数 预估人数、实际生成邮件数、过滤人数
队列积压 批量发送队列、客服回复队列、入站队列
发送成功率 按通道、发件邮箱、任务统计
失败原因分布 发送失败、退信、拒信、限流
送达率、打开率、点击率 以事件回调统计,注意打开和点击有误差
投诉率、退订率 作为发送风控核心指标
工单响应时长 首次响应、最近响应、关闭时长
未分配工单数 用于团队容量和告警

14. 参考代码位置

以下为现有项目中可参考的代码位置,重构时可按新架构重新命名和拆分:

模块 现有参考
邮件任务后台入口 app/admin/controller/MailTaskController.php
邮件任务服务 app/service/MailTaskService.php
批量邮件生成与投递参考 app/service/UserService.php
批量邮件发送消费者 app/command/kafkaConsumer/BatchMailCommand.php
工单后台入口 app/admin/controller/EdmChatController.php
工单服务 app/service/EdmChatService.php
客服回复消费者 app/command/kafkaConsumer/MailSendCommand.php
表单数据消费者 app/command/kafkaConsumer/QaForm.php
表单创建工单 app/service/WebFormDataService.php
邮件事件回调 app/controller/AmazonEmailController.php
普通邮箱服务 app/admin/controller/MailboxController.phpapp/service/MailboxService.php
邮件发送封装 app/service/Mail.php
Microsoft 邮件服务 app/service/MicrosoftService.php
策略邮件命令 app/command/EdmDoRealTimeStrategy.phpapp/command/EdmSendRealTimeStrategy.phpapp/command/EdmDayCurrentTask.php
工单辅助命令 app/command/EdmAllocate.phpapp/command/EdmMove.phpapp/command/EdmDealLine.phpapp/command/EdmTimeout.phpapp/command/EdmWorkOrderAutoClose.php