Вебхуки

Вебхуки для ERP, биллинга и CRM: новые дефекты, наряды, отключения и тревоги телеметрии отправляются POST-запросом на адрес системы с подписью.

Где найти
«Инструменты» (значок чемоданчика справа вверху) → Администрирование → «Вебхуки». То же — палитрой команд: Ctrl+K и начните набирать название.
Права
роль «Администратор» — иначе пункт в меню не виден.
Читаю как

Вебхук только сообщает «случилось событие»: в нём номер, тип, статус и время. Подробности внешняя система берёт из API v2 своим ключом.

Возможности

  • Подписка на 11 событий: новый дефект, новая заявка или наряд и смена его статуса, новое отключение и смена его статуса, тревоги датчиков телеметрии (расхождение с моделью, датчик молчит, вернулся в норму) и баланса расхода (ночной рост, небаланс, вернулся в норму).
  • «Проверить» — сразу отправляет пробное событие ping и показывает ответ адреса.
  • «Доставки» — журнал отправок подписки: событие, попытки, код ответа, ошибка; неудачную доставку события можно отправить ещё раз.
  • «Изменить» (название, адрес, события), «Выключить» и «Включить», «Новый секрет», «Удалить».
  • Под секретом новой подписки — готовый код проверки подписи для получателя на Node.js.

Как это работает

Откуда берутся события. Сервер раз в WEBHOOK_POLL_S секунд (по умолчанию 10) переносит новые записи журналов в общую ленту событий: дефекты (в том числе внесённые в десктопе), историю нарядов и отключений, тревоги телеметрии. Каждое событие ленты становится доставкой для каждой включённой подписки на этот тип. События, случившиеся до первого запуска, наружу не уходят.

Что внутри. POST с телом JSON:

{"id": "evt_almaty_1234", "type": "defect.created", "occurred_at": "2026-11-07T09:30:00Z",
 "city": "almaty", "data": {…}}

В data — короткие данные без персональных данных: номер, статус, сроки, число потребителей. Свободного текста (описание наряда, куда могут вписать телефон жителя) в событии нет.

Подпись. По спецификации Standard Webhooks. В заголовках — webhook-id, webhook-timestamp (секунды Unix) и webhook-signature: v1, + base64 от HMAC-SHA256 строки id.timestamp.тело. Ключ — секрет подписки без приставки whsec_, раскодированный из base64. Получатель считает подпись так же и сравнивает; код в окне ещё и отбрасывает запросы старше 5 минут — защита от повтора перехваченного запроса. Тело для проверки берётся как пришло, до разбора JSON.

Секрет показывается один раз — при создании и после «Новый секрет». Старый секрет после смены сразу перестаёт подходить: сначала обновите его у получателя, потом нажмите «Новый секрет» — или наоборот, но быстро.

Повторы. Доставлено — ответ 2xx за 10 секунд. Иначе повтор через 1 мин, 5 мин, 30 мин, 2 ч, 5 ч, 10 ч и 10 ч — всего 8 попыток примерно за 28 часов; после последней доставка помечается «не доставлено». Перенаправления (3xx) не выполняются и считаются неудачей. Если подписка не принимает ни одного события три дня подряд, при следующей неудаче сервер её выключает с пометкой «Выключена: адрес не принимает события 3 дн.». «Включить» обнуляет счёт.

Какие адреса можно. Только https://. Адреса внутренней сети (10.x, 192.168.x, localhost) и http:// — только если это разрешено на сервере. Адреса служебных сетей (169.254.x — метаданные облака, 100.64.x) закрыты всегда. Перед каждой отправкой сервер заново узнаёт адрес хоста и отправляет запрос именно на проверенный IP.

Сколько хранится. События ленты и их доставки — 30 дней, пробные ping — тоже 30 дней.

Что нужно для работы

  • Права: роль «Администратор».
  • Сервер: фоновая задача вебхуков включена (WEBHOOK_POLL_S больше 0). Сервер должен иметь выход к адресу получателя.
  • Получатель: адрес принимает POST с JSON и отвечает 2xx быстрее 10 секунд. Тяжёлую обработку делайте после ответа.
  • Подробности событий: ключ API v2 — его выдаёт себе пользователь внешней системы в «Личном кабинете», блок «Ключ API v2 (внешние системы)»; права ключа — права этого пользователя.

Шаги

  1. Откройте «Инструменты» и наберите в поиске «Вебхуки» — пункт выделен рамкой.

    Пункт «Вебхуки» в панели «Инструменты»

  2. Нажмите пункт — откроется окно.

    Окно «Вебхуки»

  3. «Новая подписка»: название системы, адрес приёма событий (https://, внутренние адреса — только если разрешено на сервере) и события — новый дефект, новая заявка или наряд и смена его статуса, новое отключение и смена статуса, тревоги телеметрии и баланса расхода. ТГИД отправляет каждое событие POST-запросом с подписью; если адрес не ответил, повторяет 8 раз за 28 часов; «Проверить» отправляет пробное событие сразу.

    Вебхуки: шаг 3

Примеры

Проверка подписи. На стенде с копией Алматы (almatygid_copy) событие ping отправлено на локальный приёмник и проверено кодом из окна: подпись сошлась; после изменения одного символа тела — не сошлась.

Адрес не той сети. Подписка на https://localhost/… создаётся (сервер проверяет при создании только адреса, записанные цифрами), но «Проверить» отвечает «Адрес ::1 — внутренняя сеть: разрешает служба (WEBHOOK_ALLOW_PRIVATE=1)», а в «Доставках» появляется неудачная проверка.

ERP узнаёт о новом дефекте. Подписка на «Новый дефект». Внесли дефект в десктопе — на ближайшем проходе фоновой задачи (по умолчанию раз в 10 секунд) ERP получает defect.created с номером дефекта, затем запрашивает его карточку через API v2.

Если не получается

  • При создании подписки «Некорректные параметры запроса: Адрес — https://…» — сервер отклонил адрес: нужен https://, без логина и пароля в адресе и без #; окно показывает точную причину.
  • «Проверить»: «Хост … не найден» — имя не находится в DNS сервера ТГИД; «Нет ответа за 10 с» — адрес недоступен с сервера или отвечает слишком долго; «Ответ 401/403» — получатель отверг подпись или запрос.
  • Пробные ping с ошибкой входят в счётчик «не доставлено» подписки, хотя событий не теряли.
  • Подписка выключилась сама — адрес не принимал события три дня. Почините приёмник, нажмите «Включить» и повторите нужные доставки из «Доставок».

Для администратора

  • Переменные: WEBHOOK_POLL_S (10; 0 — выключить фоновую задачу: с ней перестают работать и тревоги телеметрии), WEBHOOK_ALLOW_HTTP и WEBHOOK_ALLOW_PRIVATE (по умолчанию выключены) — для 1С или ERP во внутренней сети.
  • Не больше 50 подписок на город. Подписки, секреты и доставки — в базе города (tgid_webhook, tgid_webhook_delivery, лента — tgid_api_event). Секрет хранится открыто: он нужен серверу для подписи.
  • Несколько процессов API делят работу сами: событие уходит один раз.
  • Создание, правка, смена секрета, удаление подписки и повтор доставки пишутся в журнал действий кодами WEBHOOK_CREATE, WEBHOOK_UPDATE, WEBHOOK_SECRET, WEBHOOK_DELETE, WEBHOOK_RETRY (русских подписей у них нет).

Для разработчика

  • API: GET|POST /api/v1/webhooks, PATCH|DELETE /api/v1/webhooks/{id}, POST …/{id}/test, POST …/{id}/secret (новый секрет), GET …/{id}/deliveries, POST /api/v1/webhooks/deliveries/{id}/retry, GET /api/v1/webhooks/event-types — routers/webhooks.py, database/webhooks.py (RETRY_DELAYS_S, FAIL_DISABLE_DAYS, MAX_HOOKS, sign, check_url), события — database/api_events.py (EVENT_TYPES). Лента для опроса без вебхуков — GET /api/v2/events?after=… с ключом API v2. Описание — docs/webhooks-api-v2.md в репозитории API.
  • Веб: components/WebhooksDialog.vue, код проверки подписи — verifySnippet в utils/webhooks.ts.
  • Тесты: e2e — e2e/functions/admin.spec.ts.
Хотите увидеть эту функцию на своих данных?Покажем ТГИД на демонстрации и ответим на вопросы инженеров.
Запросить демо