Webhook
Webhook을 사용하면 콘텐츠 발행 성공/실패, 답글 완료, 플랫폼 알림 등 비동기 작업의 결과를 실시간 HTTP POST 요청으로 수신할 수 있습니다.
📌 엔드포인트 목록
섹션 제목: “📌 엔드포인트 목록”| 메서드 | 경로 | 설명 | 필요 스코프 |
|---|---|---|---|
POST | /v1/brand/webhooks/subscriptions | 새 Webhook 엔드포인트 등록 | webhooks:write 또는 * |
GET | /v1/brand/webhooks/subscriptions | 등록된 Webhook 구독 목록 조회 | webhooks:read 또는 * |
DELETE | /v1/brand/webhooks/subscriptions/{id} | Webhook 구독 삭제 | webhooks:write 또는 * |
🔔 지원 이벤트 목록
섹션 제목: “🔔 지원 이벤트 목록”| 이벤트명 | 발생 조건 |
|---|---|
sns.publish.succeeded | SNS 게시물이 대상 플랫폼에 성공적으로 등록됨 |
sns.publish.failed | SNS 게시물 등록이 최종 실패함 (에러 코드 및 재시도 여부 포함) |
sns.publish.blocked_entitlement | 요금제 한도 초과 또는 플랜 만료로 발행이 차단됨 |
sns.reply.succeeded | 댓글에 대한 답글 작성이 대상 플랫폼에 등록됨 |
sns.reply.failed | 답글 작성이 실패함 |
sns.provider.notification_received | SNS 플랫폼으로부터 실시간 피드/웹훅 알림을 수신함 |
📦 Webhook 페이로드 예시 (sns.publish.succeeded)
섹션 제목: “📦 Webhook 페이로드 예시 (sns.publish.succeeded)”{ "event_id": "evt_01jm8za2example", "event_type": "sns.publish.succeeded", "schema_version": 1, "occurred_at": "2026-08-16T03:30:00Z", "producer": "ankk.sns", "brand_ref": "brand_01jm8v4k9example", "idempotency_key": "launch-2026-001", "trace_id": "trc_9a8b7c6d", "data": { "content_id": "content_01jm8za2example", "publish_job_id": "job_01jm8za2jobexample", "sns_type": "instagram", "connection_id": "conn_01jm8x9k2example", "provider_post_id": "18029384756102938", "permalink": "https://www.instagram.com/p/C-example/" }}🔐 서명 검증 (HMAC SHA256)
섹션 제목: “🔐 서명 검증 (HMAC SHA256)”모든 Webhook 요청에는 위변조를 방지하기 위해 다음 헤더가 포함됩니다:
Social-Webhook-Signature: 서명 값 (t=1723780000,v1=hex_signature)Social-Webhook-Timestamp: 전송 타임스탬프 (Unix 초 단위)Social-Webhook-Id: 이벤트 고유 식별자
Node.js (Crypto) 검증 예제
섹션 제목: “Node.js (Crypto) 검증 예제”import crypto from 'node:crypto';
export function verifyWebhookSignature( rawBody: string, signatureHeader: string, timestampHeader: string, secret: string): boolean { const signedPayload = `${timestampHeader}.${rawBody}`; const expectedSignature = crypto .createHmac('sha256', secret) .update(signedPayload) .digest('hex');
// constant-time 비교로 타이밍 공격 방지 return crypto.timingSafeEqual( Buffer.from(signatureHeader), Buffer.from(expectedSignature) );}Python (hmac) 검증 예제
섹션 제목: “Python (hmac) 검증 예제”import hmacimport hashlib
def verify_webhook_signature(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool: signed_payload = f"{timestamp}.".encode('utf-8') + raw_body expected = hmac.new(secret.encode('utf-8'), signed_payload, hashlib.sha256).hexdigest() return hmac.compare_digest(signature, expected)[!CAUTION] 서명 검증 시 반드시 JSON 파싱 이전의 **원본 바디(Raw Body)**를 사용해야 합니다.