Integrating Lambda with S3 and SES

Malay ThakurMalay Thakur
7 min read

๐Ÿ’ก Integrating AWS Lambda with Amazon S3 (Simple Storage Service) and Amazon SES (Simple Email Service) allows you to create powerful serverless applications for processing and managing data stored in S3 while automating email communication. AWS Lambda is a serverless compute service that runs code in response to events and scales automatically, eliminating the need for server provisioning and management. ๐Ÿš€๐Ÿ“ง

๐Ÿ”— By integrating Lambda with S3, you can trigger Lambda functions in response to S3 events, such as object creation, deletion, or modification. This enables you to process files, extract data, and perform custom actions on the data stored in S3, all without managing infrastructure. ๐Ÿš€๐Ÿ’ก๐Ÿ’ป

๐Ÿ“จ On the other hand, Amazon SES is a reliable and cost-effective email service that allows you to send and receive emails using a simple API. Integrating Lambda with SES enables you to automate email communication, such as sending notifications, alerts, or reports to users or subscribers. ๐Ÿš€๐Ÿ’ก๐Ÿ“ค

๐Ÿ”„ Combining these services, you can create powerful workflows that automatically process data uploaded to S3 and send customized email notifications to specific recipients based on the content of the files. For instance, you can retrieve email addresses from a file stored in S3 and use Lambda to send personalized emails to each address using SES. This integration provides a flexible and scalable solution for various use cases, including data processing, event-driven applications, and automated email communications, without the need to manage servers or complex infrastructures. ๐Ÿš€๐Ÿ’ก๐ŸŽฏ

Integrating Lambda with S3 and SES can be achieved using the following steps:

  1. ๐Ÿ“‚ Create an S3 bucket and upload a file with multiple email IDs.

  2. ๐Ÿš€ Create an AWS Lambda function to retrieve the email IDs from the file in S3.

  3. ๐Ÿ’ป Utilize the Boto3 library to retrieve the email IDs from the S3 file within the Lambda function.

  4. ๐Ÿ“ง Use the retrieved email IDs to send an email using the SES service.

Let's break down each step:

Step 1: Upload the file with email IDs to S3

  • Log in to the AWS Management Console.

  • Create an S3 bucket if you haven't already

      aws s3api create-bucket --bucket s3-x-lambda-101 --region ap-south-1 --create-bucket-configuration LocationConstraint=ap-south-1
    

  • create a text file containing email IDs, with each email ID on a separate line.

  • Upload a text file to the bucket containing email IDs:

    For example, if you want to upload a file named emails.txt from your desktop to an S3 bucket called s3-x-lambda-101 with the object key emails/email-ids.txt, the command would look like this:

      aws s3 cp ~/Desktop/emails.txt s3://s3-x-lambda-101/emails/email-ids.txt
    

Step 2: Create an AWS Lambda function

  • Go to the AWS Management Console.

  • Open the Lambda service.

  • Click "Create function" and choose the "Author from scratch" option.

  • Enter a name for the function, and select the runtime as "Python".

  • Click on IAM Console.

  • Choose an appropriate role that grants the necessary permissions to access S3 and send emails via SES.

  • Click "Create Role" to create a role.

  • Under Change default execution role, Select "Use an existing rule" and choose the existing role created above.

Step 3: Lambda function code to retrieve email IDs from the S3 file

import boto3

import json

def lambda_handler(event, context):
    s3_bucket = 's3-x-lambda-101'
    s3_object_key = 'emails/email-ids.txt'
    ses_region = 'ap-south-1'  # e.g., 'us-east-1'
    sender_email = '201b149@juetguna.in'
    subject = 'Regarding Internship'
    email_body = 'Congratulation, you are selected!'

    # Initialize Boto3 clients
    s3_client = boto3.client('s3')
    ses_client = boto3.client('ses', region_name=ses_region)

    try:
        # Retrieve the S3 object containing email IDs
        response = s3_client.get_object(Bucket=s3_bucket, Key=s3_object_key)
        email_ids = response['Body'].read().decode('utf-8').split('\n')

        # Remove empty strings from the list of email IDs
        email_ids = [email.strip() for email in email_ids if email.strip()]

        # Send an email for each retrieved email ID
        for email_id in email_ids:
            ses_client.send_email(
                Source=sender_email,
                Destination={'ToAddresses': [email_id]},
                Message={
                    'Subject': {'Data': subject},
                    'Body': {'Text': {'Data': email_body}}
                }
            )

        return {
            'statusCode': 200,
            'body': 'Emails sent successfully.'
        }

    except Exception as e:
        return {
            'statusCode': 500,
            'body': f'Error: {str(e)}'
        }

In the above Python Code:

  • s3_client = boto3.client('s3'): This line creates an S3 client object.The boto3.client() function is used to create a client for a specific AWS service, and 's3' is passed as an argument to specify that you want an S3 client.

  • ses_client = boto3.client('ses', region_name=ses_region): This line creates an SES (Amazon Simple Email Service) client object. The region_name parameter is set to ses_region, which is a variable holding the region name where you want the SES client to be created.

  • The code inside the "try" block is executed. If an error occurs during the execution of this code, the program will "raise" an exception, and the normal flow of execution will be interrupted.

  • response = s3_client.get_object(Bucket=s3_bucket, Key=s3_object_key): This line uses the get_object() method of the S3 client to retrieve an object from the specified S3 bucket. The Bucket parameter represents the name of the S3 bucket, and the Key parameter represents the key or path to the object within the bucket. The s3_bucket and s3_object_key variables are expected to be defined with the appropriate S3 bucket name and object key.

  • email_ids = response['Body'].read().decode('utf-8').split('\n'): After getting the object, this line reads its content using the read() method of the Body attribute from the response object. The content is expected to be in bytes, so .decode('utf-8') is used to convert it to a string. Then, the string is split using the newline character '\n', assuming that each email ID is on a separate line in the object. The resulting email_ids variable will be a list of email IDs extracted from the S3 object.

    After executing this code, the email_ids list should contain the email IDs present in the specified S3 object, and you can use this list for further processing or operations related to email handling.

  • email_ids = [email.strip() for email in email_ids if email.strip()]: This is a list comprehension that iterates over each email ID in the email_ids list.

    • email.strip(): The strip() method is used to remove any leading and trailing whitespaces from each email ID. This is done to ensure that email IDs containing spaces at the beginning or end are cleaned up.

    • for email in email_ids: This part of the list comprehension specifies the iteration over each email ID in the email_ids list.

    • if email.strip(): This is the conditional part of the list comprehension. It checks whether the cleaned-up version of the email ID (after stripping) is not an empty string. If the email ID is not empty, it will be included in the new list.

  • After executing this list comprehension, the email_ids list will be updated, and any empty strings or whitespace-only email IDs will be removed. This ensures that the email_ids list contains only valid and non-empty email addresses, which can be used for further processing or email-related operations.

  • for email_id in email_ids:: This line initiates a loop that iterates through each email ID in the email_ids list. For each email ID, an email will be sent.

  • ses_client.send_email(...): This line sends an email using the SES client. The send_email() method is used to send a single email.

    The method takes the following parameters:

    • Source: The sender's email address (the email address from which the email will be sent).

    • Destination: A dictionary specifying the recipients of the email. In this case, it's a list containing a single email ID extracted from the email_ids list, represented by [email_id].

    • Message: A dictionary containing the email's subject and body.

      • 'Subject': {'Data': subject}: This sets the subject of the email. The subject variable should be defined with the desired subject for the emails.

      • 'Body': {'Text': {'Data': email_body}}: This sets the body of the email. The email_body variable should be defined with the content of the email's body in text format.

  • Click On "Deploy" and then click on "Configure test event".

Step 4: Set up a trigger for the Lambda function

In the Lambda function's configuration, add a trigger by selecting the S3 bucket you created earlier.

Step 5: Verify the Email addresses before using them as the sender in SES.

  • Click on "Amazon Simple Email Service".

  • Click on "Create Identity"

  • Verify all the email addresses mentioned in the email-ids.txt.

    After this, you will receive an email address from AWS.

Step 6: Hurrah! Start Sending Emails

  1. Click On "Test".

  2. Check the "Execution Results".

  3. Check Email.

12
Subscribe to my newsletter

Read articles from Malay Thakur directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Malay Thakur
Malay Thakur

ME101 Final Year Student at JUET Guna. DevOps in Training and AWS. React Developer. Love Learning in Public.