UnifyPort Webhook 事件筛选:用 subscribed_events 还是通配符?
单一用途的生产处理器应明确列出 subscribed_events;如果端点是完整事件采集器,或者你还在确认工作流需要哪些事件,则使用 ["*"]。通配符涵盖所有公开标准事件,但不包含内部原始事件。对于跨境团队的消息收件箱,可先订阅 message.received,只有当同一服务也负责连接状态时,再加入账号生命周期事件。
关键结论
subscribed_events接受准确的公开事件名,或单独使用["*"]订阅完整公开目录。- 创建或更新端点时,未知事件名会被拒绝。
- 订阅成功不代表每个渠道都会产生该事件,仍需查看渠道事件矩阵。
message.received可能是入站或出站消息,必须检查data.message.direction。- 事件筛选、HMAC 签名、成功确认和重试是四项独立控制。
subscribed_events 控制什么
UnifyPort 会把 subscribed_events 选中的事件通过 HTTP POST 发送到 Webhook 端点。标准信封始终包含 id、type、provider、account_id、occurred_at 和因事件而异的 data。可接受的名称与载荷结构见标准事件目录。
最小的收件订阅如下:
{
"subscribed_events": ["message.received"]
}
处理器仍要判断消息方向:
if (
event.type === 'message.received' &&
event.data?.message?.direction === 'inbound'
) {
await storeInboundMessage(event);
}
该事件表示连接的消息账号观察到一条消息,并不保证它一定是入站消息。
通配符写法是:
{
"subscribed_events": ["*"]
}
应把它作为完整选择使用,不要把 "*" 与具体事件名混在同一个数组里。它会选择全部公开标准事件,但不会开放内部原始事件。
三种实用筛选方案
1. 只做入站收件箱
适合只负责存储和分发客户来信的服务:
{
"subscribed_events": ["message.received"]
}
只处理 data.message.direction 为 inbound 的记录。以后确实需要编辑、删除、表情反应或回执时,再加入对应的准确事件名,并先定义它们如何更新已存状态。
2. 入站收件箱加账号健康状态
如果同一服务还要提示授权失效或运行连接断开,可使用:
{
"subscribed_events": [
"message.received",
"account.status.updated",
"account.started",
"account.auth.required",
"account.auth.succeeded",
"account.auth.failed"
]
}
不要把每个状态事件都当成重启指令。先同步 auth_status 与 runtime_status,再核对账号当前状态后采取动作。消息账号运行状态恢复手册说明了何时 refresh、reconnect、start 或重新认证。
3. 完整事件采集器
如果端点是统一接入边界,后续才按消费者分发,则使用 ["*"]。这样可以让 WhatsApp、Telegram、LINE、TikTok、Zalo 和 X 共用一个已签名队列,而消息、回执、群组与账号状态由不同消费者处理。
通配符采集器仍要为未来新增的公开事件准备默认分支:先安全存储标准信封并返回成功确认,无法识别的类型进入可观察的隔离队列,不要假设每个事件都是消息。
用明确筛选条件创建端点
真实 API 路由是 POST /v1/webhook-endpoints。以下请求创建一个启用签名的活动端点,接收消息和账号状态:
curl -X POST https://api.unifyport.ai/v1/webhook-endpoints \
-H "X-Api-Key: $UNIFYPORT_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"url\": \"https://inbox.example.com/webhooks/unifyport\",
\"status\": \"active\",
\"subscribed_events\": [
\"message.received\",
\"account.status.updated\",
\"account.auth.required\"
],
\"signing_secret\": \"$WEBHOOK_SIGNING_SECRET\",
\"retry_policy\": { \"max_attempts\": 3 }
}"
请求字段以创建 Webhook 端点参考为准。retry_policy.max_attempts 表示首次发送之后的重试次数;文档默认值 3 代表首次请求之外最多再重试三次,允许范围是 0 到 5。
以后需要修改筛选条件时,调用文档中的 PATCH /v1/webhook-endpoints/{endpoint_id} 并提交新的 subscribed_events;创建和更新使用相同的名称校验规则。
把筛选与传输安全分开
筛选条件决定 UnifyPort 发送什么;signing_secret 决定发送是否带有 X-Device-Timestamp 与 X-Device-Signature。启用签名后,应在解析 JSON 之前,按“时间戳、英文句点、原始请求体”的顺序计算十六进制 HMAC-SHA256 并校验。
任何 2xx 都会确认发送成功。连接错误以及 HTTP 408、429、5xx 可按配置重试,其他 4xx 不会重试。发送采用至少一次语义,因此普通事件的重试必须幂等处理。
完整实现请参考Webhook 发送与签名校验和更深入的HMAC 防重放与幂等教程。
添加事件名前先核对渠道支持
公开目录定义了合法事件名,但不同渠道解析器并不支持全部事件。message.received 与关键账号事件覆盖较广,而回执、消息编辑、会话变化和群组更新会因渠道而异。
让消费者依赖某个事件前,先查看各渠道 Webhook 事件差异。合法订阅只是筛选条件,不保证上游账号一定产生该事件。
如果你正在搭建自动化而不是通用采集器,可继续阅读n8n WhatsApp 已签名 Webhook 教程,了解为什么签名校验和可靠入库应位于 AI 工作流之前。
限制与取舍
明确事件列表能减少噪声并划清服务职责,但新增需求出现时,必须先更新配置。通配符不会漏掉新的公开类型,却要求消费者能够接纳更多事件以及未来扩展。
UnifyPort 没有通用 REST 消息历史读取 API,也不保证补发所有遗漏载荷。应先注册接收端点,再连接生产消息账号,并在事件到达时保存所需数据。有限的 WhatsApp 历史同步只用于连续性,不替代你自己的事件存储。
UnifyPort 提供非官方接口。如果项目必须走官方平台认证路径,或需要矩阵之外的渠道专属能力,应选择对应平台的官方 API。
常见问题
应该订阅 message.received 还是 ["*"]?
专用收件箱处理器用 message.received;存储并分发全部公开标准事件的通用采集器用 ["*"]。
message.received 是否只包含入站消息?
不是。工作流只处理来信时,必须检查 data.message.direction 是否为 inbound。
能订阅渠道内部事件吗?
不能。subscribed_events 只接受公开标准名称,通配符也不会开放内部原始事件。
事件名拼错会怎样?
创建或更新请求会拒绝未知名称,不会静默保存一个永远匹配不到事件的配置。
["*"] 是否保证每个渠道都产生所有事件?
不保证。它选择全部公开标准类型,但实际渠道支持和上游可用性仍有差异。
下一步
打开创建 Webhook 端点参考,从上述三种筛选方案中选择一种,并在连接生产消息账号前完成接收端注册。
资料来源
核对日期:2026 年 8 月 19 日。