Basically I cannot get a front end website message box to send message to an email as it should. I imagine I could easily do with with normal web hosting but I am using Amazon and trying to learn a lot all at once.
- On AWS I’ve setup an IAM permission policy to include AmazonFullSES
- I created a Lambda_function using SES, Simple Email Service, and the node.js code from Amazon’s documentation
- I setup an API Gateway, linked to that Lambda_function
- API Gateway has POST configured
- API Gateway has OPTIONSs and lambda as a proxy setup
- API Gateway has CORS configured.
The lambda_function file successfully sends out test emails, the status is 200, and the email is received.
The API Gateway likewise tests successfully with status 200.
This is my front end javascript:
document.getElementById('contactForm').addEventListener('submit', async function(e) {
e.preventDefault();
const formData = new FormData(this);
const data = {
name: formData.get('name'),
email: formData.get('email'),
message: formData.get('message')
};
const apiUrl = 'KEY###';
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
subject: "Message from My Website",
body: data,
source: "EMAIL###",
recipient: "EMAIL###"
})
});
const result = await response.json();
if (response.ok) {
alert('Email sent successfully!');
document.getElementById('contactForm').reset();
} else {
alert('Failed to send email. Please try again.');
}
} catch (error) {
console.error('Error:', error);
alert('There was an error sending your message. Please try again later.');
}
});
Then this is the code I am using on AWS Lambda as a node.js(20) function:
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";
const ses = new SESClient({ region: "us-west-1" });
export const handler = async (event) => {
// Parse the incoming JSON payload
const requestBody = JSON.parse(event.body);
const userData = JSON.parse(requestBody.body);
const command = new SendEmailCommand({
Destination: {
ToAddresses: [requestBody.recipient], // Using the recipient from the request
},
Message: {
Body: {
Text: {
// Constructing email body with user data
Data: Name: ${userData.name}nEmail: ${userData.email}nMessage: ${userData.message}
},
Html: {
Data: <html><body><h1>New message from ${userData.name}</h1><p>Email: ${userData.email}</p><p>Message: ${userData.message}</p></body></html>
}
},
Subject: {
Data: requestBody.subject // Using the subject from the request
}
},
Source: requestBody.source // Using the source from the request
});
try {
const response = await ses.send(command);
console.log("Email sent!", response);
return {
isBase64Encoded: false,
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({
message: "Email sent successfully!",
responseId: response.MessageId // Returning the SES MessageId
})
};
} catch (error) {
console.error("Failed to send email.", error);
return {
isBase64Encoded: false,
statusCode: 500,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({
message: "Failed to send email",
errorMessage: error.message
})
};
}
};
The front end of the website, was previously showing error 405: Method Not Allowed, until I removed the IAM permission policy from the API Gateway and just used the default. At this point the front end website gave no errors, refreshed the page as it should when the form was properly submitted and tested successfully.
So all 3/3 tested successfully, but I am not getting emails from the message box! I’ve tried double encoding JSON from the front end script, and double decoding them in the lambda_function node.js, as well as single serializing into JSON objects. Neither has worked. I am not a great javascript writer and so I imagine somehow there must be discrepancies in how my message is being collected on the front end, and then received by lambda.
I don’t know what to do, but there must be something obvious between those two codes where they aren’t talking to each other. Two days working with ChatGPT4 didn’t solve it :/