01Типы событий
Десять событий. Подпишитесь на те, которыми пользуетесь.
| Событие | Когда срабатывает | Основные поля |
|---|---|---|
| message.sent | Оператор связи принял сообщение; в этот момент списывается плата. | message_id, to, price, segments |
| message.delivered | Устройство получателя подтвердило доставку. | delivered_at |
| message.failed | Оператор связи не смог доставить сообщение. | reason, carrier_code |
| message.expired | Сообщение не доставлено за срок 48 часов. | expired_at |
| message.rejected | Сообщение отклонено до отправки. Плата не списывается. | reason |
| campaign.started | Отправлено первое сообщение кампании. | campaign_id, total |
| campaign.paused | Кампания приостановлена вами или из-за нулевого баланса. | campaign_id, reason |
| campaign.completed | Все сообщения перешли в конечное состояние. | sent, delivered, failed |
| balance.low | Баланс опустился ниже заданного порога. | balance, threshold |
| balance.credited | Пополнение подтверждено в блокчейне. | amount, currency, tx |
02Проверка подписи
Двенадцать строк кода — и данным можно доверять.
Вычислите HMAC-SHA256 от метки времени, точки и исходного тела запроса с секретом вебхука. Сравнивайте подписи за постоянное время и отклоняйте запросы старше пяти минут.
- Секрет показывается один раз при добавлении вебхука. После смены секрета в панели старое и новое значения действуют одновременно в течение 24 часов.
- Временная метка входит в заголовок и подписанную строку, поэтому старый запрос нельзя воспроизвести повторно.
- Исходное тело запроса. Проверьте подпись до разбора данных: повторно сериализованный JSON даст другую подпись.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(rawBody, headers, secret) {
const ts = headers["x-meteor-timestamp"];
const sig = headers["x-meteor-signature"].split("v1=")[1];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const mac = createHmac("sha256", secret)
.update(`${ts}.${rawBody}`).digest("hex");
return timingSafeEqual(Buffer.from(mac), Buffer.from(sig));
}
import hmac, hashlib, time
def verify(raw_body: bytes, headers: dict, secret: str) -> bool:
ts = headers["X-Meteor-Timestamp"]
sig = headers["X-Meteor-Signature"].split("v1=")[1]
if abs(time.time() - int(ts)) > 300:
return False
mac = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body,
hashlib.sha256).hexdigest()
return hmac.compare_digest(mac, sig)
function verify(string $raw, array $headers, string $secret): bool {
$ts = $headers['X-Meteor-Timestamp'];
$sig = explode('v1=', $headers['X-Meteor-Signature'])[1];
if (abs(time() - (int) $ts) > 300) return false;
$mac = hash_hmac('sha256', $ts . '.' . $raw, $secret);
return hash_equals($mac, $sig);
}
03Повторные попытки
Шесть попыток в течение суток, затем — ручной повтор.
Любой ответ вне диапазона 2xx или ответ дольше 5 секунд считается сбоем. Интервалы постепенно увеличиваются, поэтому кратковременная недоступность обработчика не приводит к потере события.
- Стабильный идентификатор события сохраняется при каждой попытке. Запоминайте его и игнорируйте дубликаты.
- Недоставленные события остаются в панели 30 дней; их можно повторить по одному или все сразу.
- Состояние вебхука включает долю успешных запросов, последнюю ошибку и среднее время ответа для каждого адреса.
- 1Немедленнопервая доставка
- 2+1 минутапосле первой неудачи
- 3+5 минут
- 4+30 минут
- 5+2 часа
- 6+12 часовзатем помечается как недоставленный, с возможностью повторного воспроизведения в течение 30 дней
04Требования к обработчику
Каким должен быть адрес вебхука.
- Протокол
- Только HTTPSДействительный сертификат TLS 1.2 или новее
- Ответ
- Любой код 2xx в течение 5 секундТело ответа игнорируется
- Метод
- POST с телом JSONUTF-8, без дополнений
- Подпись
- X-Meteor-SignatureHMAC-SHA256 от timestamp.body
- Повторные попытки
- 6 попыток в течение 24 часовПосле них доступен ручной повтор в течение 30 дней
- Адреса вебхуков
- До 10 на аккаунтДля каждого — свой секрет и список событий
- Порядок
- Не гарантированИспользуйте created_at и приоритет статуса
- IP-адреса источников
- Опубликованные, стабильныеНеобязательная вторая проверка
05Вопросы, ответы
Вопросы о вебхуках.
На какие события я могу подписаться?
<code>message.sent</code>, <code>message.delivered</code>, <code>message.failed</code>, <code>message.expired</code> и <code>message.rejected</code> для сообщений; <code>campaign.started</code>, <code>campaign.paused</code> и <code>campaign.completed</code> для кампаний; <code>balance.low</code> и <code>balance.credited</code> для аккаунта. Для каждого адреса вебхука можно выбрать свой набор.
Как подписываются вебхуки?
Каждый запрос содержит заголовок X-Meteor-Signature с подписью HMAC-SHA256. Она вычисляется с помощью секрета вебхука по строке из метки времени, точки и исходного тела запроса. Секрет показывается в панели один раз. Проверяйте подпись и отклоняйте запросы старше пяти минут.
Что произойдёт, если мой обработчик не ответит?
Мы выполним 6 попыток в течение 24 часов с увеличивающимися интервалами. После последней попытки событие будет отмечено в панели как недоставленное; в течение 30 дней его можно отправить повторно вручную.
Может ли одно и то же событие произойти дважды?
Да, при повторных попытках после медленного 2xx. Каждое событие имеет стабильный идентификатор; сохраните его и игнорируйте дубликаты. Обработчики должны быть идемпотентными.
Как быстро мне нужно ответить?
Верните любой код 2xx в течение 5 секунд. Выполняйте работу асинхронно: поставьте событие в очередь, ответьте кодом 200 и обработайте позже.
Могу ли я протестировать без отправки реальных сообщений?
Да. Из панели можно отправить тестовое событие любого типа. Запросы с тестовым ключом API также создают настоящие вебхуки со статусом <code>test</code>.
Можно ли указать несколько адресов вебхуков?
Да, до десяти на аккаунт. У каждого будет свой секрет и набор событий — например, отдельные адреса для рабочей и тестовой сред.
Можно ли ограничить приём списком IP-адресов?
Да. Стабильный диапазон адресов опубликован в справочнике API. Основной проверкой остаётся подпись, а список разрешённых IP-адресов служит дополнительным уровнем защиты.
06Больше продуктов
Всё остальное в наборе инструментов.
Один аккаунт, общий баланс и единая таблица тарифов. Все перечисленные возможности включены без дополнительной платы.
Посмотреть тарифы- Массовые SMS-кампанииЗагрузите список, напишите один раз, разошлите миллионам.
- SMS APIОдин HTTP вызов на одно сообщение. Любой язык.
- ПланированиеОкна доставки по местному времени для каждого направления.
- Идентификатор отправителя и маршрутыБуквенно-цифровые, числовые или общие отправители.
- Отчёты о доставкеСтатус каждого сообщения и экспорт одним нажатием.