第10章 实战案例与最佳实践

第10章 实战案例与最佳实践

10.1 电商平台邮件系统集成

10.1.1 需求分析

某电商平台需要实现以下邮件功能:

  • 用户注册欢迎邮件
  • 订单确认和发货通知
  • 放弃购物车提醒
  • 产品推荐和促销活动
  • 订单评价邀请

技术要求

  • 每天发送量:50,000-100,000 封
  • 高可靠性和送达率
  • 实时触发式邮件
  • 个性化推荐
  • 详细的统计分析

10.1.2 架构设计

系统架构图

电商应用服务器
    ↓
消息队列(RabbitMQ/Kafka)
    ↓
邮件发送服务(Python/Go)
    ↓
BillionMail API
    ↓
邮件服务器(Postfix/Dovecot)
    ↓
收件人

核心组件

  1. 消息队列:解耦电商应用和邮件系统,提高可靠性
  2. 邮件发送服务:从队列消费消息,调用 BillionMail API
  3. BillionMail:处理邮件发送、模板管理、统计分析

10.1.3 实施步骤

步骤 1:创建邮件模板

在 BillionMail 中创建各类邮件模板:

欢迎邮件模板welcome.html):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .header { background: #007bff; color: white; padding: 20px; text-align: center; }
        .content { background: #f8f9fa; padding: 30px; }
        .button { 
            display: inline-block; 
            background: #28a745; 
            color: white; 
            padding: 12px 30px; 
            text-decoration: none; 
            border-radius: 5px; 
            margin: 20px 0;
        }
        .footer { text-align: center; padding: 20px; color: #666; font-size: 12px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>欢迎加入 {{site_name}}!</h1>
        </div>
        <div class="content">
            <h2>您好,{{customer_name}}!</h2>
            <p>感谢您注册成为我们的会员。我们很高兴您选择了 {{site_name}}。</p>
            <p>作为新会员,您将享受:</p>
            <ul>
                <li>首次购物 9 折优惠</li>
                <li>免费配送服务</li>
                <li>会员专属优惠活动</li>
                <li>优先客户服务</li>
            </ul>
            <p>立即开始购物,使用优惠码:<strong>WELCOME10</strong></p>
            <a href="{{shop_url}}" class="button">立即购物</a>
        </div>
        <div class="footer">
            <p>© {{current_year}} {{site_name}}. 版权所有。</p>
            <p><a href="{{unsubscribe_url}}">退订</a></p>
        </div>
    </div>
</body>
</html>

订单确认模板order_confirmation.html):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        /* 样式... */
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>订单确认</h1>
        </div>
        <div class="content">
            <h2>您好,{{customer_name}}!</h2>
            <p>您的订单已成功提交,我们正在处理中。</p>
            
            <h3>订单详情</h3>
            <table>
                <tr>
                    <td><strong>订单号:</strong></td>
                    <td>{{order_id}}</td>
                </tr>
                <tr>
                    <td><strong>订单日期:</strong></td>
                    <td>{{order_date}}</td>
                </tr>
                <tr>
                    <td><strong>订单金额:</strong></td>
                    <td>¥{{order_total}}</td>
                </tr>
            </table>
            
            <h3>商品清单</h3>
            <table class="items">
                {% for item in items %}
                <tr>
                    <td>{{item.name}}</td>
                    <td>x {{item.quantity}}</td>
                    <td>¥{{item.price}}</td>
                </tr>
                {% endfor %}
            </table>
            
            <h3>配送地址</h3>
            <p>
                {{shipping_address.name}}<br>
                {{shipping_address.phone}}<br>
                {{shipping_address.address}}
            </p>
            
            <a href="{{order_url}}" class="button">查看订单详情</a>
        </div>
        <div class="footer">
            <p>如有疑问,请联系客服:{{support_email}}</p>
        </div>
    </div>
</body>
</html>

步骤 2:设置消息队列

使用 RabbitMQ:

import pika
import json

# 连接 RabbitMQ
connection = pika.BlockingConnection(
    pika.ConnectionParameters('localhost')
)
channel = connection.channel()

# 声明队列
channel.queue_declare(queue='email_queue', durable=True)

# 发送消息到队列
def send_email_task(email_type, recipient, data):
    message = {
        'type': email_type,
        'recipient': recipient,
        'data': data,
        'timestamp': time.time()
    }
    
    channel.basic_publish(
        exchange='',
        routing_key='email_queue',
        body=json.dumps(message),
        properties=pika.BasicProperties(
            delivery_mode=2,  # 持久化消息
        )
    )
    
    print(f"已添加邮件任务到队列: {email_type} -> {recipient}")

步骤 3:实现邮件发送服务

import pika
import requests
import json
from billionmail import BillionMailClient

# 初始化 BillionMail 客户端
mail_client = BillionMailClient(
    api_key="your_api_key",
    base_url="https://mail.example.com/api/v1"
)

# 邮件处理器
class EmailProcessor:
    def __init__(self):
        self.handlers = {
            'welcome': self.handle_welcome,
            'order_confirmation': self.handle_order_confirmation,
            'shipping': self.handle_shipping,
            'cart_reminder': self.handle_cart_reminder,
        }
    
    def process(self, message):
        email_type = message['type']
        handler = self.handlers.get(email_type)
        
        if handler:
            handler(message['recipient'], message['data'])
        else:
            print(f"未知的邮件类型: {email_type}")
    
    def handle_welcome(self, recipient, data):
        """处理欢迎邮件"""
        mail_client.send_email(
            recipient=recipient,
            template_id='tpl_welcome',
            variables={
                'customer_name': data['name'],
                'shop_url': 'https://shop.example.com',
            }
        )
        
        # 添加到联系人列表
        mail_client.create_contact(
            email=recipient,
            first_name=data['name'],
            tags=['customer', 'new'],
            custom_fields={
                'registration_date': data['registration_date'],
                'source': data.get('source', 'website')
            }
        )
    
    def handle_order_confirmation(self, recipient, data):
        """处理订单确认邮件"""
        mail_client.send_email(
            recipient=recipient,
            template_id='tpl_order_confirmation',
            variables={
                'customer_name': data['customer_name'],
                'order_id': data['order_id'],
                'order_date': data['order_date'],
                'order_total': data['order_total'],
                'items': data['items'],
                'shipping_address': data['shipping_address'],
                'order_url': f"https://shop.example.com/orders/{data['order_id']}"
            }
        )
        
        # 更新联系人信息
        mail_client.update_contact(
            email=recipient,
            updates={
                'custom_fields': {
                    'last_order_date': data['order_date'],
                    'total_orders': data.get('total_orders', 1),
                    'lifetime_value': data.get('lifetime_value', 0)
                }
            }
        )
    
    def handle_shipping(self, recipient, data):
        """处理发货通知"""
        mail_client.send_email(
            recipient=recipient,
            template_id='tpl_shipping',
            variables={
                'customer_name': data['customer_name'],
                'order_id': data['order_id'],
                'tracking_number': data['tracking_number'],
                'tracking_url': data['tracking_url'],
                'estimated_delivery': data['estimated_delivery']
            }
        )
    
    def handle_cart_reminder(self, recipient, data):
        """处理购物车提醒"""
        mail_client.send_email(
            recipient=recipient,
            template_id='tpl_cart_reminder',
            variables={
                'customer_name': data['customer_name'],
                'cart_items': data['cart_items'],
                'cart_total': data['cart_total'],
                'checkout_url': data['checkout_url'],
                'coupon_code': 'COMEBACK10'
            }
        )

# 消费队列
def consume_queue():
    connection = pika.BlockingConnection(
        pika.ConnectionParameters('localhost')
    )
    channel = connection.channel()
    channel.queue_declare(queue='email_queue', durable=True)
    
    processor = EmailProcessor()
    
    def callback(ch, method, properties, body):
        message = json.loads(body)
        print(f"处理邮件任务: {message['type']}")
        
        try:
            processor.process(message)
            ch.basic_ack(delivery_tag=method.delivery_tag)
            print("邮件任务处理成功")
        except Exception as e:
            print(f"邮件任务处理失败: {e}")
            # 重新入队或记录失败
            ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
    
    channel.basic_qos(prefetch_count=10)
    channel.basic_consume(queue='email_queue', on_message_callback=callback)
    
    print("等待邮件任务...")
    channel.start_consuming()

if __name__ == '__main__':
    consume_queue()

步骤 4:集成到电商应用

在电商应用中触发邮件:

from flask import Flask, request, jsonify
from rabbitmq_client import send_email_task

app = Flask(__name__)

@app.route('/api/users/register', methods=['POST'])
def register_user():
    data = request.get_json()
    
    # 创建用户账户
    user = create_user(data)
    
    # 发送欢迎邮件
    send_email_task('welcome', user['email'], {
        'name': user['name'],
        'registration_date': user['created_at'],
        'source': data.get('source', 'website')
    })
    
    return jsonify({'success': True, 'user_id': user['id']})

@app.route('/api/orders', methods=['POST'])
def create_order():
    data = request.get_json()
    
    # 创建订单
    order = create_order_in_db(data)
    
    # 发送订单确认邮件
    send_email_task('order_confirmation', order['customer_email'], {
        'customer_name': order['customer_name'],
        'order_id': order['id'],
        'order_date': order['created_at'],
        'order_total': order['total'],
        'items': order['items'],
        'shipping_address': order['shipping_address'],
        'total_orders': get_customer_order_count(order['customer_id']),
        'lifetime_value': get_customer_lifetime_value(order['customer_id'])
    })
    
    return jsonify({'success': True, 'order_id': order['id']})

@app.route('/api/orders/<order_id>/ship', methods=['POST'])
def ship_order(order_id):
    data = request.get_json()
    
    # 更新订单状态
    order = update_order_status(order_id, 'shipped')
    
    # 发送发货通知
    send_email_task('shipping', order['customer_email'], {
        'customer_name': order['customer_name'],
        'order_id': order['id'],
        'tracking_number': data['tracking_number'],
        'tracking_url': f"https://tracking.example.com/{data['tracking_number']}",
        'estimated_delivery': data['estimated_delivery']
    })
    
    return jsonify({'success': True})

步骤 5:实现定时任务

使用 Celery 实现定时任务:

from celery import Celery
from celery.schedules import crontab
from datetime import datetime, timedelta

app = Celery('tasks', broker='redis://localhost:6379/0')

@app.task
def send_cart_reminders():
    """发送购物车提醒(每小时执行)"""
    # 查询放弃购物车
    abandoned_carts = get_abandoned_carts(
        min_age=timedelta(hours=1),
        max_age=timedelta(hours=24)
    )
    
    for cart in abandoned_carts:
        if not cart.get('reminder_sent'):
            send_email_task('cart_reminder', cart['customer_email'], {
                'customer_name': cart['customer_name'],
                'cart_items': cart['items'],
                'cart_total': cart['total'],
                'checkout_url': f"https://shop.example.com/checkout/{cart['id']}"
            })
            
            mark_reminder_sent(cart['id'])

@app.task
def send_review_requests():
    """发送评价邀请(每天执行)"""
    # 查询 7 天前已送达的订单
    orders = get_delivered_orders(
        delivered_date=datetime.now() - timedelta(days=7)
    )
    
    for order in orders:
        if not order.get('review_requested'):
            send_email_task('review_request', order['customer_email'], {
                'customer_name': order['customer_name'],
                'order_id': order['id'],
                'items': order['items'],
                'review_url': f"https://shop.example.com/reviews/new/{order['id']}"
            })
            
            mark_review_requested(order['id'])

# 配置定时任务
app.conf.beat_schedule = {
    'send-cart-reminders': {
        'task': 'tasks.send_cart_reminders',
        'schedule': crontab(minute=0),  # 每小时
    },
    'send-review-requests': {
        'task': 'tasks.send_review_requests',
        'schedule': crontab(hour=10, minute=0),  # 每天 10:00
    },
}

10.1.4 效果评估

实施前

  • 邮件发送成功率:85%
  • 平均打开率:12%
  • 平均点击率:1.5%
  • 人工操作成本高

实施后

  • 邮件发送成功率:98%
  • 平均打开率:25%
  • 平均点击率:5%
  • 完全自动化,节省人力
  • 用户参与度提升 50%
  • 订单转化率提升 30%

10.2 SaaS 应用通知系统

10.2.1 场景描述

一个项目管理 SaaS 应用需要发送各种通知邮件:

  • 用户邀请和欢迎
  • 任务分配通知
  • 项目更新提醒
  • 到期提醒
  • 周报和月报

10.2.2 实现方案

使用事件驱动架构

from dataclasses import dataclass
from typing import Dict, Any
from enum import Enum

class EventType(Enum):
    USER_INVITED = "user.invited"
    TASK_ASSIGNED = "task.assigned"
    PROJECT_UPDATED = "project.updated"
    DEADLINE_APPROACHING = "deadline.approaching"
    REPORT_GENERATED = "report.generated"

@dataclass
class Event:
    type: EventType
    data: Dict[str, Any]
    user_id: str
    timestamp: float

class EventHandler:
    def __init__(self, mail_client):
        self.mail_client = mail_client
        self.handlers = {
            EventType.USER_INVITED: self.handle_user_invited,
            EventType.TASK_ASSIGNED: self.handle_task_assigned,
            EventType.PROJECT_UPDATED: self.handle_project_updated,
            EventType.DEADLINE_APPROACHING: self.handle_deadline_approaching,
            EventType.REPORT_GENERATED: self.handle_report_generated,
        }
    
    def handle(self, event: Event):
        handler = self.handlers.get(event.type)
        if handler:
            handler(event)
    
    def handle_user_invited(self, event: Event):
        user = get_user(event.user_id)
        inviter = get_user(event.data['inviter_id'])
        project = get_project(event.data['project_id'])
        
        self.mail_client.send_email(
            recipient=user['email'],
            template_id='tpl_user_invited',
            variables={
                'user_name': user['name'],
                'inviter_name': inviter['name'],
                'project_name': project['name'],
                'invitation_url': event.data['invitation_url']
            }
        )
    
    def handle_task_assigned(self, event: Event):
        user = get_user(event.user_id)
        task = get_task(event.data['task_id'])
        assigner = get_user(event.data['assigner_id'])
        
        self.mail_client.send_email(
            recipient=user['email'],
            template_id='tpl_task_assigned',
            variables={
                'user_name': user['name'],
                'task_title': task['title'],
                'task_description': task['description'],
                'deadline': task['deadline'],
                'assigner_name': assigner['name'],
                'task_url': f"https://app.example.com/tasks/{task['id']}"
            }
        )
    
    def handle_deadline_approaching(self, event: Event):
        user = get_user(event.user_id)
        task = get_task(event.data['task_id'])
        
        days_left = event.data['days_left']
        urgency = 'urgent' if days_left <= 1 else 'warning'
        
        self.mail_client.send_email(
            recipient=user['email'],
            template_id=f'tpl_deadline_{urgency}',
            variables={
                'user_name': user['name'],
                'task_title': task['title'],
                'deadline': task['deadline'],
                'days_left': days_left,
                'task_url': f"https://app.example.com/tasks/{task['id']}"
            }
        )

# 发布事件
def publish_event(event: Event):
    # 发送到消息队列
    send_to_queue('events', event)

# 使用示例
@app.route('/api/tasks', methods=['POST'])
def create_task():
    data = request.get_json()
    
    task = create_task_in_db(data)
    
    # 发布任务分配事件
    if data.get('assignee_id'):
        publish_event(Event(
            type=EventType.TASK_ASSIGNED,
            user_id=data['assignee_id'],
            data={
                'task_id': task['id'],
                'assigner_id': current_user.id
            },
            timestamp=time.time()
        ))
    
    return jsonify(task)

用户偏好设置

class NotificationPreferences:
    def __init__(self, user_id):
        self.user_id = user_id
        self.preferences = load_preferences(user_id)
    
    def should_send_email(self, event_type: EventType) -> bool:
        """检查用户是否希望接收此类邮件"""
        return self.preferences.get(f'email_{event_type.value}', True)
    
    def get_digest_preference(self) -> str:
        """获取摘要邮件偏好"""
        return self.preferences.get('digest_frequency', 'daily')

def handle_event_with_preferences(event: Event):
    prefs = NotificationPreferences(event.user_id)
    
    if prefs.should_send_email(event.type):
        event_handler.handle(event)
    else:
        # 添加到摘要队列
        add_to_digest_queue(event)

摘要邮件(Digest)

@app.task
def send_daily_digests():
    """发送每日摘要"""
    users = get_users_with_digest_preference('daily')
    
    for user in users:
        events = get_user_events_since(user['id'], last_24_hours)
        
        if events:
            send_digest_email(user, events, 'daily')

def send_digest_email(user, events, frequency):
    # 按类型分组事件
    grouped_events = group_events_by_type(events)
    
    mail_client.send_email(
        recipient=user['email'],
        template_id=f'tpl_digest_{frequency}',
        variables={
            'user_name': user['name'],
            'events': grouped_events,
            'event_count': len(events),
            'dashboard_url': 'https://app.example.com/dashboard'
        }
    )

10.3 新闻媒体订阅系统

10.3.1 场景需求

新闻媒体网站需要:

  • 发送每日/每周新闻通讯
  • 根据用户兴趣推送内容
  • 管理不同类别的订阅
  • 提供个性化推荐

10.3.2 实现策略

内容管理

class NewsletterManager:
    def __init__(self, mail_client):
        self.mail_client = mail_client
    
    def create_newsletter(self, frequency='daily'):
        """创建新闻通讯"""
        # 获取最新文章
        articles = get_latest_articles(
            since=get_last_newsletter_time(frequency),
            limit=10
        )
        
        # 按类别分组
        categorized = categorize_articles(articles)
        
        # 获取订阅者
        subscribers = get_subscribers(frequency=frequency, active=True)
        
        # 发送个性化新闻通讯
        for subscriber in subscribers:
            self.send_personalized_newsletter(subscriber, categorized)
    
    def send_personalized_newsletter(self, subscriber, articles):
        """发送个性化新闻通讯"""
        # 根据用户兴趣筛选文章
        interests = subscriber.get('interests', [])
        personalized = filter_articles_by_interests(articles, interests)
        
        # 添加推荐文章
        recommended = get_recommended_articles(subscriber['id'], limit=3)
        
        self.mail_client.send_email(
            recipient=subscriber['email'],
            template_id='tpl_newsletter',
            variables={
                'subscriber_name': subscriber['name'],
                'top_stories': personalized['top'][:5],
                'category_stories': personalized['by_category'],
                'recommended': recommended,
                'unsubscribe_url': f"https://news.example.com/unsubscribe/{subscriber['token']}"
            }
        )

兴趣追踪

def track_article_click(subscriber_id, article_id):
    """追踪文章点击"""
    article = get_article(article_id)
    
    # 更新用户兴趣
    update_user_interests(subscriber_id, article['categories'])
    
    # 更新联系人标签
    mail_client.update_contact(
        email=get_subscriber_email(subscriber_id),
        updates={
            'tags': article['categories'],
            'custom_fields': {
                'last_click': datetime.now().isoformat(),
                'engagement_score': calculate_engagement_score(subscriber_id)
            }
        }
    )

A/B 测试

def ab_test_newsletter():
    """A/B 测试新闻通讯"""
    subscribers = get_active_subscribers()
    
    # 分成两组
    group_a, group_b = split_subscribers(subscribers, ratio=0.5)
    
    # 版本 A:传统布局
    for subscriber in group_a:
        send_newsletter(subscriber, layout='traditional', test_group='A')
    
    # 版本 B:卡片布局
    for subscriber in group_b:
        send_newsletter(subscriber, layout='card', test_group='B')
    
    # 24小时后分析结果
    schedule_analysis(delay=timedelta(hours=24))

def analyze_ab_test():
    """分析 A/B 测试结果"""
    results_a = get_campaign_stats(test_group='A')
    results_b = get_campaign_stats(test_group='B')
    
    print(f"版本 A - 打开率: {results_a['open_rate']}%, 点击率: {results_a['click_rate']}%")
    print(f"版本 B - 打开率: {results_b['open_rate']}%, 点击率: {results_b['click_rate']}%")
    
    # 选择表现更好的版本
    if results_b['click_rate'] > results_a['click_rate']:
        update_default_layout('card')

10.4 最佳实践总结

10.4.1 邮件内容最佳实践

DO(应该做的)

✅ 使用清晰简洁的主题行
✅ 个性化内容(使用收件人姓名)
✅ 提供明确的价值主张
✅ 包含清晰的行动号召(CTA)
✅ 优化移动设备显示
✅ 使用高质量的图片
✅ 包含退订链接
✅ 保持品牌一致性
✅ A/B 测试不同版本
✅ 分段受众,发送相关内容

DON'T(不应该做的)

❌ 使用全大写或过多感叹号
❌ 发送过于频繁
❌ 使用误导性主题行
❌ 包含过多图片,缺少文字
❌ 忽略移动优化
❌ 购买邮件列表
❌ 不提供退订选项
❌ 忽略垃圾邮件过滤规则
❌ 发送无关内容
❌ 忽略分析数据

10.4.2 技术实施最佳实践

架构设计

  1. 使用消息队列:解耦邮件发送和业务逻辑
  2. 实现重试机制:处理临时失败
  3. 监控和告警:及时发现问题
  4. 日志记录:便于故障排查
  5. 速率限制:避免被ISP封锁

安全性

  1. 启用 SPF、DKIM、DMARC
  2. 使用 HTTPS:保护 API 通信
  3. 加密敏感数据
  4. 实施访问控制
  5. 定期安全审计

性能优化

  1. 批量操作:减少API调用次数
  2. 使用缓存:减少数据库查询
  3. 异步处理:提高响应速度
  4. 数据库优化:索引、分区
  5. 负载均衡:分散流量

10.4.3 合规性最佳实践

遵守法规

  1. CAN-SPAM Act(美国):

    • 提供退订链接
    • 包含真实的发件人信息
    • 使用准确的主题行
    • 及时处理退订请求
  2. GDPR(欧盟):

    • 获得明确的同意
    • 提供数据访问和删除权利
    • 说明数据使用方式
    • 实施适当的安全措施
  3. CASL(加拿大):

    • 获得明确或暗示的同意
    • 提供身份信息
    • 提供退订机制

同意管理

class ConsentManager:
    def __init__(self, db):
        self.db = db
    
    def record_consent(self, email, consent_type, source):
        """记录用户同意"""
        self.db.insert('consents', {
            'email': email,
            'consent_type': consent_type,
            'source': source,
            'timestamp': datetime.now(),
            'ip_address': request.remote_addr,
            'user_agent': request.user_agent.string
        })
    
    def has_consent(self, email, consent_type):
        """检查是否有同意"""
        return self.db.exists('consents', {
            'email': email,
            'consent_type': consent_type,
            'withdrawn_at': None
        })
    
    def withdraw_consent(self, email, consent_type):
        """撤回同意"""
        self.db.update('consents', {
            'email': email,
            'consent_type': consent_type
        }, {
            'withdrawn_at': datetime.now()
        })

10.4.4 可维护性最佳实践

代码组织

# 项目结构
project/
├── models/
│   ├── user.py
│   ├── contact.py
│   └── campaign.py
├── services/
│   ├── email_service.py
│   ├── template_service.py
│   └── analytics_service.py
├── tasks/
│   ├── send_emails.py
│   ├── process_events.py
│   └── generate_reports.py
├── api/
│   ├── routes.py
│   └── handlers.py
├── config/
│   └── settings.py
└── tests/
    ├── test_email_service.py
    └── test_tasks.py

配置管理

# config/settings.py
import os

class Config:
    # BillionMail 配置
    BILLIONMAIL_API_KEY = os.getenv('BILLIONMAIL_API_KEY')
    BILLIONMAIL_BASE_URL = os.getenv('BILLIONMAIL_BASE_URL')
    
    # 队列配置
    RABBITMQ_URL = os.getenv('RABBITMQ_URL', 'amqp://localhost')
    
    # 数据库配置
    DATABASE_URL = os.getenv('DATABASE_URL')
    
    # 邮件配置
    DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL')
    DEFAULT_FROM_NAME = os.getenv('DEFAULT_FROM_NAME')
    
    # 速率限制
    MAX_EMAILS_PER_HOUR = int(os.getenv('MAX_EMAILS_PER_HOUR', 10000))

测试

import unittest
from unittest.mock import Mock, patch

class TestEmailService(unittest.TestCase):
    def setUp(self):
        self.mail_client = Mock()
        self.email_service = EmailService(self.mail_client)
    
    def test_send_welcome_email(self):
        """测试发送欢迎邮件"""
        user = {'email': 'test@example.com', 'name': 'Test User'}
        
        self.email_service.send_welcome_email(user)
        
        self.mail_client.send_email.assert_called_once()
        args = self.mail_client.send_email.call_args
        self.assertEqual(args[1]['recipient'], 'test@example.com')
        self.assertEqual(args[1]['template_id'], 'tpl_welcome')
    
    @patch('services.email_service.get_user')
    def test_send_order_confirmation(self, mock_get_user):
        """测试发送订单确认"""
        mock_get_user.return_value = {'email': 'test@example.com', 'name': 'Test'}
        
        order = {'id': '123', 'user_id': '1', 'total': 100}
        self.email_service.send_order_confirmation(order)
        
        self.assertTrue(self.mail_client.send_email.called)

文档

  1. API 文档:使用 Swagger/OpenAPI
  2. 代码注释:说明复杂逻辑
  3. README:项目概述和快速开始
  4. 运维文档:部署、监控、故障排除指南
  5. 变更日志:记录重要变更

10.5 总结

通过本教程系列,我们全面学习了 BillionMail 从入门到精通的全部内容:

  1. 第一章:了解了 BillionMail 的基本概念和特性
  2. 第二章:深入理解了系统架构和技术栈
  3. 第三章:掌握了环境准备和安装部署
  4. 第四章:学习了核心功能和配置管理
  5. 第五章:深入配置了邮件服务器
  6. 第六章:实践了邮件营销功能
  7. 第七章:掌握了 API 集成和开发
  8. 第八章:学习了高级功能和性能优化
  9. 第九章:了解了运维监控和故障排除
  10. 第十章:通过实战案例综合应用

BillionMail 是一个功能强大、灵活可靠的自托管邮件服务器和营销平台。通过正确的配置、优化和维护,它可以成为企业邮件通信的坚实基础。希望本教程能够帮助你充分利用 BillionMail 的强大功能,实现高效的邮件营销和通信目标。

继续学习

  • 参与 BillionMail 社区
  • 关注项目更新
  • 分享使用经验
  • 贡献代码和文档

祝你在使用 BillionMail 的旅程中一切顺利!

posted @ 2025-12-17 07:35  我才是银古  阅读(1)  评论(0)    收藏  举报