Envio de e-mail com nodemailer
Nesta postagem vamos aprender como fazer o envio de e-mails utilizando o node mailer.
O código completo está disponível no github.
Primeiramente vamos criar uma aplicação de envio de email, para fazer o envio vamos utilizar o nodejs em conjunto com o nodemailer.
Para este exemplo temos que ter uma conta do Gmail, pois é com a conta do Gmail que vamos fazer o encaminhamento das mensagens para uma caixa postal de e-mail.
Vamos criar uma aplicação express, que mostra uma pagina web com um formulário para envio de mensagem. Após o usuário preencher os dados e clicar em enviar
é feita a submissão de dados do formulário (utilizando o método HTTP post) para o e-mail, através do backend.
Crie um novo diretório que vai armazenar a sua aplicação, escolha um nome representativo e depois é só iniciar um novo projeto nodejs com o comando init.
Após criar o projeto basta adicionar duas dependências, o express e o nodemailer. Para isto execute o comando:
npm i express nodemailer
No código inicial, na raiz do diretório, crie um arquivo app.js
que vai conter o esboço inicial da aplicação. E aos poucos vamos incrementar até ter um fluxo completo de envio de e-mail.
const express = require('express');
const app = express();
module.exports = app;
Depois criar o executável da aplicação, este executável vai conter apenas as instruções de fazer o listen da aplicação em uma porta.
Conteúdo do arquivo bin/www
#!/usr/bin/env node
const app = require('../app');
const port = process.env.PORT || 3000
try {
app.listen(port);
console.log(`Microsservice listening at http://localhost:${port}`);
} catch (err) {
throw err;
}
Agora vamos apenas adicionar uma nova entrada na seção scripts
do package.json
.
{
"name": "mailsender",
"version": "1.0.0",
"description": "mail sender with express nodemailer",
"main": "app.js",
"scripts": {
"start": "node ./bin/www",
"dev": "nodemon ./bin/www"
},
"keywords": [
"express",
"nodemailer"
],
"dependencies": {
"express": "^4.17.3",
"nodemailer": "^6.6.3"
}
}
Este era apenas o boilerplate inicial para a gente começar o projeto, vamos iniciar a implementação de nosso serviço, a aplicação vai seguir este fluxo para realizar o envio de um e-mail.
De maneira geral, o nosso formulário de contato vai seguir o fluxo deste diagrama de máquina de estado:
Para isso basta implementar agora as rotas disponíveis em nossa aplicação.
Rota GET - Servindo o formulário
Vamos criar a rota GET /contato que vai servir o formulário e a rota POST /contato que vai fazer a submissão dos dados do formulário.
Após fazer a submissão do formulário o usuário será redirecionado para uma página de enviado com sucesso.
Para implementar este fluxo, crie a rota /contato
na aplicação. Para isso vamos estruturar o nossa aplicação e criar uma pasta server
e dentro desta pasta vamos criar um arquivo chamado index.js
A estrutura atual do projeto deve estar desta forma:
.
├── _app.js
├── _server
│ └── index.js
└── _bin
└── www
A seguir temos o conteúdo do arquivo server/index.js
const nodemailer = require('nodemailer');
const router = require('express').Router();
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Contato</title>
</head>
<body>
<form id="suggestion-form" method="post" action="/contato">
<label><span>Name</span></label>
<input id="name" name="name" type="text" placeholder="Name" required/>
<br>
<label>E-mail</label>
<input id="email" name="email" type="email" placeholder="E-mail" required></input>
<br>
<label><span>Suggestions</span></label>
<input id="message" name="message" type="text" placeholder="How can we improve?" required></input>
<br>
<button type="submit" value="submit"><span>Submit</span></button>
</form>
</body>
</html>`
router.get('/contato', (req, res) => {
res.status(200).send(html);
});
module.exports = router;
Estamos declarando a variável html
onde estamos servindo o html inline. Isso é apenas para facilitar o desenvolvimento da aplicação, ao final vamos refatorar para fazer a utilização correta, servindo o html via o sistema de arquivos da máquina.
Depois de criar esta rota, basta adicionar agora ao nosso app.js
a referência para este arquivo criado.
require('dotenv').config();
const express = require('express');
const app = express();
app.use(express.json());
app.use(require('./server/index'));
module.exports = app;
Agora para visualizar o que já implementamos, basta iniciar a aplicação e via um browser entrar no endereço que está sendo servido pela aplicação express.
Para isto basta executar o comando:
npm start
Isso é o conteúdo de nossa página ao acessar via o browser:
Pronto, agora já temos a base para a iniciar a nossa página de contato e começar a utilizar o nodemailer.
A ideia aqui é não expor publicamente o nosso e-mail em uma página publica.
Rota POST - enviando e-mail com nodemailer.
Primeiramente vamos criar o transporter, esse objeto vai ser o responsável por fazer a conexão com o servidor de e-mail. Para este exemplo vamos utilizar o Gmail. Vou deixar os valores para você preencher com os seus dados. Então use a sua conta do Gmail para fazer o acesso. Digite o nome do usuário no atributo user
e a senha no atributo pass
.
O transporter é um objeto compartilhado e global. Sempre que a gente quiser fazer o envio de email é com esta instância que vamos interagir.
Depois vamos definir um middleware para tratar quando houver uma chamada post na rota /contato
, ela vai ser responsável por fazer o envio dos dados do form.
Vamos incrementar o conteúdo do arquivo server/index.js
const transporter = nodemailer.createTransport({
service: 'smtp.gmail.com',
host: 'smtp.gmail.com',
port: 587,
secure: false, // true for 465, false for other ports
tls: {
rejectUnauthorized: false
},
auth: {
user: 'nomedousuario',
pass: 'senha-do-endereço-de-email'
},
logger: false, // log to console
debug: false // include SMTP traffic in the logs
});
sendEmail = (req, res) => {
const mailmsg = {
from: 'nomedousuario',
subject: 'Teste',
text: 'Mensagem de: ' + req.body.name + ', email: [' + req.body.email + '] ' + req.body.message,
to: 'email@teste.com.br'
}; // preencher destinatário do email
transporter.sendMail(mailmsg).then((trans) => {
res.status(200).send('E-mail enviado ✔️ com sucesso');
}).catch((error) => {
res.status(500).send('Houve um erro ao enviar e-mail. Detalhe: ' + error);
});
}
router.post('/contato', sendEmail);
Agora ao preencher o atributo from
você deve colocar o mesmo valor do atributo usuário. Ao preencher o atributo to
devemos preencher com o endereço de email para o qual desejamos encaminhar as mensagens que serão enviadas a partir da nossa página de contato.
Com isso finalizamos o nosso fluxo de envio de mensagens.
Você pode baixar este projeto.