讲师中心 微信公众号
AI工具推荐 视频效率加速

Email Campaign Management

Polar Sponsor
爱发电 赞助
.NET 9.0

完整的邮件营销工作流程,包含转化追踪和试用激活。适用于(1)创建邮件营销活动,(2)发送营销邮件...

电子邮件活动管理 - 完整工作流程. 目的:可重新使用的工作流程,用于创建、跟踪和管理电子邮件营销活动,并配有转换跟踪、提醒电子邮件和试验a

功能概述

电子邮件活动管理 - 完整工作流程. 目的:可重新使用的工作流程,用于创建、跟踪和管理电子邮件营销活动,并配有转换跟踪、提醒电子邮件和试验a是一项面向实际任务的技能。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。

核心要点

  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
  • 该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。
  • 从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。

使用与执行

实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。

结果检查与注意事项

执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。

邮件营销活动管理——完整工作流

目的:可复用的工作流,用于创建、追踪和管理邮件营销活动,支持转化追踪、提醒邮件发送及试用期激活。

适用范围:增长营销、邮件活动、转化追踪、试用期激活、活动数据分析

活动数据库结构

campaigns 表

CREATE TABLE campaigns (
    id UUID PRIMARY KEY,
    campaign_id VARCHAR(255) UNIQUE NOT NULL,  -- 例如 "ny2026", "summer2026"
    name VARCHAR(255) NOT NULL,
    description TEXT,
    trial_days INTEGER,
    tier VARCHAR(50),  -- ENTERPRISE, SCALE 等
    plan_name TEXT,
    offer_expires_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

campaign_clicks 表

CREATE TABLE campaign_clicks (
    id UUID PRIMARY KEY,
    campaign_id VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    click_source VARCHAR(100),  -- 例如 "cta_button", "events_click"
    utm_source VARCHAR(100),
    utm_medium VARCHAR(100),
    utm_campaign VARCHAR(100),
    converted BOOLEAN DEFAULT FALSE,
    converted_at TIMESTAMP,
    user_id UUID,
    created_at TIMESTAMP DEFAULT NOW()
);

活动统计查询模式

获取活动概览

SELECT
    COUNT(*) as total_clicks,
    COUNT(DISTINCT email) as unique_users,
    COUNT(CASE WHEN converted = TRUE THEN 1 END) as converted_count,
    COUNT(CASE WHEN converted = FALSE THEN 1 END) as pending_count,
    ROUND(100.0 * COUNT(CASE WHEN converted = TRUE THEN 1 END) / COUNT(*), 2) as conversion_rate
FROM campaign_clicks
WHERE campaign_id = 'campaign-id-here';

已注册用户 vs 未注册用户

SELECT
    COUNT(CASE WHEN u.id IS NOT NULL THEN 1 END) as registered_users,
    COUNT(CASE WHEN u.id IS NULL THEN 1 END) as non_registered_users,
    COUNT(CASE WHEN s.tier != 'free' AND s.status = 'active' THEN 1 END) as already_paid_users
FROM campaign_clicks cc
LEFT JOIN users u ON u.email = cc.email
LEFT JOIN subscriptions s ON s.user_id = u.id
WHERE cc.campaign_id = 'campaign-id-here'
  AND cc.converted = FALSE;

Resend API 集成

速率限制(关键)

Resend 免费版限制:每秒 2 次请求(注意:不是每分钟 100 次!)

正确实现方式:

import time

RATE_LIMIT_DELAY = 0.5  # 每秒发送 2 封邮件

for email in emails:
    send_email(email)
    if i < len(emails):
        time.sleep(RATE_LIMIT_DELAY)  # 等待 0.5 秒

错误实现方式(将导致 429 错误):

# 切勿如此操作 —— 发送速度过快
RATE_LIMIT = 100  # 每分钟 100 封邮件
for email in emails:
    send_email(email)
    # 每 100 封才暂停一次 —— 为时已晚!
    if i % RATE_LIMIT == 0:
        time.sleep(60)

邮件发送函数

import os
import requests

RESEND_API_KEY = os.getenv("RESEND_API_KEY")
RESEND_API_URL = "https://api.resend.com/emails"
FROM_EMAIL = "no-reply@ainative.studio"

def send_campaign_email(email: str, campaign_id: str, template_html: str):
    """通过 Resend 发送活动邮件。"""

    # 替换模板变量
    html = template_html.replace("{{email}}", email)
    html = html.replace("{{campaign_id}}", campaign_id)

    payload = {
        "from": FROM_EMAIL,
        "to": [email],
        "subject": "Your campaign subject here",
        "html": html,
        "tags": [
            {"name": "campaign", "value": campaign_id},
            {"name": "type", "value": "reminder"}
        ]
    }

    response = requests.post(
        RESEND_API_URL,
        headers={
            "Authorization": f"Bearer {RESEND_API_KEY}",
            "Content-Type": "application/json"
        },
        json=payload,
        timeout=10
    )

    if response.status_code in [200, 201]:
        return True, response.json().get("id")
    else:
        return False, response.text

试用期激活工作流

激活试用期(关键:使用大写枚举值)

def activate_trial(user, campaign_id: str, trial_days: int, plan_name: str):
    """为用户激活 ENTERPRISE 试用期。"""

    trial_end = datetime.utcnow() + timedelta(days=trial_days)

    # 关键:PostgreSQL 枚举值为大写
    # 'enterprise' → 'ENTERPRISE'
    # 'active' 而非 'trial'(不存在 trial 状态)

    if user['subscription_id']:
        # 更新已有订阅
        cur.execute("""
            UPDATE subscriptions
            SET tier = 'ENTERPRISE',
                status = 'active',
                trial_ends_at = %s,
                plan_name = %s,
                plan_price = 0,
                current_period_end = %s,
                updated_at = NOW()
            WHERE id = %s
        """, (trial_end, plan_name, trial_end, user['subscription_id']))
    else:
        # 创建新订阅
        cur.execute("""
            INSERT INTO subscriptions (
                user_id, tier, status,
                trial_ends_at, plan_name, plan_price,
                billing_email, start_date,
                current_period_start, current_period_end,
                max_users, max_projects, monthly_token_limit,
                max_ai_requests_per_day, max_models,
                created_at, updated_at
            ) VALUES (
                %s, 'ENTERPRISE', 'active',
                %s, %s, 0,
                %s, NOW(),
                NOW(), %s,
                10, 15, 1000000,
                10000, 100,
                NOW(), NOW()
            )
        """, (
            str(user['user_id']),
            trial_end,
            plan_name,
            user['email'],
            trial_end
        ))

    # 标记点击记录为已转化
    cur.execute("""
        UPDATE campaign_clicks
        SET converted = TRUE,
            converted_at = NOW(),
            user_id = %s
        WHERE id = %s
    """, (str(user['user_id']), user['click_id']))

    conn.commit()

常见陷阱与解决方案

陷阱 1:枚举值大小写敏感

问题:'enterprise' 报错 “invalid input value for enum” 解决方案:始终使用大写形式:'ENTERPRISE'、'SCALE'、'FREE'

陷阱 2:无效的状态值

问题:使用 status = 'trial'(该状态不存在) 解决方案:使用 status = 'active' 并配合 trial_ends_at 字段

陷阱 3:速率限制设置过高

问题:将速率限制设为每分钟 100 次,导致 429 错误 解决方案:采用每秒 2 次(两次发送之间延迟 0.5 秒)

陷阱 4:缺失组织 ID

问题:部分用户无 organization_id,引发 NULL 约束错误 解决方案:INSERT 前检查 organization_id 是否存在;若为 NULL,则单独执行查询

陷阱 5:模板中硬编码邮箱地址

问题:生产环境模板中残留测试邮箱 解决方案:使用 {{email}} 模板变量,并在发送时动态替换

陷阱 6:未关闭数据库连接

问题:“too many clients already” 错误 解决方案:始终使用 try/finally 确保连接被关闭

邮件模板要求

模板结构

所有活动邮件模板必须存放在:

src/backend/app/services/templates/{campaign_id}_{type}.html

示例文件名:

  • ny2026_gift.html —— 初始活动邮件
  • ny2026_reminder.html —— 面向未注册用户的提醒邮件
  • summer2026_welcome.html —— 欢迎邮件

必需的模板变量



    Claim Your Trial

样式规范(深色主题)

/* 基础配色 */
body {
    font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background-color: #131726;
}

.email-container {
    background-color: #22263c;
    border-radius: 16px;
}

/* 头部渐变 */
.header {
    background: linear-gradient(135deg, #4B6FED 0%, #5867EF 100%);
    padding: 50px 40px;
}

/* 主要操作按钮(CTA) */
.cta-button {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: #ffffff;
    padding: 18px 48px;
    border-radius: 12px;
}

速查命令

查看活动统计数据

railway run -s "AINative- Core -Production" psql -c "
SELECT
    COUNT(*) as total_clicks,
    COUNT(DISTINCT email) as unique_users,
    COUNT(CASE WHEN converted THEN 1 END) as converted
FROM campaign_clicks
WHERE campaign_id = 'your-campaign-id';
"

发送提醒邮件活动

railway run -s "AINative- Core -Production" 
  python3 scripts/send_{campaign_id}_reminder.py --yes

端到端活动上线核对清单

  • 在数据库中创建活动记录
  • 将活动添加至后端 VALID_CAMPAIGNS 配置项
  • 创建邮件模板(赠礼邮件 + 提醒邮件)
  • 向自己测试邮件发送流程
  • 将后端变更部署至 Railway
  • 启动初始活动
  • 监控点击追踪数据(前 24 小时)
  • 检查转化率(第 3 天)
  • 发送提醒邮件(第 7 天)
  • 为已注册用户激活试用期
  • 生成最终活动报告
目录

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

相关专题

更多
Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

0

2026.10.22

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

0

2026.10.22

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

0

2026.10.22

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

0

2026.10.22

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

0

2026.10.22

Golangci-lint安装与入门教程
Golangci-lint安装与入门教程

本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。

0

2026.10.22

PHP2Shell高危漏洞修复教程
PHP2Shell高危漏洞修复教程

PHP2Shell漏洞是什么,哪些PHP版本和运行环境会受到影响,服务器应该如何检测与修复?本专题提供版本自查脚本、Linux与Docker升级命令、PHP-FPM和Apache排查步骤,以及修复验证、临时缓解和应急响应方案。

0

2026.10.22

剧云人物设定与关系管理教程
剧云人物设定与关系管理教程

本专题介绍剧云人物设定与关系管理,讲解角色小传、性格职业、人物目标、背景资料和关系网络的创建及维护方法。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn