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

🔔 Webhooks

Webhooks позволяют получать уведомления о событиях в Fixorix — например, когда создаётся тикет, обновляется статус или добавляется сообщение.

После настройки Webhooks Fixorix будет отправлять события на ваш сервер в режиме реального времени через HTTP POST запросы.


🧭 1. Как это работает

  1. Вы настраиваете URL в интерфейсе Fixorix.
  2. Вы выбираете типы событий, которые хотите получать.
  3. Fixorix отправляет POST-запрос на ваш URL при каждом событии.
  4. Ваш сервер принимает JSON и отвечает 200 OK.

⚙️ 2. Настройка в интерфейсе

В разделе:

Настройки проекта → Интеграции → Webhooks

вы указываете:

  • адрес приёма (ваш URL)
  • события, которые необходимо получать
  • секрет для подписи (не обязателен, но рекомендуется)

Вы можете создать несколько Webhooks для разных интеграций.


🧾 3. Формат webhook-уведомления

Fixorix отправляет POST-запрос следующего формата:

HTTP запрос

POST <ваш URL>
Content-Type: application/json
X-Fixorix-Signature: sha256=<подпись>

Тело события

{
"id": "evt_8736ba78",
"type": "ticket.created",
"createdAt": "2025-01-02T10:00:00Z",
"projectId": "tenant-001",
"data": {
"ticketId": "tck_475746",
"title": "Cannot login",
"status": "new",
"priority": "high"
}
}

📋 4. Типы событий

Webhook уведомления делятся на несколько категорий:

  • 🎫 Tickets — события, связанные с тикетами
  • 💬 Messages — сообщения и заметки
  • 📨 Appeals — события по обращениям
к сведению

Полный список событий и структуры их data смотрите на странице
Events — Webhooks.


🔐 5. Проверка подлинности (подпись)

Чтобы убедиться, что событие действительно от Fixorix, в заголовке передается подпись:

X-Fixorix-Signature: sha256=<hex-значение>

Подпись формируется как:

HMAC_SHA256(<секрет>, <сырой JSON>)

Пример проверки подписи

import hmac
import hashlib

def verify(body: bytes, signature: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(
key=secret.encode("utf-8"),
msg=body,
digestmod=hashlib.sha256,
).hexdigest()

return hmac.compare_digest(expected, signature)

Если подпись некорректна — верните 400 или 401.


🧪 6. Ответ сервера

Ваш сервер должен ответить:

HTTP 200 OK

Можно также вернуть:

  • 202 Accepted
  • 204 No Content

🔁 7. Повторная доставка

Если Fixorix не получает ответ 2xx:

  • выполняется повторная отправка
  • до 10 попыток
  • с увеличивающимися интервалами
  • в течение 24 часов

Повторные события содержат:

"retry": true

События имеют постоянное поле "id", поэтому их можно дедуплицировать.


📌 8. Требования к вашему серверу

Ваш обработчик должен:

  1. Принимать POST с JSON
  2. Возвращать ответ < 3 секунд
  3. Быть доступным по HTTPS
  4. Понимать дубликаты событий (идемпотентность)
  5. (опционально) проверять подпись

🧩 9. Пример простого обработчика

import hashlib
import hmac
import json
import os
from flask import Flask, request, abort

app = Flask(__name__)

SECRET = os.getenv("FIXORIX_WEBHOOK_SECRET")

def verify_signature(body: bytes, signature: str) -> bool:
expected = "sha256=" + hmac.new(
SECRET.encode("utf-8"),
body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)

@app.post("/fixorix-webhook")
def webhook():
signature = request.headers.get("x-fixorix-signature")

if not signature or not verify_signature(request.data, signature):
abort(400, "Invalid signature")

event = json.loads(request.data.decode())

if event["type"] == "ticket.created":
print("New ticket:", event["data"]["ticketId"])

return "", 200

❓ FAQ

Нужно ли использовать REST API вместе с webhook?

Webhooks уведомляют о событиях. REST API позволяет получить больше данных или выполнить действия.

Обычно интеграции используют оба метода.

Можно ли тестировать webhooks локально?

Да, с помощью инструментов:

  • ngrok
  • webhook.site
  • localtunnel
Что делать при ошибках?
  • Если ваш сервер недоступен, Fixorix повторит доставку автоматически.
  • Если вы возвращаете 500, Fixorix тоже повторит попытку.
  • Если вы возвращаете 400 (например, неверная подпись или неверные данные) — повторов не будет.
  • Ответ 2xx означает успешную обработку и повторов не будет.