TicketWave Logo
Webhooks

개요

서명된 HTTP 요청으로 TicketWave 이벤트를 자신의 애플리케이션에서 받아보세요.

웹훅

웹훅은 TicketWave가 당신에게 보내는 HTTP 요청입니다. 서버에서 무언가가 발생할 때마다 — 티켓이 열리거나, 멤버가 블랙리스트에 추가되거나 — TicketWave가 당신이 소유한 URL로 JSON 본문을 POST합니다.

이것이 로그 채널과의 차이입니다. 로그 채널은 사람이 읽을 수 있도록 Discord에 임베드를 작성하고, 웹훅은 원시 이벤트를 당신의 코드에 전달합니다.

웹훅은 프리미엄 기능입니다. 프리미엄이 없으면 엔드포인트를 만들 수 없고 어떤 이벤트도 전달되지 않습니다.

엔드포인트 만들기

엔드포인트 페이지 열기

서버 대시보드 → WebhooksEndpoints.

엔드포인트 추가하기

Add Endpoint를 클릭하고 두 필드를 입력하세요:

FieldDescription
Endpoint URL요청을 받는 https:// URL
Event Types이 엔드포인트가 받아야 하는 이벤트

엔드포인트는 체크한 유형만 받습니다. 아무것도 선택하지 않는 것은 허용되지 않습니다 — 최소 하나는 선택하세요.

서명 비밀키 복사하기

TicketWave는 엔드포인트가 생성되는 순간 서명 비밀키(whsec_…)를 생성합니다. 엔드포인트 목록을 열고 눈 아이콘으로 표시한 뒤, 애플리케이션 설정에 복사하세요.

비밀키는 비밀번호처럼 다루세요. 이 값을 가진 사람은 서명 검사를 통과하는 요청을 위조할 수 있습니다. 저장소에는 절대 넣지 말고 환경 변수에 보관하세요.

테스트 이벤트 보내기

엔드포인트 행의 Send test event 버튼(종이비행기)을 사용하세요. 그러면 "test": true가 포함된 실제 서명 요청이 전송되므로, 실제 티켓이 걸리기 전에 수신기가 제대로 동작하는지 확인할 수 있습니다.

결과는 다른 전달과 마찬가지로 Webhooks 기록에 표시됩니다.

엔드포인트 요구 사항

RequirementDetail
Schemehttps://만 허용 — http://는 거부됨
Host공개적으로 확인 가능해야 합니다. 사설, 루프백, 링크 로컬, CGNAT 주소는 허용되지 않습니다
Response어떤 2xx 상태든 성공으로 간주됩니다
Timeout응답 시간은 10초입니다
Redirects따라가지 않습니다. 3xx는 실패로 간주됩니다
Limit서버당 최대 5개 엔드포인트

호스트 검사는 엔드포인트를 저장할 때와 모든 전달 직전에 둘 다 수행되므로, 나중에 내부 주소로 해석되기 시작한 도메인에는 더 이상 전달되지 않습니다.

요청

모든 전달은 JSON 본문을 가진 POST입니다.

헤더

HeaderExampleMeaning
Content-Typeapplication/json항상 JSON
User-AgentTicketWave-Webhooks/1.0.5요청을 보낸 봇 버전
X-TicketWave-Eventticket.created이벤트 유형
X-TicketWave-Deliverywh_3f2a…이 전달의 고유 ID
X-TicketWave-Timestamp1786224191서명의 일부인 Unix 초
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"
  }
}

모든 유형의 data 객체는 이벤트 레퍼런스를 참고하세요.

서명 검증하기

당신의 엔드포인트 URL을 알아낸 사람은 누구나 POST 요청을 보낼 수 있습니다. 서명은 실제 TicketWave 전달과 위조된 요청을 구분하는 방법입니다.

항상 검증하세요. 검증하지 않은 엔드포인트가 시스템에서 무언가를 생성하거나 닫을 수 있다면, 그건 열린 문과 같습니다.

서명이 만들어지는 방식

TicketWave는 타임스탬프와 원시 요청 본문을 점으로 이어 붙인 뒤, 엔드포인트 비밀키를 사용해 그 결과에 HMAC-SHA256을 적용합니다:

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

헤더에는 그 다이제스트가 16진수로 인코딩되어 접두사와 함께 들어갑니다: sha256=<digest>.

수신기가 해야 할 일

원시 본문을 읽으세요. 받은 정확한 바이트와 대조해야 합니다. 프레임워크가 먼저 JSON을 파싱한 뒤 다시 직렬화하면 키 순서나 공백이 바뀔 수 있고, 그러면 다이제스트가 일치하지 않습니다.

비밀키로 timestamp + "." + rawBody에 대해 HMAC을 다시 계산하세요.

상수 시간으로 비교하세요(Node의 crypto.timingSafeEqual). 단순한 ===는 타이밍 정보를 노출합니다.

타임스탬프가 최근 값인지 확인하세요 — 기본값으로는 5분 정도의 허용 오차가 적당합니다. 타임스탬프는 서명된 페이로드 안에 있으므로, 공격자가 오래된 요청에 새 타임스탬프를 붙여 재전송할 수는 없습니다.

완전한 구현 예시는 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로 중복 제거하세요

다음 단계

How is this guide?