Enviar Correos Electrónicos con Nodemailer en Node.js y Express

Nodemailer es la solución más popular para enviar correos electrónicos en Node.js. Esta guía cubrirá configuraciones para múltiples proveedores de correo.

Configuración Inicial del Proyecto


Instalación de Dependencias

bash
# Crear nuevo proyecto
mkdir nodemailer-demo
cd nodemailer-demo

Inicializar proyecto

bash
npm init -y

Instalar dependencias

bash
npm install express nodemailer dotenv

Configuración de Variables de Entorno

Crea un archivo .env para almacenar credenciales de forma segura:

bash
# Credenciales de Gmail
GMAIL_USER=tu_correo@gmail.com
GMAIL_PASS=tu_contraseña_de_aplicacion

# Credenciales de Outlook/Hotmail
OUTLOOK_USER=tu_correo@hotmail.com
OUTLOOK_PASS=tu_contraseña

# Credenciales de SendGrid (servicio de envío)
SENDGRID_API_KEY=your_sendgrid_api_key

Métodos de Envío de Correos


Configuración Básica de Nodemailer

javascript
const nodemailer = require('nodemailer');
require('dotenv').config();

// Función genérica para crear transportador
function crearTransportador(servicio) {
const configuraciones = {
  gmail: {
    service: 'gmail',
    auth: {
      user: process.env.GMAIL_USER,
      pass: process.env.GMAIL_PASS
    }
  },
  outlook: {
    service: 'hotmail',
    auth: {
      user: process.env.OUTLOOK_USER,
      pass: process.env.OUTLOOK_PASS
    }
  },
  custom: {
    host: 'smtp.tuservidor.com',
    port: 587,
    secure: false, // usar true para puerto 465
    auth: {
      user: process.env.CUSTOM_USER,
      pass: process.env.CUSTOM_PASS
    }
  }
};

return nodemailer.createTransport(configuraciones[servicio]);
}

Envío de Correo Simple

javascript
async function enviarCorreoSimple(transportador, opciones) {
try {
  const resultado = await transportador.sendMail({
    from: opciones.from,
    to: opciones.to,
    subject: opciones.subject,
    text: opciones.text,
    html: opciones.html
  });

  console.log('Correo enviado:', resultado);
  return resultado;
} catch (error) {
  console.error('Error al enviar correo:', error);
  throw error;
}
}

Ejemplos de Envío por Proveedor


Gmail (Usando Contraseña de Aplicación)

javascript
async function enviarCorreoGmail() {
const transportador = crearTransportador('gmail');

await enviarCorreoSimple(transportador, {
  from: process.env.GMAIL_USER,
  to: 'destinatario@example.com',
  subject: 'Prueba de Correo Gmail',
  text: 'Correo de prueba enviado desde Node.js',
  html: '<b>Correo HTML de prueba</b>'
});
}

Outlook/Hotmail

javascript
async function enviarCorreoOutlook() {
const transportador = crearTransportador('outlook');

await enviarCorreoSimple(transportador, {
  from: process.env.OUTLOOK_USER,
  to: 'destinatario@example.com',
  subject: 'Prueba de Correo Outlook',
  text: 'Correo de prueba enviado desde Node.js'
});
}

Envío con Servicios Transaccionales


SendGrid

javascript
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

async function enviarCorreoSendGrid() {
const msg = {
  to: 'destinatario@example.com',
  from: 'tu_correo@tudominio.com',
  subject: 'Correo con SendGrid',
  text: 'Correo enviado a través de SendGrid',
  html: '<strong>Contenido HTML</strong>'
};

try {
  await sgMail.send(msg);
  console.log('Correo enviado con SendGrid');
} catch (error) {
  console.error('Error en SendGrid:', error);
}
}

Ejemplo Completo con Express

javascript
const express = require('express');
const nodemailer = require('nodemailer');
require('dotenv').config();

const app = express();
app.use(express.json());

// Transportador de Gmail
const transportador = nodemailer.createTransport({
service: 'gmail',
auth: {
  user: process.env.GMAIL_USER,
  pass: process.env.GMAIL_PASS
}
});

// Ruta para enviar correos
app.post('/enviar-correo', async (req, res) => {
const { to, subject, text } = req.body;

try {
  const resultado = await transportador.sendMail({
    from: process.env.GMAIL_USER,
    to,
    subject,
    text
  });

  res.status(200).json({ 
    mensaje: 'Correo enviado exitosamente',
    resultado 
  });
} catch (error) {
  res.status(500).json({ 
    mensaje: 'Error al enviar correo',
    error: error.message 
  });
}
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Servidor corriendo en puerto ${PORT}`);
});
  Mejores Prácticas

  • Configura límites de envío
  • Implementa colas de correo para alto volumen
  • Usa servicios transaccionales para producción
  • Implementa reintentos y manejo de errores
  • Usa autenticación de dos factores
  • Habilitar “Acceso de aplicaciones menos seguras”
  • Verificar límites de envío