If forwarding emails (with some calculations in-between) is what you need, then AWS Lambda is the simplest solution for you.
As the official documentation says:
AWS Lambda is a compute service that lets you run code without provisioning or managing servers. AWS Lambda executes your code only when needed and scales automatically, from a few requests per day to thousands per second.
Lambda executes the code (and its dependencies) stored in Functions; We can write a Function directly inside the AWS Lambda or we can use a distinct service to create Lambdas and upload Functions: this service is named Serverless and it does just what we want!
Enough talking, let's dive into some code!
Setup the service
First of all, we want to run npm install serverless -g
to install Serverless, and then create our service:
serverless create --template aws-nodejs --path email_sender
Our Serverless project is ready and we just need to setup our AWS IAM credentials that we will store inside ~/.aws/credentials
.
Our credentials list looks like this:
[default]
aws_access_key_id=**************
aws_secret_access_key=***************
but if we have more credentials we can use the one we prefer by typing: export AWS_PROFILE="profileName" && export AWS_REGION=eu-west-1
from inside our serverless project.
As soon as we open the project there are two files (and the .gitignore
): handler.js
and serverless.yml
.
serverless.yml
determines the structure of our service. We will have something similar to this:
service: email-sender
provider:
name: aws
runtime: nodejs4.3
functions:
send:
handler: handler.send
events:
- http:
path: submissions
method: post
response:
headers:
Content-Type: "text/json"
cors:
origins:
- '*'
In this file we can add properties like which packages or plugins we want to upload to Lambda:
package:
exclude:
- node_modules/**
include:
- node_modules/serverless-offline/**
plugins:
- serverless-offline
note: serverless-offline is a very useful plugin which allows you to make requests to localhost without having to deploy to Lambda every time you make a change. Run npm install serverless-offline -g
to install the offline plugin
The handler.js
file is where we will write our methods, the code that we want to execute. From the serverless.yml
file we declare which method has to be executed when we call a certain function. So as you might have guessed, in the handler.js
file our method will be named 'send':
'use strict';
var https = require("https");
var http = require("http");
var AWS = require('aws-sdk');
module.exports.send = (event, context, callback) => {};
We are now ready to do our first deploy.
Deploying to Lambda
serverless deploy
will upload the function on a Lambda and gives us back an endpoint to call it, as we can see from the logs:
endpoints:
POST - https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/submissions
functions:
email-sender-dev-send: arn:aws:lambda:us-east-1:32xxxxxx:function:email-sender-dev-send
Adding SES
The last thing we need to look at is the actual email service, which is another Amazon service called SES (Simple Email Service) and it's very easy to implement:
var ses = new AWS.SES();
ses.sendEmail(params, function(err) {
callback(null, {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({ status: "success" })
});
})
Sending our first email
By now, `handler.js looks like this:
'use strict';
var https = require("https");
var http = require("http");
var AWS = require('aws-sdk');
var ses = new AWS.SES();
module.exports.send = (event, context, callback) => {
const data = JSON.parse(event.body);
const params = {
Destination: {
ToAddresses: [ "receiver@example.com" ],
},
Message: {
Subject: {
Data: data.subject,
Charset: 'UTF-8'
},
Body: {
Text: {
Data: data.text,
Charset: "UTF-8"
}
}
},
Source: "sender@example.com"
};
ses.sendEmail(params, function(err) {
callback(null, {
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "*" },
body: JSON.stringify({ status: "success" })
});
})
};
And we are ready to send! We can try with a simple curl POST request:
curl -H "Content-Type: application/json" -X POST -d '{subject: "test email", text: "this is a test email"}' https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/submissions
ps: if you are in a SES sandbox you have to verify both sender and receiver emails. As stated in the documentation: