📥 Входящие вебхуки
Что это. Точка приёма на стороне Fixorix: внешняя система отправляет POST на секретную ссылку, платформа принимает событие и передаёт его дальше.
Когда нужно. Когда события чужой системы — платёжного сервиса, CRM, мессенджера, вашего собственного бэкенда — должны попадать внутрь Fixorix.
Раздела для настройки вебхуков в дашборде пока нет.
Чтобы внешняя система уже сейчас запускала ваш сценарий, используйте вебхук-триггер сценария: он вызывается через публичный API по API-ключу проекта.
Ссылка приёма
У каждой точки приёма две равнозначные ссылки, ведущие на один и тот же токен приёма:
| Ссылка | Когда пригодится |
|---|---|
https://webhook.fixorix.ru/<токен> | Основной вариант |
https://webhook-world.fixorix.ru/<токен> — «всемирная» | Для внешних систем, которым основной домен недоступен |
Обе принимают одинаковые запросы и приводят к одному и тому же результату. Ссылка вида https://webhook.fixorix.ru/ingest/<токен> тоже работает: префикс /ingest/ необязателен.
Сам токен приёма — 43 случайных символа в конце ссылки.
Токен в ссылке — единственное средство аутентификации на точке приёма: кто знает ссылку, тот может слать события. Храните её как пароль, не публикуйте в репозиториях и в клиентском коде.
Что настраивается
| Поле | Обязательно | Описание |
|---|---|---|
| Имя | да | До 128 символов, уникально в проекте: повторное создание точки приёма с тем же именем вернёт уже существующую |
| Проверка секрета | нет | Где внешняя система предъявляет общий секрет: способ (HEADER или FIELD) и имя, до 255 символов |
| Challenge-рукопожатие | нет | Пара «что пришло» → «что ответить» для верификационного «пинга» провайдера |
| Успешный ответ | нет | Тело, которое возвращается отправителю при успешном приёме |
| Постоянные метки события | нет | Пары «имя → значение», которые добавляются к каждому принятому событию |
При создании выдаются обе ссылки приёма и, если включена проверка, секрет проверки — 64 символа (URL-safe base64).
Точку приёма нельзя отредактировать: повторное создание с тем же именем возвращает существующую точку и ничего в ней не обновляет — ни проверку секрета, ни challenge, ни успешный ответ, ни постоянные метки. Единственный способ поменять настройку — удалить точку приёма и создать заново. Ссылка приёма при этом сменится, и внешнюю систему придётся перенастроить.
Как отправлять события
- Метод — только
POST. - Заголовок
Content-Type: application/json. Любой другой тип даёт415. - Тело — JSON; платформа его не разбирает и передаёт как есть. Пустое тело отклоняется с
400. - Максимальный размер тела — 1 048 576 байт (1 МиБ). Заявленная длина сверх лимита отклоняется сразу, тело без заявленной длины обрывается на превышении. В обоих случаях ответ —
413.
Тело сохраняется байт в байт: платформа не переупаковывает и не переформатирует его.
Проверка секрета
Необязательная проверка: Fixorix сам генерирует секрет при создании точки приёма и потом сверяет его с тем, что предъявила внешняя система.
| Способ | Где лежит секрет |
|---|---|
HEADER | В HTTP-заголовке с заданным именем — например, X-Telegram-Bot-Api-Secret-Token у Telegram |
FIELD | В поле JSON-тела: имя поля или путь через точку, например data.token |
Правила:
- секрет придумывает не отправитель, а Fixorix — его значение выдаётся при создании точки приёма;
- сравнение идёт константным временем;
- отсутствующее, пустое или несовпадающее значение —
401, событие не принимается; - для проверки обязательны и способ, и имя заголовка или поля;
- секрет можно посмотреть и позже, поэтому настройку внешней системы можно повторить без перевыпуска.
У точек приёма, заведённых до появления открытого хранения секрета, его значение посмотреть нельзя — доступна только проверка. Если такой секрет утерян, точку приёма придётся пересоздать.
Challenge-рукопожатие
Многие внешние системы перед началом работы присылают верификационный «пинг» и ждут в ответ определённое тело. Для этого задаётся пара: что должно прийти и что на это ответить.
Как это работает:
- Пришедшее тело сверяется с шаблоном.
- Если шаблон совпал — Fixorix сразу отвечает
200с заданным телом и событие никуда не передаёт. - Если не совпал — запрос обрабатывается как обычное событие.
Шаблон — частичный. Сверяются только те поля, которые в нём перечислены, всё лишнее в пришедшем теле игнорируется. Это важно: провайдеры обычно досылают в «пинге» собственные поля, и полное сравнение никогда бы не совпало.
| Что в шаблоне | Как сравнивается |
|---|---|
| Объект | Каждое поле шаблона должно присутствовать и совпасть — рекурсивно, вглубь вложенных объектов |
| Массив | Для каждого элемента шаблона должен найтись подходящий элемент пришедшего массива; порядок и лишние элементы значения не имеют |
| Простое значение | Обычное равенство |
| Не-JSON тело | С шаблоном не совпадает никогда: шаблон всегда JSON, поэтому рукопожатие не срабатывает и запрос обрабатывается как обычное событие |
Шаблон {} или [] задать нельзя: он совпал бы с любым событием, и точка приёма перестала бы передавать что-либо вообще. Ответ на рукопожатие тоже не может быть пустым.
При сработавшем рукопожатии проверка секрета не выполняется вовсе — порядок обработки такой: рукопожатие → проверка секрета → передача события → ответ.
Успешный ответ и постоянные метки
Успешный ответ. Если задать тело успешного ответа — например, ok, — оно и вернётся отправителю с кодом 200. Если не задавать, при успешном приёме придёт 202 с пустым телом. Тип ответа выбирается автоматически: application/json, если тело разбирается как JSON, иначе text/plain.
Постоянные метки события. Пары «имя → значение», которые Fixorix добавляет к каждому принятому событию этой точки приёма. Нужны, когда события приходят через несколько точек приёма и получателю надо различать источник — например, по идентификатору бота, — не разбирая тело.
| Ограничение | Значение |
|---|---|
| Количество меток | не больше 16 |
| Имя метки | [A-Za-z0-9][A-Za-z0-9._-]{0,63}, не может начинаться с двух подчёркиваний |
| Значение метки | строка не длиннее 256 символов |
Коды ответа точки приёма
| Код | Когда возникает | Что делать отправителю |
|---|---|---|
200 | Сработало challenge-рукопожатие или задан успешный ответ | Ничего, всё в порядке |
202 | Событие принято и записано; успешный ответ не задан | Ничего, всё в порядке |
400 | Тело пустое или отсутствует (malformed_body) | Отправлять непустое тело |
401 | Проверка секрета не прошла: значения нет, оно пустое или не совпало | Проверить, тот ли секрет и в том ли месте отправляется |
404 | Токен в ссылке неизвестен | Проверить ссылку; точка приёма могла быть удалена |
405 | Метод не POST (method_not_allowed, заголовок Allow: POST) | Использовать POST |
413 | Тело больше 1 МиБ. Ответ может прийти от балансировщика, не в JSON-формате | Уменьшить событие или отправлять его частями |
415 | Заголовок Content-Type не application/json | Исправить заголовок |
503 | Событие не удалось записать за отведённое время | Повторить отправку — событие не принято |
Ошибки приходят в JSON, например {"code": "invalid_secret", "message": "…", "details": [], "timestamp": "…"}. Коды: malformed_body (400), invalid_secret (401), not_found (404), method_not_allowed (405), payload_too_large (413, только code и message), unsupported_media_type (415), publish_failed (503).
202 возвращается только после подтверждения записи. Если подтверждения нет, приходит 503, и событие считается непринятым — молча оно не пропадает, но и не сохраняется. Внешняя система обязана повторить отправку.
Ограничения
- Самостоятельно завести точку приёма пока нельзя — раздела в дашборде нет.
- Конфигурацию после создания изменить нельзя: только удалить и создать заново, с новой ссылкой.
- Тело события — не больше 1 МиБ.
- Принимается только
application/jsonи только методPOST. - Ссылка приёма — секрет: относитесь к ней как к паролю и пересоздавайте точку приёма, если ссылка могла утечь.
→ Вебхуки · Исходящие вебхуки · Типы событий · Вебхуки на дашборде · Триггеры сценариев