Create New Document

The title of your document (will be displayed as H1)
URL-friendly name (no spaces, use dashes)
Path where to create document (optional, use forward slashes to create subdirectories)

Move/Rename Document

Current location of the document
New path for the document (including the slug)
This only changes the document's path. It does not modify the document's title (H1 heading).

Delete Document

Are you sure you want to delete this document? This action cannot be undone.

Warning: If this is a folder, all contents including subfolders and documents will be deleted.

Message

Message content goes here.

Confirm Action

Are you sure?

Attachments

Allowed file types: jpg, jpeg, png, gif, svg, webp, txt, log, csv, sfd, zip, pdf, docx, xlsx, pptx, mp4 (Max: 10MB)

Document Files

Loading attached files...

Document History

Previous Versions

Loading versions...

Preview

Select a version to preview

Wiki Settings

Language for the user interface
Number of versions to keep per document. Set to 0 to disable versioning.
Maximum allowed file size for uploads in MB.

User Management

Add New User

Leave empty to keep current password
Users with these groups can access restricted sections.

Define path-based access rules for sections of your wiki, then assign users to groups in the Users tab. Rules are evaluated in order. First match wins.

Active Rules

Import markdown files from a ZIP archive. Files will be processed and stored in the appropriate document structure. Directory structure in the ZIP (category/subcategory) will be preserved in the wiki.

Upload a ZIP file containing markdown (.md) files to import.

Create and manage backups of your wiki data. Backups include all documents, images, and configuration files.

Available Backups

Loading backups...

Add/Edit Access Rule

Selected: /

Add Column

SES Email Notification Implementation Guide

Complete step-by-step guide to implement SES bounce and complaint notifications via email.


Table of Contents

  1. Prerequisites
  2. Step 1: Verify Email Addresses in SES
  3. Step 2: Create SNS Topic
  4. Step 3: Create SES Configuration Set
  5. Step 4: Create IAM Role for Lambda
  6. Step 5: Create Lambda Function
  7. Step 6: Subscribe Lambda to SNS Topic
  8. Step 7: Test the Implementation
  9. Step 8: Apply Configuration Set to Your Emails
  10. Troubleshooting

Prerequisites


Step 1: Verify Email Addresses in SES

Via AWS Console:

  1. Navigate to Amazon SES console
  2. Click Verified identities in the left menu
  3. Click Create identity
  4. Choose Email address
  5. Enter the email address you want to use as the sender (this will send notifications)
  6. Click Create identity
  7. Check your email inbox and click the verification link
  8. Repeat for the recipient email address if different

Via AWS CLI:

# Verify sender email
aws ses verify-email-identity --email-address sender@yourdomain.com

# Verify recipient email
aws ses verify-email-identity --email-address recipient@yourdomain.com

Note: Both sender and recipient must be verified if your SES account is in sandbox mode. For production, you can request to move out of sandbox.


Step 2: Create SNS Topic

Via AWS Console:

  1. Navigate to Amazon SNS console
  2. Click Topics in the left menu
  3. Click Create topic
  4. Choose Standard type
  5. Enter topic name: ses-bounce-complaint-notifications
  6. Click Create topic
  7. Copy the Topic ARN - you'll need this later

Via AWS CLI:

# Create SNS topic
aws sns create-topic --name ses-bounce-complaint-notifications

# Note the TopicArn from the response

Example ARN: arn:aws:sns:us-east-1:123456789012:ses-bounce-complaint-notifications


Step 3: Create SES Configuration Set

Via AWS Console:

  1. Navigate to Amazon SES console
  2. Click Configuration sets in the left menu
  3. Click Create set
  4. Enter name: email-tracking-config-set
  5. Click Create set

Add Event Destination for Bounces:

  1. Click on your newly created configuration set
  2. Go to Event destinations tab
  3. Click Add destination
  4. Select Amazon SNS as destination type
  5. Click Next
  6. Configure:
    • Name: bounce-notifications
    • Event types: Check Bounce
    • Amazon SNS topic: Select your SNS topic created in Step 2
  7. Click Next and then Add destination

Add Event Destination for Complaints:

  1. Click Add destination again
  2. Select Amazon SNS as destination type
  3. Click Next
  4. Configure:
    • Name: complaint-notifications
    • Event types: Check Complaint
    • Amazon SNS topic: Select the same SNS topic
  5. Click Next and then Add destination

Via AWS CLI:

# Create configuration set
aws sesv2 create-configuration-set \
  --configuration-set-name email-tracking-config-set

# Add bounce event destination
aws sesv2 create-configuration-set-event-destination \
  --configuration-set-name email-tracking-config-set \
  --event-destination-name bounce-notifications \
  --event-destination '{
    "Enabled": true,
    "MatchingEventTypes": ["BOUNCE"],
    "SnsDestination": {
      "TopicArn": "arn:aws:sns:us-east-1:123456789012:ses-bounce-complaint-notifications"
    }
  }'

# Add complaint event destination
aws sesv2 create-configuration-set-event-destination \
  --configuration-set-name email-tracking-config-set \
  --event-destination-name complaint-notifications \
  --event-destination '{
    "Enabled": true,
    "MatchingEventTypes": ["COMPLAINT"],
    "SnsDestination": {
      "TopicArn": "arn:aws:sns:us-east-1:123456789012:ses-bounce-complaint-notifications"
    }
  }'

Step 4: Create IAM Role for Lambda

Via AWS Console:

  1. Navigate to IAM console
  2. Click Roles in the left menu
  3. Click Create role
  4. Select AWS service and choose Lambda
  5. Click Next
  6. Attach these managed policies:
    • AWSLambdaBasicExecutionRole (for CloudWatch Logs)
  7. Click Next
  8. Enter role name: SESNotificationLambdaRole
  9. Click Create role
  10. Click on the role you just created
  11. Click Add permissionsCreate inline policy
  12. Switch to JSON tab and paste:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ses:SendEmail",
      "Resource": "*"
    }
  ]
}
  1. Click Review policy
  2. Name it: SESSendEmailPolicy
  3. Click Create policy

Via AWS CLI:

# Create trust policy file
cat > trust-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

# Create role
aws iam create-role \
  --role-name SESNotificationLambdaRole \
  --assume-role-policy-document file://trust-policy.json

# Attach basic execution policy
aws iam attach-role-policy \
  --role-name SESNotificationLambdaRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

# Create SES send email policy
cat > ses-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ses:SendEmail",
      "Resource": "*"
    }
  ]
}
EOF

# Create and attach inline policy
aws iam put-role-policy \
  --role-name SESNotificationLambdaRole \
  --policy-name SESSendEmailPolicy \
  --policy-document file://ses-policy.json

Step 5: Create Lambda Function

Via AWS Console:

  1. Navigate to AWS Lambda console
  2. Click Create function
  3. Choose Author from scratch
  4. Configure:
    • Function name: SESNotificationHandler
    • Runtime: Python 3.12 (or latest Python version)
    • Architecture: x86_64
    • Execution role: Use an existing role → SESNotificationLambdaRole
  5. Click Create function

Upload Function Code:

  1. In the Code tab, delete the default code
  2. Copy and paste the contents of lambda_function.py from this repository
  3. Click Deploy

Configure Environment Variables:

  1. Go to Configuration tab
  2. Click Environment variables
  3. Click Edit
  4. Add these variables:
    • Key: SENDER_EMAIL | Value: sender@yourdomain.com (verified in Step 1)
    • Key: RECIPIENT_EMAIL | Value: recipient@yourdomain.com (where you want notifications)
  5. Click Save

Adjust Timeout (Optional):

  1. Still in Configuration tab
  2. Click General configuration
  3. Click Edit
  4. Set Timeout to 30 seconds
  5. Click Save

Via AWS CLI:

# Package the Lambda function
zip lambda_function.zip lambda_function.py

# Create Lambda function (replace ACCOUNT_ID and REGION)
aws lambda create-function \
  --function-name SESNotificationHandler \
  --runtime python3.12 \
  --role arn:aws:iam::ACCOUNT_ID:role/SESNotificationLambdaRole \
  --handler lambda_function.lambda_handler \
  --zip-file fileb://lambda_function.zip \
  --timeout 30 \
  --environment Variables="{
    SENDER_EMAIL=sender@yourdomain.com,
    RECIPIENT_EMAIL=recipient@yourdomain.com
  }"

Step 6: Subscribe Lambda to SNS Topic

Via AWS Console:

  1. Navigate to Amazon SNS console
  2. Click Topics
  3. Click on your topic: ses-bounce-complaint-notifications
  4. Click Create subscription
  5. Configure:
    • Protocol: AWS Lambda
    • Endpoint: Select SESNotificationHandler function
  6. Click Create subscription
  7. The subscription should automatically be confirmed (Status: Confirmed)

Via AWS CLI:

# Get Lambda function ARN
LAMBDA_ARN=$(aws lambda get-function \
  --function-name SESNotificationHandler \
  --query 'Configuration.FunctionArn' \
  --output text)

# Subscribe Lambda to SNS topic (replace TOPIC_ARN)
aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:ACCOUNT_ID:ses-bounce-complaint-notifications \
  --protocol lambda \
  --notification-endpoint $LAMBDA_ARN

# Grant SNS permission to invoke Lambda
aws lambda add-permission \
  --function-name SESNotificationHandler \
  --statement-id AllowSNSInvoke \
  --action lambda:InvokeFunction \
  --principal sns.amazonaws.com \
  --source-arn arn:aws:sns:us-east-1:ACCOUNT_ID:ses-bounce-complaint-notifications

Step 7: Test the Implementation

Test with AWS CLI:

# Send a test email using the configuration set
aws sesv2 send-email \
  --from-email-address sender@yourdomain.com \
  --destination "ToAddresses=recipient@example.com" \
  --content '{
    "Simple": {
      "Subject": {"Data": "Test Email"},
      "Body": {"Text": {"Data": "This is a test email"}}
    }
  }' \
  --configuration-set-name email-tracking-config-set

Test with Python (boto3):

import boto3

ses_client = boto3.client('ses', region_name='us-east-1')

response = ses_client.send_email(
    Source='sender@yourdomain.com',
    Destination={
        'ToAddresses': ['recipient@example.com']
    },
    Message={
        'Subject': {'Data': 'Test Email'},
        'Body': {'Text': {'Data': 'This is a test email'}}
    },
    ConfigurationSetName='email-tracking-config-set'
)

print(f"Email sent! Message ID: {response['MessageId']}")

Simulate a Bounce (for testing):

Use the SES mailbox simulator to test bounce notifications:

aws sesv2 send-email \
  --from-email-address sender@yourdomain.com \
  --destination "ToAddresses=bounce@simulator.amazonses.com" \
  --content '{
    "Simple": {
      "Subject": {"Data": "Bounce Test"},
      "Body": {"Text": {"Data": "Testing bounce notification"}}
    }
  }' \
  --configuration-set-name email-tracking-config-set

You should receive an email notification about the bounce within a few minutes.

Simulate a Complaint (for testing):

aws sesv2 send-email \
  --from-email-address sender@yourdomain.com \
  --destination "ToAddresses=complaint@simulator.amazonses.com" \
  --content '{
    "Simple": {
      "Subject": {"Data": "Complaint Test"},
      "Body": {"Text": {"Data": "Testing complaint notification"}}
    }
  }' \
  --configuration-set-name email-tracking-config-set

Verify the Flow:

  1. Check Lambda CloudWatch Logs for execution logs
  2. Check your recipient email inbox for notification emails
  3. Check SNS Topic metrics to verify messages were published
  4. Check SES sending statistics in the SES console

Step 8: Apply Configuration Set to Your Emails

Option 1: Using boto3 (Python):

import boto3

ses_client = boto3.client('ses')

response = ses_client.send_email(
    Source='sender@yourdomain.com',
    Destination={
        'ToAddresses': ['customer@example.com']
    },
    Message={
        'Subject': {'Data': 'Your Subject'},
        'Body': {
            'Text': {'Data': 'Your email content'},
            'Html': {'Data': '<h1>Your HTML content</h1>'}
        }
    },
    ConfigurationSetName='email-tracking-config-set'  # Add this line
)

Option 2: Using AWS CLI:

aws sesv2 send-email \
  --from-email-address sender@yourdomain.com \
  --destination "ToAddresses=customer@example.com" \
  --content '{
    "Simple": {
      "Subject": {"Data": "Your Subject"},
      "Body": {"Text": {"Data": "Your email content"}}
    }
  }' \
  --configuration-set-name email-tracking-config-set

Option 3: Using SMTP Headers:

If you're using SMTP to send emails, add this header:

X-SES-CONFIGURATION-SET: email-tracking-config-set

Option 4: Set Default Configuration Set (Advanced):

You can set a default configuration set for all emails sent from a verified identity:

aws sesv2 put-email-identity-configuration-set-attributes \
  --email-identity sender@yourdomain.com \
  --configuration-set-name email-tracking-config-set

Troubleshooting

Issue: Not receiving notification emails

Check:

  1. Verify both sender and recipient emails are verified in SES
  2. Check Lambda CloudWatch Logs for errors
  3. Verify environment variables are set correctly
  4. Check SES sending limits (sandbox mode restrictions)
  5. Check spam/junk folder for notification emails

Solution:

# Check Lambda logs
aws logs tail /aws/lambda/SESNotificationHandler --follow

# Test Lambda function directly
aws lambda invoke \
  --function-name SESNotificationHandler \
  --payload file://test-event.json \
  response.json

Issue: Lambda not being triggered

Check:

  1. Verify SNS subscription is confirmed
  2. Check Lambda permissions for SNS invocation
  3. Verify SES configuration set event destinations are enabled

Solution:

# Check SNS subscriptions
aws sns list-subscriptions-by-topic \
  --topic-arn arn:aws:sns:REGION:ACCOUNT_ID:ses-bounce-complaint-notifications

# Verify Lambda permissions
aws lambda get-policy --function-name SESNotificationHandler

Issue: Permission denied errors

Check:

  1. Lambda execution role has correct permissions
  2. SES sender email is verified
  3. SNS topic policy allows SES to publish

Solution:

# Update SNS topic policy to allow SES
aws sns set-topic-attributes \
  --topic-arn arn:aws:sns:REGION:ACCOUNT_ID:ses-bounce-complaint-notifications \
  --attribute-name Policy \
  --attribute-value '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ses.amazonaws.com"},
      "Action": "SNS:Publish",
      "Resource": "arn:aws:sns:REGION:ACCOUNT_ID:ses-bounce-complaint-notifications"
    }]
  }'

Issue: Configuration set not found

Check:

  1. Verify configuration set name matches exactly
  2. Check you're in the correct AWS region

Solution:

# List all configuration sets
aws sesv2 list-configuration-sets

# Verify configuration set details
aws sesv2 get-configuration-set \
  --configuration-set-name email-tracking-config-set

Testing Lambda Function Directly

Create a test event file (test-event.json):

{
  "Records": [
    {
      "EventSource": "aws:sns",
      "Sns": {
        "Message": "{\"notificationType\":\"Bounce\",\"bounce\":{\"bounceType\":\"Permanent\",\"bounceSubType\":\"General\",\"bouncedRecipients\":[{\"emailAddress\":\"bounce@simulator.amazonses.com\",\"action\":\"failed\",\"status\":\"5.1.1\",\"diagnosticCode\":\"smtp; 550 5.1.1 user unknown\"}],\"timestamp\":\"2025-01-01T12:00:00.000Z\"},\"mail\":{\"timestamp\":\"2025-01-01T12:00:00.000Z\",\"source\":\"sender@example.com\"}}"
      }
    }
  ]
}

Test with:

aws lambda invoke \
  --function-name SESNotificationHandler \
  --payload file://test-event.json \
  response.json

cat response.json

Monitoring and Maintenance

CloudWatch Metrics to Monitor:

  1. Lambda Invocations: Number of times Lambda is triggered
  2. Lambda Errors: Failed executions
  3. Lambda Duration: Execution time
  4. SNS Messages Published: Messages sent to SNS topic
  5. SES Bounce Rate: Overall bounce rate
  6. SES Complaint Rate: Overall complaint rate

Set Up CloudWatch Alarms:

# Alarm for Lambda errors
aws cloudwatch put-metric-alarm \
  --alarm-name SESNotificationLambdaErrors \
  --alarm-description "Alert on Lambda function errors" \
  --metric-name Errors \
  --namespace AWS/Lambda \
  --dimensions Name=FunctionName,Value=SESNotificationHandler \
  --statistic Sum \
  --period 300 \
  --evaluation-periods 1 \
  --threshold 1 \
  --comparison-operator GreaterThanThreshold

# Alarm for high bounce rate
aws cloudwatch put-metric-alarm \
  --alarm-name SESHighBounceRate \
  --alarm-description "Alert on high bounce rate" \
  --metric-name Reputation.BounceRate \
  --namespace AWS/SES \
  --statistic Average \
  --period 3600 \
  --evaluation-periods 1 \
  --threshold 0.05 \
  --comparison-operator GreaterThanThreshold

Best Practices:

  1. Monitor bounce and complaint rates regularly
  2. Remove bounced emails from your mailing list
  3. Review notification emails to identify patterns
  4. Keep Lambda function updated with latest runtime
  5. Test configuration changes in a development environment first
  6. Set up CloudWatch alarms for critical metrics
  7. Rotate access keys regularly if using programmatic access
  8. Document any customizations you make to the Lambda function

Additional Resources


Cost Estimation

Approximate monthly costs for 10,000 emails:

Total: ~$2.00/month

Note: Costs scale with volume. Always check current AWS pricing.


Security Considerations

  1. Use IAM roles instead of access keys where possible
  2. Apply principle of least privilege to IAM policies
  3. Encrypt sensitive data in environment variables using KMS
  4. Enable CloudTrail for audit logging
  5. Regularly review IAM policies and permissions
  6. Use VPC endpoints if Lambda needs to be in a VPC
  7. Monitor suspicious activity in CloudWatch Logs
  8. Keep Python runtime updated to latest version

Next Steps

  1. Production Readiness:

    • Request SES production access (move out of sandbox)
    • Set up CloudWatch dashboards for monitoring
    • Implement automated bounce/complaint list management
    • Add HTML email support for richer notifications
  2. Enhancements:

    • Add support for delivery notifications
    • Implement notification aggregation (daily digest)
    • Add DynamoDB for storing bounce/complaint history
    • Create API for querying notification history
    • Add support for multiple recipient emails
    • Integrate with ticketing systems (Jira, ServiceNow)
  3. Scaling:

    • Implement DLQ (Dead Letter Queue) for failed Lambda executions
    • Add retry logic with exponential backoff
    • Consider SQS between SNS and Lambda for buffering
    • Implement concurrent execution limits

Support

If you encounter issues:

  1. Check CloudWatch Logs for detailed error messages
  2. Review the Troubleshooting section above
  3. Verify all prerequisites are met
  4. Test each component individually
  5. Consult AWS documentation and support forums

For questions or improvements to this guide, please open an issue in the repository.

Attached Files

Loading attached files...

Comments

No comments yet. Be the first to comment!

Search Results