0
votes

My Lambda function creates a text file in /tmp location within in lambda environment.

I am failing to send the file as an attachment using Lambda SES Python

I am following code from below AWS documentation to send RAW email with attachment using SES Python3.6

https://docs.aws.amazon.com/ses/latest/DeveloperGuide/examples-send-raw-using-sdk.html

def send_mail_with_attach_ses(sender, recipient, aws_region, subject, file_name):
    # The email body for recipients with non-HTML email clients.
    BODY_TEXT = "Hello,\r\nPlease find the attached file."

    # The HTML body of the email.
    BODY_HTML = """\
    <html>
    <head></head>
    <body>
    <h1>Hello!</h1>
    <p>Please find the attached file.</p>
    </body>
    </html>
    """

    CHARSET = "utf-8"
    client = boto3.client('ses',region_name=aws_region)

    msg = MIMEMultipart('mixed')
    # Add subject, from and to lines.
    msg['Subject'] = subject 
    msg['From'] = sender 
    msg['To'] = recipient    

    msg_body = MIMEMultipart('alternative')
    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(file_name, 'rb').read())

    att.add_header('Content-Disposition','attachment',filename=os.path.basename(file_name))

    if os.path.exists(file_name):
        print("File exists")
    else:
        print("File does not exists")

    # 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)

    try:
        #Provide the contents of the email.
        response = client.send_raw_email(
            Source=msg['From'],
            Destinations=[
                msg['To']
            ],
            RawMessage={
                'Data':msg.as_string(),
            },
            ConfigurationSetName="ConfigSet"
        )
    # 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'])


    # 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=os.path.basename(ATTACHMENT))

    # 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)

After trigger the lambda the function is reaching to response = client.send_raw_email and never returning until the lambda timesout. My lambda timeout is configured for 3 minutes.

{
  "errorMessage": "2019-07-30T10:14:45.180Z fc3ca995-58f9-4f89-8a35-114d941ee063 Task timed out after 180.06 seconds"
}

Can anyone help to send email with attachment using Lambda SES Python?

1
Where is the file located and what is the size of it? - abdullahkhawer
Can your lambda reach ses endpoint. Are you running in VPC? - titogeo
@abdullahkhawer the file size is tiny, it's around 10KB - LG555
@titogeo - Yes, my lambda is in vpc, my vpc has route table with internet gateway and attached to all subnets in the vpc. How to check the connectivity between lambda and ses endpoint? - LG555
@user3276214 and where is the file located? - abdullahkhawer

1 Answers

0
votes

you just have to extend the timeout value under basic settings of the function. It can go up to 15 mins.