Эндпоинты
`webhooks.list`, `get`, `create`, `update`, `delete`, `rotateSecret`, `test` и `listDeliveries`.
Все методы
const endpoint = await openemail.webhooks.create({ url: 'https://acme.com/hooks/mail', eventTypes: ['email.sent', 'email.bounced'], description: 'Billing service',}) await store(endpoint.secret) await openemail.webhooks.list()await openemail.webhooks.get(endpoint.id)await openemail.webhooks.update(endpoint.id, { enabled: false })await openemail.webhooks.test(endpoint.id)const rotated = await openemail.webhooks.rotateSecret(endpoint.id)await openemail.webhooks.delete(endpoint.id)create — ЕДИНСТВЕННЫЙ случай, когда секрет возвращается, не считая rotateSecret. При чтении он никогда не выдаётся, поэтому сохраните его прежде всего остального. Опустите eventTypes, чтобы получать все события, включая появившиеся позже.
У rotateSecret нет окна перекрытия. Старый секрет перестаёт работать немедленно, поэтому выкатывайте новый до ротации. Автоматически этот вызов никогда не повторяется: повтор выполнил бы ротацию второй раз и обесценил секрет, который вернула первая попытка.
На что можно подписаться
WEBHOOK_EVENTS экспортируется, чтобы вы могли отрисовать список. События — это события **почтового ящика**, а не этого API: email.received срабатывает для почты, пришедшей в приложение, а email.sent — для письма, отправленного из композера. Подписка — это не то же самое, что наблюдение за собственным трафиком API.
Как убедиться, что это работает
const result = await openemail.webhooks.test('whe_…')console.log(result.delivery?.status, result.delivery?.responseCode) const deliveries = await openemail.webhooks.listDeliveries('whe_…')for (const d of deliveries) console.log(d.eventType, d.status, d.responseCode, d.error)responseCode, равный null, означает, что ответа не было вовсе (DNS, TLS, таймаут), и это другой факт, нежели ответ со значением 0. Каждая строка несёт attempt и maxAttempts, поэтому одно событие могут описывать несколько строк: одинаковый payload.id в них — это событие, а номер попытки — это попытка.
Параметры: webhooks.create
urlstringобязательно- Куда доставки отправляются методом POST. Только HTTPS, и хостом не может быть `localhost`, имя в `.localhost`/`.local`/`.internal` или IP-литерал петлевого, частного, CGNAT- либо link-local-диапазона. Это серверный запрос по адресу, который даёте вы, поэтому такие значения дают 422 по `url`; проверка читает имя хоста как написано и никогда не разрешает DNS. Хранится сериализация того, что вы отправили, выполненная парсером URL, поэтому `https://acme.com` читается обратно как `https://acme.com/`.
eventTypesWebhookEvent[]- Какие события доходят до этого эндпоинта: любые имена из `WEBHOOK_EVENTS`. `POST /webhooks` ограничивает массив числом существующих событий, поэтому на одно больше — это 422 по `eventTypes`; `PATCH` такого ограничения не накладывает. Ограничена только длина, а повторяющееся имя сохраняется и читается обратно ровно так, как вы его отправили. Пропущенное или пустое значение сохраняется как пустой список — потому оно и читается обратно как `['*']`, — и означает все события `email.*`, кроме `email.replied`, то есть четырнадцать на сегодня, и никогда не семейства доменов или подавлений. Семейство, добавленное позже, никогда не доходит до эндпоинта, который его не назвал, поэтому интеграция не может начать получать форму, которой она никогда не видела, просто из-за релиза.
descriptionstring- Подпись для эндпоинта, не длиннее 200 символов, чтобы список вебхуков читался как имена, а не как колонка URL. Если не указана, сохраняется и возвращается как null.
Ответ: CreatedWebhookResource
object'webhook'- Всегда `'webhook'` — тот же дискриминатор, который возвращает обычное чтение, потому что секрет — это один дополнительный ключ в обычной форме, а не отдельный тип объекта. Присутствует ли `secret`, определяется тем, какой метод вы вызвали, а не этим полем.
idstring- Идентификатор эндпоинта: `whe_`, за которым следуют 24 шестнадцатеричных символа. Его принимают все прочие вызовы вебхуков: `get`, `update`, `delete`, `rotateSecret`, `test` и `listDeliveries`.
urlstring- Эндпоинт в сохранённом виде, прошедший проверки на HTTPS и на запрещённые хосты. Это разобранный и заново сериализованный URL, поэтому сравнивайте с этим значением, а не со строкой, которую вы отправили.
descriptionstring | null- Подпись, которую вы ему дали, или null, если не давали. `update` с явным null возвращает её в null.
eventTypesWebhookEvent[] | ['*']- Подписанные события или `['*']`, когда эндпоинт не назвал ни одного. `['*']` — это то, как пустой сохранённый список отображается при чтении; отправить его обратно нельзя, и он обозначает тринадцать событий о письмах, а не весь каталог. `create` и `update` принимают только буквальные имена событий.
enabledboolean- Предпринимаются ли попытки доставки; выключенный эндпоинт пропускается при рассылке событий и сохраняет свой секрет и историю доставок. Здесь всегда true, поскольку в `WebhookCreate` нет `enabled` — он есть только в `WebhookPatch`.
lastDeliveryAtstring | null- Отметка времени ISO 8601 последней ПОПЫТКИ доставки, а не последнего успеха. Она проставляется и после неудавшегося POST, поэтому она говорит, что эндпоинт пробовали, а как всё прошло — говорит `listDeliveries`. Null до первой попытки, а значит, всегда null при `create`.
createdAtstring- Отметка времени ISO 8601 того, когда эндпоинт был зарегистрирован. `list` возвращает эндпоинты от новых к старым по этому полю.
secretstring- Ключ HMAC-SHA-256, которым подписывается `X-OpenEmail-Signature` каждой доставки: `whsec_`, за которым следуют 32 случайных байта в base64url; именно его вы передаёте в `verifyWebhookSignature`. Возвращается `create` и `rotateSecret` и больше ничем. При чтении он никогда не выдаётся, поэтому сохраните его сразу; потерянный секрет можно только заменить через `rotateSecret`, который немедленно обесценивает старый.