Ir a la documentación
Base de conocimiento

Muévete desde Mailgun

Conserva el SDK de Mailgun y envía a través de OpenEmail. Cambia su URL base y su clave, y tu código de envío queda como está.

Qué cambiar

Apunta el SDK a https://api.openemail.uk/compat/mailgun y dale, en lugar de la clave de Mailgun, una clave de API de OpenEmail con el permiso emails:send. Viaja como contraseña del mismo inicio de sesión HTTP Basic, y el nombre de usuario no se comprueba. El dominio de la ruta tiene que ser uno de los dominios del espacio de trabajo, y la dirección From decide si un mensaje puede salir, como en todo OpenEmail.

import formData from 'form-data'import Mailgun from 'mailgun.js' const mailgun = new Mailgun(formData)const mg = mailgun.client({  username: 'api',  key: process.env.OPENEMAIL_API_KEY,  url: 'https://api.openemail.uk/compat/mailgun',}) await mg.messages.create('acme.com', {  from: 'Acme Billing <[email protected]>',  to: ['[email protected]'],  subject: 'Your invoice',  html: '<p>Your invoice is attached.</p>',})

En Ruby, el segundo argumento es el host y la ruta sin esquema. En PHP, el SDK solo conserva el host del endpoint que recibe, así que la ruta se añade con AddPathPlugin de php-http, que el SDK ya instala. El paquete oficial de Python puede registrar un aviso de que el host no es el de Mailgun, y envía igualmente. También reintenta una solicitud que falló con 429 o un 5xx, por eso OpenEmail responde 400 en vez de 5xx cuando ya ha salido parte de un lote.

Qué corresponde a qué

El endpoint que se sirve es POST /v3/{domain}/messages, como multipart/form-data, que necesitan los adjuntos, o como application/x-www-form-urlencoded. Un nombre de campo que termina en [] se lee sin ese final.

MailgunEn OpenEmail
fromEl remitente, con su nombre.
toDestinatarios, repetidos o separados por comas. Con cc y bcc, hasta 50 por mensaje.
subjectEl asunto.
htmlEl cuerpo HTML. text pasa a ser el cuerpo de texto, y uno de los dos, o template, es obligatorio.
attachmentArchivos, 20 como máximo y 5 MB en total.
inlineUna imagen que el HTML usa como cid: con su nombre de archivo se incrusta donde aparece. Cualquier otro archivo insertado llega como adjunto normal.
o:tagEtiquetas llamadas tag, tag_2 y así sucesivamente, cada una con una etiqueta.
v:Cada variable se convierte en una etiqueta con su nombre y su valor. Con o:tag, como máximo 10 por mensaje.
o:deliverytimeUn envío programado, con hasta un año de antelación. Una hora ya pasada envía en el acto.
o:trackingJunto con o:tracking-clicks y o:tracking-opens, activa o desactiva el seguimiento del mensaje. htmlonly cuenta como activado.
o:testmodeyes registra el mensaje como enviado sin entregarlo, como hace una clave oe_test_.
h:Reply-ToLa dirección de respuesta. Cualquier otro campo h: se convierte en una cabecera propia: X-*, List-*, Precedence, Auto-Submitted, Importance, Priority y Feedback-ID.
recipient-variablesUn envío por lotes. Cada dirección de to recibe su propio mensaje, con %recipient.key% rellenado con sus variables y %recipient% con su dirección, y cc y bcc van en cada uno. Un marcador sin valor queda como está.
templateEl slug o el id (tpl_...) de una plantilla de OpenEmail, rellenada con t:variables, o si no con h:X-Mailgun-Variables. t:version elige una versión por su número.

Qué se rechaza, y por qué

  • Un template con html o text, porque una plantilla de OpenEmail aporta todo el cuerpo, y un t:version que no es un número de versión.
  • o:deliverytime-optimize-period y o:time-zone-localize, porque OpenEmail no elige una hora de envío para cada destinatario. Otras cabeceras h:X-Mailgun-, que son instrucciones para Mailgun: usa en su lugar la opción o: correspondiente.
  • amp-html por sí solo. Junto a html o text se deja fuera, porque estos ya llevan el mensaje.
  • Más de una dirección de respuesta, más de 10 etiquetas, un nombre de etiqueta con algo distinto de letras, dígitos, _ y -, y un lote de más de 100 destinatarios. Mailgun acepta 1000, así que divide los lotes más grandes.

o:dkim, o:require-tls, o:skip-verification, o:sending-ip, o:sending-ip-pool, o:tracking-pixel-location-top, o:archive-to, o:deliver-within y t:text se aceptan y no cambian nada.

Respuestas y errores

  • Un envío responde 200 con el mensaje Queued. Thank you. y un id: el id del mensaje de OpenEmail entre corchetes angulares, que GET /emails/{id} y los webhooks usan sin ellos. Un envío por lotes crea un mensaje por destinatario, cada uno con su propio id, y responde con el primero. Una cabecera Idempotency-Key funciona como en el resto de la API.
  • Una clave ausente o desconocida responde 401 con el texto plano Forbidden, y un dominio que el espacio de trabajo no tiene responde 404 con Domain not found. Todo lo demás llega como un message: 400 para un mensaje que no se puede enviar, 403 para una clave sin emails:send, una dirección From que la clave no puede usar, un dominio que aún no puede enviar o un espacio de trabajo que ha agotado su cupo de envío, y 413 para un cuerpo de más de 25 MB o adjuntos de más de 5 MB.
  • Cuando un destinatario de un lote falla después de que se aceptaran otros, el error nombra los mensajes ya enviados y responde 400, para que un SDK que reintenta no los envíe dos veces.