Webhooks
Последнее обновление: 16 июня 2026
Webhook — это HTTP-запрос, который WWPager отправляет на указанный вами URL при поступлении нового письма. Так вы можете обрабатывать входящую почту в своих сервисах в реальном времени. URL и секрет подписи настраиваются для каждого адреса в приложении (раздел «Почтовые клиенты»).
Когда срабатывает
WWPager отправляет webhook при следующих событиях:
- email.received — на адрес поступило новое письмо.
Доставка
Запрос отправляется методом POST на ваш URL. Тело запроса — JSON в кодировке UTF-8 (заголовок Content-Type: application/json). Вместе с запросом передаются следующие заголовки:
X-WWPager-Event— тип события, напримерemail.received.X-WWPager-Delivery— уникальный идентификатор доставки (совпадает с полемidв теле).X-WWPager-Signature— подпись тела запроса (см. раздел «Подпись»).User-Agent—WWPager-Webhook/1.0.
Формат полезной нагрузки
Тело запроса имеет следующую структуру:
{
"id": "evt_8Kf2mQ1pZ0xW",
"type": "email.received",
"timestamp": "2026-06-16T12:34:56.789012Z",
"data": {
"message_id": "msg_123456",
"email": "you@wwpnext.com",
"from": "sender@example.com",
"subject": "Привет!",
"html": "<p>Текст письма в HTML</p>",
"text": "Текст письма (plain)",
"attachments": [
{
"filename": "invoice.pdf",
"content_type": "application/pdf",
"size": 102400
}
],
"headers": {
"Message-ID": "<abc@example.com>",
"Reply-To": "noreply@example.com",
"In-Reply-To": "<prev@example.com>",
"References": "<prev@example.com>"
},
"is_spam": false,
"received_at": "2026-06-16T12:34:56Z"
}
}
id— идентификатор события (совпадает сX-WWPager-Delivery).type— тип события.timestamp— время отправки события (UTC, ISO 8601).data.email— ваш адрес, на который пришло письмо.data.from— адрес отправителя.data.html/data.text— содержимое письма; одно из полей может быть пустым.data.attachments— список вложений (имя, MIME-тип, размер в байтах).data.is_spam— пометка о том, что письмо классифицировано как спам.
Подпись (HMAC-SHA256)
Чтобы вы могли убедиться, что запрос пришёл именно от WWPager и не был изменён, каждое тело подписывается секретным ключом. Секрет показывается в приложении рядом с настройкой webhook. Подпись передаётся в заголовке X-WWPager-Signature и формируется так:
- Берётся точное тело запроса (необработанные байты, как они получены).
- Вычисляется HMAC-SHA256 с использованием вашего секрета подписи в качестве ключа.
- Результат кодируется в hex (нижний регистр) и предваряется префиксом
sha256=.
X-WWPager-Signature: sha256=3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
Проверка подписи
На своей стороне вычислите HMAC от полученного тела с тем же секретом и сравните его с заголовком, используя сравнение за константное время.
Python
import hmac, hashlib
def verify(raw_body: bytes, secret: str, signature_header: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)
Node.js
const crypto = require('crypto');
function verify(rawBody, secret, signatureHeader) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader || '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Важно: подпись считается от необработанного тела запроса. Не сериализуйте JSON заново перед проверкой — повторная сериализация изменит байты (пробелы, порядок ключей) и подпись не совпадёт.
Ответ и повторные попытки
Ваш сервер должен ответить кодом 2xx, чтобы подтвердить получение. Любой другой код или таймаут считается ошибкой доставки. Обрабатывайте webhook идемпотентно: используйте поле id для защиты от повторной обработки одного и того же события.
Вопросы
Если у вас есть вопросы по интеграции, свяжитесь с нами:
- Email: support@wwpager.com
- Telegram: @wwpagersupportbot