Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 25, 2022 10:45 pm GMT

Criando um envio de newsletter com AWS SNS e Nodejs

Ser que d pra criar uma aplicao de envio de newsletter utilizando AWS SNS e Nodejs?

Nesse post irei ajudar vocs a criar um projeto de publicao de newsletter de um blog de receitas .

O que newsletter?

o recebimento de emails recorrentes enviados para uma lista de assinantes, para que voc sempre receba as novidades sobre um determinado assunto.

O que AWS SNS?

SNS(servio de notificao simples) um servio da AWS que voc pode criar um TOPICO e toda vez que ele for publicado os servios que esto subscritos a ele iro receber uma notificao com os dados passados para esse TOPICO. Com isso podemos criar uma esteira de processos. Pensando no processo do nosso newsletter:

Do blog de receitas(publicador/pub/publish) setas para o servio da Amazon SNS(topico/topic) e setas em direo aos assinantes(subscritos/sub/subscribe)

Na imagem acima podemos ver como ficaria um processo de envio de emails do blog de receitas, no site podemos colocar um boto de se inscrever no newsletter aonde o usurio envia seu email para receber novidades sobre o blog. Toda semana o autor(publish) do blog envia as receitas mais acessadas para as pessoas(subscription) que esto cadastradas no newsletter, quem ficar como intermpedi.

Pr-requisitos

Antes de comear voc precisa ter uma conta na AWS, eles possuem servios gratuitos mas no momento do cadastro eles pedem seu carto de crdito s para verificao, mas sempre fique atento aos custos dos servios que voc est utilizando para no exceder o limite gratuito.

Voc precisa baixar a CLI da AWS e para configurar o login da CLI voc pode seguir esse Tutorial CLI da prpria AWS para criar um perfil administrador em sua conta na AWS para ter acesso aos servios AWS no terminal e por fim no terminal voc pode executar o Comando aws configure que vai te pedir algumas informaes referente ao perfil que voc criou na AWS.

Por ltimo tenha instalado na sua mquina o nodejs(estou utilizando a verso 16.14.0) e serverless framework(estou utilizando a verso 3.14.0).

Criando o projeto

Para criar o projeto abra o terminal e execute o comando abaixo:

serverless create --template aws-nodejs --path newsletter

Esse comando cria um projeto serverless utilizando o template da AWS para Nodejs e o path o nome da aplicao no meu caso o nome newsletter.

Abrindo o projeto no seu editor voc ir encontrar uma estrutura assim:

  • .gitignore: so arquivos e pastas que no vo ser enviados para o github
  • handler.js: uma funo j criada pelo serverless
  • serverless.yml: aonde fica toda a configurao da AWS

Para esse projeto podemos deletar o arquivo handler.js.Precisamos instalar algumas dependncias:

Para rodar nossa aplicao localmente utilizaremos dois pacotes o serverless-offline-sns que cria um ambiente de SNS local para gente testar e o serverless-offline para rodar nossa aplicao offline:

npm i -D serverless-offline-sns serverless-offline

Para utilizar alguns recursos da AWS dentro do nosso cdigo, precisamos instalar uma SDK aws-sdk e para o envio de emails vamos instalar o nodemailer:

npm i aws-sdk nodemailer

Agora vamos estruturar nosso cdigo:

Crie uma pasta utils na raiz do projeto, nessa pasta podem englobar coisa teis para nossa aplicao, dentro dele crie um arquivo users.json:

{  "data": ["[email protected]"]}

Como no temos um banco de dados com os emails cadastrados fiz esse arquivo para facilitar o envio de emails, voc pode colocar sua lista de emails no qual voc quer testar o envio.

Ainda dentro da pasta utils vamos criar um arquivo formatMessageEmail.js:

module.exports.formatMessageEmail = (data) => {  return `  <html>  <head>  </head>  <body style="font-size: 18px;color: #353535;font-family: monospace;display: flex;align-items: center;justify-content: center;flex-direction: column;">    <div>      <h2>Temos novidades essa semana no blog das receitinhas </h2>      <p>${data.introduction}</p>      <ul style="list-style:none;display: flex;flex-flow: wrap;">        ${data.recipes          .map((item) => {            return `          <li style="margin:10px;padding: 8px;width: max-content;background: #F8B400;height: max-content;border-radius: 4px;box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%);">          <p>Nome da receita: ${item.name}</p>          <p>Tempo da receita: ${item.time}</p>          <p>Quantidade de ingredientes: ${item.ingredients}</p>          </li>          `;          })          .join("")}      </ul>      <footer> <p>Obrigado por nos acompanhar durante a semana e semana que vem tem mais =)</p> </footer>    </div>  </body></html>`;};

Essa funo vai fazer a formatao da mensagem que ser enviado por email, mais fique a vontade para estilizar do seu jeito .

Vamos criar uma pasta functions na raiz do projeto e essa pasta vai conter as funes que vo ser acionadas. Vamos criar um arquivo publish-newsletter.js:

"use strict";const AWS = require("aws-sdk");module.exports.handler = async (event) => {  try {    let config = {      region: process.env.AWS_REGION, //regio aonde est localizado seu servio    };    if (process.env.IS_OFFLINE)      config.endpoint = process.env.SNS_ENDPOINT_LOCAL; //caso for rodar offline ele utilizara esse endpoint    const sns = new AWS.SNS(config); // inicializa AWS SNS    const { subject, introduction, recipes } = JSON.parse(event.body); // pegar informaes do body da requisio como titulo do email, introduo do email e as receitas    const params = {      Message: JSON.stringify({ subject, introduction, recipes }),      TopicArn: process.env.SNS_ARN,    };// alguns parametros que sero passado para o topico como a mensagem que ser enviada e o arn do TOPICO(um identificador do topico)    await sns.publish(params).promise(); // publicar no topico essas informacoes    console.log("PUBLISH_NEWSLETTER");    return {       statusCode: 200,      body: JSON.stringify({}),    };  } catch (error) {    console.log(error);    return {      statusCode: 500,      body: JSON.stringify({ error: error.message }),    };  }};

Essa funo vai ser acionada partir de uma requisio HTTP do tipo POST. Nessa funo fazemos a publicao para um TOPICO com as informaes que sero utilizadas por todos que esto inscritos nele, esse TOPICO ser configurado no arquivo serverless.yml mais adiante.

Vamos criar mais uma funo dentro da pasta functions.Crie um arquivo send-email.js.

"use strict";const nodemailer = require("nodemailer");const { formatMessageEmail } = require("../utils/formatMessageEmail");const emails = require("../utils/users.json");module.exports.handler = async (event) => {  try {    if (event.Records && event.Records.length) { // verifica se tem records dentro do evento      const data = JSON.parse(event.Records[0].Sns.Message); // pega os dados que enviamos na publicao do TOPICO no arquivo *publish-newsletter.js*      const transporter = nodemailer.createTransport({ // configurao do envio do email        host: process.env.MAIL_HOST,        port: process.env.MAIL_PORT,        secure: false,        auth: {          user: process.env.MAIL_USER,          pass: process.env.MAIL_PASS,        },      });      const message = formatMessageEmail(data); // formata a mensagem do email      await transporter.sendMail({         from: '"Receitinhas" <[email protected]>', // de qual email est sendo enviado        to: emails.data, // emails que cadastramos em utils/users.json        subject: data.subject, // titulo do email que passamos ao publicar o TOPICO        html: message, // a mensagem que ser entregue no corpo do email      });      console.log("SEND_EMAIL");      return {        statusCode: 200,        body: JSON.stringify({}),      };    }  } catch (error) {    console.log(error);    return {      statusCode: 500,      body: JSON.stringify({ error: error.message }),    };  }};

Esse arquivo um inscrito no nosso TOPICO e nele fazemos o envio da newsletter para os emails cadastrados no utils/users.json.Eu utilizei para configurar o nodemailer o mailtrap ele possui um servio aonde voc pode testar envios de emails, o nodemailer tambem possui uma servio de teste que voc pode encontrar na documentao deles.

Agora vamos ajustar o arquivo serverless.yml:

service: newsletter # nome do servicoframeworkVersion: '3' # versao do serverlessprovider:  name: aws # nome da cloud  runtime: nodejs12.x # versao do nodejs  stage: ${opt:stage,'dev'} # estgio  region: ${opt:region, 'us-east-1'} # regiao do servico  environment:    SNS_ENDPOINT_LOCAL: "http://127.0.0.1:4002" # configuraao de endpoint do serverles-offline-sns    SNS_TOPIC_SEND_NEWSLETTER: "${self:service}-${self:provider.stage}-sns-send-newsletter" # o nome do topico    MAIL_HOST: "SEU_HOST" # host do seu provedor de email    MAIL_PORT: SUA_PORTA # porta do seu provedor de email    MAIL_USER: "SEU_USUARIO" # usuario do seu provedor de email    MAIL_PASS: "SUA_SENHA" # senha do seu provedor de email  iamRoleStatements: # permisses    - Effect: Allow # aplicado a todos      Action:        - SNS:Publish # publicar um topico      Resource: "*" # em todos os recursoscustom:  serverless-offline-sns: # configuraes para rodar local    port: 4002    debug: false  sns_arn: # configurao para montar o ARN    send_newsletter:      local: "arn:aws:sns:us-east-1:123456789012:${self:provider.environment.SNS_TOPIC_SEND_NEWSLETTER}" # localmente      dev: { "Fn::Join" : ["", ["arn:aws:sns:${self:provider.region}:", { "Ref" : "AWS::AccountId" }, ":${self:provider.environment.SNS_TOPIC_SEND_NEWSLETTER}" ] ]  } # quando subimos para AWS desenvolvimentoresources: # recursos da AWS utilizados  Resources:    sendNewsletter: # nome para o recurso      Type: AWS::SNS::Topic # tipo do servio       Properties:        TopicName: "${self:provider.environment.SNS_TOPIC_SEND_NEWSLETTER}" # Nome do topicofunctions: #lista de funoes  send-email: # faz o envio do email    handler: functions/send-email.handler #local aonde est nosso cdigo que ser executado    events: #qual evento vai acionar nosso cdigo      - sns: # servio SNS          arn: "${self:custom.sns_arn.send_newsletter.${self:provider.stage}}" # ARN do send newsletter criado na parte de resources          topicName: "${self:provider.environment.SNS_TOPIC_SEND_NEWSLETTER}" # Nome do topico do send newsletter criado na parte de resources  publish-newsletter: # faz a publicao para o topico send newsletter    handler: functions/publish-newsletter.handler #local aonde est nosso cdigo que ser executado    events: #qual evento vai acionar nosso cdigo      - http: #requisio http          path: publish-newsletter #rota          method: post #metodo    environment: # variaveis de ambiente      SNS_ARN: "${self:custom.sns_arn.send_newsletter.${self:provider.stage}}" # ARN do send newsletter criado na parte de resourcesplugins: #lista de plugin que instalamos no inicio do processo, temos que colocar eles aqui tambem  - serverless-offline  - serverless-offline-sns

A nossa funo publish-newsletter acionada atravs de uma requisio HTTP com mtodo do tipo POST e passamos uma varivel de ambiente SNS_ARN essa varivel vai ser usada para gente publicar no TOPICO sendNewsletter, depois que a gente publica a funo send-email acionada automaticamente por que passamos pra ela um evento sns que est atrelado ao TOPICO sendNewsletter, ento toda vez que tiver uma publicao no TOPICO sendNewsletter ela ser acionada.

Nesse arquivos podemos configurar tudo relacionado a AWS como: banco de dados, lambdas, SQS e outros servios. No nosso caso vamos apenas usar a parte de lambda e SNS. Tambm configuramos tanto a parte para rodar local serverless-offline-sns quanto para subir para AWS com permisses e servios.

Quando a gente faz um deploy para AWS a prpria AWS l esse nosso arquivo e a partir dessas instrues ela comea a criar e configurar tudo que foi passado nesse arquivo e isso muito legal , esse tipo de instruo chamado de Infraestrutura como cdigo (IaC) uma prtica que consiste na estruturao e configurao de recursos de infraestrutura em cdigos.

Rodando local

Para rodar local abra seu terminal e dentro da pasta do seu projeto execute o comando abaixo:

sls offline start --stage local

Voc pode testar a rota http://localhost:3000/local/publish-newsletter no postman, passando no body esse json:

{    "subject": " Temos novidades essa semana",    "introduction": "Nessa semana no blog da receita temos uma lista de receitas mais acessadas pelos nossos usuarios.Essas sao as receitas que mais tiveram curtidas :",    "recipes": [{        "name": "Feijoada",        "time": "40m",        "ingredients": 10    },    {        "name": "Macarrao com queijo",        "time": "30m",        "ingredients": 6    },    {     "name": "Pur de batata",        "time": "15m",        "ingredients": 4    }    ]}

e o resultado que teremos :
print de uma requisio com status 200 no postman

Voc pode ver se em sua caixa de email tem um email novo ou se usar o mailtrap veja sua caixa de email nele.

Subindo para AWS

Para fazer o deploy abra seu terminal e dentro da pasta do seu projeto execute o comando abaixo:

sls deploy --stage dev

Lembrando que cada servio da AWS tem custo e tem uma parte gratuita fique sempre atento a isso.

Demora um pouco para terminar de executar porque ele cria toda a estrutura e tudo que precisa para nossa API funcionar, voc pode acompanhar o andamento no cloudformation dentro do console da AWS, no final da execuo ele mostra um endpoint acessando esse endpoint no curl, postman ou insomnia teremos o mesmo resultado que tivemos rodando localmente.

Para deletar tudo que subimos voc pode esvaziar o s3 bucket que foi criado e depois deletar o cloudformation com isso ele vai deletar tudo relacionado a API que a gente subiu.

Fonte dos meus estudos

Finalizao

O projeto final est aqui exemplo-sns no esquece de deixar um estrelinha se te ajudou .

Existem muitos projetos que podemos fazer utilizando o SNS e outros servios da AWS ou usar um servio com outro servio, so muitas possibilidades basta buscar mais a respeito de cada servio e ver qual ir te ajudar no seu projeto .

Tem um outro projeto que eu fiz utilizando coisas que eu aprendi pipeline-order

Espero ter ajudado de alguma forma e muito obrigado por ler .


Original Link: https://dev.to/feministech/criando-um-envio-de-newsletter-com-aws-sns-e-nodejs-4a2a

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To