Skip to content

Commit 2387920

Browse files
Feat: Serverless function for email
AWS lambda serverless function for sending emails using SES
1 parent b0d77e9 commit 2387920

File tree

6 files changed

+385
-1
lines changed

6 files changed

+385
-1
lines changed

Diff for: .gitignore

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
# Created by https://www.gitignore.io/api/node,code,serverless
3+
# Edit at https://www.gitignore.io/?templates=node,code,serverless
4+
5+
### Code ###
6+
.vscode/*
7+
!.vscode/settings.json
8+
!.vscode/tasks.json
9+
!.vscode/launch.json
10+
!.vscode/extensions.json
11+
12+
### Node ###
13+
# Logs
14+
logs
15+
*.log
16+
npm-debug.log*
17+
yarn-debug.log*
18+
yarn-error.log*
19+
lerna-debug.log*
20+
21+
# Diagnostic reports (https://nodejs.org/api/report.html)
22+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
23+
24+
# Runtime data
25+
pids
26+
*.pid
27+
*.seed
28+
*.pid.lock
29+
30+
# Directory for instrumented libs generated by jscoverage/JSCover
31+
lib-cov
32+
33+
# Coverage directory used by tools like istanbul
34+
coverage
35+
36+
# nyc test coverage
37+
.nyc_output
38+
39+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
40+
.grunt
41+
42+
# Bower dependency directory (https://bower.io/)
43+
bower_components
44+
45+
# node-waf configuration
46+
.lock-wscript
47+
48+
# Compiled binary addons (https://nodejs.org/api/addons.html)
49+
build/Release
50+
51+
# Dependency directories
52+
node_modules/
53+
jspm_packages/
54+
55+
# TypeScript v1 declaration files
56+
typings/
57+
58+
# Optional npm cache directory
59+
.npm
60+
61+
# Optional eslint cache
62+
.eslintcache
63+
64+
# Optional REPL history
65+
.node_repl_history
66+
67+
# Output of 'npm pack'
68+
*.tgz
69+
70+
# Yarn Integrity file
71+
.yarn-integrity
72+
73+
# dotenv environment variables file
74+
.env
75+
.env.test
76+
77+
# parcel-bundler cache (https://parceljs.org/)
78+
.cache
79+
80+
# next.js build output
81+
.next
82+
83+
# nuxt.js build output
84+
.nuxt
85+
86+
# vuepress build output
87+
.vuepress/dist
88+
89+
# Serverless directories
90+
.serverless/
91+
92+
# FuseBox cache
93+
.fusebox/
94+
95+
# DynamoDB Local files
96+
.dynamodb/
97+
98+
### Serverless ###
99+
# Ignore build directory
100+
.serverless
101+
102+
# End of https://www.gitignore.io/api/node,code,serverless

Diff for: README.md

+60-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,61 @@
11
# serverless-node-simple-messaging
2-
Simple email AWS lambda function
2+
3+
Simple AWS lambda serverless function for sending emails using AWS SES
4+
5+
## Prerequisites
6+
- [Get Amazon SES Production Access] (https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html)
7+
8+
## Setup
9+
Run the following commands
10+
```sh
11+
$ npm install -g serverless # Install serverless globally
12+
$ serverless config credentials --provider aws --key <AWS Access Key ID> --secret <AWS Secret Access Key> # Setting up default aws credentials
13+
$ cd aws-serverless-messaging
14+
$ npm install # Installing dependency
15+
```
16+
17+
## Deployment
18+
```sh
19+
$ serverless deploy # Deploying serverless function to aws
20+
```
21+
22+
By this command `serverless deploy` you should be able to see the lambda function in your aws lambda dashboard and it should have returned an endpoint and api_key in your terminal keep these for now.
23+
24+
Setup the following variables into your aws lambda function
25+
- ACCESS_KEY_ID (AWS account access key)
26+
- SECRET_ACCESS_KEY (AWS account secret key)
27+
- API_VERSION (API version for AWS SES)
28+
- REGION (AWS SES region as it's not supported in all the region for now)
29+
30+
## Running
31+
32+
Run ```export MY_API_KEY=<any random key value for your lambda function>```
33+
34+
Make a POST API call to the endpoint and send x-api-key into headers with the api_key value returned after deploy command. The API supports the following body parameters
35+
- toAddresses (Array of valid email addresses)
36+
- bccAddresses (Array of valid email addresses, optional)
37+
- ccAddresses (Array of valid email addresses, optional)
38+
- textBody (Text email body)
39+
- body (HTML email body)
40+
- subject (Email subject)
41+
- sender (Sender email)
42+
43+
For example -
44+
```
45+
{
46+
"toAddresses": ["[email protected]"],
47+
"textBody": "Hello",
48+
"body": "Hello",
49+
"subject": "Subject"
50+
"sender": "[email protected]"
51+
}
52+
```
53+
54+
## Running by postman collection
55+
56+
- Import the postman collection and set the endpoint and x-api-key and make a hit.
57+
58+
## Contributors
59+
60+
[Sparsh Pipley](https://in.linkedin.com/in/sparsh-pipley-6ab0b1a4/)
61+

Diff for: handler.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict';
2+
3+
let AWS = require('aws-sdk');
4+
let ses = new AWS.SES({
5+
apiVersion: process.env.API_VERSION,
6+
accessKeyId: process.env.ACCESS_KEY_ID,
7+
secretAccessKey: process.env.SECRET_ACCESS_KEY,
8+
region: process.env.REGION
9+
});
10+
11+
module.exports.sendEmail = async (event) => {
12+
let body = JSON.parse(event.body);
13+
14+
let params = {
15+
Destination: {
16+
CcAddresses: body.ccAddresses || [],
17+
BccAddresses: body.bccAddresses || [],
18+
ToAddresses: body.toAddresses
19+
},
20+
Message: {
21+
Body: {
22+
Html: {
23+
Data: body.body,
24+
Charset: 'utf-8'
25+
},
26+
Text: {
27+
Data: body.textBody,
28+
Charset: 'utf-8'
29+
}
30+
},
31+
Subject: {
32+
Data: body.subject,
33+
Charset: 'utf-8'
34+
}
35+
},
36+
Source: body.sender
37+
};
38+
39+
return await ses.sendEmail(params).promise().then(function (data) {
40+
return {
41+
statusCode: 200,
42+
body: JSON.stringify({
43+
message: data
44+
}),
45+
};
46+
}).catch(function (err) {
47+
return {
48+
statusCode: err.statusCode || 500,
49+
body: JSON.stringify({
50+
message: err,
51+
}),
52+
};
53+
});
54+
};

Diff for: package-lock.json

+100
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"info": {
3+
"_postman_id": "6158c038-d0b3-4df4-855c-15319d9baf18",
4+
"name": "lambda-email",
5+
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
6+
},
7+
"item": [
8+
{
9+
"name": "lambda-email",
10+
"request": {
11+
"method": "POST",
12+
"header": [
13+
{
14+
"key": "Content-Type",
15+
"name": "Content-Type",
16+
"value": "application/json",
17+
"type": "text"
18+
},
19+
{
20+
"key": "x-api-key",
21+
"value": "<your x-api-key>",
22+
"type": "text"
23+
}
24+
],
25+
"body": {
26+
"mode": "raw",
27+
"raw": "{\n\t\"toAddresses\": [\"[email protected]\"],\n\t\"textBody\": \"Hello\",\n\t\"body\": \"Hello\",\n\t\"subject\": \"Subject\",\n\t\"sender\": \"[email protected]\"\n}"
28+
},
29+
"url": {
30+
"raw": "<your endpoint>/dev/sendEmail",
31+
"host": [
32+
"<your endpoint>"
33+
],
34+
"path": [
35+
"dev",
36+
"sendEmail"
37+
]
38+
}
39+
},
40+
"response": []
41+
}
42+
]
43+
}

Diff for: serverless.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
service: email
2+
3+
provider:
4+
name: aws
5+
runtime: nodejs8.10
6+
region: ap-south-1
7+
apiKeys:
8+
- ${env:MY_API_KEY}
9+
usagePlan:
10+
quota:
11+
limit: 50 #The maximum number of requests that can be made in a given time period.
12+
offset: 2 #The number of requests subtracted from the given limit in the initial time period.
13+
period: MONTH #The time period in which the limit applies. Valid values are "DAY", "WEEK" or "MONTH".
14+
throttle:
15+
burstLimit: 10 #The maximum API request rate limit over a time ranging from one to a few seconds. The maximum API request rate limit depends on whether the underlying token bucket is at its full capacity.
16+
rateLimit: 10 #The API request steady-state rate limit (average requests per second over an extended period of time)
17+
18+
functions:
19+
sendEmail:
20+
handler: handler.sendEmail
21+
events:
22+
- http:
23+
path: sendEmail
24+
method: post
25+
cors: true
26+
private: true

0 commit comments

Comments
 (0)