Cloud Native Email Automation with AWS SES, Python, Flask, and Jinja2 - Explore

AWS
AWS SES
Email Automation
Python
Flask
Jinja2
Cloud Native Email Automation with AWS SES, Python, Flask, and Jinja2

by: Sharath Vijayan Nair

January 23, 2025

titleImage

Cloud Native Email Automation with AWS SES, Python, Flask, and Jinja2

Email automation is a crucial component of modern enterprise applications, and Amazon Simple Email Service (AWS SES) provides a robust platform for handling scalable email communications. In this comprehensive guide, we'll explore how to create a custom email automation system using AWS SES, Python Flask, and Jinja2 - perfect for businesses seeking secure, cloud-native email solutions.

Overview

We'll build a cloud-native email system that can:

  • Generate dynamic email templates
  • Create reports using email templates
  • Send formatted HTML emails through AWS SES

Setting Up the Email Template System

1. Creating Custom HTML Email Templates

First, let's create a professional HTML email template using Jinja2 for business process automation:

<!DOCTYPE html>
<html>
<head>
    <style>
        .body {
            font-family: Arial, sans-serif;
        }
        table {
            border-collapse: collapse;
            width: 100%;
        }
        th, td {
            border: 1px solid black;
            padding: 8px;
            text-align: left;
        }
    </style>
</head>
<body>
    <div>
        <p>Dear {{ full_name }},</p>
        
        <p>Here is your report for {{ today_ordinal_format }}:</p>
        
        <table>
            <tr>
                <th>Metric</th>
                <th>Amount</th>
            </tr>
            <tr>
                <td>Funds In</td>
                <td>£{{ fund_in }}</td>
            </tr>
            <tr>
                <td>Funds Out</td>
                <td>£{{ fund_out }}</td>
            </tr>
        </table>
        
        <p>Best regards,<br>
        {{ sender_name }}<br>
        {{ designation }}<br>
        {{ phone_number }}</p>
    </div>
</body>
</html>

2. Implementing the Email Microservice API

Let's create a Flask-based microservice API to generate our email templates:

from flask import Flask, Response
from jinja2 import Environment, FileSystemLoader
import boto3

@email_api.route("/template", methods=["GET"])
@user_required()
def get_email_template(access_token):
    # Get required parameters
    client_id = request.args.get("clientId")
    fund_in = request.args.get("fundIn")
    fund_out = request.args.get("fundOut")
    
    # Get user details from Cognito
    name, designation, phone_number = get_email_signature_details(access_token)
    
    # Generate template
    template = email_service.fetch_email_template(
        client_id, fund_in, fund_out,
        name, designation, phone_number
    )
    
    return Response(template, content_type="text/html")

2.1 User Details and Email Signature Management

A key part of our system is retrieving user details from AWS Cognito for email signatures. Here's how we implement this:

def get_email_signature_details(access_token):
    """
    Retrieve user details from AWS Cognito for email signature.
    
    Args:
        access_token: AWS Cognito access token
        
    Returns:
        tuple: (name, designation, phone_number)
    """
    client = boto3.client("cognito-idp")
    user = client.get_user(AccessToken=access_token)

    name = ""
    designation = ""
    phone_number = ""

    for item in user["UserAttributes"]:
        if item["Name"] == "name":
            name = item["Value"]
        elif item["Name"] == "custom:designation":
            designation = item["Value"]
        elif item["Name"] == "phone_number":
            phone_number = item["Value"]
            
    return name, designation, phone_number

2.2 Custom Template Generation

Our scalable template generation process combines authenticated user details with dynamic content:

def fetch_email_template(
        self,
        client_id,
        fund_in,
        fund_out,
        name,
        designation,
        phone_number,
    ):
    """
    Generate email template with dynamic content.
    
    Args:
        client_id: Client identifier
        fund_in: Incoming funds amount
        fund_out: Outgoing funds amount
        name: Sender's full name
        designation: Sender's designation
        phone_number: Sender's contact number
        
    Returns:
        str: Rendered HTML template
    """
    try:
        # Initialize Jinja2 environment
        env = Environment(loader=FileSystemLoader("templates"))
        template = env.get_template("report_email_template.html")
        
        # Get client information
        client_basic_info = self._get_client_info(client_id)
        full_name = client_basic_info["full_name"]
        
        # Format dates
        today = datetime.date.today()
        today_ordinal_format = format_ordinal_date(today)  # e.g., "1st January 2024"
        day_month_year_format_today = today.strftime("%d/%m/%Y")
        
        # Extract first name for personalized signing
        sender_first_name = self._extract_first_name(name)

        # Render template with all required variables
        email_content = template.render(
            full_name=full_name,
            today_ordinal_format=today_ordinal_format,
            day_month_year_format_today=day_month_year_format_today,
            fund_in=fund_in,
            fund_out=fund_out,
            sender_name=name,
            designation=designation,
            phone_number=phone_number,
            sender_first_name=sender_first_name,
        )
        return email_content
    except Exception as e:
        return None, str(e)

3. Email: Composition and Sending

The core email sending functionality leverages AWS SES for reliable enterprise communication:

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def compose_email(client_id, email_content, sender, is_monthly, to_date):
    # Create MIME message
    msg = MIMEMultipart("mixed")
    msg["From"] = sender
    msg["To"] = recipients
    msg["Subject"] = f"{client_name} - Report {to_date}"
    
    # Attach HTML content
    msg_body = MIMEMultipart("alternative")
    htmlpart = MIMEText(email_content.encode("utf-8"), "html", "utf-8")
    msg_body.attach(htmlpart)
    msg.attach(msg_body)
    
    return msg.as_string()

def send_email(email_content):
    try:
        response = ses_client.send_raw_email(
            RawMessage={"Data": email_content}
        )
        return {"status": "success", "message_id": response["MessageId"]}
    except ClientError as e:
        raise ServiceException(e.response["Error"]["Message"])

Enterprise-Grade Features and Best Practices

Cloud-Native Template ManagemenT:

  • Implement separate template storage using Jinja2's FileSystemLoader
  • Enable DevOps-friendly template versioning
  • Support regulatory compliance requireme

Secure Error Handling:

  • Implement comprehensive error handling for template generation
  • Maintain detailed logging for compliance
  • Monitor email delivery status

Enterprise MIME Handling:

  • Professional formatting for multipart emails
  • Support for rich HTML content
  • Maintain consistent branding across templates

Dynamic Content Integration:

  • Real-time data injection into templates
  • Support for personalized content
  • Business process automation integration

Secure Authentication:

  • AWS Cognito integration for enterprise security
  • Role-based access control
  • Audit trail implementation

Security Considerations

  • Always validate email recipients
  • Use proper authentication for API endpoints
  • Sanitize input data before injecting into templates
  • Keep AWS credentials secure and use IAM roles
  • Implement rate limiting for email sending

Conclusion

AWS SES combined with Flask and Jinja2 provides a powerful foundation for building an email automation system. By following these patterns, you can create a robust, scalable email service that handles both simple and complex use cases.

Remember to:

  • Test templates thoroughly before sending
  • Monitor AWS SES sending quotas
  • Keep templates maintainable and modular
  • Handle edge cases and errors gracefully

This system can be extended to handle more complex scenarios like A/B testing, analytics tracking, and dynamic content based on user preferences.

contact us

Get started now

Get a quote for your project.
logofooter
title_logo

USA

Edstem Technologies LLC
254 Chapman Rd, Ste 208 #14734
Newark, Delaware 19702 US

INDIA

Edstem Technologies Pvt Ltd
Office No-2B-1, Second Floor
Jyothirmaya, Infopark Phase II
Ernakulam, Kerala 682303
iso logo

© 2024 — Edstem All Rights Reserved

Privacy PolicyTerms of Use