Muévete desde Postmark
Conserva la biblioteca de Postmark y envía a través de OpenEmail. Cambia su host y su token de servidor, y tu código de envío queda como está.
Qué cambiar
Apunta la biblioteca a https://api.openemail.uk/compat/postmark y pon, donde va el token de servidor, una clave de API de OpenEmail con el permiso emails:send. Viaja en la misma cabecera X-Postmark-Server-Token. Tus llamadas que envían correo quedan como están, y la dirección From decide si un mensaje puede salir, como en todo OpenEmail.
import { ServerClient } from 'postmark' const client = new ServerClient(process.env.OPENEMAIL_API_KEY, { requestHost: 'api.openemail.uk/compat/postmark',}) await client.sendEmail({ From: '[email protected]', To: '[email protected]', Subject: 'Your invoice', HtmlBody: '<p>Your invoice is attached.</p>', MessageStream: 'outbound',})En Node, requestHost es el host y la ruta juntos, sin esquema y sin barra final. En Ruby, path_prefix necesita una barra en cada extremo. En Python, usa el paquete oficial postmark-python con base_url. El paquete comunitario postmarker no puede llegar a una ruta bajo un host, así que aquí no funciona. En PHP, PostmarkClient::$BASE_URL lleva el esquema, el host y la ruta sin barra final. Es estático, así que se aplica a todos los clientes de Postmark del proceso, PostmarkAdminClient incluido.
Qué corresponde a qué
Los endpoints que se sirven son POST /email, /email/batch, /email/withTemplate y /email/batchWithTemplates. Los nombres de campo coinciden sin importar mayúsculas y minúsculas, como en Postmark, y una cadena vacía cuenta como omitida.
| Postmark | En OpenEmail |
|---|---|
| From | El remitente, con su nombre. |
| To | Destinatarios separados por comas. Con Cc y Bcc, hasta 50 por mensaje. |
| ReplyTo | Una sola dirección de respuesta. |
| Subject | El asunto. |
| HtmlBody | El cuerpo HTML. TextBody pasa a ser el cuerpo de texto, y uno de los dos es obligatorio. |
| Headers | Cabeceras propias dadas como Name y Value: X-*, List-*, Reply-To, Precedence, Auto-Submitted, Importance, Priority y Feedback-ID. |
| Attachments | Archivos, 20 como máximo y 5 MB en total. Una imagen cuyo ContentID usa el HTML como cid: se incrusta donde aparece. Cualquier otro archivo llega como adjunto normal. |
| Tag | Una etiqueta llamada tag. |
| Metadata | Etiquetas con los mismos nombres y valores. Con Tag, como máximo 10 por mensaje. |
| TrackOpens | Activa o desactiva el seguimiento de aperturas del mensaje. |
| TrackLinks | HtmlAndText y HtmlOnly activan el seguimiento de clics, y None lo desactiva. |
| MessageStream | outbound, o el id de cualquier otro flujo transaccional, envía el mensaje como siempre. |
| TemplateAlias | El slug o el id (tpl_...) de una plantilla de OpenEmail, rellenada con TemplateModel. InlineCss se acepta y no cambia nada. |
Qué se rechaza, y por qué
TemplateId, con el ErrorCode 1101. Un id de plantilla de Postmark no significa nada aquí, así que vuelve a crear la plantilla en OpenEmail y envía su slug o su id comoTemplateAlias.- El flujo
broadcast, con el ErrorCode 1236. Estos endpoints envían correo transaccional, y los boletines salen como difusiones de OpenEmail. Subject,HtmlBodyoTextBodyen un mensaje con plantilla, con el ErrorCode 1123, porque los aporta la plantilla.TrackLinkscon el valorTextOnly, porque OpenEmail sigue los enlaces de la parte HTML.- Más de una dirección de respuesta, una cabecera repetida o fuera de la lista anterior, más de 10 etiquetas, y un nombre de etiqueta o de
Metadatacon algo distinto de letras, dígitos,_y-. - Un lote de más de 100 mensajes, con el ErrorCode 410. Postmark acepta 500, así que divide los lotes más grandes.
Respuestas y errores
- Un envío responde 200 con
To,SubmittedAt,MessageID,ErrorCodea 0 yMessagea OK.MessageIDes el id del mensaje de OpenEmail, el que usanGET /emails/{id}y los webhooks. Una cabeceraIdempotency-Keyfunciona como en el resto de la API. - Un lote responde 200 con un resultado por mensaje, en orden. Un mensaje que falló lleva solo su
ErrorCodey suMessage, y los demás salen igualmente. - Los errores llegan como
ErrorCodeyMessage. Una clave ausente o desconocida, o una sinemails:send, responde HTTP 401 con el ErrorCode 10. El resto responde HTTP 422: ErrorCode 300 para el propio mensaje, 400 para una dirección From que la clave no puede usar, 401 para un dominio que aún no puede enviar, 402 para un cuerpo que no es JSON y 405 para un espacio de trabajo que ha agotado su cupo de envío. HTTP 413 significa que el cuerpo supera 10 MB, o 50 MB en un lote, o que los adjuntos superan 5 MB.