Amazon Simple Email Service (SES) is primarily designed for sending emails, not receiving them. Many developers initially assume SES handles both directions, but the receiving functionality requires a different AWS service combination.
To implement email receiving in AWS, you'll need to combine multiple services:
1. Amazon SES (for email verification and sending)
2. Amazon S3 (for storing raw emails)
3. AWS Lambda (for processing logic)
4. Amazon SNS (for notifications)
5. Route 53 (for DNS configuration)
First, verify your domain in SES:
aws ses verify-domain-identity --domain example.com
Then configure receipt rules in SES:
aws ses create-receipt-rule-set --rule-set-name MyRuleSet
aws ses create-receipt-rule --rule-set-name MyRuleSet --rule "{
\"Name\":\"StoreAndProcess\",
\"Enabled\":true,
\"Recipients\":[\"example.com\"],
\"Actions\":[
{\"S3Action\":{\"BucketName\":\"my-email-bucket\",\"ObjectKeyPrefix\":\"emails/\"}},
{\"LambdaAction\":{\"FunctionArn\":\"arn:aws:lambda:us-east-1:123456789012:function:ProcessEmail\",\"InvocationType\":\"Event\"}}
],
\"ScanEnabled\":true
}"
Here's a sample Lambda function to parse and store emails:
const AWS = require('aws-sdk');
const ses = new AWS.SES();
const s3 = new AWS.S3();
exports.handler = async (event) => {
const record = event.Records[0].ses;
const messageId = record.mail.messageId;
const recipients = record.receipt.recipients;
// Store raw email in S3
await s3.putObject({
Bucket: 'processed-emails',
Key: ${messageId}.eml,
Body: record.content
}).promise();
// Process for each recipient
recipients.forEach(recipient => {
const customerId = recipient.split('@')[0];
// Your business logic here
// Store in database or trigger workflows
});
return {statusCode: 200};
};
For high-volume email processing, consider:
- Using Amazon WorkMail for full email server functionality
- Implementing a custom solution with Postfix on EC2
- Third-party services like SendGrid's Inbound Parse
When implementing this solution:
- Set up proper IAM roles with least privilege
- Implement email content scanning for security
- Configure DLQ for failed Lambda executions
- Monitor S3 bucket sizes and lifecycle policies
For high-volume scenarios:
- Use S3 batch operations for bulk processing
- Consider Kinesis Firehose for streaming email data
- Implement proper Lambda concurrency limits
- Use ElastiCache for customer lookup caching
Many developers mistakenly assume Amazon Simple Email Service (SES) can handle both sending and receiving emails. While SES excels at email sending, receiving functionality requires integration with other AWS services. The proper architecture combines SES with S3 and SNS for complete email processing.
To implement email receiving in AWS, you'll need:
- Amazon SES configured for your domain
- S3 bucket for email storage
- SNS for notification triggers
- Lambda function for processing logic
First, verify your domain in SES:
aws ses verify-domain-identity --domain example.com
Configure receipt rules to handle incoming emails:
aws ses create-receipt-rule-set --rule-set-name MyRuleSet
aws ses create-receipt-rule --rule-set-name MyRuleSet --rule {
"Name": "StoreEmails",
"Enabled": true,
"Recipients": ["example.com"],
"Actions": [
{
"S3Action": {
"BucketName": "my-email-bucket",
"ObjectKeyPrefix": "incoming/"
}
},
{
"SNSAction": {
"TopicArn": "arn:aws:sns:us-east-1:123456789012:email-notification",
"Encoding": "Base64"
}
}
]
}
Create a Lambda function to process stored emails:
import boto3
import email
from email.policy import default
def lambda_handler(event, context):
s3 = boto3.client('s3')
sns = boto3.client('sns')
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = record['s3']['object']['key']
# Get the email object from S3
response = s3.get_object(Bucket=bucket, Key=key)
email_content = response['Body'].read()
# Parse the email
msg = email.message_from_bytes(email_content, policy=default)
# Extract relevant information
subject = msg['subject']
from_address = msg['from']
to_address = msg['to']
# Your business logic here
process_email(to_address, msg)
# Optionally notify via SNS
sns.publish(
TopicArn='arn:aws:sns:us-east-1:123456789012:email-notification',
Message=f"New email received from {from_address} with subject {subject}"
)
For applications requiring high-volume email processing, consider:
- Amazon WorkMail for full email service
- Third-party solutions like SendGrid or Mailgun
- Self-hosted solutions using Postfix or Exim
When implementing this solution:
- Implement proper error handling in your Lambda function
- Set appropriate S3 lifecycle policies for email storage
- Monitor your SNS topics for delivery failures
- Consider using AWS Step Functions for complex processing workflows