Using API Gateway with SES to send Emails with Attachments for a simple contact form. (Amplify Framework/React JS)
AWS Amplify simplifies the manual setup for our backend. Having created a React project as well as configuring it with the Amplify Console we can begin setting up our serverless backend.
Make sure you have the Amplify CLI npm package
npm install -g @aws-amplify/cli
Install all Amplify modules or just the API Gateway module.
npm i aws-amplify or npm i @aws-amplify/api
Now we begin installing our backend API which creates a lambda function to perform our serverless operations.
amplify add api
…make sure you create a lambda function with an Express template when prompted, this integrates API Gateway with Lambda so you can make REST calls (POST/GET/PUT etc.) which is computed using your preferred runtime, in this case NodeJS.
cd amplify/backend/function/<function name>/srcnpm i nodemailer express-fileupload aws-sdk
Nodemailer handles the headers for sending a raw email, raw emails are the only way to attach files to emails), where express-fileupload will parse our files from our REST calls.
For our front end we will be using a few packages including a UI-Framework.
npm i formik yup
npm i @material-ui/core
And of course we are including my favorite UI-Framework Material-UI, This makes use of a clean UX/UI for our front-end.
Before I jump to our App.js we need to include a utils.js to our src code.
Notice we use:
const formData = new FormData();
This is different than just sending the object as is. FormData allows us to attach files however since FormData encodes data in ASCII (7-bit), data is unreadable on the backend. To prevent this we encode in base64 before transmission to avoid this.
Don’t get intimidated by the reduce function that is adding files to the FormData object. You can read here how it works, but this allows us to sequentially iterate an async/await loop instead of simultaneously (parallel) iterate through the loop.
Also note our new Blob accepts a string array. Be sure to include file type and name.
And that’s it. You can send your data via the API.post function (or prefered request function such as axios, fetch, etc.) by including it in the body key of the options parameter. Make sure you use the correct API name and path you plan to use.
Note both API Gateway and SES have both a limit of 10 MB in size.
For our backend we edit our lambda function, assuming you have installed the packaged mentioned at the beginning of our article we can begin implementing our Express backend.
Be sure to have verified your sending email and domain, (e.g. firstname.lastname@example.org) as for receiving you may either send to your personal email or also set that up with Amazon SES or Amazon WorkMail (e.g. email@example.com). If you are not using Route53 for your domain hosting then you should change your DNS settings with your current DNS provider.
Also very important, add the IAM policy ‘SES Full Access’ (or similar) to your lambda function role. This gives your lambda function permission to send emails via SES.
There you have it, test your app and you should see a response on your front-end. Check your emails to see if you received your message.
Thank you for reading, hope you enjoyed.