Come inviare email da un sito statico usando AWS Lambda e SES
I siti statici sono più sicuri, sono più veloci e richiedono meno manutenzione. Ma cosa succede quando vogliamo implementare un mailer personalizzato invece di usarne uno prefabbricato?
La soluzione più veloce e facile si chiama AWS Lambda + SES (Simple Email Service).
I siti statici sono più sicuri, sono più veloci e richiedono meno manutenzione. Ma cosa succede quando vogliamo implementare un mailer personalizzato invece di usarne uno prefabbricato?
La soluzione più veloce e facile si chiama AWS Lambda + SES (Simple Email Service).
Come dice la documentazione ufficiale:
AWS Lambda consente di eseguire codice senza dover effettuare il provisioning né gestire server. AWS Lambda esegue il codice solo quando necessario e scala automaticamente, da poche richieste al giorno fino a migliaia al secondo.
Lambda esegue il codice (e le sue dipendenze) scritto nelle Functions; Possiamo scrivere direttamente le funzioni dentro le Lambda tramite la console AWS oppure usare un servizio che ci lasci usare il nostro editor preferito e le carichi per noi. Serverless fa esattamente ciò di cui abbiamo bisogno.
Ok, fine delle presentazioni, vediamo ora come funziona.
Setup di Serverless
Prima di tutto, assicuriamoci di installare Serverless npm install serverless -g
, e creiamo il nostro progetto:
serverless create --template aws-nodejs --path email_sender
Il nostro progetto è ora pronto e abbiamo bisogno di fornire delle credenziali per l'accesso a AWS IAM per far si che Serverless abbia il permesso di uploadare.
Le nostre credenziali andranno dentro ~/.aws/credentials
:
[default] aws_access_key_id=************** aws_secret_access_key=***************
In questo caso serverless prenderà ovviamente le credenziali di default, ma se volessimo creare un nuovo profilo potremmo specificare quale utilizzare scrivendo export AWS\_PROFILE="profileName" && export AWS\_REGION=eu-west-1
da dentro il progetto Serverless.
Una volta aperto il progetto possiamo vedere che sono presenti 3 file: il .gitignore, handler.js e serverless.yml
Serverless.yml determina la struttura del nostro progetto:
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 questo file possiamo anche gestire le nostre dipendenze e specificare quali pacchetti o plugin verranno caricati su Lambda:
package: exclude: - node_modules/** include: - node_modules/serverless-offline/** plugins: - serverless-offline
Nota: serverless-offline è un plugin essenziale che permette di utilizzare il servizio che stiamo scrivendo facendo richieste verso localhost, senza dover caricare tutte le volte la funzione Lambda per provarla. Installiamo serverless-offline con npm install serverless-offline -g
.
Il file handler.js è dove andremo a scrivere il codice che vorremo eseguire. Dal file serverless.yml, invece, dichiariamo quali metodi verranno eseguiti quando chiamiamo determinate funzioni. Nel nostro caso, in handler.js il nostro metodo si chiamerà ‘send’:
'use strict'; var https = require("https"); var http = require("http"); var AWS = require('aws-sdk'); module.exports.send = (event, context, callback) => {};
Siamo ora pronti per deployare la nostra funzione.
Deploy su AWS Lambda
serverless deploy
carica la funzione su AWS Lambda e ci ritorna gli endpoint ai quali puntare per chiamare il metodo che abbiamo appena scritto.
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
Aggiungere SES
L'ultima cosa che abbiamo bisogno di impostare è il nostro servizio di email.
var ses = new AWS.SES(); ses.sendEmail(params, function(err) { callback(null, { statusCode: 200, headers: { "Access-Control-Allow-Origin": "*" }, body: JSON.stringify({ status: "success" }) }); })
Inviare la nostra prima email
Adesso il nostro handler.js sarà pronto per inviare la nostra prima mail:
'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" }) }); }) };
Facciamo una richiesta curl POST al nostro endpoint e riceviamo la nostra email!
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: Se si sta utilizzando la versione sandbox di SES dobbiamo verificare entrambe le email, sia quella del mittente che del ricevente, come esplicitamente scritto nella documentazione: