简体   繁体   中英

Lambda function unable to send email with HTML form data

I am new to AWS Lambda and I am trying to send an email with details submitted in an HTML form using AWS SES. I tested out the lambda function with hard coded values and the emails worked fine. Below is the initial code:

# Lambda Function for Contact Forms using AWS SES

import boto3
import datetime

def lambda_handler(event, context):
    client = boto3.client('ses')

    response = client.send_email(
        Destination={
            'BccAddresses': [
            ],
            'CcAddresses': [
                'abc@gmail.com',
            ],
            'ToAddresses': [
                'abc@example.com',
            ],
        },
        Message={
            'Body': {
                'Html': {
                    'Charset': 'UTF-8',
                    'Data': 'This message body contains HTML formatting. It can, for example, contain links like this one: <a class="ulink" href="http://docs.aws.amazon.com/ses/latest/DeveloperGuide" target="_blank">Amazon SES Developer Guide</a>.',
                },
                'Text': {
                    'Charset': 'UTF-8',
                    'Data': 'This is the message body in text format.',
                },
            },
            'Subject': {
                'Charset': 'UTF-8',
                'Data': 'Test email sent at '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            },
        },
        ReplyToAddresses=['xyz@gmail.com',
        ],
        Source='abc@example.com',
    )

I am now trying to replace the form data (post method) in the email body. This is my new code:

# Lambda Function for Contact Forms using AWS SES

import boto3
import datetime

def lambda_handler(event, context):
    client = boto3.client('ses')
    error = None

    # Read form values.
    full_name = event.get('fullname')
    email_addr = event.get('emailid')
    subject = event.get('subject')
    msg_body = event.get('msgbody')
    
    # Check form data.
    if not full_name:
        error = 'Full name is required.'
    elif not email_addr:
        error = 'Email address is required.'
    elif not subject:
        error = 'Subject is required.'
    elif not msg_body:
        error = 'Message body is required.'

    if error is None:
        response = client.send_email(
            Destination={
                'BccAddresses': [
                ],
                'CcAddresses': [
                    'abc@gmail.com',
                ],
                'ToAddresses': [
                    'abc@example.com',
                ],
            },
            Message={
                'Body': {
                    'Html': {
                        'Charset': 'UTF-8',
                        'Data': msg_body,
                    },
                    'Text': {
                        'Charset': 'UTF-8',
                        'Data': msg_body,
                    },
                },
                'Subject': {
                    'Charset': 'UTF-8',
                    'Data': subject+' | example.com | '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                },
            },
            ReplyToAddresses=[email_addr,
            ],
            Source='abc@example.com',
        )

The above code does not throw any error in the Cloud Watch logs but it does not deliver the email also. What am I missing here?

Following is the cloud watch log:

START RequestId: 9ce6de23-9f1d-4d67-a686-ea043692221e Version: $LATEST
END RequestId: 9ce6de23-9f1d-4d67-a686-ea043692221e
REPORT RequestId: 9ce6de23-9f1d-4d67-a686-ea043692221e  Duration: 25.39 ms  Billed Duration: 26 ms  Memory Size: 128 MB Max Memory Used: 65 MB  

The HTML form code is shared below:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Contact | Example Website</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Example Description">
    <meta name="keywords" content="example,contact,form">
    <meta name="author" content="example.com">
    <script src="js/jquery-3.4.1.min.js"></script>
    <link rel="stylesheet" href="css/bootstrap.min.css"></link>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/formcheck.js"></script>
    <link rel="icon" href=""></link>
    <link href="css2/sticky-footer-navbar.css" rel="stylesheet"></link>
    <link rel="icon" href="assets/example-logo-small.png" type="image/png" sizes="16x16"></link>
    <!-- Google ReCaptcha v2 -->
    <script src="https://www.google.com/recaptcha/api.js"></script>
  </head>
  <body>
   <header>
    <!-- Fixed navbar -->
      <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
        <a class="navbar-brand" href="index.html">
         <img src="assets/example-logo-small.png" alt="Logo" style="width:50px;">
        </a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarCollapse">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item">
              <a class="nav-link" href="index.html">Home</a>
            </li>
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" id="navbardrop1" data-toggle="dropdown">Products</a>
              <div class="dropdown-menu">
               <a class="dropdown-item" href="1.html">1</a>
               <a class="dropdown-item" href="2.html">2</a>
               <a class="dropdown-item" href="3.html">3</a>
               <a class="dropdown-item" href="4.html">4</a>
               <a class="dropdown-item" href="5.html">5</a>
               <a class="dropdown-item" href="6.html">6</a>
              </div>
            </li>
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" id="navbardrop2" data-toggle="dropdown">Details</a>
              <div class="dropdown-menu">
               <a class="dropdown-item" href="7.html">7</a>
               <a class="dropdown-item" href="8.html">8</a>
               <a class="dropdown-item" href="9.html">9</a>
               <a class="dropdown-item" href="10.html">10</a>
              </div>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="list.html">List</a>
            </li>
            <li class="nav-item active">
              <a class="nav-link" href="contact.html">Contact<span class="sr-only">(current)</span></a>
            </li>
          </ul>
        </div>
      </nav>
   </header>
   <!-- Begin page content -->
   <main role="main" class="container">
    <div class="container mt-5" style="width:75%">
     <form action="https://mylambdafunction.lambda-url.us-east-1.on.aws/"  method="post" class="needs-validation" novalidate>
      <div class="form-group">
       <label for="fullname">Full Name:</label>
       <input type="text" class="form-control" id="fullname" placeholder="Enter full name" name="fullname" required>
       <div class="valid-feedback">Valid.</div>
       <div class="invalid-feedback">Please fill out this field.</div>
      </div>
      <div class="form-group">
       <label for="emailid">Email Address:</label>
       <input type="email" class="form-control" id="emailid" placeholder="Enter email address" name="emailid" required>
       <div class="valid-feedback">Valid.</div>
       <div class="invalid-feedback">Please fill out this field in correct format.</div>
      </div>
      <div class="form-group">
       <label for="subject">Subject:</label>
       <input type="text" class="form-control" id="subject" placeholder="Enter subject" name="subject" required>
       <div class="valid-feedback">Valid.</div>
       <div class="invalid-feedback">Please fill out this field.</div>
      </div>
      <div class="form-group">
       <label for="msgbody">Message:</label>
       <textarea class="form-control" rows="5" id="msgbody" placeholder="Enter message" name="msgbody" required></textarea>
       <div class="valid-feedback">Valid.</div>
       <div class="invalid-feedback">Please fill out this field.</div>
      </div>
      <div class="form-group form-check">
       <label class="form-check-label">
       <input class="form-check-input" type="checkbox" name="checkdata" required> I agree to the <a href="declaration.html" target="_blank">declaration</a>.
       <div class="valid-feedback">Valid.</div>
       <div class="invalid-feedback">Please select the checkbox to continue.</div>
       </label>
      </div>
      <button type="submit" class="btn btn-dark mb-2">Send</button>
      <div class="g-recaptcha" data-sitekey="my-site-key"></div>
     </form>
    </div>
   </main>
   <!-- Footer Navbar -->
   <div class="container">
    <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-bottom justify-content-center">
     <span class="navbar-text text-white">Copyright &copy Example</span>
    </nav>
   </div>
  </body>
</html>

I can't diagnose in it's entirety, but I've re-written the snippet in a way the allows me to debug my Lambda's with a little more feedback. Keep in a mind, a lambda succeeding doesn't necessarily mean the code was executed as you expect it to, which is where feedback from the invocation helps validate expected behavior.

If the final response provides a MessageId and a code of 200, I would explore the email client settings next.

import boto3
import datetime, json

def lambda_handler(event, context):
    client = boto3.client('ses')

    full_name = event.get('fullname')
    email_addr = event.get('emailid')
    subject = event.get('subject')
    msg_body = event.get('msgbody')

    if None in [full_name, email_addr, subject, msg_body]:
        return {
            "statusCode": 500,
            "body": json.dumps("Error in email variable definitions.")
        }
    

    try:
        response = client.send_email(...)
    except Exception as e:
        return {
            "statusCode": 500,
            "body": json.dumps("Failed to send email: {}".format(e))
        }

    return {
        "statusCode": 200,
        "body": "Email ID: {} sent from Lambda.".format(response.get("MessageId"))
    }
    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM