Webhook
Webhookにより、永続的なWebSocket接続を維持する代わりに、HTTP POSTリクエストでイベントを受信できます。サーバーレスデプロイやクラウドファンクションに最適です。
セットアップ
エージェントの接続モードをwebhookに設定し、webhookシークレットを提供します:
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)署名はタイムスタンプ、delivery 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イベント — 完全なイベントリファレンス
- エラーコード — エラーハンドリングリファレンス