-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial Commit. Implemented send mail function.
- Loading branch information
0 parents
commit e8fb0f2
Showing
8 changed files
with
2,674 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
.idea/ | ||
.vscode/ | ||
.vs/ | ||
.next/ | ||
node_modules/ | ||
jspm_packages | ||
build/ | ||
.build/ | ||
dist/ | ||
tmp/ | ||
temp/ | ||
logs/ | ||
.env | ||
out/ | ||
.serverless | ||
.netlify |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"scripts": { | ||
"dev": "serverless offline start --printOutput", | ||
"deploy:dev": "serverless deploy --stage dev function --function", | ||
"deploy:prod": "serverless deploy --stage production function --function", | ||
"full-deploy:dev": "serverless deploy --stage dev", | ||
"full-deploy:prod": "serverless deploy --stage production" | ||
}, | ||
"devDependencies": { | ||
"@types/aws-lambda": "^8.10.56", | ||
"@types/nodemailer": "^6.4.0", | ||
"aws-sdk": "^2.701.0", | ||
"serverless-offline": "^6.4.0", | ||
"serverless-plugin-typescript": "^1.1.9", | ||
"typescript": "^3.9.5" | ||
}, | ||
"dependencies": { | ||
"nodemailer": "^6.4.10" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
service: portfolio-mail-service | ||
|
||
provider: | ||
name: aws | ||
runtime: nodejs12.x | ||
stage: dev | ||
region: ${self:custom.region} | ||
stackTags: | ||
STACK: ${self:service} | ||
REGION: ${self:custom.region} | ||
profile: serverless-admin | ||
|
||
custom: | ||
region: us-east-1 | ||
serverless-offline: | ||
useChildProcesses: true | ||
|
||
plugins: | ||
- serverless-plugin-typescript | ||
- serverless-offline | ||
|
||
functions: | ||
ascii-text: | ||
handler: src/lambdas/endpoints/send-mail.handler | ||
memorySize: 256 | ||
timeout: 30 | ||
events: | ||
- http: | ||
path: send-mail | ||
method: POST | ||
cors: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import AWS from 'aws-sdk'; | ||
import { APIGatewayEvent, Context } from 'aws-lambda'; | ||
import nodemailer from 'nodemailer'; | ||
import Mail from 'nodemailer/lib/mailer'; | ||
|
||
import { Response, createResponse } from '../utilities'; | ||
import { createMailOutput } from '../output'; | ||
|
||
interface SendConfig { | ||
companyName: string; | ||
responseBot: string; | ||
receiver: string; | ||
} | ||
|
||
interface MessageConfig { | ||
firstname: string; | ||
lastname: string; | ||
email: string; | ||
message: string; | ||
subject: string; | ||
} | ||
|
||
interface RequestBody { | ||
sendConfig: SendConfig; | ||
messageConfig: MessageConfig; | ||
} | ||
|
||
const DEFAULT_SUCCESS_MSG = 'Message has been sent.'; | ||
const DEFAULT_ERROR_PARAM_MSG = 'Invalid parameters.'; | ||
const DEFAULT_ERROR_MSG = 'Something went wrong with your email. Please try again later.'; | ||
|
||
const transporter = nodemailer.createTransport({ | ||
SES: new AWS.SES({ apiVersion: '2010-12-01' }) | ||
}); | ||
|
||
export async function handler(event: APIGatewayEvent, context: Context): Promise<Response> { | ||
const body = JSON.parse(event.body || '{}') as RequestBody; | ||
const { sendConfig, messageConfig } = body; | ||
|
||
if(!sendConfig || !messageConfig) return createResponse(422, { error: DEFAULT_ERROR_PARAM_MSG }); | ||
|
||
const { companyName = 'N/A', receiver, responseBot = 'DEFAULT_BOT' } = sendConfig; | ||
const { email = 'N/A', firstname = 'N/A', lastname = 'N/A', message = 'Empty message', subject = `[Contact Request] ${email}` } = messageConfig; | ||
|
||
if(!receiver) return createResponse(422, { error: DEFAULT_ERROR_PARAM_MSG }); | ||
|
||
const mailOptions: Mail.Options = { | ||
from: `${companyName} ${responseBot}`, | ||
to: receiver, | ||
subject, | ||
html: createMailOutput({ email, message, name: `${firstname} ${lastname}` }) | ||
}; | ||
|
||
try { | ||
const data = await transporter.sendMail(mailOptions); | ||
return createResponse(200, { message: DEFAULT_SUCCESS_MSG, data }); | ||
} catch (e) { | ||
console.error(e); | ||
return createResponse(422, { error: DEFAULT_ERROR_MSG }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const DEFAULT_OUTPUT = (name: string, email: string, message: string) => | ||
`<p>You have a new contact request</p><h3>Contact Details</h3> <ul> <li>Name: ${name}</li><li>Email: ${email}</li></ul> <h3>Message</h3> <p>${message}</p>`; | ||
|
||
type MailOutputType = 'default'; | ||
|
||
interface MailParams { | ||
name: string; | ||
email: string; | ||
message: string; | ||
} | ||
|
||
export function createMailOutput(params: MailParams, type?: MailOutputType) { | ||
const { name, email, message } = params; | ||
|
||
switch(type) { | ||
default: | ||
case 'default': | ||
return DEFAULT_OUTPUT(name, email, message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
export interface Response { | ||
statusCode: number; | ||
body: string; | ||
headers?: { [name: string]: string | boolean }; | ||
} | ||
|
||
export type ResponseCode = 200 | 400 | 401 | 403 | 404 | 422 | 500 | 502 | 504; | ||
|
||
export const DEFAULT_HEADERS = { | ||
'Access-Control-Allow-Origin': '*', | ||
'Access-Control-Allow-Credentials': true, | ||
}; | ||
|
||
export function createResponse( | ||
code: ResponseCode, | ||
body: { [key: string]: any }, | ||
headers?: { [key: string]: string | boolean } | ||
): Response { | ||
return { | ||
body: JSON.stringify(body), | ||
headers: { ...DEFAULT_HEADERS, ...headers }, | ||
statusCode: code, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ES5", | ||
"lib": ["ES2015"], | ||
"sourceMap": true, | ||
"outDir": "./build", | ||
"moduleResolution": "node", | ||
"preserveConstEnums": true, | ||
"removeComments": true, | ||
"esModuleInterop": true, | ||
"noImplicitAny": true, | ||
"strictNullChecks": true, | ||
"strictFunctionTypes": true, | ||
"noImplicitThis": true, | ||
"noImplicitReturns": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"allowSyntheticDefaultImports": true, | ||
"emitDecoratorMetadata": true, | ||
"experimentalDecorators": true, | ||
"plugins": [ | ||
{ | ||
"name": "typescript-tslint-plugin" | ||
} | ||
] | ||
}, | ||
"exclude": ["node_modules", ".vscode"], | ||
"include": ["./src/**/*.ts"], | ||
"typeRoots": ["./src/@types/", "./node_modules/@types"] | ||
} |
Oops, something went wrong.