📥 Входящие вебхуки
Что это. Точка приёма на стороне 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-рукопожатие
Многие внешние системы перед началом работы присылают верификационный «пинг» и ждут в ответ определённое тело. Для этого задаётся пара: что должно прийти и что на это ответить.
Как это работает:
- Пришедшее тело сверяется с шаблоном.
- Если шаблон совпал — сервис сразу отвечает
200с заданным телом и событие никуда не передаёт. - Если не совпал — запрос обрабатывается как обычное событие.
Шаблон — частичный. Сверяются только те поля, которые в нём перечислены, всё лишнее в пришедшем теле игнорируется. Это важно: провайдеры обычно досылают в «пинге» собственные поля, и полное сравнение никогда бы не совпало.
| Что в шаблоне | Как сравнивается |
|---|---|
| Объект | Каждое поле шаблона должно присутствовать и совпасть — рекурсивно, вглубь вложенных объектов |
| Массив | Для каждого элемента шаблона должен найтись подходящий элемент пришедшего массива; порядок и лишние элементы значения не имеют |
| Простое значение | Обычное равенство |
| Не-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 | Событие не удалось записать за отведённое время | Повторить отправку — событие не принято |
202 возвращается только после подтверждения записи. Если подтверждения нет, приходит 503, и событие считается непринятым — молча оно не пропадает, но и не сохраняется. Внешняя система обязана повторить отправку.
Ограничения
- Заводится и удаляется только через управляющее API со служебным токеном — в интерфейсе такой настройки нет.
- Конфигурацию после создания изменить нельзя: только удалить и создать заново, с новой ссылкой.
- Тело события — не больше 1 МиБ.
- Принимается только
application/jsonи только методPOST. - Токен приёма не маскируется в служебных журналах сервиса. Относитесь к ссылке как к паролю и пересоздавайте точку приёма, если ссылка могла утечь.
- Системные точки приёма удалить нельзя — на удаление возвращается
409 system_webhook. Создать такую точку через API невозможно, при обычной регистрации системной она не становится.
Кто что может
| Действие | Минимальная роль |
|---|---|
| Создать, посмотреть, удалить точку приёма | Роли проекта здесь не действуют — нужен служебный токен |
| Отправить событие на точку приёма | Достаточно знать ссылку и, если она настроена, секрет проверки |
→ Вебхуки · Исходящие вебхуки · Типы событий · Вебхуки на дашборде · Триггеры сценариев