跳到正文

长连接接收事件 ​

推荐从长连接开始:应用服务端主动建立连接,不需要公网接收地址、Challenge、HMAC Secret、Verification Token 或 Encrypt Key。使用应用身份的 Client Credentials;用户登录凭据不能接收这条连接。

本文提供 Node.js 22、零依赖的可运行示例,不是 SDK。已有公网接收服务时也可以选择 HTTPS Webhook,同步回调继续单独使用 HTTPS。

事件接收方式与独立同步回调图示

图示:异步事件选择长连接或 HTTPS;同步回调独立配置。此图用于解释流程,不是后台截图。

1. 选择事件 ​

进入当前应用 → 事件与 Webhook,使用推荐的“长连接”。没有可用应用身份时,在当前事件页点击“启用应用身份”,等平台回读确认后继续;启用身份不会授予业务 API 权限。添加至少一个事件并保存。零事件或配置未生效时没有事件可接收;页面不会替你的服务建立连接。

2. 配置并运行示例 ​

下载 event-connection.mjs,复制事件页的“当前应用参数”到服务端 .env。模板包含精确的 Application ID、环境和应用身份 OAuth Client ID;补入当前环境提供的 API Base 和该 Client 的 Secret,Identity Issuer 若未提供也须补齐。不要使用用户身份 Client 或其他应用/环境的凭据。

dotenv
GOODVISION_API_BASE=<GOODVISION_API_BASE>
GOODVISION_IDENTITY_ISSUER=<GOODVISION_IDENTITY_ISSUER>
GOODVISION_APPLICATION_ID=<CURRENT_APPLICATION_ID>
GOODVISION_APPLICATION_ENVIRONMENT=sandbox
GOODVISION_SERVICE_CLIENT_ID=<CURRENT_SERVICE_CLIENT_ID>
GOODVISION_SERVICE_CLIENT_SECRET=<CURRENT_SERVICE_CLIENT_SECRET>

保护 .env,不提交到源码或发给浏览器。运行:

bash
node --env-file=.env event-connection.mjs

示例从精确的 Issuer Discovery 读取 Token Endpoint,以 client_credentials 获取包含 openplatform.api.invoke 的 Bearer。Token 只在内存和 Authorization 请求头中使用,不进入 URL、Inbox 或日志。连接和 ACK 均受当前应用权限与来源限制控制,示例不绕过限制。

原事件保存在服务端 event-inbox/,示例结果在 event-inbox/results/。可用 GOODVISION_EVENT_INBOX 指定持久目录;每个应用/环境使用独立目录,仅运行一个接收进程。保留这些文件用于重启恢复,不把目录当作可随时清空的缓存。

3. 发送测试并接入业务 ​

在 Sandbox 的“事件调试”发送已订阅事件,查看示例状态和“投递日志”。connected 只说明连接已建立;delivery_processed 表示本次示例处理与 ACK 已成功。测试入队不等于接收完成。

示例的 onEvent 只持久保存示例结果,不执行开通、支付或权限变更。接入业务时替换该独立回调:按当前事件 Schema 校验客户、资源与环境,在业务事务内使用 event_id 幂等处理,成功后才返回。Sandbox 合成事件须与真实业务分开处理。

Inbox 先持久记录 received,调用 onEvent,成功后持久记录 processed,最后 ACK。仅有 received 的事件会重新执行;已有 processed 的重复投递只确认新的当前租约,不重复执行回调。崩溃可能发生在业务效果提交与 processed 写入之间,业务仍需幂等,不提供一般业务的“恰好一次”保证。

连接与恢复合同 ​

项目行为
连接GET /open-platform/v1/applications/{id}/events:stream;SSE 帧为 connected、delivery、heartbeat、error
当前投递包含 subscription_id、delivery_id、event_id、lease_receipt、lease_expires_at 和完整 event
确认POST /open-platform/v1/applications/{id}/events:ack;Body 只有 delivery_id 和 lease_receipt
租约30 秒;同一订阅只有一条未确认投递;过期/重复/旧领取 ACK 返回 409
断线/503指数退避重连;未确认事件仍可重新投递;Last-Event-ID 不是 ACK
ACK 响应丢失不复用旧回执强行确认;重连后使用实际重新投递的当前租约,processed 防止重复回调
401/403停止;核对当前应用身份、Secret、Scope、应用状态及来源限制,修正后再运行
处理失败不写 processed,不 ACK;修正处理逻辑后恢复
json
{"delivery_id":"delivery_opaque","lease_receipt":"receipt_opaque"}

成功响应为 schema_version: "1"、原 delivery_id 和 status: "delivered"。不持久记录租约回执,不把 Token 响应、原始网络错误或事件正文写入普通日志。完整字段见事件目录。

开发者文档。第三方接入不需要内部运营平台权限。