Перейти к основному содержимому

📥 Входящие вебхуки

Что это. Точка приёма на стороне Fixorix: внешняя система отправляет POST на секретную ссылку, платформа принимает событие и передаёт его дальше.

Когда нужно. Когда события чужой системы — платёжного сервиса, CRM, мессенджера, вашего собственного бэкенда — должны попадать внутрь Fixorix.

Заводится пока не из интерфейса

Точку приёма создаёт управляющее API сервиса вебхуков, закрытое служебным токеном. В дашборде такой настройки нет, по API-ключу проекта она недоступна. Как раздел будет выглядеть, когда появится, описано на странице Вебхуки на дашборде.

Где находится

ЧтоАдрес
Регистрация точки приёмаPOST /webhook-service/api/v1/inbound-webhooks — служебный токен
Список точек приёма проектаGET /webhook-service/api/v1/inbound-webhooks — служебный токен
УдалениеDELETE /webhook-service/api/v1/inbound-webhooks/{id} — служебный токен
Сам приём событийPOST на секретную ссылку — токен в самой ссылке, ничего больше не нужно

Приём событий — единственное, что выставлено наружу на тестовом стенде.

Две ссылки приёма

При регистрации выдаются две равнозначные ссылки, ведущие на один и тот же токен приёма:

СсылкаКогда пригодится
Обычная — на домене webhook.fixorix.devОсновной вариант
«Всемирная» — на домене webhook-world.fixorix.devДля внешних систем, которым основной домен недоступен

Обе принимают одинаковые запросы и приводят к одному и тому же результату. Вторая ссылка выдаётся не всегда: если «всемирный» адрес на контуре не настроен, её просто нет.

Сам токен приёма — 43 случайных символа в конце ссылки.

Ссылка приёма — это и есть секрет

Токен в ссылке — единственное средство аутентификации на точке приёма: кто знает ссылку, тот может слать события. Храните её как пароль, не публикуйте в репозиториях и в клиентском коде.

Что задаётся при регистрации

ПолеОбязательноОписание
ПроектдаПроект, от имени которого принимаются события
ИмядаДо 128 символов. Вместе с проектом — ключ идемпотентности: повторная регистрация с тем же именем вернёт существующую точку приёма
Источник событийдаПоток, в который складываются принятые события. Формат — [A-Za-z0-9][A-Za-z0-9._-]{0,248}
Проверка секретанетГде внешняя система предъявляет общий секрет: способ (HEADER или FIELD) и имя, до 255 символов
Challenge-рукопожатиенетПара «что пришло» → «что ответить» для верификационного «пинга» провайдера
Успешный ответнетТело, которое возвращается отправителю при успешном приёме
Постоянные метки событиянетПары «имя → значение», которые добавляются к каждому принятому событию

В ответе приходят идентификатор точки приёма, обе ссылки и секрет проверки, если он был запрошен.

Конфигурацию изменить нельзя

Ни одного метода изменения у точки приёма нет: повторная регистрация с тем же именем возвращает существующую запись и ничего в ней не обновляет — ни проверку секрета, ни challenge, ни успешный ответ, ни постоянные метки. Единственный способ поменять настройку — удалить точку приёма и создать заново. Ссылка приёма при этом сменится, и внешнюю систему придётся перенастроить.

Как отправлять события

  • Метод — только POST.
  • Заголовок Content-Type: application/json. Любой другой тип даёт 415.
  • Тело — произвольный JSON.
  • Максимальный размер тела — 1 048 576 байт (1 МиБ). Заявленная длина сверх лимита отклоняется сразу, тело без заявленной длины обрывается на превышении. В обоих случаях ответ — 413.

Тело сохраняется байт в байт: платформа не переупаковывает и не переформатирует его.

Проверка секрета

Необязательная проверка: сервис сам генерирует секрет при регистрации и потом сверяет его с тем, что предъявила внешняя система.

СпособГде лежит секрет
HEADERВ HTTP-заголовке с заданным именем — например, X-Telegram-Bot-Api-Secret-Token у Telegram
FIELDВ поле JSON-тела: имя поля или путь через точку, например data.token

Правила:

  • секрет придумывает не отправитель, а сервис — его значение приходит в ответе на регистрацию;
  • сравнение идёт константным временем;
  • отсутствующее, пустое или несовпадающее значение — 401, событие не принимается;
  • проверка включается, только когда заданы и способ, и имя;
  • секрет доступен и позже — в списке точек приёма проекта он отдаётся открытым текстом, поэтому настройку внешней системы можно повторить без перевыпуска.
У старых точек приёма секрет не читается

У точек приёма, заведённых до появления открытого хранения, значение секрета прочитать нельзя — доступна только проверка. Если такой секрет утерян, точку приёма придётся пересоздать.

Challenge-рукопожатие

Многие внешние системы перед началом работы присылают верификационный «пинг» и ждут в ответ определённое тело. Для этого задаётся пара: что должно прийти и что на это ответить.

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

  1. Пришедшее тело сверяется с шаблоном.
  2. Если шаблон совпал — сервис сразу отвечает 200 с заданным телом и событие никуда не передаёт.
  3. Если не совпал — запрос обрабатывается как обычное событие.

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

Что в шаблонеКак сравнивается
ОбъектКаждое поле шаблона должно присутствовать и совпасть — рекурсивно, вглубь вложенных объектов
МассивДля каждого элемента шаблона должен найтись подходящий элемент пришедшего массива; порядок и лишние элементы значения не имеют
Простое значениеОбычное равенство
Не-JSONПострочное сравнение без учёта отступов
Пустой шаблон не принимается

Шаблон {} или [] отклоняется при регистрации с ошибкой 400 invalid_challenge: он совпал бы с любым событием, и точка приёма перестала бы передавать что-либо вообще. Ответ на рукопожатие тоже не может быть пустым.

При сработавшем рукопожатии проверка секрета не выполняется вовсе — порядок обработки такой: рукопожатие → проверка секрета → передача события → ответ.

Успешный ответ и постоянные метки

Успешный ответ. Если задать тело успешного ответа — например, ok, — оно и вернётся отправителю с кодом 200. Если не задавать, при успешном приёме придёт 202 с пустым телом. Тип ответа выбирается автоматически: application/json, если тело разбирается как JSON, иначе text/plain.

Постоянные метки события. Пары «имя → значение», которые сервис добавляет к каждому принятому событию этой точки приёма. Нужны, когда в один поток пишут несколько точек приёма и получателю надо различать источник — например, по идентификатору бота, — не разбирая тело.

ОграничениеЗначение
Количество метокне больше 16
Имя метки[A-Za-z0-9][A-Za-z0-9._-]{0,63}, не может начинаться с двух подчёркиваний
Значение меткистрока не длиннее 256 символов
Нарушение любого правила400 invalid_headers при регистрации

Коды ответа точки приёма

КодКогда возникаетЧто делать отправителю
200Сработало challenge-рукопожатие или задан успешный ответНичего, всё в порядке
202Событие принято и записано; успешный ответ не заданНичего, всё в порядке
401Проверка секрета не прошла: значения нет, оно пустое или не совпалоПроверить, тот ли секрет и в том ли месте отправляется
404Токен в ссылке неизвестенПроверить ссылку; точка приёма могла быть удалена
413Тело больше 1 МиБУменьшить событие или отправлять его частями
415Заголовок Content-Type не application/jsonИсправить заголовок
503Событие не удалось записать за отведённое времяПовторить отправку — событие не принято
Ответ 503 означает, что событие потеряно

202 возвращается только после подтверждения записи. Если подтверждения нет, приходит 503, и событие считается непринятым — молча оно не пропадает, но и не сохраняется. Внешняя система обязана повторить отправку.

Ограничения

  • Заводится и удаляется только через управляющее API со служебным токеном — в интерфейсе такой настройки нет.
  • Конфигурацию после создания изменить нельзя: только удалить и создать заново, с новой ссылкой.
  • Тело события — не больше 1 МиБ.
  • Принимается только application/json и только метод POST.
  • Токен приёма не маскируется в служебных журналах сервиса. Относитесь к ссылке как к паролю и пересоздавайте точку приёма, если ссылка могла утечь.
  • Системные точки приёма удалить нельзя — на удаление возвращается 409 system_webhook. Создать такую точку через API невозможно, при обычной регистрации системной она не становится.

Кто что может

ДействиеМинимальная роль
Создать, посмотреть, удалить точку приёмаРоли проекта здесь не действуют — нужен служебный токен
Отправить событие на точку приёмаДостаточно знать ссылку и, если она настроена, секрет проверки

Вебхуки · Исходящие вебхуки · Типы событий · Вебхуки на дашборде · Триггеры сценариев