Appearance
上线检查清单
上线前逐项核对;每一项都链到原文,拿不准时点进去核对。
凭证
- App Token 只放服务端,不下发到浏览器、App 或任何客户端。见认证与凭证 · 保管要求
- App Token 不写进前端构建产物,包括环境变量注入的前端配置。见认证与凭证 · 保管要求
- App Token 不提交进代码仓库,用密钥管理服务或部署环境变量。见认证与凭证 · 保管要求
- 日志脱敏时把
Authorization加进屏蔽名单。见认证与凭证 · 保管要求
实例与代理
- 一个企微账号只用一个
appid;拿到appid先存进数据库,之后每次取码都带原appid。见实例与代理 · 生命周期 - 在数据库里把
appid和业务主体(门店、销售组、客服组)做了映射。见实例与代理 · 多实例 - 代理地区与账号持有人手机企微常用登录省份一致。见实例与代理 · 代理三选一
调用
- 同一个
appid的发送进队列,不并发直发。见错误码 · 幂等与重试 uin、conversationId、roomId等 int64 标识发送时是 JSON number,解析时不经过浮点数。见概览 · 调用模型- 发送类接口不盲目重试,重试前先确认上一次是否已成功。见错误码 · 幂等与重试
- 加好友类接口遇到
-18000039会降频,不立即重试。见错误码 · 幂等与重试 - 高风险接口调用前有二次确认。见接口总览
回调
- 回调地址已设置,测试推送的
data.ok=true且data.httpStatus为 2xx,不能只看测试接口的 HTTP 200 或code=0。见回调说明 · 三步接上 - 每次推送都校验签名,用原始请求体计算。见回调说明 · 校验签名
- 分两层去重:推送层用
X-Eyun-Delivery,消息层用消息id。见回调说明 · 回调地址要求 - 验签、解析并可靠入队后返回
{},耗时业务处理在消费者中异步执行;入队失败不返回成功。不认识的事件也按此流程接收,不因事件名未知返回 5xx。见回调说明 · 回调地址要求 - 每次推送都记录
X-Eyun-Event、X-Eyun-Delivery、处理耗时与处理结果,日志已脱敏。见回调说明 · 回调地址要求 - 已读回执
contentType 2001被忽略,不当作新消息处理。见回调字典 · 类型速查表
掉线
- 只有
-11001可以自动调断线重连;code=0只代表已经开始恢复,还要核对后续业务调用是否再报-11002/-2007 -11002不要自动重连,避免和另一台设备互相顶号、反复掉线;置为离线并提示「已在其他设备登录」,由用户决定是否重新登录- 返回
-2007时带原appid重新获取二维码,由账号持有人扫码;重连失败间隔几十秒以上再试,连续失败就重新扫码 -11001和-11002都会推送instance.offline,记录code与message,按连接事件码表处理- 定时调用只读接口获取个人信息探测,返回上述码时按对应方式处理。见实例与代理 · 掉线检测与恢复
验证
| 验证 | 怎么做 | 预期 |
|---|---|---|
| 重放推送 | 把同一个 X-Eyun-Delivery 的推送原样再发一次 | 不重复处理 |
| 签名错误 | 带一个错误的 X-Eyun-Signature 请求回调地址 | 不进入处理 |
| 回调失败 | 让回调地址临时返回 500,再调测试投递 | 测试响应里的 data.ok=false 且 data.httpStatus 为 500 |
| 入队失败 | 暂停接收端队列,再向回调地址发送一条有效签名请求 | 回调地址不返回 2xx;不会把未保存的消息确认成已接收 |
appid 归属 | 用不属于当前应用的 appid 调一次业务接口 | 调用返回 appid_not_bound |
| 端到端 | 用另一个企微账号在客户端手动发一句话 | 回调地址收到 message.received |