TicketWave Logo
Webhooks

Обзор

Получайте события TicketWave в виде подписанных HTTP-запросов в своём приложении.

Вебхуки

Вебхук — это HTTP-запрос, который TicketWave отправляет вам. Каждый раз, когда на вашем сервере что-то происходит — открывается тикет, участник попадает в чёрный список — TicketWave отправляет POST с JSON-телом на принадлежащий вам URL.

В этом и есть отличие от Log Channels: log channels записывают embed в Discord для чтения людьми, а вебхуки передают сырое событие прямо в ваш код.

Вебхуки — это премиум-функция. Без премиума эндпоинты нельзя создать, и события не будут доставляться.

Создание эндпоинта

Откройте страницу эндпоинтов

Панель сервера → WebhooksEndpoints.

Добавьте эндпоинт

Нажмите Add Endpoint и заполните два поля:

FieldDescription
Endpoint URLURL с https://, на который будут приходить запросы
Event TypesКакие события должен получать этот эндпоинт

Эндпоинт получает только те типы, которые вы отметите. Выбрать ничего нельзя — укажите как минимум один тип.

Скопируйте секрет подписи

TicketWave генерирует секрет подписи (whsec_…) в момент создания эндпоинта. Откройте список эндпоинтов, покажите его с помощью значка глаза и скопируйте в конфигурацию вашего приложения.

Относитесь к секрету как к паролю. Любой, у кого он есть, может подделать запросы, которые пройдут проверку подписи. Храните его в переменной окружения, никогда не в репозитории.

Отправьте тестовое событие

Используйте кнопку Send test event (бумажный самолётик) в строке эндпоинта. Она отправляет настоящий, полностью подписанный запрос с "test": true в полезной нагрузке, чтобы вы могли убедиться, что ваш приёмник работает, ещё до того, как на него будет зависеть реальный тикет.

Результат появится в истории Webhooks как и любая другая доставка.

Требования к эндпоинту

RequirementDetail
SchemeТолько https://http:// отклоняется
HostДолжен быть публично разрешаемым. Частные, loopback, link-local и CGNAT-адреса отклоняются
ResponseЛюбой статус 2xx считается успехом
TimeoutНа ответ у вас есть 10 секунд
RedirectsНе следуются. 3xx считается ошибкой
LimitДо 5 эндпоинтов на сервер

Проверка хоста выполняется и при сохранении эндпоинта, и перед каждой отдельной доставкой, поэтому домен, который позже начнёт разрешаться во внутренний адрес, перестанет получать события.

Запрос

Каждая доставка — это POST с JSON-телом.

Заголовки

HeaderExampleMeaning
Content-Typeapplication/jsonВсегда JSON
User-AgentTicketWave-Webhooks/1.0.5Версия бота, который отправил запрос
X-TicketWave-Eventticket.createdТип события
X-TicketWave-Deliverywh_3f2a…Уникальный id этой доставки
X-TicketWave-Timestamp1786224191Unix-время в секундах, часть подписи
X-TicketWave-Signaturesha256=9f86d0…HMAC запроса

Тело

Каждая полезная нагрузка использует одну и ту же оболочку. Отличается только data для каждого типа события:

{
  "event": "ticket.created",
  "timestamp": "2026-08-26T08:23:11.000Z",
  "guild_id": "123456789012345678",
  "data": {
    "ticket_id": "ticket-1042",
    "ticket_num_id": 1042,
    "channel_id": "998877665544332211",
    "category": "🤖 Support",
    "user": { "id": "987654321098765432", "username": "Luna" },
    "created_at": "2026-08-26T08:23:11.000Z"
  }
}

См. Event Reference для объекта data каждого типа.

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

Любой, кто узнает URL вашего эндпоинта, может отправить на него POST-запрос. Подпись нужна, чтобы отличить настоящую доставку TicketWave от поддельной.

Всегда проверяйте. Непроверенный эндпоинт, который создаёт или закрывает что-то в вашей системе, — это открытая дверь.

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

TicketWave соединяет timestamp и сырой body запроса через точку и вычисляет HMAC-SHA256 от результата, используя секрет вашего эндпоинта:

signed_payload = X-TicketWave-Timestamp + "." + raw_request_body
signature      = HMAC_SHA256(signed_payload, your_endpoint_secret)

В заголовке этот дайджест передаётся в hex-формате и с префиксом: sha256=<digest>.

Что должен делать ваш приёмник

Считывайте сырой body. Проверяйте его по точным байтам, которые вы получили. Если ваш фреймворк сначала парсит JSON, а потом вы сериализуете его заново, порядок ключей или пробелы могут измениться, и дайджест не совпадёт.

Пересчитывайте HMAC по timestamp + "." + rawBody с вашим секретом.

Сравнивайте в постоянное время (crypto.timingSafeEqual в Node). Обычный === раскрывает информацию по времени выполнения.

Проверяйте, что timestamp свежий — хороший стандарт по умолчанию: допуск в пять минут. Timestamp находится внутри подписанной полезной нагрузки, поэтому злоумышленник не сможет повторно отправить старый запрос с новым timestamp.

Полная реализация есть на странице Example Server.

Повторы

Неудачная доставка автоматически повторяется.

Attempts3 (первая попытка плюс 2 повтора)
Backoff1 секунда, затем 5 секунд
Retried onОшибки сети, таймауты, 408, 429 и любые 5xx
Not retried onВсе остальные 4xx — они означают, что ваш эндпоинт намеренно отклонил запрос

Из-за повторов ваш эндпоинт может получить одно и то же событие дважды. Используйте X-TicketWave-Delivery как ключ идемпотентности: запоминайте уже обработанные id и игнорируйте повторы.

Доставки не упорядочены. Если два тикета создаются одновременно, запросы могут прийти в любом порядке — используйте поле timestamp в теле, если порядок для вас важен.

История доставок

На странице Webhooks в панели отображаются все доставки со статусом, кодом ответа, длительностью и числом попыток. Откройте строку, чтобы увидеть точную полезную нагрузку запроса и ответ, который вернул ваш сервер.

Неудачные доставки можно отправить повторно со страницы деталей с помощью Retry Webhook. Он снова отправляет исходную полезную нагрузку на тот же эндпоинт и записывает новую доставку.

История хранится 30 дней, после чего автоматически очищается.

Устранение неполадок

ProblemFix
Эндпоинт не удаётся сохранитьURL должен начинаться с https:// и разрешаться в публичный адрес
Всё отображается как неудачное, без кода ответаЗапрос до вас так и не дошёл — таймаут, сбой DNS или отказ в соединении
Подпись никогда не совпадаетВы хэшируете распарсенное тело вместо сырых байтов или забыли префикс timestamp + "."
Доставки через некоторое время прекращаютсяПроверьте, не начал ли ваш хост возвращать 4xx — они не повторяются
Событие так и не приходитЭндпоинт не подписан на этот тип, либо сервер потерял премиум
Дублирующиеся событияОжидаемо при повторах — дедуплицируйте по X-TicketWave-Delivery

Следующие шаги

  • Event Reference (Каждое событие и его полезная нагрузка)
  • Example Server (Рабочий приёмник на Express)
  • Log Channels (Те же события, но отправляются в Discord)

How is this guide?