Cómo Enviar Correo Transaccional Desde Heroku (Con Mailer To Go)
Un dyno de Heroku es un excelente lugar para ejecutar tu aplicación y un lugar terrible para ejecutar un servidor de correo. El sistema de archivos es efímero, las IP de los dynos son compartidas y rotan, y el puerto 25 saliente es prácticamente inutilizable, por lo que cualquier correo que intentes enviar directamente desde un dyno termina en spam, si es que sale. La solución es delegar el envío a un servicio de correo. Mailer To Go es un complemento de Heroku que se aprovisiona en segundos y se integra en tu aplicación, para que envíes a través de una conexión autenticada y con reputación gestionada en el puerto 587.
Esta guía te lleva de cero a un correo enviado y en la bandeja de entrada en Heroku, y cubre las trampas específicas de Heroku (variables de configuración, aplicaciones de revisión, trabajos en segundo plano) que atrapan a las personas.
Paso 1 — Aprovisiona el complemento
Desde la CLI:
heroku addons:create mailertogo --app your-app
O agrégalo desde el Mercado de Heroku Elements. De cualquier forma, el aprovisionamiento establece estas variables de configuración en tu aplicación automáticamente, sin necesidad de copiar y pegar credenciales:
heroku config --app your-app | grep MAILERTOGO
# MAILERTOGO_SMTP_HOST: smtp.mailertogo.com
# MAILERTOGO_SMTP_USER: ...
# MAILERTOGO_SMTP_PASSWORD: ...
# MAILERTOGO_API_KEY: ...
Para declarlo como una dependencia para que cada despliegue y aplicación de revisión lo obtenga, agrégalo a app.json:
{
"addons": ["mailertogo"]
}
Paso 2 — Verifica tu dominio de envío
Agrega un subdominio de envío — mtg.yourdomain.com — en el panel de Mailer To Go y publica los registros SPF y DKIM que te muestra (además de una política DMARC en tu raíz). Un subdominio mantiene la reputación de envío de tu aplicación separada de tu dominio raíz, y es exactamente lo que hace que el correo de una plataforma efímera como Heroku llegue de manera confiable. Consulta Por qué Mailer To Go envía desde mtg.yourdomain.com y la guía de configuración de SPF/DKIM/DMARC.
Paso 3 — Apunta tu aplicación a las variables de configuración
Tu aplicación ya tiene las credenciales como variables de entorno, solo necesitas hacer referencia a ellas.
Rails:
# config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: ENV["MAILERTOGO_SMTP_HOST"], # smtp.mailertogo.com
port: 587,
user_name: ENV["MAILERTOGO_SMTP_USER"],
password: ENV["MAILERTOGO_SMTP_PASSWORD"],
authentication: :plain,
enable_starttls: true
}
Node.js (Nodemailer):
const transport = require("nodemailer").createTransport({
host: process.env.MAILERTOGO_SMTP_HOST,
port: 587,
auth: { user: process.env.MAILERTOGO_SMTP_USER, pass: process.env.MAILERTOGO_SMTP_PASSWORD },
});
¿Prefieres HTTP sobre SMTP, o estás en otro lenguaje? Usa la API REST en su lugar, ejemplos completos en Envía correo con la API y SMTP de Mailer To Go.
Paso 4 — Despliegua y envía una prueba
git push heroku main
heroku run rails runner 'ActionMailer::Base.mail(from: "hello@mtg.yourdomain.com", to: "you@example.com", subject: "Hello from Heroku", body: "It works.").deliver_now' --app your-app
heroku logs --tail --app your-app # watch the send
Abre el mensaje en Gmail → Mostrar original y confirma que SPF, DKIM y DMARC todos digan PASS.
Trampas específicas de Heroku
- Nunca codifiques las credenciales. Establecer una variable de configuración reinicia tus dynos y rota limpiamente; una contraseña codificada sobrevive a una rotación de credenciales y falla silenciosamente. Siempre lee desde
ENV. - Envía desde un trabajo en segundo plano. El sistema de archivos del dyno es efímero y las solicitudes web tienen un tiempo de espera de 30 segundos, así que no envíes en línea en una acción de controlador. Encola a Sidekiq / Delayed Job / GoodJob y envía desde el trabajador, respuestas más rápidas y reintentos automáticos en errores SMTP transitorios.
- Aplicaciones de revisión y pipelines. Con
mailertogoenapp.json, cada aplicación de revisión puede aprovisionar su propia instancia; si prefieres no enviar correo real desde aplicaciones efímeras, sobrescribe el mailer a:test(Rails) o un destino común en esos entornos. - El puerto 25 es un callejón sin salida, no lo necesitas. Heroku (como todos los grandes proveedores en la nube) hace que el puerto 25 saliente sea inutilizable; Mailer To Go usa el puerto de sumisión 587, que está abierto. Si alguna vez ves conexiones que se cuelgan en el puerto 25, es por eso.
- Escalar dynos está bien. SMTP es sin estado por mensaje, así que ejecutar múltiples dynos web/worker no necesita manejo especial, cada dyno lee las mismas variables de configuración.
Por qué esto funciona cuando enviar desde el dyno no
La capacidad de entrega es un juego de reputación jugado por la IP de envío y el dominio. Un dyno de Heroku no tiene ni una IP estable ni una reputación calentada, y no puede publicar los registros de autenticación que exigen los proveedores de bandeja de entrada. Mailer To Go proporciona las IP gestionadas, la firma DKIM y rotación de claves, la alineación SPF/DMARC y el manejo de rebotes/quejas, para que tu dyno haga lo que se le da bien (ejecutar tu aplicación) mientras tu correo viaja en infraestructura construida para ser entregada.
¿Implementando a través de Addons.io o Build.io? La configuración es idéntica, consulta Usando Mailer To Go en Heroku, Addons.io y Build.io. ¿Trabajando con subdominios de Heroku en general? Consulta Subdominios de Heroku: una guía introductoria.