Muévete desde SendGrid
Conserva el SDK de SendGrid 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/sendgrid y dale, en lugar de la clave de SendGrid, una clave de API de OpenEmail con el permiso emails:send. Viaja en la misma cabecera Authorization: Bearer. 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 sgMail from '@sendgrid/mail'import client from '@sendgrid/client' client.setApiKey(process.env.OPENEMAIL_API_KEY)client.setDefaultRequest('baseUrl', 'https://api.openemail.uk/compat/sendgrid')sgMail.setClient(client) await sgMail.send({ from: '[email protected]', to: '[email protected]', subject: 'Your invoice', html: '<p>Your invoice is attached.</p>',})En Node, pon primero la clave en el cliente, luego la URL base, y después pásale el cliente al paquete de correo. No llames a sgMail.setApiKey después, porque devuelve la URL base a SendGrid. El SDK avisa de que la clave no empieza por SG., lo cual es inofensivo. En Python, Ruby y PHP, indica el host sin barra final.
Qué corresponde a qué
El endpoint que se sirve es POST /v3/mail/send. Cada entrada de personalizations se convierte en su propio mensaje de OpenEmail con su propio id, así que una solicitud envía como máximo 100 mensajes.
| SendGrid | En OpenEmail |
|---|---|
| from | El remitente, con su nombre. Una personalización puede indicar su propio from. |
| personalizations | Un mensaje cada una. Sus to, cc y bcc suman hasta 50 destinatarios entre los tres, y sus subject, headers, custom_args, send_at y substitutions se aplican solo a ese mensaje. |
| subject | El asunto, salvo que una personalización fije el suyo. |
| content | text/plain pasa a ser el cuerpo de texto y text/html el cuerpo HTML. text/x-amp-html se deja fuera, porque el cuerpo HTML ya lleva el mensaje. |
| attachments | Archivos, 20 como máximo y 5 MB en total. Una imagen insertada cuyo content_id usa el HTML como cid: se incrusta donde aparece. Cualquier otro archivo insertado llega como adjunto normal. |
| reply_to | La dirección de respuesta. reply_to_list también sirve mientras tenga una sola dirección. |
| headers | Cabeceras propias: X-*, List-*, Reply-To, Precedence, Auto-Submitted, Importance, Priority y Feedback-ID. Una personalización añade las suyas. |
| categories | Etiquetas llamadas category, category_2 y así sucesivamente, cada una con una categoría. |
| custom_args | Etiquetas con los mismos nombres y valores. Los valores de una personalización tienen prioridad. |
| send_at | Un envío programado, con hasta un año de antelación. Una hora ya pasada envía en el acto. |
| substitutions | Cada clave se sustituye por su valor en el asunto, el cuerpo de texto y el cuerpo HTML de ese mensaje. |
| template_id | El id (tpl_...) o el slug de una plantilla de OpenEmail, rellenada con dynamic_template_data. |
| tracking_settings | open_tracking.enable y click_tracking.enable activan o desactivan el seguimiento de aperturas y de clics del mensaje. |
| mail_settings | sandbox_mode.enable comprueba la solicitud, el remitente y la plantilla, y luego responde 200 sin enviar nada. |
Un mensaje lleva como máximo 10 etiquetas, contando juntas las categorías y los custom_args. Una solicitud que necesita más se rechaza en lugar de recortarse, para que nada de lo que enviaste se pierda sin avisar.
Qué se rechaza, y por qué
- Un id de plantilla de SendGrid en
template_id, comod-…. Las plantillas se quedan en SendGrid, así que vuelve a crear la plantilla en OpenEmail y envía su id o su slug. contentjunto atemplate_id, porque una plantilla de OpenEmail aporta todo el cuerpo.substitutionscon una plantilla por la misma razón: pasa los valores endynamic_template_data.- Más de una dirección de respuesta,
reply_toyreply_to_lista la vez, y tipos de contenido distintos de texto y HTML. Envía una invitación de calendario como adjunto.ics. mail_settings.footeractivado, ysections, porque OpenEmail no escribe texto en tu mensaje.- Más de 10 etiquetas, un nombre de etiqueta con algo distinto de letras, dígitos,
_y-, una cabecera fuera de la lista anterior y más de 100 personalizaciones en una solicitud.
asm, batch_id, ip_pool_name, los ajustes de bypass de mail_settings, subscription_tracking, ganalytics, click_tracking.enable_text y open_tracking.substitution_tag se aceptan y no cambian nada. Las direcciones de la lista de supresión del espacio de trabajo siempre se omiten, diga lo que diga un ajuste de bypass.
Respuestas y errores
- Un envío responde 202 con el cuerpo vacío y el id del mensaje de OpenEmail en
X-Message-Id, el que usanGET /emails/{id}y los webhooks. Con varias personalizaciones contiene el id del primer mensaje. Una cabeceraIdempotency-Keyfunciona como en el resto de la API. - Los errores llegan como
errors, una lista demessage,fieldyhelp: 400 para una solicitud que no se puede enviar, 401 para una clave ausente o desconocida, 403 para una clave sinemails:sendo una dirección From que la clave no puede usar o cuyo dominio aún no puede enviar, 413 para un cuerpo de más de 30 MB o adjuntos de más de 5 MB, y 429 cuando el espacio de trabajo ha agotado su cupo de envío. - Cuando una personalización falla después de que se aceptaran otras anteriores, el error nombra los mensajes ya enviados, para que un reintento pueda dejarlos fuera.