웹훅 연동
SORI API 웹훅은 SORI 플랫폼에서 발생하는 주요 이벤트를 사내 시스템에 알려 줍니다. 엔드포인트를 연결하면 캠페인 활동, 디바이스 인증, 관리 작업을 거의 실시간으로 처리할 수 있습니다.
개요
SORI API는 중요한 이벤트가 발생하는 즉시 구조화된 JSON 페이로드를 전송하는 웹훅 기능을 제공합니다. 웹훅은 SORI 콘솔에서 설정하며, 다음과 같은 카테고리를 지원합니다.
- 캠페인 이벤트(`campaign.*`) 디바이스에서 캠페인이 인식되거나 사용자가 액션 URL로 이동하면 트리거됩니다.
- 인증 이벤트(`authentication`) 디바이스가 SORI 인증 플로우를 완료하면 발생합니다.
- 관리 이벤트(`admin.material.*`) 콘솔에서 소재를 생성·수정·삭제할 때 전송되는 선택적 알림입니다.
실시간 알림을 사용하면 다음과 같은 이점을 얻을 수 있습니다.
- 즉시 분석 활동이 발생하는 즉시 캠페인 지표를 추적·분석합니다.
- 인증 감사 디바이스 로그인과 사내 세션 기록을 대조합니다.
- 사기 탐지 비정상적인 패턴을 즉시 감지합니다.
- 라이브 대시보드 최신 데이터로 대시보드를 갱신합니다.
웹훅 설정
SORI에서는 두 가지 방식으로 웹훅 엔드포인트를 구성할 수 있습니다.
전역 웹훅 URL
- 설정 섹션에서 구성합니다.
- 기본적으로 모든 캠페인에 적용됩니다.
- 캠페인에서 별도로 지정하지 않았을 때 사용되는 기본 엔드포인트 역할입니다.
캠페인별 웹훅 URL
- 각 캠페인의 고급 설정에서 구성합니다.
- 해당 캠페인에서는 전역 URL보다 우선합니다.
- 캠페인마다 다른 처리가 필요할 때 유용합니다.
이벤트 구독 (설정 → Webhooks)
계정 설정에서 어떤 이벤트 카테고리를 수신할지 선택할 수 있습니다.
- 캠페인 이벤트: 인프레션과 클릭 활동을 포함한
campaign.*
알림을 구독합니다. - 인증 이벤트: 디바이스 로그인 시 발생하는
authentication
이벤트를 구독합니다. - 관리 이벤트: 콘솔에서 발생하는
admin.material.*
알림을 구독합니다.
새 계정은 캠페인 이벤트와 인증 이벤트가 기본으로 활성화되어 있습니다. 관리자는 언제든지 체크박스를 조정할 수 있으며, 변경 사항은 이후 웹훅 전송에 즉시 반영됩니다.
웹훅 설정 절차
- HTTPS를 사용하는 웹훅 수신 엔드포인트를 준비합니다.
- 다음 중 하나를 구성합니다.
- 설정 화면에서 전역 웹훅 URL을 등록합니다.
- 각 캠페인 설정에서 개별 웹훅 URL을 등록합니다.
- 설정 → Webhooks 에서 수신할 이벤트 카테고리를 선택합니다.
- JSON 페이로드가 포함된 POST 요청을 수락하고 5초 이내에 응답하도록 엔드포인트를 구현합니다.
이벤트 유형
각 웹훅 페이로드에는 표준화된 event
필드와 하위 호환을 위한 event_type
필드가 함께 포함됩니다. 신규 연동에서는 event
값을 기준으로 분기하는 것을 권장합니다.
캠페인 인프레션 이벤트(campaign.impression
)
캠페인이 사용자 디바이스에 표시될 때 전송됩니다. 캠페인 이벤트 를 활성화하면 수신할 수 있습니다.
캠페인 클릭 이벤트(campaign.click
)
사용자가 캠페인을 탭하고 액션 URL로 이동할 때 전송됩니다. 캠페인 이벤트 를 활성화하면 수신할 수 있습니다.
인증 이벤트(authentication
)
디바이스가 SORI 인증을 완료한 뒤 전송됩니다. 인증 요청에 포함된 쿼리 파라미터가 metadata
에 담기므로, 사내 세션 ID 등과 매칭할 수 있습니다.
웹훅 이벤트 처리
웹훅을 수신하면 이벤트 세부 정보가 담긴 JSON 페이로드가 전달됩니다. 아래는 각 이벤트 유형의 예시입니다. null
로 표시된 필드는 값이 없을 경우 생략될 수 있습니다.
인프레션 이벤트 예시:
{
"event": "campaign.impression",
"event_type": "campaign.impression",
"account_id": "acc_123456",
"created_at": "2025-10-14T05:25:12.421Z",
"activity_id": "act_7890",
"campaign_id": "cmp_1234",
"campaign_name": "Fall Promotion",
"material_id": "mat_5678",
"material_name": "Audio Spot 15s",
"device_id": "device_abc",
"platform": "Android",
"metadata": {
"session": "abcd-1234"
},
"geolocation": {
"viewer_country": "United States",
"viewer_region": "Michigan",
"viewer_city": "Ann Arbor"
},
"timestamp": "2025-10-14T05:25:12.421Z"
}
클릭 이벤트 예시:
{
"event": "campaign.click",
"event_type": "campaign.click",
"account_id": "acc_123456",
"created_at": "2025-10-14T05:26:03.009Z",
"activity_id": "act_7890",
"campaign_id": "cmp_1234",
"campaign_name": "Fall Promotion",
"material_id": "mat_5678",
"device_id": "device_abc",
"platform": "Android",
"metadata": {
"session": "abcd-1234",
"utm_source": "push"
},
"geolocation": {
"viewer_country": "United States",
"viewer_region": "Michigan",
"viewer_city": "Ann Arbor"
},
"timestamp": "2025-10-14T05:26:03.009Z"
}
인증 이벤트 예시:
{
"event": "authentication",
"event_type": "authentication",
"account_id": "acc_123456",
"created_at": "2025-10-14T05:15:44.832Z",
"device_id": "device_abc",
"platform": "Android",
"metadata": {
"app_version": "1.8.0",
"session": "abcd-1234"
},
"geolocation": {
"viewer_country": "United States",
"viewer_region": "Michigan",
"viewer_city": "Ann Arbor"
},
"timestamp": "2025-10-14T05:15:44.832Z"
}
커스텀 메타데이터
metadata
필드는 캠페인 이벤트에서는 SDK가 전달하는 키-값 쌍을, 인증 이벤트에서는 인증 요청의 쿼리 파라미터를 담는 맵입니다. 사용자나 디바이스를 식별하거나 부가 정보를 전달할 때 활용할 수 있으며, 선택 사항입니다. 자세한 내용은 Metadata Provider 섹션을 참고하세요.
위치 정보 안내
위치 정보는 geolocation
오브젝트에 포함되어 있습니다. CloudFront GeoIP 추정치에 기반하므로 항상 정확하지 않을 수 있습니다. 값을 확인할 수 없는 경우 Unknown
으로 전달됩니다.
응답 요구 사항
웹훅 엔드포인트는 다음 사항을 준수해야 합니다.
- 수신을 확인하기 위해
2xx
상태 코드로 응답합니다. - 가능하다면 비동기로 처리하여 블로킹을 피합니다.
- 타임스탬프나 activity ID를 활용해 멱등하게 처리합니다.
- 타임아웃을 피하기 위해 5초 이내에 응답합니다.
보안 고려 사항
- 데이터 보호를 위해 가능한 한 HTTPS를 사용하세요.
- 수신한 페이로드 구조와
event
값을 검증하세요. - 웹훅 URL을 기밀 정보로 취급하세요.
app_id
와secret_key
를 설정한 경우, 페이로드 사본으로X-SORI-Signature
헤더를 검증해 진위 여부를 확인하세요.
오류 처리
엔드포인트가 이벤트를 수신하지 못하면 SORI API Server는 다음과 같이 동작합니다.
- 실패한 전송을 최대 3회 재시도합니다.
- 재시도 간격은 지수 백오프로 증가합니다.
- 모든 재시도가 실패하면 해당 이벤트를 폐기합니다.
구현 예시
Python(FastAPI)
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/webhook")
async def webhook(request: Request):
payload = await request.json()
event = payload.get("event") or payload.get("event_type")
if event == "campaign.impression":
# 인프레션 이벤트 처리
pass
elif event == "campaign.click":
# 클릭 이벤트 처리
pass
elif event == "authentication":
# 인증 이벤트 처리
pass
return {"status": "success"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=3000)
Node.js(Express)
import express from "express";
const app = express();
app.use(express.json());
app.post("/webhook", (req, res) => {
const payload = req.body;
const event = payload.event || payload.event_type;
if (event === "campaign.impression") {
// 인프레션 이벤트 처리
} else if (event === "campaign.click") {
// 클릭 이벤트 처리
} else if (event === "authentication") {
// 인증 이벤트 처리
}
res.status(200).send({ status: "success" });
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});