DEV Community

Cover image for Building a serverless contact form with AWS Lambda and AWS SES

Building a serverless contact form with AWS Lambda and AWS SES

Adnan Rahić on July 17, 2018

What if I told you it can be done with zero dependencies? Hope you're up for a challenge because that's exactly what we'll be doing. This tutorial...
Collapse
 
developing_dev profile image
Cris Acosta

Hi Adnan,

Thanks for this guide. Just recently completed my portfolio and I am creating a serverless form through this guide. That said, I am lost as to where specifically should I paste this code?

{
  "NODE_ENV":"dev",
  "EMAIL":"john.doe@mail.com",
  "DOMAIN":"*"
}
Enter fullscreen mode Exit fullscreen mode

Am I suppose to do it this way?


custom:
  secrets: ${file(secrets.json)} <---- delete content and replace this

//result:
custom:
  secrets: ${
  "NODE_ENV":"dev",
  "EMAIL":"john.doe@mail.com",
  "DOMAIN":"*"}
Enter fullscreen mode Exit fullscreen mode

Is this right?
This is my first time doing this. Never had experience with APIs.

Collapse
 
developing_dev profile image
Cris Acosta

sad. never got an answer on this

Collapse
 
jeremyprioux profile image
Jérémy Prioux

actually you have to use ${self:custom.secrets:NODE_ENV} instead of ${self:custom.secrets.NODE_ENV}

(same for EMAIL, DOMAIN)

Collapse
 
varaprasadhvsh profile image
varaprasadhVSH

you dont need to replace anything,just create a file called secrets.json and paste that snippet

Collapse
 
fimpr profile image
Fimpr

This is a nice writeup. But you may want to mention that this requires the pligin github.com/functionalone/serverles... to be installed prior to running this code. Otherwise, it fails to create the Role for the function.

Collapse
 
adnanrahic profile image
Adnan Rahić

Thanks! But it doesn't need that plugin to work. You define the IAM roles in the provider section of the serverless.yml file.

Collapse
 
fimpr profile image
Fimpr

Interesting. It failed to create role the first time around. But on second run, it worked fine.

Collapse
 
lazaruswist profile image
lazarusWist • Edited

Does not work for me; Dashbird and AWS mark the send as successful but it never shows up in my inbox. I suspect as others have suggested that my email provider is intercepting it somewhere along the line but I have no idea how to remedy it on my local machine (short of setting up a less secure email?).

Edit: I went ahead and set up a mail.com account and it worked fine when sending it to that. Doesn't help much as I have to use a stricter provider in production. Tips anyone? Would be much appreciated.

Collapse
 
mattwitter profile image
mattwitter

Where is this here living? When I set it up and I test with the CURL command everything works flawlessly. But when I try to hit the submit button on the front end nothing happens?

const form = document.getElementById('contactForm')
const url = 'https://{id}.execute-api.{region}.amazonaws.com/{stage}/email/send'
const toast = document.getElementById('toast')
const submit = document.getElementById('submit')

function post(url, body, callback) {
var req = new XMLHttpRequest();
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/json");
req.addEventListener("load", function () {
if (req.status < 400) {
callback(null, JSON.parse(req.responseText));
} else {
callback(new Error("Request failed: " + req.statusText));
}
});
req.send(JSON.stringify(body));
}
function success () {
toast.innerHTML = 'Thanks for sending me a message! I\'ll get in touch with you ASAP. :)'
submit.disabled = false
submit.blur()
form.name.focus()
form.name.value = ''
form.email.value = ''
form.content.value = ''
}
function error (err) {
toast.innerHTML = 'There was an error with sending your message, hold up until I fix it. Thanks for waiting.'
submit.disabled = false
console.log(err)
}

form.addEventListener('submit', function (e) {
e.preventDefault()
toast.innerHTML = 'Sending'
submit.disabled = true

const payload = {
name: form.name.value,
email: form.email.value,
content: form.content.value
}
post(url, payload, function (err, res) {
if (err) { return error(err) }
success()
})
})

Collapse
 
coyr profile image
Alejandro Barrero

I have the same problem. I don't know where to put that code...

Collapse
 
willdante profile image
willdante

Hello,

I've followed the tuto up to lambda deployment but got an error during the test.

When I go to my AWS account I can't see any API Gateway nor Lambda function.

As I realize I don't understand how all of this works, I'd like to delete/uninstall what I've done.

How can I delete everything that was created following this tuto ?

Thanks in advance.

Collapse
 
willdante profile image
willdante

I've finally managed to make it work thanks to your lambda-mailer GitHub Repo, thank you.

But now I'd like to add recaptcha or another antispam solution to my serverless contact form.

Could you help us with that ?

Thanks in advance.

Collapse
 
sahilg14 profile image
Sahil

Thanks a ton! I was able to do it successfully.

Collapse
 
kaxi1993 profile image
Lasha Kakhidze

Great Article! thanks Adnan

Collapse
 
gergelyszabo94 profile image
Gergely Szabo

Be aware that if you set your gmail (and probably most other big providers as well like Microsoft) will not deliver your mail if it's set up like this. They will be rejected because of DMARC.

Collapse
 
oedo808 profile image
Tony Young

Works fine with MS O365 Exchange, but I think it's all about making sure SES is all set up correctly in your name servers with SPF and DKIM records which is what DMARC enforces. Before I even enabled SES I migrated name servers to Route53 and SES auto configured the necessary records.

I was shocked when I saw Route53 charges for DNS, as I think I've always just used a free service, but at the price of a can of soda per month I suppose it's worth it :-)

Cheers!

Collapse
 
steve_mazin profile image
Kinyua Munene • Edited

Thanks a lot for this. I was able to replicate it. Cheers!