Перейти до вмісту

Отримання подій вебхуків

LTESocks надсилає події вебхуків на налаштований endpoint як HTTP-запит POST із JSON-тілом. Використовуйте вебхуки, щоб реагувати на зміни життєвого циклу й підключення портів без постійного опитування.

Створіть новий вебхук у користувацькому кабінеті LTESocks. Укажіть кінцевий публічний HTTPS endpoint для отримання подій, а потім збережіть signing secret у серверному сховищі секретів. Не передавайте секрет у браузерний код, журнали або клієнтські застосунки.

Якщо кабінет дозволяє, надішліть тестову подію; інакше перевірте наступну реальну доставку до використання інтеграції. Для відстеження завершення зміни IP підпишіться на port.ip_changed і дотримуйтеся розділу Скидання та готовність порту.

Кожна доставка має такий формат:

POST /your-webhook-path HTTP/1.1
Content-Type: application/json
X-Signature: BASE64_HMAC_SHA256

Підпис обчислюється з точного тіла запиту. Bearer-токен із вебхуком не надсилається.

Усі події використовують версіонований конверт:

{
"id": "66c5f99e2f66247a9284620f",
"version": "v1",
"type": "port.ip_changed",
"occurred_at": "2026-08-26T09:15:37.123Z",
"data": {
"port": {
"id": "66bca5147010246361dbe256",
"service_id": "service-123",
"number": 1042,
"status": "active"
},
"modem": {
"id": "66bca4d67010246361dbe213",
"name": "modem-kyiv-01"
},
"old_ip": "198.51.100.10",
"new_ip": "203.0.113.24"
}
}
ПолеТипЗначення
idstringУнікальний ідентифікатор події. Використовуйте його як ключ ідемпотентності.
versionstringВерсія контракту даних. Поточне значення — v1.
typestringТип події.
occurred_atstringЧас події в UTC у форматі RFC 3339.
data.portobjectПорт, пов’язаний із подією. Присутній завжди.
data.modemobjectДані модема, якщо подія пов’язана з модемом.
data.old_ipstringПопередня IP-адреса для port.ip_changed.
data.new_ipstringНова IP-адреса для port.ip_changed.

Об’єкт port містить id, service_id, number і status. Об’єкт modem містить id і name; для подій відключення модема також додається last_seen_at.

Клієнтам слід ігнорувати невідомі поля, щоб сумісні доповнення не порушували обробку подій.

Надсилається, коли строк дії порту завершується:

{
"id": "66c5f99e2f66247a92846210",
"version": "v1",
"type": "port.expired",
"occurred_at": "2026-08-26T09:20:00Z",
"data": {
"port": {
"id": "66bca5147010246361dbe256",
"service_id": "service-123",
"number": 1042,
"status": "disabled"
}
}
}

Надсилається, коли змінюється публічна IP-адреса модема, що обслуговує порт. Дані містять modem, old_ip і new_ip:

{
"id": "66c5f99e2f66247a92846211",
"version": "v1",
"type": "port.ip_changed",
"occurred_at": "2026-08-26T09:21:00Z",
"data": {
"port": {
"id": "66bca5147010246361dbe256",
"service_id": "service-123",
"number": 1042,
"status": "active"
},
"modem": {
"id": "66bca4d67010246361dbe213",
"name": "modem-kyiv-01"
},
"old_ip": "198.51.100.10",
"new_ip": "203.0.113.24"
}
}

Надсилається, коли модем, що обслуговує порт, відключається. last_seen_at — це час останньої зафіксованої активності модема:

{
"id": "66c5f99e2f66247a92846212",
"version": "v1",
"type": "port.modem_disconnected",
"occurred_at": "2026-08-26T09:22:00Z",
"data": {
"port": {
"id": "66bca5147010246361dbe256",
"service_id": "service-123",
"number": 1042,
"status": "disconnected"
},
"modem": {
"id": "66bca4d67010246361dbe213",
"name": "modem-kyiv-01",
"last_seen_at": "2026-08-26T09:21:45Z"
}
}
}

LTESocks обчислює:

Base64(HMAC-SHA256(webhook_secret, raw_request_body))

Результат надсилається в X-Signature. Зберігайте секрет whsec_... на сервері й порівнюйте підписи за сталий час.

import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyWebhook(rawBody, receivedSignature, secret) {
const expected = createHmac('sha256', secret)
.update(rawBody)
.digest('base64');
const received = Buffer.from(receivedSignature ?? '', 'base64');
const calculated = Buffer.from(expected, 'base64');
return (
received.length === calculated.length &&
timingSafeEqual(received, calculated)
);
}
<?php
$rawBody = file_get_contents('php://input');
$received = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$expected = base64_encode(hash_hmac('sha256', $rawBody, $webhookSecret, true));
if (!hash_equals($expected, $received)) {
http_response_code(401);
exit;
}

Офіційні бібліотеки порівнюють підпис за сталий час і декодують JSON лише після успішної перевірки:

import { WebhookVerifier } from '@ltesocks/sdk';
const event = await WebhookVerifier.decodeVerifiedJson(
rawRequestBody,
request.headers.get('x-signature') ?? '',
process.env.LTESOCKS_WEBHOOK_SECRET,
);

Безпечна обробка доставок

Section titled “Безпечна обробка доставок”
  1. Збережіть необроблене тіло й перевірте X-Signature.
  2. Відхиляйте непідтримувані значення version.
  3. Збережіть id до запуску побічних ефектів.
  4. Якщо id уже оброблено, поверніть 2xx, не повторюючи побічний ефект.
  5. Поставте подію в чергу для асинхронної обробки.
  6. Швидко поверніть відповідь 2xx.

LTESocks вважає успішною будь-яку відповідь 2xx. Тіло відповіді ігнорується. Перенаправлення не виконуються.

Повторні спроби й таймаути

Section titled “Повторні спроби й таймаути”

Доставка може бути повторена після помилок DNS або мережі, таймаутів, відповідей HTTP 408, HTTP 429 і 5xx. Перенаправлення, помилки перевірки TLS, помилки політики endpoint та інші відповіді 4xx не повторюються.

Стандартна політика доставки:

НалаштуванняСтандартне значення
Таймаут читання5 секунд
Таймаут запису й з’єднання5 секунд
Повторні спроби після початкового запиту3
Затримка між спробами10 секунд

За стандартної політики одна подія може бути доставлена до чотирьох разів. Кожна повторна спроба використовує те саме тіло, ідентифікатор події id і підпис, тому одержувачі мають бути ідемпотентними.

  • Використовуйте URL-адресу http або https; рекомендовано HTTPS із TLS 1.2 або новішої версії.
  • Ім’я хоста має визначатися лише в публічні IP-адреси.
  • Адреси localhost, приватні, link-local, multicast і зарезервовані адреси відхиляються.
  • Облікові дані в URL-адресі та фрагменти заборонені.
  • Не покладайтеся на перенаправлення; одразу налаштуйте кінцеву URL-адресу.