API 参考
出站 Webhooks
出站 Webhook 让互客鱼在发生有趣的事情时将事件推送到您的端点。
在 /app/integrations/webhooks 下按工作区配置它们。
lead.captured。
交付是单次尝试(无重试),带有 HMAC-SHA256 签名。
对话级别事件(conversation.started、conversation.message、conversation.routed)被推迟,尚未发出。
配置
每个 webhook 订阅有:
- URL — 您的端点。强烈推荐 HTTPS。
- Events — 目前只有
lead.captured。 - Signing secret — 自动生成。用于 HMAC 主体。
- Active — 切换。
标头
调度器发送两个标头:
| 标头 | 值 |
|---|---|
Content-Type | application/json |
X-hukeyu-Signature | t={timestamp},v1={hmac} — Stripe 风格的时间戳签名 |
签名验证
签名是 "{timestamp}.{body}" 的 HMAC-SHA256,使用订阅的签名密钥。
要验证:
// Node
const crypto = require('crypto');
function verify(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(
signatureHeader.split(',').map(p => p.split('='))
);
const ts = parts.t;
const sig = parts.v1;
const expected = crypto
.createHmac('sha256', secret)
.update(`${ts}.${rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(sig)
);
}
始终使用恒定时间比较(Node 中的 timingSafeEqual,PHP 中的 hash_equals)以避免时序攻击。
如果 t 早于约 5 分钟,则拒绝交付 — 重放保护在您的方面。
交付语义
每次交付都是单个 HTTP POST,超时时间为 5 秒。 没有内置重试:非 2xx 响应或超时会丢弃事件。 如果您的端点暂时关闭,您将丢失该事件。 推荐模式:
- 快速回复 2xx。 缓冲到您自己的队列并异步处理。
- 幂等性。 使用事件的
occurred_at+data内容去重 — 还没有每个交付 ID。 - 对账。 对于业务关键数据,定期从管理员潜在客户列表拉取,而不是仅依赖 webhook。
事件有效负载
lead.captured
{
"event": "lead.captured",
"occurred_at": "2026-05-07T12:00:00Z",
"data": {
"lead_id": "01HXY...",
"agent_id": "01HXY...",
"conversation_id": "01HXZ...",
"name": "Alex",
"email": "alex@example.com",
"phone": "+1...",
"fields": { "company": "Acme" }
}
}
确切的字段集取决于访客填写到内联表单中的内容以及您在智能体上定义的任何自定义字段。
键是稳定的;缺失值是 null 而不是不存在。
Stripe webhooks(传入)
这些是分开的 — Stripe 发送到 /billing/webhook,
Cashier 使用 STRIPE_WEBHOOK_SECRET 验证标准的 Stripe-Signature 标头。
它们驱动订阅状态。
您不需要从集成页面配置这些;它们是平台管理员关注的问题。
本地测试
将 webhook 指向 https://webhook.site 或隧道本地 URL(ngrok)。
通过 playground 或实时小部件提交潜在客户;webhook 在一秒内触发。
路线图
Webhook 表面将扩展到包括对话级别事件、每个交付 ID 和至少一次重试语义。
在此之前,轮询管理员端点以获取 lead.captured 之外您关心的状态。