Guia Nodemailer: Configuração, Setup de SMTP e Envio de Emails

On junho 13, 2024
10min read
Diana Lepilkina Content Specialist @Mailtrap
Ivan Djuric, an author at Mailtrap
Ivan Djuric Technical Content Writer @Mailtrap
nodemailer emails

Adicionar funcionalidade de envio de email ao seu backend Node.js com o módulo Nodemailer é super simples.

Neste tutorial, explico o processo, desde a instalação até o envio de vários tipos de emails, e até mesmo testá-los para garantir que cheguem às caixas de entrada de seus destinatários sem problemas.

Se você já tem o Nodemailer instalado e está pronto para começar a enviar emails, clique aqui.

Como instalar o Nodemailer

Para instalar e começar a usar o Nodemailer, você primeiro precisa instalar o Node.js — baixe-o do site oficial ou confira este guia atualizado sobre como instalar o Node.js.

Para instalar o Nodemailer, você pode usar o gerenciador de pacotes npm:

npm install nodemailer

Ou o gerenciador de pacotes Yarn:

yarn add nodemailer

Uma vez instalado, inclua-o em sua aplicação web com o seguinte código:

const nodemailer = require('nodemailer');

Ou este código, se você estiver usando módulos ES:

import nodemailer from 'nodemailer';

Como enviar emails com o Nodemailer

Para começar a enviar emails com o Nodemailer, tudo o que você precisa fazer é:

  1. Criar um objeto de transporte
  2. Configurar o objeto mailOptions
  3. Enviar uma mensagem com sendMail()

Para simplificar, criei um snippet de código que você pode usar — basta colá-lo no arquivo de configuração do seu JavaScript (por exemplo, index.js):

// Importar a biblioteca Nodemailer
const nodemailer = require('nodemailer');

// Criar um objeto de transporte
const transporter = nodemailer.createTransport({
  host: 'live.smtp.mailtrap.io',
  port: 587,
  secure: false, // usar SSL
  auth: {
    user: '1a2b3c4d5e6f7g',
    pass: '1a2b3c4d5e6f7g',
  }
});

// Configurar o objeto mailOptions
const mailOptions = {
  from: 'seunomeusuario@email.com',
  to: 'seuamigo@email.com',
  subject: 'Enviando Email usando Node.js',
  text: 'Isso foi fácil!'
};

// Enviar o email
transporter.sendMail(mailOptions, function(error, info){
  if (error) {
    console.log(‘Erro:’ error);
  } else {
    console.log('Email enviado: ' + info.response);
  }
});

Para salvar e executar o script, use o seguinte comando:

node src/index.js

E voilà, seu aplicativo agora pode enviar emails!

Com este snippet de código, você pode enviar emails em texto simples e HTML usando qualquer serviço de email que desejar (Gmail, Office, etc.). Mas, como você pode ver no objeto transporter, usei o Email API/SMTP do Mailtrap, que oferece um SMTP fiável, com capacidades robustas de envio.

Além disso, o Mailtrap tem um plano gratuito generoso e, ao contrário do Gmail, por exemplo, me fornece análises detalhadas, IPs dedicados, aquecimento automático de IPs, listas de supressão e outras funcionalidades avançadas, para ajustar minha infraestrutura de email.

Dica: Para verificar se sua conexão SMTP está correta, adicione a chamada verify(callback) para testar a conexão e autenticação, assim:

transporter.verify(function(error, success) {
  if (error) {
        console.log('Erro de conexão:' error);
  } else {
        console.log('O servidor está pronto para receber nossas mensagens');
  }
});

Se você continuar enfrentando problemas, consulte a documentação oficial do Nodemailer no GitHub.

Enviar emails em HTML

Para enviar um email com conteúdo HTML no Nodemailer, adicione o campo html às opções da mensagem e use as tags apropriadas (ex: <h1>, <p>, etc.).

Aqui está um exemplo:

const mailOptions = {
  from: 'seuemail@email.com',
  to: 'seuamigo@yahoo.com',
  subject: 'Enviar email HTML usando Node.js é muito fácil',
  text: 'Isso foi fácil!',
  html: '<h1>Bemvindo</h1><p>Isso foi fácil!</p>'
}

Alternativamente, você pode adicionar qualquer tipo de dado como conteúdo do corpo principal, além de texto e HTML.

Por exemplo:

let message = {
    ...
    html: '<b>Olá mundo!</b>',
    alternatives: [
        {
            contentType: 'text/x-web-markdown',
            content: '**Olá mundo!**'
        }
    ]
}

Observe que você pode adicionar quantas alternativas quiser.

Enviar emails para múltiplos destinatários

Em outras linguagens de programação e frameworks, você usa cc e bcc para adicionar múltiplos destinatários. Com o Nodemailer, no entanto, é muito mais simples – você pode adicionar os endereços no mesmo campo to, assim:

const mailOptions = {
  from: 'seuemail@email.com',
  to: 'seuamigo@email.com, seuoutroamigo@email.com',
  subject: 'Enviando Email usando Node.js',
  text: 'Isso foi fácil!'
}

Enviar emails com anexos

Para adicionar anexos no Nodemailer, você pode usar a opção attachments no objeto da mensagem:

Veja:

let message = {
    ...
    attachments: [
        {   // string utf-8 como um anexo
            filename: 'texto1.txt',
            content: 'olá mundo!'
        },
        {   // buffer binário como um anexo
            filename: 'texto2.txt',
            content: Buffer.from('olá mundo!','utf-8')
        },
        {   // arquivo no disco como um anexo
            filename: 'texto3.txt',
            path: '/path/to/arquivo.txt' // stream deste arquivo
        },
        {   // nome do arquivo e tipo de conteúdo são derivados do caminho
            path: '/path/to/arquivo.txt'
        },
        {   // stream como um anexo
            filename: 'texto4.txt',
            content: fs.createReadStream('file.txt')
        },
        {   // definir tipo de conteúdo personalizado para o anexo
            filename: 'texto.bin',
            content: 'olá mundo!',
            contentType: 'text/plain'
        },
        {   // usar URL como um anexo
            filename: 'licenca.txt',
            path: 'https://raw.github.com/nodemailer/nodemailer/master/LICENSE'
        },
        {   // string codificada como um anexo
            filename: 'texto1.txt',
            content: 'aGVsbG8gd29ybGQh',
            encoding: 'base64'
        },
        {   // dados uri como um anexo
            path: 'data:text/plain;base64,aGVsbG8gd29ybGQ='
        },
        {
            // usar node MIME pré-gerado
            raw: 'Content-Type: text/plain\r\n' +
                 'Content-Disposition: attachment;\r\n' +
                 '\r\n' +
                 'Olá mundo!'
        }
    ]
}

Envio de email com uma imagem embutida

Para adicionar uma imagem embutida no corpo HTML, você também pode usar a opção attachments. Tudo o que você precisa fazer é definir uma propriedade adicional do anexo ‘cid’ que referencia o arquivo do anexo.

Lembre-se de que o valor cid deve ser usado como URL da imagem no HTML, assim:

let message = {
    ...
    html: 'Embedded image: <img src="cid:unique@nodemailer.com"/>',
    attachments: [{
        filename: 'imagem.png',
        path: '/path/to/file',
        cid: 'unique@nodemailer.com' //mesmo valor de cid que no src da imagem no HTML
    }]
}

Envio assíncrono de emails

Para enviar emails assíncronos no Nodemailer, teremos que usar um software de fila de mensagens, como o RabbitMQ.

Aqui está como todo o processo funciona:

1. Configure RabbitMQ

Para instalar e configurar o RabbitMQ, visite o site oficial e siga as instruções para o seu sistema operacional. Você pode consultar as instruções detalhadas fornecidas pelo RabbitMQ como seu guia principal.

2. Instale amqlib

Para se comunicar com o RabbitMQ, sua aplicação precisará de um protocolo de mensagens como amqplib. Instale-o com o seguinte comando:

npm install amqplib

3. Crie um produtor para enfileirar mensagens

Então, precisamos de um produtor que enviará mensagens para a fila. Para isso, você pode brincar com o seguinte snippet de código e adicioná-lo ao seu arquivo de configuração:

const amqp = require('amqplib');

async function sendToQueue(emailData) {
    const conn = await amqp.connect('amqp://localhost'); // Conectar ao servidor RabbitMQ
    const channel = await conn.createChannel(); // Criar um canal
    const queue = 'emails'; // Nome da fila de espera

    await channel.assertQueue(queue, { durable: true }); // Garantir que a fila exista e seja durável
    channel.sendToQueue(queue, Buffer.from(JSON.stringify(emailData)), { persistent: true }); // Enviar dados do email para a fila

    console.log('Pedido de email enviado para a fila');
    setTimeout(() => {
        channel.close();
        conn.close();
    }, 500);
}

// Dados de email de exemplo
const emailData = {
    from: 'remetente@exemplo.com',
    to: 'destinatario@exemplo.com',
    subject: 'Email de Teste',
    text: 'Este é um email de teste enviado de forma assíncrona usando RabbitMQ e Nodemailer.'
};

sendToQueue(emailData);

4. Crie um worker para enviar mensagens

E, finalmente, vamos criar um worker (trabalhador) que escuta mensagens na fila e as envia via Nodemailer:

const amqp = require('amqplib');
const nodemailer = require('nodemailer');

async function startWorker() {
    try {
        const conn = await amqp.connect('amqp://localhost');
        const channel = await conn.createChannel();
        const queue = 'emails';

        await channel.assertQueue(queue, { durable: true });
        console.log("Aguardando mensagens em %s. Para sair, pressione CTRL+C", queue);

        channel.consume(queue, async msg => {
            if (msg !== null) {
                const emailData = JSON.parse(msg.content.toString());
                await sendEmail(emailData);
                channel.ack(msg);
            }
        });
    } catch (error) {
        console.error('Erro ao iniciar o worker:', error);
    }
}


async function sendEmail(emailData) {
    let transporter = nodemailer.createTransport({
        service: 'gmail', // ou seu serviço de email
        auth: {
            user: 'endereço do remetente (ex: seuemail@email.com)’,
            pass: 'sua-senha'
        }
    });

    try {
        let info = await transporter.sendMail(emailData);
        console.log('Email Enviado: %s', info.messageId);
    } catch (error) {
        console.error('Erro ao enviar email:', error);
    }
}

startWorker();

Não se esqueça de substituir variáveis como user e pass com suas credenciais de email reais.

Enviar emails em massa

Enviar emails em massa com o Nodemailer é basicamente o mesmo que enviar mensagens assíncronas, com algumas diferenças.

Mais especificamente, você deve:

  • Usar SMTP agrupado (pool) – Para evitar que seu código faça a dança do handshake SMTP para cada email enviado em massa, defina a opção [pool] como [true] se você usar as mesmas credenciais.
  • Aumentar o valor padrão de envio – O valor padrão para [maxMessages] é 100, o que significa que a conexão será abortada após 100 mensagens serem enviadas do pool. Para contornar isso, basta definir a opção [maxMessages] para [Infinity].
  • Ajustar o número máximo de conexões – Dependendo da quantidade de conexões que seu sistema pode suportar, você deve definir o valor de [maxConnections] adequadamente.
  • Usar caminhos de arquivos em vez de URLs para anexos – Ler o mesmo arquivo do disco várias vezes ao enviar emails em massa é muito mais rápido do que usar URLs, e nesse caso todas as novas mensagens precisam fazer uma nova solicitação HTTP para receber o arquivo do servidor.
  • Usar um provedor de entrega em massa dedicado – Uma das razões pelas quais não uso minha conta do Gmail é por que ela não foi feita para envio em massa de emails. Se você não quiser atingir limites rígidos ou ser rotulado como spammer, deve usar um provedor que ofereça um SMTP dedicado para emails em massa.

Se isso parece complicado, não se preocupe, eu ajudo com isso. Aqui está um snippet de código que você pode usar para enviar emails em massa de forma fácil:

const nodemailer = require('nodemailer');


// Configurar o Nodemailer para usar o Mailtrap para SMTP com conexão agrupada
const transporter = nodemailer.createTransport({
   host: 'bulk.mailtrap.io',
   port: 2525,
   pool: true, // Usar agrupamento SMTP para manter a conexão aberta para múltiplos emails
   auth: {
       user: 'seu-usuario-mailtrap', // Substitua por seu nome de usuário Mailtrap
       pass: 'sua-senha-mailtrap'  // Substitua pela sua senha Mailtrap
   },
   maxMessages: Infinity, // Permitir um número ilimitado de mensagens por conexão
   maxConnections: 5 // Limitar o número de conexões simultâneas
});


// Lista de exemplo de destinatários para envio em massa
const recipients = [
   {email: 'destinatario1@exemplo.com', name: 'Destinatário Um'},
   {email: 'destinatario2@exemplo.com', name: 'Destinatário Dois'},
   {email: 'destinatario3@exemplo.com', name: 'Destinatário Três'},
   // Adicione mais destinatários conforme necessário
];


// Preparar promessas de email para envio em massa
const emailPromises = recipients.map(recipient =>
   transporter.sendMail({
       from: '"Nome do Remetente" <remetente@exemplo.com>',
       to: `${recipient.name} <${recipient.email}>`, // Personalizado para cada destinatário
       subject: 'Teste de Email em Massa',
       text: 'Este é um email de teste enviado em massa usando Nodemailer e Mailtrap.',
       html: `<b>Olá ${recipient.name},</b><p>Este é um email de teste enviado em massa usando Nodemailer e Mailtrap.</p>`
   })
);


// Enviar todos os emails em paralelo e lidar com os resultados
Promise.all(emailPromises)
   .then(results => {
       console.log('Todos os emails foram enviados com sucesso');
       results.forEach(result => {
           console.log(`Mensagem para ${result.envelope.to} enviada: ${result.messageId}`);
       });
   })
   .catch(errors => {
       console.error('Falha ao enviar um ou mais emails:', errors);
   });

Para isso, também uso o Email API/SMTP do Mailtrap, pois ele me fornece um fluxo para mensagens transacionais e um fluxo separado para envio de emails em massa. Dessa forma, posso manter minha entregabilidade de email alta em ambos os fluxos sem custos adicionais.

Configurações de SMTP/API do Email API/SMTP do Mailtrap

Além disso, o Mailtrap oferece uma API de email consciente de envio em massa, o que significa que você pode enviar um email HTML personalizado para um milhão de destinatários com uma única chamada de API, e ele compilará as informações nos próprios emails.

Depuração no Nodemailer

Para testar o envio de emails com sucesso, vamos usar a depuração nativa.

É simples com o Nodemailer: defina ambos debug e logger como true e você poderá ver todos os dados que são passados para o servidor como um output no console.

Dessa forma, você poderá analisar o processo de envio de emails e corrigir os erros rapidamente, se houver algum.

Especifique opções de depuração na seção de transporte do script de email em seu aplicativo Node.js:

const transport = nodemailer.createTransport({
  host: "live.smtp.mailtrap.io",
  port: 2525,
  auth: {
    user: "1a2b3c4d5e6f7g",
    pass: "1a2b3c4d5e6f7g"
  },
  debug: true, // mostrar output de depuração
  logger: true // registrar informações no console
});

Aqui está o que você verá no console:

[2018-12-28 18:05:10] DEBUG Creating transport: nodemailer (5.0.0; +https://nodemailer.com/; SMTP/5.0.0[client:5.0.0])
[2018-12-28 18:05:10] DEBUG Sending mail using SMTP/5.0.0[client:5.0.0]
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] Resolved smtp.mailtrap.io as 54.87.153.8 [cache miss]
[2018-12-28 18:05:10] INFO  [nJWMVEIqQCE] Connection established to 54.87.153.8:2525
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 220 smtp.mailtrap.io ESMTP ready
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] C: EHLO [127.0.0.1]
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250-smtp.mailtrap.io
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250-SIZE 5242880
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250-PIPELINING
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250-ENHANCEDSTATUSCODES
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250-8BITMIME
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250-DSN
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250-AUTH PLAIN LOGIN CRAM-MD5
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 250 STARTTLS
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] C: STARTTLS
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] S: 220 2.0.0 Start TLS
[2018-12-28 18:05:10] INFO  [nJWMVEIqQCE] Connection upgraded with STARTTLS
[2018-12-28 18:05:10] DEBUG [nJWMVEIqQCE] C: EHLO [127.0.0.1]
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250-smtp.mailtrap.io
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250-SIZE 5242880
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250-PIPELINING
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250-ENHANCEDSTATUSCODES
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250-8BITMIME
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250-DSN
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250 AUTH PLAIN LOGIN CRAM-MD5
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] SMTP handshake finished
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] C: MAIL FROM:<de@exemplo.com>
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250 2.1.0 Ok
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] C: RCPT TO:<usuario1@exemplo.com>
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] C: RCPT TO:<usuario2@exemplo.com>
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250 2.1.0 Ok
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 250 2.1.0 Ok
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] C: DATA
[2018-12-28 18:05:11] DEBUG [nJWMVEIqQCE] S: 354 Go ahead
…
[2018-12-28 18:05:12] DEBUG [nJWMVEIqQCE] S: 250 2.0.0 Ok: queued
[2018-12-28 18:05:12] DEBUG [nJWMVEIqQCE] Closing connection to the server using "end"
Message sent: <74bfe12e-92fa-91f8-8643-a166b66c62d7@exemplo.com>
[2018-12-28 18:05:12] INFO  [nJWMVEIqQCE] Connection closed

Testar emails e envio de emails em staging

Depurar garante que sua funcionalidade de envio de email funcione, mas como você garante que suas mensagens aparentam como você deseja e que estão chegando às caixas de entrada de seus destinatários?

Você pode usar o Ethereal, um serviço de SMTP falso para testar emails no Nodemailer. Ou, você pode usar o NodemailerApp, que tem servidores POP3 e SMTP locais. Embora essas duas soluções funcionem bem, você deve lembrar que elas são limitadas em funcionalidades.

Por exemplo, o Ethereal não tem capacidades de pré-visualização de email e o NodemailerApp não possui funcionalidades anti-spam, entre outras coisas.

Agora, se você quiser usá-los, vá em frente, mas como eles são bastante minimalistas, eu pessoalmente uso o Email Testing do Mailtrap, que é parte da Plataforma de Email Delivery do Mailtrap. Ao contrário do Ethereal, ele me permite inspecionar o HTML/CSS dos meus emails e corrigir facilmente qualquer linha de código defeituosa, visualizar minhas mensagens e muito mais.

Funcionalidade de Verificação de HTML do Mailtrap

E, ao contrário do NodemailerApp, com o Mailtrap posso verificar minha pontuação de spam, o que, se for mantida abaixo de 5, evita uma quantidade significativa de problemas de entregabilidade que eu poderia enfrentar, quando meu aplicativo passe para a produção.

Funcionalidade de Análise de Spam do Mailtrap

O Mailtrap também oferece uma API de email, que permite testar facilmente seus templates de email e alternar do ambiente de testes para produção assim que você estiver pronto para começar a enviar. Tudo o que você precisa fazer é habilitar o sandbox, especificar o ID da caixa de entrada, receber o teste do template e então despachá-lo através da API.

Funcionalidade de Templates de Email do Mailtrap

E também é super fácil de usar!

Primeiro, crie uma conta gratuita no Mailtrap e então:

  • Navegue até Email Testing e escolha sua caixa de entrada
  • Copie suas credenciais na aba SMTP Settings
  • Insira as credenciais no script de sua aplicação Node.js

Além disso, você pode usar a integração pronta para usar do Mailtrap com o Nodemailer:

  • Selecione Nodemailer na lista de integrações (Integrations)
  • Copie e cole o snippet no código de sua aplicação

O snippet de código contém atributos de transporter e sintaxe, e se parece com isso:

const transport = nodemailer.createTransport({
  host: "sandbox.smtp.mailtrap.io",
  port: 2525,
  auth: {
    user: "1a2b3c4d5e6f7g",
    pass: "1a2b3c4d5e6f7g"
  }
});

Concluindo

Como você pode ver, enviar emails com o Nodemailer open-source realmente é, como seu criador diz, ”a piece of cake”. 🎂

Agora, para facilitar ainda mais, aproveite as capacidades de teste e envio de emails do Mailtrap, e garanta que suas mensagens cheguem quando e onde devem.

Além disso, se este pedaço de bolo Nodemailer deixou você com fome de mais conhecimento, confira nosso blog, onde você pode encontrar outros artigos relacionados, como:

Article by Diana Lepilkina Content Specialist @Mailtrap
Ivan Djuric, an author at Mailtrap
Article by Ivan Djuric Technical Content Writer @Mailtrap

I’m a Technical Content Writer with 5 years of background covering email-related topics in tight collaboration with software engineers and email marketers. I just love to research and share actionable insights with you about email sending, testing, deliverability improvements, and more. Happy to be your guide in the world of emails!