UnifyPort v1 API 正式生产可用:首个稳定版本里有什么 — UnifyPort
UnifyPort v1 API 现已正式生产可用。这是首个稳定版本:一个发送端点、一套归一化的 Webhook 事件层,以及覆盖全部六大渠道——WhatsApp、Telegram、LINE、TikTok、Zalo、X——的账号接入流程,全部收敛在同一个 API 之下。
这篇文章就是本次发布的更新日志。如果你一直在等一个可以放心构建、不必担心底层随时破坏性变更的版本,那就是它。下面按端点逐一说明本次上线的内容,包含真实的事件名、认证流程和可靠性行为。
一个发送 API,贯通六大渠道
v1 的核心是一个端点。POST /v1/messages 通过你选定的 provider 账号发送一条归一化的文本消息。你不需要学六套 SDK 或六种载荷格式——只学一套。
平台特有的能力并没有消失,而是收进了结构化的 provider_data 字段。需要回复某条特定消息,或设置 Telegram 的 parse mode?这些都放在 provider_data 里(例如 reply_to、parse_mode),顶层请求的结构保持不变。常见场景保持简单,平台特定场景依然可行。
六大渠道为 WhatsApp、Telegram、LINE、TikTok、Zalo、X。在 API 里,provider 账号通过 telegram、whatsapp、twitter、line、zalo 等名称创建。
11 个标准 Webhook 事件
v1 的另一半是标准事件层。每一条来自 provider 的消息、每一次投递状态变更、每一个账号生命周期事件,都会被转换成同一套稳定的 JSON 结构。本次发布共有 11 个标准事件,你的后端通过同一个处理器消费它们全部。
最常用的两个:
message.received—— 已连接账号收到一条入站消息message.status.updated—— 你发出的某条消息投递状态发生变化
账号生命周期事件让连接状态变得可观测,而不再是一团黑盒:
account.auth.required—— 账号需要一次登录操作(扫码或验证码)account.auth.succeeded—— 登录完成;provider_account_ref此时已填充,事件还携带标准资料字段(display_name、picture_url、region、status_message)account.started—— 账号运行时已上线account.status.updated—— 账号状态发生变化
无论来自六大渠道中的哪一个,message.received 事件长得都一样:
{
"event": "message.received",
"account_id": "acct_8Q2vK",
"provider": "whatsapp",
"from": "+6591234567",
"text": "你好,我的订单好了吗?",
"timestamp": 1749254400,
"message_id": "wamid.HBgLNTU..."
}
把 whatsapp 换成 line 或 zalo,你的路由逻辑一行都不用改。这正是标准层存在的意义。
账号接入:扫码与验证码两种流程
在 v1 里,账号接入是一条独立的流程,其设计理念是:认证状态是你的 Webhook 可以”观察”的东西,而不是需要你时刻盯着的东西。
你通过向账号端点 POST 创建账号,并选择与接入方式匹配的 auth_mode:
{
"provider": "whatsapp",
"auth_mode": "code",
"provider_data": { "phone": "+6591234567" }
}
对于验证码流程,E.164 格式的手机号通过 provider_data.phone 提供。它会被持久化在账号上,并在后续认证动作中自动回放,因此你无需每一步都重新提交。创建重复的 provider 身份会返回干净的 409 duplicate_provider_account,而不是悄悄生成第二个账号。
对于扫码流程,凭据通过你的 Webhook 异步送达:
- WhatsApp —— 调用
/auth/qr/start开启设备会话。二维码 token 会作为account.auth.required事件落到你的 Webhook(auth_payload.qr_code是你 UI 要渲染成二维码的原始 token),同时也通过/auth/qr/check提供同步轮询。扫码后,account.auth.succeeded到达并带上provider_account_ref,随后是account.started。 - LINE —— 二维码 URL 与 PIN 异步送达。监听
account.auth.required,或轮询/auth/session读取auth_payload.url(二维码图片)和auth_payload.pin。
账号配置好时,Webhook URL 会被自动注入——认证状态变更和登录事件,与你的入站消息走同一个端点。一个 Webhook,所有事件。
account.auth.succeeded 一旦到达,POST /v1/accounts/{account_id}/runtime/start 即可让账号上线(若运行时已启动则为空操作)。
Webhook 控制面
v1 里的 Webhook 端点是一等公民、可配置的对象,而不是埋在设置里的单个 URL 字段。
创建 Webhook 接收器时,你精确选择它接收哪些事件。subscribed_events 接受标准事件名(如 message.received、account.status.updated),或用 ["*"] 订阅全部。未知的事件名在写入时即被拒绝,而不是稍后悄悄失败。
签名是内建的。提供 signing_secret,每次投递都会用 HMAC-SHA256 签名,你的端点即可验证真实性。留空则显式禁用签名——这是一个明确的选择,而非意外。
重试行为由你设定。retry_policy.max_attempts 是非负整数;0 表示完全禁用重试,非整数值会被拒绝。重投由平台负责,你的端点只需作出响应。
把波动留在平台层的可靠性
一个生产版本需要生产级默认值,v1 自带了它们。入站投递经过一条带限流、重试、幂等和故障隔离的队列,因此 provider 端的波动被留在平台层内部,不会级联到你的应用。
账号运行时状态也被归一化。runtime_status 不再是各家 provider 自己的术语,而是八个平台标准值之一——unknown、starting、running、stopping、stopped、reconnecting、disconnected、error——provider 特有的标签在你看到之前就已映射进这套取值。你只写一个状态机,而不是六个。
对于需要按地域路由的账号,可选的 proxy_config 对象会随账号持久化并自动应用。
这次发布意味着什么
v1 达到生产可用,是一种承诺,而不只是一个版本号。发送端点、11 个标准事件、认证流程、Webhook 控制面,就是你可以在其上构建产品的稳定面。UnifyPort 的初衷一直是:让团队不必把同一套集成做六遍;v1 就是这套面”停止移动”的那个版本。
如果你读过我们关于”绕开官方 API 摩擦接收消息”的其他文章——不走官方 API 接收 WhatsApp 入站、无需官方账号接收 LINE 消息,或 WhatsApp 与 Telegram 成本对比——这就是那些路径所运行的 API。
上手步骤:创建一个 API key,用与渠道匹配的 auth_mode 连接第一个账号,注册一个带 signing_secret 的 Webhook 端点,订阅 message.received。同一个工作时段内,你就能看到归一化的入站事件打到后端。从此每多接一个渠道,都是同样的流程——而不是又一个集成项目。