Webhooks
Webhooks를 사용하면 에이전트가 영구 WebSocket 연결을 유지하는 대신 HTTP POST 요청으로 이벤트를 수신할 수 있습니다. 서버리스 배포 및 클라우드 함수에 이상적입니다.
설정
에이전트의 연결 모드를 webhook으로 구성하고 webhook secret을 제공하세요:
const agent = await HasheeAgent.init({ agentId: process.env.HASHEE_AGENT_ID!, token: process.env.HASHEE_AGENT_TOKEN!, baseUrl: "https://api.hashee.ai", connectionMode: "webhook", webhookSecret: process.env.HASHEE_WEBHOOK_SECRET!,});서명 검증
모든 webhook 전달에는 서명 헤더가 포함됩니다. 처리 전에 항상 검증하세요:
import { verifyWebhookSignature, parseWebhookPayload,} from "@hasheeai/agent-sdk-ts";
// HTTP 핸들러에서:const isValid = await verifyWebhookSignature( webhookSecret, request.headers, rawBody);
if (!isValid) { return new Response("Unauthorized", { status: 401 });}
const payload = parseWebhookPayload(rawBody);서명 알고리즘
HMAC-SHA256(webhook_secret, timestamp + "." + delivery_id + "." + body)서명은 타임스탬프, 전달 ID, 요청 본문을 점으로 연결한 것에 대해 계산됩니다.
내장 검증
SDK의 verifyWebhookSignature는 자동으로 다음을 검사합니다:
| 검사 | 동작 |
|---|---|
| 타임스탬프가 5분 이상 경과 | 거부 (재생 공격 방지) |
| HMAC 불일치 | 거부 (위변조) |
중복 delivery_id | 거부 (슬라이딩 윈도우 내) |
이벤트 유형
Webhook 이벤트는 WebSocket 이벤트의 하위 집합입니다. 메시지 및 관계 이벤트만 전달됩니다:
| 이벤트 | 설명 |
|---|---|
message.new | 에이전트에 새 메시지가 전송됨 |
relation.established | 사용자가 에이전트 사용을 시작함 |
relation.terminated | 사용자가 에이전트와 연결을 끊음 |
relation.suspended | 사용자가 크리에이터에 의해 정지됨 |
relation.restored | 사용자가 크리에이터에 의해 복원됨 |
artifact_response | 사용자가 아티팩트에 응답함 |
Webhook으로 전달되지 않는 이벤트 (WebSocket 전용):
agent.governance— 거버넌스 상태 변경reaction.update— 메시지 반응group.updated— 그룹 정보 변경artifact.expired— 아티팩트 TTL 만료session.invalidated— 세션 종료auth.expiring— 토큰 만료 알림
재시도 정책
엔드포인트가 2xx가 아닌 응답을 반환하면 Hashee가 지수 백오프로 재시도합니다. 각 전달에는 중복 제거를 위한 고유 delivery_id가 있습니다.
예제: Express 핸들러
import express from "express";import { verifyWebhookSignature, parseWebhookPayload,} from "@hasheeai/agent-sdk-ts";
const app = express();
app.post("/webhook", express.raw({ type: "application/json" }), async (req, res) => { const isValid = await verifyWebhookSignature( process.env.HASHEE_WEBHOOK_SECRET!, req.headers, req.body );
if (!isValid) { return res.status(401).send("Invalid signature"); }
const payload = parseWebhookPayload(req.body);
// 이벤트 처리 console.log(`Received: ${payload.type}`);
res.status(200).send("OK");});다음 단계
- 에이전트 아키텍처 — 연결 모드 비교
- WebSocket 이벤트 — 전체 이벤트 레퍼런스
- 오류 코드 — 오류 처리 레퍼런스