Sending E-mail Using Amazon SES With PDF Attachment

Doesn’t it look like the good old email is standing the test of time — tall and strong? Whether it’s sending a message to a colleague or writing down a well-wor

Sending E-mail Using Amazon SES With PDF Attachment

Doesn’t it look like the good old email is standing the test of time — tall and strong? Whether it’s sending a message to a colleague or writing down a well-worded business proposal to a client, the email never goes out of style! 

Even if you need to share an image with your recipient — that’s where email attachments, particularly sending a PDF document come in handy. Are you looking for a way to easily send high-volume emails for your business, without breaking the bank? Look no further than email using Amazon SES!  In this exciting blog, we'll dive into the world of Amazon SES and sending email with PDF attachment using Amazon SES.

Specifically, we'll be using AWS Lambda to create a script that will automatically send your emails when triggered. With this powerful combination of tools, you can streamline your email communication process and save time and effort. So buckle up and get ready to learn how to send professional-looking email using Amazon SES with ease!

 

What is Amazon SES?

Amazon ses logo

As a cloud-based email service provided by Amazon, SES enables businesses of all sizes to send transactional emails, marketing messages, and other types of communication with ease. But that's not all - SES is also scalable and reliable, ensuring that your messages get delivered to your recipients without fail. Additionally, sending email with PDF attachment using Amazon SES offers a seamless solution for sharing important documents with your customers or clients.

 

Implementation

In this blog, we will only focus on Amazon SES email sending with PDF attachment and not how to set up userpool.

Amazon SES is a cost-effective email service that charges only for the number of emails sent and received. If you’re wondering how to send bulk email with Amazon SES, know that it is designed to be highly scalable, which means it can handle a large volume of emails without any issues.
 

Step 1: Set up Amazon SES

Now, you are a step closer to Amazon SES email sending with attached PDF.

 

Step 2: Create an IAM user for SES

We need to give  lambda role and policies to use cognito-idp services and ses services

    ## policy for allowing cognito-idp start ##

        lambda_role.add_to_policy(

            statement=iam.PolicyStatement(

                actions=['cognito-idp:*'],

                resources=['*']

            )

        )

        ## policy for allowing cognito-idp end ##

 

        ## policy to allow using ses start ##

        lambda_role.add_to_policy(

            statement=iam.PolicyStatement(

                actions=['ses:*'],

                resources=['*']

            )

        )

        ## policy to allow using ses end ##

 

These are the two services we are using and we are providing access to those resources for our lambda function.

 

Step 3: Creating Lambda Function for Sending Email 

Now, let’s move to sending email with Amazon SES using lambda function.

The next step is to create a lambda function that will send the email with the PDF attachment. Follow the steps below to create a lambda function:

 

Taking receiver email id from cognito user pool

Now for the Amazon SES email sending with PDF attachment, we will use the pdf file stored in s3 bucket, which we will attach to our email to send it as an attachment.

AWS SES offers two functions, namely send_email and send_raw_email, for sending emails. When it comes to sending an email with a PDF attachment, it is necessary to utilize the send_raw_email function to ensure successful delivery of the email along with the attached PDF file.
 

For the Amazon SES send email with attachment, here's the sample code that demonstrates how to send an email with a PDF attachment using Amazon SES:

 

from os import environ

import json

import boto3

import time

from datetime import datetime

from botocore.exceptions import ClientError  #added for email

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

from email.mime.application import MIMEApplication

 

client = boto3.client('lambda')

cognito_client = boto3.client('cognito-idp')  #create cognito client

 

def lambda_handler(event, context):

    body = json.loads(event['body'])

    user_name = body['user_id']

 

    ##  get the user data from cognito start ##

    get_user_response = cognito_client.admin_get_user(

         UserPoolId ='enter your user pool id', Username=user_name

         )

 

    user_attributes = get_user_response['UserAttributes']

               

    print('userAttributes',user_attributes)

               

    user_email = get_user_response["UserAttributes"][3]["Value"]

    print('email of user is',user_email)

               

    ##  get the user data from cognito end ##

 

    print('reciver email',user_email)

 

    # create s3 client

    s3 = boto3.client('s3')

    #enter the file path where it is store in s3

    #s3_file_key = "path/to/my-file.pdf"

    s3_file_key = ""

 

    s3.download_file(environ["invoice_bucket_name"],s3_file_key,'/tmp/{}'.format(s3_file_key))

 

   

    # This address must be verified with Amazon SES.

    SENDER ="sender@emailaddress.com"

 

    RECIPIENT =user_email

 

    # If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.

    AWS_REGION = "us-east-1"

 

    # The subject line for the email.

    SUBJECT = "Invoice Easy Shop"

 

    # The email body for recipients with non-HTML email clients.

    BODY_TEXT = (" Hi...\\r\ "

                "This is invoice for order id  "

                "Please find the attached invoice below"

                "Thank you for shopping at Easy Shop"

                )

 

    # The HTML body of the email.

    BODY_HTML = """<html>

    <head></head>

    <body>

    <h3> Hi...</h3>

    <p>This is invoice for order id .</p>

    <p>Please find the attached invoice below</p>

    <p>Thank you for shopping at easy shop </p>

    </body>

    </html>

                """            

 

    CHARSET = "UTF-8"

 

    # Create a new SES resource and specify a region.

    client = boto3.client('ses',region_name=AWS_REGION)

 

    # Define the attachment to be send

    attachment = '/tmp/{}'.format(s3_file_key)

 

    # Create a multipart/mixed parent container.

    msg = MIMEMultipart('mixed')

    # Add subject, from and to lines.

    msg['Subject'] = SUBJECT

    msg['From'] = SENDER

    msg['To'] = RECIPIENT

 

    # Create a multipart/alternative child container.

    msg_body = MIMEMultipart('alternative')

 

    # Encode the text and HTML content and set the character encoding. This step is

    # necessary if you're sending a message with characters outside the ASCII range.

    textpart = MIMEText(BODY_TEXT.encode(CHARSET), 'plain', CHARSET)

    htmlpart = MIMEText(BODY_HTML.encode(CHARSET), 'html', CHARSET)

 

    # Add the text and HTML parts to the child container.

    msg_body.attach(textpart)

    msg_body.attach(htmlpart)

 

    # Define the attachment part and encode it using MIMEApplication.

    att = MIMEApplication(open(attachment, 'rb').read())

 

    # Add a header to tell the email client to treat this part as an attachment,

    # and to give the attachment a name.

    att.add_header('Content-Disposition','attachment',filename=s3_file_key)

 

    # Attach the multipart/alternative child container to the multipart/mixed

    # parent container.

    msg.attach(msg_body)

 

    # Add the attachment to the parent container.

    msg.attach(att)

    print(msg)

 

    # Try to send the email.

    try:

        #Provide the contents of the email.

        response = client.send_raw_email(

            Destinations=[

                RECIPIENT

            ],

            RawMessage={

                'Data':msg.as_string(),

            },

            Source=SENDER

        )

        print('email res', response)

    # Display an error if something goes wrong.

    except ClientError as e:

        print(e.response['Error']['Message'])

    else:

        print("Email sent! Message ID:"),

        print(response['MessageId'])

 

Note: Replace ‘bucket-name’,’sender-email-address’,’aws-region’,’cognito-user-pool-id’ with your own values

In the above code, the required libraries are imported, including boto3 (the AWS SDK for Python), time, datetime, and various classes from the email.mime module.


Note: As we will be using AWS SES service in testing environment, we need to verify the email address of receiver as well with SES.

In this blog, we have discussed Amazon SES sending email with attachment and how to send email with PDF attachment using Amazon SES and AWS Lambda. We have gone through the steps required to set up Amazon SES, create an IAM user for SES, and create a Lambda function that sends the email with the PDF attachment. We have also discussed how to get the receiver email from Cognito User Pool using Boto3, download the PDF file from an S3 bucket, and send the email with the PDF attachment using the send_raw_email function. 

 

By following these steps, businesses can easily send emails with PDF attachments to their customers or users. If you want further information on sending email with PDF attachment using Amazon SES, please contact our AWS experts today!