I’m trying use JavaScript, Lambda and SES to generate an email from a contact form. The code works when I test it from the Lambda console, but when I invoke it with HTTP it doesn’t work, even though I have confirmed the data is the same and the appropriate headers are allowed.
Here are the console errors in the browser:
Here’s my Lambda function:
import boto3
import json
ses = boto3.client('ses')
def lambda_handler(event, context):
name = event['name']
email = event['email']
phone_number = event['phone_number']
message = event['message']
# Construct the email message
subject = f"New message from {name}"
body = f"From: {name}nEmail: {email}nPhone: {phone_number}nMessage: {message}"
sender = '[email protected]'
recipient = '[email protected]'
# Send the email using AWS SES
response = ses.send_email(
Source=sender,
Destination={
'ToAddresses': [
recipient,
]
},
Message={
'Subject': {
'Data': subject,
'Charset': 'UTF-8'
},
'Body': {
'Text': {
'Data': body,
'Charset': 'UTF-8'
}
}
}
)
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*'
},
'body': json.dumps('Email sent successfully!')
}
Here’s my JavaScript:
const formEl = document.querySelector(".contact_form");
formEl.addEventListener('submit', event => {
event.preventDefault()
const formData = new FormData(formEl);
const data = Object.fromEntries(formData);
fetch('https://myapigatewayuri/prod/contact-form', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then( response => {
console.log('Here is the response:')
console.log(response);
if (response.status === 200) {
formEl.reset();
window.alert("Your message was sent successfully. Thank you for reaching out!")
} else if (response.status !== 200) {
window.alert("There was a problem sending your message.")
}
})
});
Here’s the data that is getting sent in the request:
{
'name': 'test name',
'phone_number': '12345678',
'email': '[email protected]',
'message': 'test message'
}
CloudWatch Logs shows this error:
"errorMessage": "'name'",
"errorType": "KeyError",
"stackTrace": [
" File "/var/task/lambda_function.py", line 16, in lambda_handlern name = event['name']n"
]
This error does not occur when testing in the console with the same data.
If I change the variable assignment to use the get() method like this:
name = event.get('name')
email = event.get('email')
phone_number = event.get('phone_number')
message = event.get('message')
The CORS error goes away and the email generates but all the values are ‘none’.
I would have thought this indicates that the data isn’t making it to the function at all, however when running this version of the function I get the following output in CloudWatch logs:
(e5f7444e-a6a5-4b8f-8f47-8f586a342a4a) Method request body before transformations: {
"name": "test name",
"phone_number": "12345678",
"email": "[email protected]",
"message": "test message"
}
I can’t figure out what is going on here and I’ve run out of things to do to try and narrow down the problem. Any help appreciated.