Переезд с Mailgun
Оставьте SDK Mailgun и отправляйте через OpenEmail. Смените его базовый URL и ключ, а код отправки останется как есть.
Что изменить
Направьте SDK на https://api.openemail.uk/compat/mailgun и дайте ему вместо ключа Mailgun ключ API OpenEmail с разрешением emails:send. Он передаётся как пароль того же входа HTTP Basic, а имя пользователя не проверяется. Домен в пути должен быть одним из доменов рабочего пространства, а адрес From решает, может ли письмо уйти, как и везде в 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>',})В Ruby второй аргумент указывает хост и путь без схемы. В PHP SDK берёт из переданного адреса только хост, поэтому путь добавляется через AddPathPlugin из php-http, который SDK уже устанавливает. Официальный пакет для Python может записать в журнал предупреждение, что хост не принадлежит Mailgun, и всё равно отправляет. Ещё он повторяет запрос, который завершился 429 или 5xx, поэтому OpenEmail отвечает 400, а не 5xx, когда часть пакета уже ушла.
Что чему соответствует
Обслуживается эндпоинт POST /v3/{domain}/messages, в виде multipart/form-data, который нужен для вложений, или application/x-www-form-urlencoded. Имя поля, оканчивающееся на [], читается без этого окончания.
| Mailgun | В OpenEmail |
|---|---|
| from | Отправитель вместе с именем. |
| to | Получатели, повторами или через запятую. Вместе с cc и bcc до 50 на письмо. |
| subject | Тема. |
| html | Часть HTML. text становится текстовой частью, и одна из двух или template обязательна. |
| attachment | Файлы, не больше 20 и 5 МБ в сумме. |
| inline | Изображение, которое HTML использует как cid: со своим именем файла, встраивается там, где оно стоит. Любой другой встроенный файл приходит обычным вложением. |
| o:tag | Теги с именами tag, tag_2 и так далее, в каждом по одному тегу. |
| v: | Каждая переменная становится тегом со своим именем и значением. Вместе с o:tag не больше 10 на письмо. |
| o:deliverytime | Отложенная отправка, до года вперёд. Время, которое уже прошло, означает отправку сразу. |
| o:tracking | Вместе с o:tracking-clicks и o:tracking-opens включает или выключает отслеживание для письма. htmlonly считается включённым. |
| o:testmode | yes записывает письмо как отправленное, не доставляя его, как это делает ключ oe_test_. |
| h:Reply-To | Адрес для ответа. Любое другое поле h: становится своим заголовком: X-*, List-*, Precedence, Auto-Submitted, Importance, Priority и Feedback-ID. |
| recipient-variables | Пакетная отправка. Каждый адрес из to получает своё письмо, где %recipient.key% заполняется из его переменных, а %recipient% его адресом, и cc и bcc идут в каждое из них. Заполнитель без значения остаётся как есть. |
| template | slug или id (tpl_...) шаблона OpenEmail, заполненного из t:variables, а если их нет, из h:X-Mailgun-Variables. t:version выбирает версию по её номеру. |
Что отклоняется и почему
templateвместе сhtmlилиtext, потому что шаблон OpenEmail даёт всё тело письма, иt:version, который не является номером версии.o:deliverytime-optimize-periodиo:time-zone-localize, потому что OpenEmail не подбирает время отправки для каждого получателя. Другие заголовкиh:X-Mailgun-, которые являются указаниями для Mailgun: используйте вместо них подходящий параметрo:.amp-htmlсам по себе. Рядом сhtmlилиtextон опускается, потому что письмо и так несут они.- Больше одного адреса для ответа, больше 10 тегов, имя тега из чего-то, кроме букв, цифр,
_и-, а также пакет больше 100 получателей. Mailgun принимает 1000, поэтому делите пакеты побольше.
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 и t:text принимаются и ничего не меняют.
Ответы и ошибки
- Отправка отвечает 200 с сообщением
Queued. Thank you.иid: id письма OpenEmail в угловых скобках, которыйGET /emails/{id}и вебхуки используют без них. Пакетная отправка создаёт по письму на получателя, у каждого свой id, и отвечает первым. ЗаголовокIdempotency-Keyработает так же, как в остальном API. - Отсутствующий или неизвестный ключ получает 401 с простым текстом
Forbidden, а домен, которого нет в рабочем пространстве, получает 404 сDomain not found. Всё остальное приходит какmessage: 400 для письма, которое нельзя отправить, 403 для ключа безemails:send, адреса From, который ключу нельзя использовать, домена, который ещё не может отправлять, или рабочего пространства, исчерпавшего лимит отправки, и 413 для тела больше 25 МБ или вложений больше 5 МБ. - Если один получатель пакета не прошёл после того, как другие были приняты, ошибка называет уже отправленные письма и отвечает 400, чтобы SDK, который повторяет запросы, не отправил их дважды.