imansi-correos-node
v0.1.2
Published
Plantillas de correo reutilizables en español con envío SMTP integrado. HTML responsive compatible con Gmail, Outlook y Apple Mail.
Maintainers
Readme
imansi-correos-node
Plantillas de correo reutilizables en español con envío SMTP integrado. HTML responsive compatible con Gmail, Outlook y Apple Mail.
Parte del ecosistema Imansi — autenticación moderna para tus apps.
✨ Características
- 26 plantillas listas para usar (autenticación, seguridad, transaccionales y comerciales).
- Multi-idioma: español, inglés y portugués.
- 100% configurable desde un solo JSON (marca, colores, tipografía, pie, redes).
- HTML responsive compatible con todos los clientes de correo modernos.
- Envío SMTP integrado con nodemailer.
- JavaScript puro. Sin TypeScript, sin frameworks, sin sorpresas.
- Nombres en español en toda la API pública.
- Editor visual disponible próximamente.
📦 Instalación
npm install imansi-correos-nodeTambién necesitas nodemailer (peer dependency):
npm install nodemailer🚀 Uso rápido
1. Configurar la marca
Crea un archivo correos.json en la raíz de tu proyecto:
{
"marca": {
"nombre": "Mi App",
"colores": {
"primario": "#0066cc",
"fondo": "#f4f4f4"
}
},
"remitente": {
"nombre": "Mi App",
"direccion": "[email protected]"
},
"idioma": "es"
}2. Configurar SMTP
Crea un archivo .env con tus credenciales:
SMTP_HOST=smtp.gmail.com
SMTP_PUERTO=587
SMTP_SEGURO=false
[email protected]
SMTP_CONTRASENA=tu-contraseña-de-aplicacion
SMTP_REMITENTE=Mi App <[email protected]>3. Usar en tu backend
import {
configurarCorreos,
configurarSmtp,
verificarSmtp,
correoVerificacion2FA,
enviarCorreo
} from "imansi-correos-node";
import correosJson from "./correos.json" with { type: "json" };
// Al arrancar el servidor:
configurarCorreos(correosJson);
configurarSmtp(); // lee de .env
const { ok, mensaje } = await verificarSmtp();
if (!ok) console.warn("⚠️ SMTP:", mensaje);
// Al enviar un correo:
const correo = correoVerificacion2FA({
destinatario: {
correo: "[email protected]",
nombre: "Ivan"
},
datos: {
codigo: "353251",
minutosExpiracion: 5
}
});
await enviarCorreo(correo);Listo. El correo se envía con tus colores, tu marca y una plantilla profesional.
📧 Plantillas disponibles
Autenticación básica
| Función | Uso |
| ----------------------- | ----------------------------------- |
| correoVerificacion2FA | Código de verificación en dos pasos |
| correoBienvenida | Bienvenida tras registrarse |
| correoNuevaSesion | Aviso de nuevo inicio de sesión |
| correoSesionRevocada | Sesión cerrada remotamente |
Contraseñas
| Función | Uso |
| ------------------------------ | ---------------------------------- |
| correoRecuperacionContrasena | Enlace para restablecer contraseña |
| correoContrasenaCambiada | Aviso tras cambio de contraseña |
Verificación de correo
| Función | Uso |
| -------------------------- | ------------------------------------ |
| correoVerificacionCorreo | Confirmar dirección de correo |
| correoCorreoVerificado | Confirmación de correo verificado |
| correoCambioCorreo | Cambio de correo (a antiguo y nuevo) |
Seguridad
| Función | Uso |
| ----------------------- | ----------------------------------- |
| correoCuentaBloqueada | Cuenta bloqueada temporalmente |
| correoInicioFallido | Intento de inicio de sesión fallido |
Dos factores
| Función | Uso |
| -------------------------- | -------------------- |
| correoActivacion2FA | Activación de 2FA |
| correoDesactivacion2FA | Desactivación de 2FA |
| correoCodigosRespaldo2FA | Códigos de respaldo |
Transaccionales
| Función | Uso |
| ---------------------------- | ------------------------------------ |
| correoNotificacionGenerica | Notificación flexible |
| correoContactoRecibido | Confirmación al usuario que escribió |
| correoContactoInterno | Aviso al equipo interno |
| correoEncuestaSatisfaccion | Encuesta / NPS |
| correoRecordatorio | Recordatorio genérico |
Comerciales
| Función | Uso |
| ------------------------------- | ------------------------------ |
| correoConfirmacionSuscripcion | Suscripción activada |
| correoReciboPago | Recibo de pago |
| correoFactura | Factura con líneas e impuestos |
| correoPagoFallido | Pago fallido |
| correoCancelacionSuscripcion | Cancelación de suscripción |
| correoBienvenidaPlan | Bienvenida a un plan |
| correoPeriodoPrueba | Aviso de fin de trial |
🎨 Personalización completa
Todo se configura desde correos.json. No necesitas tocar código.
Estructura completa
{
"marca": {
"nombre": "Mi App",
"descripcion": "La mejor app del mundo",
"logo": {
"url": "https://miapp.com/logo.png",
"alto": 48,
"ancho": "auto"
},
"colores": {
"primario": "#0066cc",
"primarioSecundario": "#4C8DFF",
"primarioTexto": "#ffffff",
"texto": "#12141A",
"textoSecundario": "#6B7280",
"textoTerciario": "#9AA1AC",
"borde": "#E7E9EE",
"bordeSuave": "#E4ECFF",
"fondo": "#EEF1F6",
"tarjeta": "#FFFFFF",
"suave": "#F4F7FF",
"suaveGradienteInicio": "#F7F9FF",
"suaveGradienteFin": "#F0F4FF",
"exito": "#006644",
"error": "#b00020"
},
"tipografia": {
"fuente": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif",
"fuenteMono": "'Courier New', Courier, monospace",
"tamanoBase": 16
},
"radio": 16,
"radioSuave": 10,
"radioPill": 20
},
"remitente": {
"nombre": "Mi App",
"direccion": "[email protected]",
"responderA": "[email protected]"
},
"pie": {
"sitioWeb": "https://miapp.com",
"soporteEmail": "[email protected]",
"direccion": "Calle Falsa 123, Ciudad, País",
"telefono": "",
"redes": {
"twitter": "",
"instagram": "",
"linkedin": "",
"facebook": "",
"github": ""
},
"textoLibre": "Recibes este correo porque tienes una cuenta en Mi App.",
"mostrarIconoSitio": true,
"mostrarIconoSoporte": true
},
"idioma": "es",
"plantillas": {
"verificacion2FA": { "variante": "moderna", "asunto": "Tu código de verificación" },
"bienvenida": { "variante": "moderna", "asunto": "¡Bienvenido a {marca}!" }
}
}Marca
| Campo | Descripción |
| -------------------- | ----------------------------------------------------------------- |
| nombre | Nombre que aparece en el header y footer |
| descripcion | Tagline corto (opcional) |
| logo.url | URL pública del logo (si está vacío, se usa el cuadrado + nombre) |
| logo.alto | Altura del logo en píxeles |
| logo.ancho | Ancho ("auto" para proporcional) |
Colores
Todos los colores son configurables. El editor visual (próximamente) permitirá cambiarlos con un color picker.
| Color | Uso |
| -------------------- | -------------------------------------------- |
| primario | Botones, enlaces, acentos |
| primarioSecundario | Gradiente de botones y barra superior |
| primarioTexto | Texto encima del color primario |
| texto | Texto principal |
| textoSecundario | Subtítulos, notas |
| textoTerciario | Texto muy secundario (footer) |
| borde | Líneas divisorias |
| bordeSuave | Bordes de cajas destacadas |
| fondo | Fondo del body del correo |
| tarjeta | Fondo de la tarjeta blanca |
| suave | Fondo de cajas destacadas (código, píldoras) |
| exito | Iconos de confirmación |
| error | Iconos de alerta |
Remitente
| Campo | Descripción |
| -------------------- | --------------------------------------- |
| nombre | Nombre visible en la bandeja de entrada |
| direccion | Dirección desde la que se envía |
| responderA | A dónde van las respuestas del usuario |
Pie de correo
| Campo | Descripción |
| -------------------- | -------------------------------------- |
| sitioWeb | URL del sitio web |
| soporteEmail | Email de soporte |
| direccion | Dirección física (recomendado por ley) |
| telefono | Teléfono de contacto (opcional) |
| redes | URLs de redes sociales (opcionales) |
| textoLibre | Texto libre al pie |
Idioma
{ "idioma": "es" }Opciones: "es", "en", "pt".
Asuntos
Los asuntos admiten placeholders como {marca}, {codigo}, {nombre}.
{
"plantillas": {
"verificacion2FA": {
"asunto": "Tu código de verificación"
},
"bienvenida": {
"asunto": "¡Bienvenido a {marca}!"
},
"factura": {
"asunto": "Factura {numeroFactura}"
}
}
}🧪 Pruebas locales
# Ver todas las plantillas renderizadas (26 HTML en pruebas/salida/)
npm run pruebas
# Verificar la conexión SMTP
npm run pruebas:smtp
# Enviar un correo real de prueba
npm run pruebas:enviar [email protected]Los HTML generados se guardan en pruebas/salida/. Ábrelos en el navegador para verlos.
📚 API pública
Configuración de correos
configurarCorreos(json)
Aplica la configuración de marca y plantillas. Se llama una sola vez al arrancar el backend.
configurarCorreos(correosJson);obtenerConfiguracion()
Devuelve la configuración actual efectiva.
obtenerConfiguracionPorDefecto()
Devuelve la configuración por defecto del paquete.
Configuración SMTP
configurarSmtp(config?)
Configura el transporte SMTP.
- Sin argumentos: lee de
process.env(SMTP_HOST, SMTP_PUERTO, ...). - Con objeto: usa esos valores.
Devuelve { ok: boolean, faltantes: string[] }.
const { ok, faltantes } = configurarSmtp();
if (!ok) console.warn("Faltan:", faltantes);obtenerConfiguracionSmtp()
Devuelve la configuración SMTP actual.
Envío
verificarSmtp()
Comprueba que la conexión SMTP funcione. Útil llamarlo al arrancar.
const { ok, mensaje } = await verificarSmtp();
if (!ok) console.warn("SMTP:", mensaje);enviarCorreo(correo)
Envía un correo generado por una plantilla.
const resultado = await enviarCorreo(correo);
console.log(resultado.id); // messageIdenviarVariosCorreos(correos)
Envía un array de correos en serie.
Plantillas
Cada función recibe { destinatario, datos } y devuelve un objeto:
{
from: '"Mi App" <[email protected]>',
to: '"Ivan" <[email protected]>',
replyTo: '[email protected]',
subject: 'Tu código de verificación',
html: '<!DOCTYPE html>...',
text: '...'
}Listo para pasarle directamente a enviarCorreo() o a cualquier transportador de nodemailer.
Utilidades
reemplazar(texto, variables)
Reemplaza {clave} por valores.
reemplazar("Hola {nombre}", { nombre: "Ivan" }); // "Hola Ivan"obtenerTextos(idioma, plantilla)
Devuelve el bloque de textos de una plantilla en un idioma.
colorSeguro(hex, fallback)
Valida un color hexadecimal. Si es inválido, devuelve el fallback.
contrasteTexto(hex)
Devuelve #ffffff o #000000 según qué tenga mejor contraste sobre el color dado.
🔒 Seguridad SMTP
- Nunca subas tu
.enva Git. Añádelo a.gitignore. - En Gmail necesitas una contraseña de aplicación, no tu contraseña normal. Actívala en myaccount.google.com/apppasswords.
- En producción usa siempre
SMTP_SEGURO=truecon puerto465. - Respeta los límites de tu proveedor SMTP. Para volúmenes grandes, usa servicios como Resend, SendGrid o Brevo.
- Nunca compartas tus credenciales SMTP. Si se filtran, revócalas inmediatamente.
Proveedores comunes
| Proveedor | Host | Puerto | Seguro | | ----------------------------- | ------------------------------------------------------------- | --- | ----- | | Gmail | smtp.gmail.com | 587 | false | | Outlook | smtp-mail.outlook.com | 587 | false | | Mailtrap (test) | sandbox.smtp.mailtrap.io | 587 | false | | Resend | smtp.resend.com | 587 | false | | SendGrid | smtp.sendgrid.net | 587 | false | | Brevo | smtp-relay.brevo.com | 587 | false |
🌍 Multi-idioma
Los textos internos de las plantillas están disponibles en 3 idiomas. Se configuran desde el correos.json:
{ "idioma": "es" }| Código | Idioma |
| ---------------- | --------- |
| es | Español |
| en | English |
| pt | Português |
Puedes añadir más idiomas extendiendo src/utilidades/textos.js.
🎯 Casos de uso
Autenticación con React
Combínalo con imansi-auth-react y imansi-auth-node para tener autenticación completa en minutos.
// Backend con imansi-auth-node + imansi-correos-node
import { configurarCorreos } from "imansi-correos-node";
import { crearServidorAutenticacion } from "imansi-auth-node";
configurarCorreos(correosJson);
const app = express();
app.use(crearServidorAutenticacion());Notificaciones transaccionales
const correo = correoNotificacionGenerica({
destinatario: { correo: "[email protected]", nombre: "Ivan" },
datos: {
titulo: "Tu pedido fue enviado",
mensaje: "Tu paquete está en camino. Llega mañana.",
urlAccion: "https://miapp.com/pedidos/123",
textoAccion: "Ver seguimiento"
}
});
await enviarCorreo(correo);Facturación
const correo = correoFactura({
destinatario: { correo: "[email protected]", nombre: "Ivan" },
datos: {
numeroFactura: "FAC-2026-00123",
moneda: "USD",
items: [
{ descripcion: "Plan Pro — Mensual", cantidad: 1, precio: 29.99 },
{ descripcion: "Usuarios extra", cantidad: 3, precio: 5.0 }
],
subtotal: 44.99,
impuestos: 9.45,
total: 54.44,
urlPDF: "https://miapp.com/facturas/123.pdf"
}
});
await enviarCorreo(correo);🛠️ Desarrollo
Estructura del proyecto
imansi-correos-node/
├── src/
│ ├── componente/ ← bloques HTML reutilizables
│ ├── configuracion/ ← defaults y fusión de config
│ ├── plantillas/ ← las 26 plantillas
│ ├── servicios/ ← transporte SMTP y envío
│ ├── utilidades/ ← colores, textos, reemplazos
│ └── index.js ← punto de entrada
├── pruebas/ ← scripts de prueba
├── .env.example
├── LICENSE
├── package.json
└── README.mdAñadir una plantilla nueva
- Crea
src/plantillas/miPlantilla.js. - Exporta una función
correoMiPlantilla({ destinatario, datos }). - Usa
layout,titulo,boton, etc. para construir el HTML. - Añade los textos en
src/utilidades/textos.js(en los 3 idiomas). - Añade el asunto por defecto en
src/configuracion/correosPorDefecto.js. - Expórtala desde
src/plantillas/index.jsysrc/index.js. - Añade un caso de prueba en
pruebas/todas.js.
🧬 Ecosistema Imansi
imansi-auth-react— Componentes de autenticación para React.imansi-auth-node— Servidor de autenticación con Express + PostgreSQL.imansi-correos-node— Este paquete.
Todos comparten el mismo contrato HTTP y los mismos nombres en español.
📄 Licencia
MIT © 2026 IMANSI.PRO
💬 Soporte
- Documentación: docs.imansi.pro
- Issues: github.com/imansi-pro/imansi-correos-node/issues
