I've created websites with php web forms before, but I'm launching out to try to use a Lambda / API Gateway / SES combination in AWS while launching a website from S3, in order to create a dynamic submission form. If you'd like to take a quick look at the submission form (and error), it's here: https://precious-gemstones.com/about.html
Here is my javascript, which I've stored at the root level in my S3 bucket:
function submitToAPI(e) {
e.preventDefault();
var URL = "https://ryj32uh9ki.execute-api.us-east-1.amazonaws.com/email/email";
var Namere = /[A-Za-z]{1}[A-Za-z]/;
if (!Namere.test($("#name-input").val())) {
alert ("Name must be at least 2 characters.");
return;
}
if ($("#email-input").val()=="") {
alert ("Please enter your email.");
return;
}
var reemail = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,6})?$/;
if (!reemail.test($("#email-input").val())) {
alert ("Please enter a valid email address.");
return;
}
var name = $("#name-input").val();
var email = $("#email-input").val();
var message = $("#message-input").val();
var data = {
name : name,
email : email,
message : message
};
$.ajax({
type: "POST",
url : "https://ryj32uh9ki.execute-api.us-east-1.amazonaws.com/email/email",
dataType: "json",
crossDomain: "true",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
success: function () {
// clear form and show a success message
alert("Thank you for your inquiry!");
document.getElementById("contact-form").reset();
location.reload();
},
error: function () {
// show an error message
alert("Error; please try again.");
}});
}
Here is my Lambda function:
var AWS = require('aws-sdk');
var ses = new AWS.SES();
var RECEIVER = 'inquiry@precious-gemstones.com';
var SENDER = 'no-reply@precious-gemstones.com';
var response = {
"isBase64Encoded": false,
"headers": { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': 'precious-gemstones.com'},
"statusCode": 200,
"body": "{\"result\": \"Success.\"}"
};
exports.handler = function (event, context) {
console.log('Received event:', event);
sendEmail(event, function (err, data) {
context.done(err, null);
});
};
function sendEmail (event, done) {
var params = {
Destination: {
ToAddresses: [
RECEIVER
]
},
Message: {
Body: {
Text: {
Data: 'name: ' + event.name + '\nemail: ' + event.email + '\nmessage: ' + event.message,
Charset: 'UTF-8'
}
},
Subject: {
Data: 'Gemstone inquiry: ' + event.name,
Charset: 'UTF-8'
}
},
Source: SENDER
};
ses.sendEmail(params, done);
}
And here is my html code snippet:
<div class="contact-form">
<form id="contact-form" method="post" action="https://ryj32uh9ki.execute-api.us-east-1.amazonaws.com/email/email">
<input name="name" type="text" class="form-control" placeholder="Your Name" required>
<br />
<input name="email" type="email" class="form-control" placeholder="Your Email" required>
<br />
<textarea name="message" class="form-control" required rows="10">Your Message</textarea>
<br />
<input type="submit" class="form-control submit" value="Send inquiry">
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="submitToAPI.js"></script>
</body>
Any ideas?
My API Gateway info as seen from my Lambda trigger is as follows: API endpoint: https://ryj32uh9ki.execute-api.us-east-1.amazonaws.com/email/email API type: REST Authorization: NONE Method: POST Resource path: /email Stage: email
No keys or authorization required, and the setup works (I receive the email) when I test from Lambda. The test from the API Gateway post method is also successful. However, it doesn't work from my site, which leads me to believe it's something in my html/JavaScript code, and I shall review/revise that soon.
When you create a stage, the link displayed does not contain the resource part of the URL:
In the code your
aws api gateway URL : https://ryj32uh9ki.execute-api.us-east-1.amazonaws.com/email
the actual url you should be calling the code must be
api + your resource name : https://ryj32uh9ki.execute-api.us-east-1.amazonaws.com/email/<resource_name>
So if I am correct you are missing the resource name at the end of your api url.
For example I've this api gateway deployment
api url : https://asdasdsadsa.execute-api.eu-central-1.amazonaws.com/v1
actual URL which I am calling from my browser for my resource named myaccounts is like below:
api + resource : Request URL: https://asdasdsadsa.execute-api.eu-central-1.amazonaws.com/v1/myaccounts
If your method configuration looks like below means it doesnt have any authorization configured( I am assuming you dont have as per the question you described here)
EDIT
Seems from the error message you shared
{"message": "Could not parse request body into json: Could not parse payload into json: Unrecognized token 'name': was expecting 'null', 'true', 'false' or NaN\n at [Source: (byte[])"name=test&email=test%40yahoo.com&message=Your+Message"; line: 1, column: 6]"}
You have URL encoded data which is being sent to application/json type settings on the API gateway.
So you need to convert your URL encoded data to json format while calling the api endpoint
corresponding developer form thread : HOWTO: Mapping Template v3.0 to convert form POST data or GET query to JSON