Saltar al contenido principal

Enviar correo por SMTP

Para desarrolladores

Además de la API HTTP, la plataforma acepta correo por SMTP submission. El caso de uso típico es una aplicación o un sistema legado que ya envía por SMTP y no puede cambiar a HTTP: se apunta el cliente al relay y no hay código nuevo que escribir.

Ambos caminos entregan al mismo pipeline y producen los mismos reportes. La diferencia está en cómo se expresan las opciones del envío: en HTTP son campos del body JSON, en SMTP son headers del mensaje.

Conexión

ParámetroValor
Hostcl2relay.fidelizador.com
Puerto587 (STARTTLS) o 465 (TLS implícito)
Autenticaciónobligatoria — usuario y contraseña de una credencial SMTP
Cifradoobligatorio; no se acepta AUTH antes de TLS

Las credenciales SMTP se administran por dominio desde el panel. El remitente del mensaje (From) debe pertenecer a un dominio verificado de la instancia.

Comprobar la credencial

Antes de tocar la configuración de su aplicación, conviene verificar la credencial sola. Con swaks, en una línea:

swaks --to destinatario@ejemplo.com \
--from noreply@su-dominio.com \
--server cl2relay.fidelizador.com:587 \
--tls --auth -au "<usuario-de-la-credencial>" -ap "<contraseña>" \
--header "Subject: Prueba de credencial"

--tls fuerza STARTTLS y --auth autentica. Un 250 final significa que el correo fue aceptado; a partir de ahí el estado de la entrega se consulta en los reportes, no en la sesión SMTP. Para probar sin llegar a un destinatario real, envíe a un destinatario *.sandbox (ver sandbox).

Los rechazos que puede ver en esta etapa:

RespuestaQué significa
550 5.7.1 Access deniedCredencial inexistente, revocada, con la contraseña equivocada, o su IP fuera de la lista permitida. El servidor no distingue el motivo a propósito: revise las cuatro cosas.
554 5.7.1 Sender ... not foundLa dirección del remitente no corresponde a un remitente registrado sobre un dominio verificado.
554 5.7.1 Sender mismatchEl From del mensaje no coincide con el remitente del sobre (MAIL FROM).
554 5.6.0Un valor inválido en un header x-fd-*, o el asunto supera los 254 caracteres.

Enviar HTML desde Python

Con la biblioteca estándar — EmailMessage arma el mensaje y smtplib lo entrega:

import smtplib
from email.message import EmailMessage

HOST = "cl2relay.fidelizador.com"
USER = "<usuario-de-la-credencial>"
PASSWORD = "<contraseña>"

message = EmailMessage()
message["From"] = "Notificaciones <noreply@su-dominio.com>"
message["To"] = "destinatario@ejemplo.com"
message["Subject"] = "Su pedido fue confirmado"
message["Reply-To"] = "soporte@su-dominio.com"

# Opciones de la plataforma (ver "Opciones de envío por header").
message["x-fd-category"] = "transactional"
message["x-fd-custom-msg-id"] = "order-123"

# El texto plano primero y el HTML como alternativa: el cliente de correo
# elige, y un lector que no renderiza HTML igual recibe algo legible.
message.set_content("Su pedido fue confirmado.")
message.add_alternative("<p>Su pedido fue confirmado.</p>", subtype="html")

with smtplib.SMTP(HOST, 587) as smtp:
smtp.starttls()
smtp.login(USER, PASSWORD)
smtp.send_message(message)

En el puerto 465 el cifrado es implícito, así que la conexión se abre ya cifrada y no hay starttls() que llamar:

with smtplib.SMTP_SSL(HOST, 465) as smtp:
smtp.login(USER, PASSWORD)
smtp.send_message(message)

send_message no devuelve un identificador del mensaje — el protocolo no lo entrega. Para correlacionar con sus propios registros, use x-fd-custom-msg-id como en el ejemplo y consulte después por ese valor (ver Diferencias con la API HTTP).

ℹ️ Nota. Los adjuntos y la composición MIME completa quedan fuera de esta página a propósito. Se envían por SMTP como en cualquier cliente de correo —son una parte MIME estándar, y el único límite propio es el de Límites— pero armarlos a mano es trabajo que la API HTTP resuelve con un campo. Si su integración necesita adjuntos, ése es el camino más corto.