IM 前后端逐图对接协议

版本:v2.0
日期:2026-08-11
需求依据:IM 产品原型需求文档
设计依据:IM 系统设计文档
说明:第 1 至第 11 章的章节编号、图片标题和顺序与产品原型完全一致。每张图均给出可直接开发、联调和验收的协议。

0. 公共对接约定

0.1 实现状态

状态含义
已实现当前服务端已有能力,可按本文联调
需改造已有基础能力,但字段、鉴权或业务规则需要调整
新增当前服务端没有该产品接口或数据模型
纯客户端界面或系统能力,不调用服务端;关联的提交协议会单独指出

文档中所有 新增、需改造 接口都是目标契约,不代表当前代码已经可用。前后端必须以本文字段为准实施,接口完成前可使用同结构 Mock。

0.2 API Key、启动入口与通道

0.2.1 现有系统的 API Key 从哪里来

API Key 不是客户端启动后向 IM 服务端申请得到的值。现有代码没有“获取 API Key”的 HTTP 或 WebSocket 接口。

API Key 是应用级接入标识,由部署人员在发布客户端前生成并配置:

  1. 新部署同时生成 API Key 和 HMAC Salt:在项目根目录执行 go run ./keygen。
  2. 已有服务端继续使用当前 api_key_salt 时,执行 go run ./keygen -sequence <新序号> -salt '<服务端 api_key_salt>' 生成兼容的普通应用 Key。
  3. 输出中的 HMAC salt 配置到服务端 server/tinode.conf 的 api_key_salt;输出中的 API key 配置到 iOS、Android 或 Web 客户端构建配置/受控环境配置。
  4. 客户端启动时从自己的应用配置读取 API Key,不调用 IM 接口获取。禁止把 -isroot 1 生成的 Root Key 放进客户端。

生成示意:


$ go run ./keygen
API key v1 seq1 [ordinary]: <client-api-key>
HMAC salt: <server-hmac-salt>

API Key、企业码和用户 Token 是三个不同概念:

值取得时间作用是否代表用户身份
api_key应用发布/环境配置时预置允许应用访问 Tinode 入口否
tenant_code用户输入企业码将 Session 路由并绑定到企业否
token用户登录成功后由服务端返回标识当前租户内的登录用户是

API Key 可以被客户端应用提取,因此不能把它当成用户密码或租户授权。现有 checkAPIKey 只校验 Key 的格式和 HMAC 签名;最终权限仍必须依赖租户 Session、用户 Token 和 Topic/业务 ACL。

当前 checkAPIKey 没有按 sequence 吊销旧 Key 的逻辑。生成新序号不会自动让旧 Key 失效;若需要精细轮换,服务端必须增加最低可接受序号或撤销表。直接更换 api_key_salt 会让所有旧 Key 同时失效,必须与客户端升级协调。

0.2.2 客户端怎样携带 API Key

通道地址认证用途
WebSocket(浏览器/通用方式)wss://{host}/{api_path}v0/channels?apikey={api_key}Upgrade 校验 API Key,hi 绑定租户,login 登录Topic、消息、回执、在线状态、通话信令
WebSocket(支持自定义 Header 的原生客户端)wss://{host}/{api_path}v0/channelsUpgrade Header X-Tinode-APIKey同上
产品 HTTPhttps://{host}/{api_path}v1/im/*Authorization: Bearer <params.token>好友、群、收藏、搜索、工作台和设置
文件 HTTPPOST /v0/file/u/、GET /v0/file/s/{file_id}当前用 X-Tinode-Auth: token <base64_token>文件上传下载;禁止 Query 传 Token

HTTP 请求统一通过 X-Tinode-APIKey 携带。浏览器 WebSocket 无法设置自定义 Upgrade Header 时才使用 apikey Query;日志和监控必须对该参数脱敏。产品 HTTP 还必须带 X-IM-Schema: 1 和 X-Request-ID;写操作带 Idempotency-Key。生产环境只允许 HTTPS/WSS。Token、密码、验证码、证件号不得写入 URL、普通日志、埋点或崩溃报告。

WebSocket Upgrade 阶段由 server/hdl_websock.go 先调用 checkAPIKey。缺少或无效时不会建立 WebSocket,直接返回 HTTP 403:


{"ctrl":{"code":403,"text":"valid API key required","ts":"2026-08-11T08:30:15.123Z"}}

客户端应把该错误视为应用配置/环境配置错误,停止自动重连并上报脱敏诊断;它不是账号密码错误,也不能通过重新登录解决。

两种连接方式的第一个请求对照如下:

连接方式发起第一个网络请求前已有的值第一个网络请求第一个响应得到的值下一步
WebSocket(推荐)host + api_key + tenant_code带 API Key Upgrade /v0/channelsHTTP 101 和已建立的 WebSocket;不会返回新 API Key 或 sid发送 {hi tenant}
Long Polling(兼容)host + api_key + tenant_codePOST /v0/channels/lpHTTP 201 和 ctrl.params.sid带 sid POST {hi},再 GET 等待响应

现有实现对应关系:

源码作用
keygen/keygen.go生成普通/Root API Key 和服务端 HMAC Salt
server/api_key.gocheckAPIKey 校验 API Key 格式与签名
server/http.go按 Header、Query、Form、Cookie 顺序读取 API Key
server/hdl_websock.goWebSocket Upgrade 前校验 API Key,无效直接 403
server/hdl_longpoll.go创建 Long Polling Session 并返回 sid
server/session.go处理 {hi} 租户绑定、{login} 和登录 Token 返回

现有 API Key 是应用级、非租户级,同一个普通应用 Key 可以进入不同企业;具体租户只能由后续 {hi}.tenant 决定。若将来要求每个租户独立 API Key,需要新增 Key 与租户绑定关系,不能只修改客户端配置。

0.3 多租户强制规则

  1. 未登录阶段只传公开的 tenant_code;客户端永远不接收、不提交数据库 tenant_id。
  2. WebSocket 第一条消息必须是 {hi},其中 tenant 为企业码。服务端解析后把租户固定到 Session。
  3. Token 内部绑定租户。Token 租户与当前 Session 租户不一致时返回 TENANT_MISMATCH,不得自动切换。
  4. 切换企业必须退出登录、关闭 WebSocket、清除该租户的 Token/缓存,再重新解析企业码和握手。
  5. 已登录 HTTP 请求的租户和用户只从 Token Principal 获取。请求体中的 tenant_id、user_id 不能覆盖身份。
  6. 跨租户对象统一返回 RESOURCE_NOT_FOUND 或 FORBIDDEN,不得暴露对象是否存在。

0.4 HTTP 请求与响应

成功响应统一为:


{
  "code": 0,
  "data": {},
  "request_id": "01K...",
  "server_time": "2026-08-11T08:30:15.123Z"
}

失败响应统一为:


{
  "code": 30001,
  "reason": "GROUP_MUTED",
  "message": "permission denied",
  "details": {},
  "request_id": "01K...",
  "server_time": "2026-08-11T08:30:15.123Z"
}

客户端只使用稳定的 reason 分支和本地化文案,不解析 message。ID、Topic、Seq 游标在客户端均按字符串处理;时间统一为 UTC RFC3339 毫秒。分页统一使用 limit 与不透明 cursor,返回 items、next_cursor、has_more。

0.5 WebSocket 建连、登录和恢复顺序

0.5.1 现有服务端可直接执行的冷启动流程


读取客户端预置的 host 和普通 API Key
-> 用户输入/客户端读取 tenant_code
-> 可选:POST /v1/im/tenants/resolve 校验企业码并取得公开配置
-> 带 API Key 完成 WebSocket Upgrade
-> hi(tenant_code)
-> 收到 hi 的 201 ctrl,确认 tenant 与服务端限制
-> 有历史 Token 时 token login,否则 basic login/acc
-> 收到 login 的 200 ctrl,保存 user/token/expires
-> sub(me) 拉取本人资料和会话订阅
-> sub(fnd) 建立搜索 Topic
-> 订阅需要在线的会话并按 seq 增量拉取
-> 进入可发送状态

当前服务端已提供 /v1/im/tenants/resolve,用于进入企业前校验企业码并返回公开配置;但它不能代替 WebSocket 第一帧 {hi}。即使 HTTP 解析成功,WebSocket Upgrade 返回 101 Switching Protocols 后仍必须先发送下面的 {hi} JSON 文本帧,并使用同一个 tenant_code 绑定当前 Session。

hi 请求:


{"hi":{"id":"hi-1","ver":"0.25","ua":"android/1.0.0","dev":"device-id","lang":"zh-CN","tenant":"acme"}}

login 请求使用 basic 或 token:


{"login":{"id":"login-1","scheme":"basic","secret":"base64(username:password)"}}

{"login":{"id":"login-2","scheme":"token","secret":"<上次登录响应原样返回的 token 字符串>"}}

basic.secret 是 base64(username + ":" + password)。Token 登录必须把上次 params.token 的 JSON 字符串原样填入 secret,不能再次 Base64 编码。登录成功 {ctrl} 的 params 至少包含 user、authlvl、token、expires。产品 HTTP 也使用同一个 params.token:Authorization: Bearer <params.token>,客户端不要解码或二次编码。Token 对客户端是不可解析的 opaque 字符串,只能存入系统安全存储。id 只用于匹配本次 Session 的命令响应,不是业务幂等键。

hi 成功示例:


{
  "ctrl": {
    "id": "hi-1",
    "code": 201,
    "text": "created",
    "params": {
      "ver": "0.25",
      "tenant": {"code": "acme", "name": "示例企业"},
      "maxFileUploadSize": 104857600,
      "callTimeout": 30,
      "iceServers": []
    }
  }
}

客户端只使用实际响应中存在的限制字段;未知字段忽略。hi 返回非 2xx 时必须关闭连接,不得继续发送 login。

登录成功后发送:


{"sub":{"id":"sub-me-1","topic":"me","get":{"what":"desc sub tags cred"}}}

客户端按相同 id 接收 {ctrl} 和一个或多个 {meta},从 meta.desc 取得本人资料和读写游标,从 meta.sub 取得会话 Topic、访问权限、seq/read/recv 与会话摘要。不要依赖 {ctrl}、{meta} 的固定先后顺序。

随后建立查找 Topic:


{"sub":{"id":"sub-fnd-1","topic":"fnd"}}

进入具体会话时订阅并增量拉取,since 使用客户端已完整持久化的最后 seq + 1:


{"sub":{"id":"sub-topic-1","topic":"grp...","get":{"what":"desc sub data del","data":{"since":125,"limit":50},"del":{"since":1,"limit":50}}}}

订阅成功后才允许 {pub}、note read/recv 等会话操作。断线恢复必须重新执行 WebSocket Upgrade -> hi -> token login -> sub me -> 恢复 Topic,同一连接内不得跳过 hi 或切换企业码。

0.5.2 Long Polling 兼容流程:先取得的是 sid

如果客户端无法使用 WebSocket,可以使用现有 /v0/channels/lp。该模式确实需要“先请求取得一个值”,但取得的是短期 Session ID sid,API Key 仍然必须由客户端预先持有。

第一步,创建 Long Polling Session:


POST /v0/channels/lp HTTP/1.1
Host: im.example.com
X-Tinode-APIKey: <预置的普通 API Key>
Content-Length: 0

服务端返回 HTTP 201:


{"ctrl":{"code":201,"text":"created","params":{"sid":"session-id"},"ts":"2026-08-11T08:30:15.123Z"}}

第二步开始,所有 Long Polling 请求都同时携带 API Key 和 sid。发送 hi:


POST /v0/channels/lp?sid=session-id HTTP/1.1
X-Tinode-APIKey: <预置的普通 API Key>
Content-Type: application/json

{"hi":{"id":"hi-1","ver":"0.25","ua":"android/1.0.0","platf":"android","lang":"zh-CN","tenant":"acme"}}

POST 只负责把命令送入 Session。客户端再保持一个不带 Body 的 GET 来接收下一条 {ctrl}、{meta}、{data}、{pres} 或 {info}:


GET /v0/channels/lp?sid=session-id HTTP/1.1
X-Tinode-APIKey: <预置的普通 API Key>

收到 hi 成功后,以相同方式 POST {login},再 GET 登录结果;登录成功后依次 POST {sub me}、{sub fnd} 和会话订阅,并持续发起下一次 GET 等待下行消息。

sid 无效或过期时服务端返回 HTTP 403 invalid or expired session,客户端必须重新创建 Long Polling Session 并从 hi 开始,不能只重发 login。Long Polling 是兼容方案,移动端和 Web 端正常网络条件下优先使用 WebSocket。

0.5.3 企业解析与产品流程

第 1.1 节的 POST /v1/im/tenants/resolve 已实现,推荐产品入口流程为:


读取预置 API Key
-> POST /v1/im/tenants/resolve 校验企业码并取得服务地址/品牌配置
-> 带同一 API Key 建立返回地址的 WebSocket
-> hi 再次绑定并校验 tenant_code
-> login -> sub me -> 恢复会话

企业解析接口只改善入口、服务发现和品牌配置,不能代替 {hi} 的租户绑定。即使 HTTP 解析成功,WebSocket 第一帧仍必须带相同 tenant_code。如果解析响应中的 endpoints 不符合当前发布环境,客户端应优先使用内置的公网环境配置,并上报脱敏诊断。

0.6 Topic 与产品消息

核心命令:sub 订阅、pub 发送、get 拉取、set 更新 Topic、leave 离开、del 删除、note 发送回执/临时状态。发送成功为 {ctrl code:202, params:{seq}},服务端下行消息为 {data}。

所有产品消息在 pub.head 中携带:


{
  "pub": {
    "id": "pub-1",
    "topic": "p2p...",
    "noecho": false,
    "head": {
      "x-im-schema": 1,
      "x-im-type": "text",
      "x-im-client-mid": "01K...",
      "mentions": []
    },
    "content": {"text":"你好"}
  }
}

x-im-client-mid 由客户端生成 ULID/UUID,作用域为“租户 + 发送人”,断线重试必须复用;服务端目标实现应返回第一次写入的同一 seq。未知 x-im-type 显示“暂不支持的消息”,不得崩溃或删除消息。

消息类型首版固定为:text、image、video、voice、file、contact_card、link、forward_bundle、call、system_event。自定义表情启用后追加 sticker。媒体内容只保存 file_id、文件元数据和缩略图 ID,不保存可长期绕过鉴权的公共 URL。

0.7 HTTP 幂等、重试和安全

  1. 创建、提交、同意、拒绝、删除、转让、收藏、转发等写请求必须携带 Idempotency-Key。
  2. GET、断线同步和同幂等键写请求可自动重试;密码、验证码和风控确认只按接口返回的 retry_after_seconds 重试。
  3. 401 TOKEN_EXPIRED 只允许一次静默刷新;刷新失败必须退出登录。403 不重试,429 按服务端退避。
  4. 服务端必须在最终写入前再次校验好友关系、群角色、禁言、消息归属、文件 ACL、租户配额和风控,不能信任前端按钮状态。
  5. 普通用户禁止向系统 Topic 发布;系统通知必须由服务端受控身份生成。

1. 账号注册、登录与身份安全

1.1 企业码登录.png

企业码登录
企业码登录

状态:企业解析接口与 WebSocket 租户握手均已实现。

当前系统的执行方式:

企业解析接口:

成功响应示例:


{
  "code": 0,
  "data": {
    "tenant": {"code": "acme", "name": "示例企业", "tenant_desc": null, "branding": {}},
    "endpoints": {
      "websocket": "wss://im.example.com/v0/channels",
      "api": "https://im.example.com/v1/im",
      "file": "https://im.example.com/v0/file"
    },
    "auth_methods": ["password", "sms"],
    "password_policy": {"min_length": 8, "max_length": 64},
    "app_update": {"type": "none"}
  },
  "request_id": "01K...",
  "server_time": "2026-08-11T08:30:15.123Z"
}

1.2 登录页面.png

登录页面
登录页面

状态:基本账号密码登录已实现;WS Token 可复用于产品 HTTP。

登录成功示例:


{
  "ctrl": {
    "id": "login-1",
    "code": 200,
    "text": "ok",
    "params": {
      "user": "usr...",
      "authlvl": "auth",
      "token": "base64-opaque-token",
      "expires": "2026-08-11T10:30:15.123Z"
    }
  }
}

失败仍是同一 {ctrl} 结构,使用 code 和改造后的稳定 params.reason 分支;客户端不得用 text 做程序判断。

1.3 登录页面-密码错误.png

登录页面-密码错误
登录页面-密码错误

状态:已实现基础错误,错误码和限流需改造。

1.4 注册页面.png

注册页面
注册页面

状态:Tinode {acc} 基础注册和验证码预校验已实现;短信供应商接入前固定测试码为 123456。


{"acc":{"id":"acc-1","user":"new","scheme":"basic","secret":"base64(+86138...:password)","login":true,"cred":[{"meth":"tel","val":"+86138...","resp":"verification_token","params":{"challenge_id":"challenge-id"}}],"desc":{"public":{"fn":"用户昵称"}}}}

1.5 注册页面-倒计时.png

注册页面-倒计时
注册页面-倒计时

状态:新增。

1.6 忘记密码.png

忘记密码
忘记密码

状态:新增。

1.7 身份验证(安卓).png

身份验证(安卓)
身份验证(安卓)

状态:新增。

1.8 实名认证.png

实名认证
实名认证

状态:新增。

1.9 实名认证-已实名.png

实名认证-已实名
实名认证-已实名

状态:新增。

1.10 实名认证(安卓).png

实名认证(安卓)
实名认证(安卓)

状态:新增。

1.11 设置独立密码(安卓).png

设置独立密码(安卓)
设置独立密码(安卓)

状态:新增。

2. 消息首页、全局导航与系统通知

2.1 消息.png

消息
消息

状态:会话订阅已实现;产品摘要和系统入口需改造。

2.2 消息-无网络状态.png

消息-无网络状态
消息-无网络状态

状态:需改造客户端恢复流程和消息幂等。

2.3 消息-更多.png

消息-更多
消息-更多

状态:菜单为纯客户端;权限数据新增。

2.4 消息页面—长按弹出.png

消息页面—长按弹出
消息页面—长按弹出

状态:基础消息操作部分已实现;产品权限矩阵需改造。

2.5 系统消息.png

系统消息
系统消息

状态:需改造。

3. 单聊会话、会话建立与消息状态

3.1 个人对话框(对方的状态).png

个人对话框(对方的状态)
个人对话框(对方的状态)

状态:需改造好友关系状态。

3.2 个人对话框(对方的状态)(1).png

!个人对话框(对方的状态)(1).png)

状态:在线状态已具备基础能力;关系文案新增。

3.3 个人对话框(我的状态).png

个人对话框(我的状态)
个人对话框(我的状态)

状态:新增好友申请状态。

3.4 个人对话框(我的状态)(1).png

!个人对话框(我的状态)(1).png)

状态:发送和读回执已实现基础能力;送达状态映射需统一。

3.5 开启沟通页面.png

开启沟通页面
开启沟通页面

状态:新增好友审批与 Topic 联动。

3.6 双方沟通状态.png

双方沟通状态
双方沟通状态

状态:上传基础已实现;媒体消息 Schema、ACL 和恢复需改造。

3.7 个人对话—拉黑状态/已读状态.png

个人对话—拉黑状态/已读状态
个人对话—拉黑状态/已读状态

状态:黑名单产品规则新增。

3.8 个人对话—删除状态.png

个人对话—删除状态
个人对话—删除状态

状态:新增好友删除后的发送约束。

3.9 个人对话-键盘收起状态.png

个人对话-键盘收起状态
个人对话-键盘收起状态

状态:纯客户端。

3.10 个人对话-发各种文件状态.png

个人对话-发各种文件状态
个人对话-发各种文件状态

状态:面板纯客户端;上传需改造。

3.11 个人对话-发各种文件状态(1).png

!个人对话-发各种文件状态(1).png)

状态:需改造产品消息 Schema。

3.12 个人对话-发送名片状态.png

个人对话-发送名片状态
个人对话-发送名片状态

状态:新增产品消息类型。

4. 消息输入、媒体内容与消息操作

4.1 键盘展开.png

键盘展开
键盘展开

状态:纯客户端。

4.2 @人员—选择提醒人.png

@人员—选择提醒人
@人员—选择提醒人

状态:新增群成员查询。

4.3 @人员—完成.png

@人员—完成
@人员—完成

状态:纯客户端选择;发送协议需改造。

4.4 @人员状态.png

@人员状态
@人员状态

状态:需改造提醒和 Push。

4.5 表情包展开(发送按钮默认状态).png

表情包展开(发送按钮默认状态)
表情包展开(发送按钮默认状态)

状态:纯客户端。

4.6 表情包发送页面.png

表情包发送页面
表情包发送页面

状态:Unicode 表情使用已实现文本消息;独立表情包新增。

4.7 语音—按住说话.png

语音—按住说话
语音—按住说话

状态:录音纯客户端;上传和语音消息需改造。

4.8 语音按住说话.png

语音按住说话
语音按住说话

状态:纯客户端。

4.9 内容沟通对话3-语音录音中.png

内容沟通对话3-语音录音中
内容沟通对话3-语音录音中

状态:录音纯客户端;临时状态可选改造。

4.10 内容沟通对话3-图片和语音发送中.png

内容沟通对话3-图片和语音发送中
内容沟通对话3-图片和语音发送中

状态:客户端任务管理新增;服务端上传需改造。

4.11 内容沟通对话3-语音/视频/图片状态.png

内容沟通对话3-语音/视频/图片状态
内容沟通对话3-语音/视频/图片状态

状态:需改造媒体 Schema 和受权下载。

4.12 语音图片发送状态.png

语音图片发送状态
语音图片发送状态

状态:需改造。

4.13 上传文件.png

上传文件
上传文件

状态:纯客户端视觉资源。

4.14 文件发送状态.png

文件发送状态
文件发送状态

状态:上传已实现基础能力;消息引用和 ACL 需改造。

4.15 多选-选中对话框.png

多选-选中对话框
多选-选中对话框

状态:选择纯客户端;批量动作新增。

4.16 多选-选中对话内容-收藏成功.png

多选-选中对话内容-收藏成功
多选-选中对话内容-收藏成功

状态:新增。

4.17 转发-单选.png

转发-单选
转发-单选

状态:新增。

4.18 转发-多选.png

转发-多选
转发-多选

状态:新增。

4.19 转发—逐条转发.png

转发—逐条转发
转发—逐条转发

状态:新增。

4.20 转发—合并转发—多选状态.png

转发—合并转发—多选状态
转发—合并转发—多选状态

状态:新增。

5. 通讯录、好友关系与黑名单

5.1 通讯录.png

通讯录
通讯录

状态:新增产品通讯录接口。

5.2 新朋友.png

新朋友
新朋友

状态:新增。

5.3 添加好友.png

添加好友
添加好友

状态:新增。

5.4 添加好友(1).png

!添加好友(1).png)

状态:新增。

5.5 添加好友-输入精准用户ID.png

添加好友-输入精准用户ID
添加好友-输入精准用户ID

状态:新增。

5.6 添加好友验证.png

添加好友验证
添加好友验证

状态:新增。

5.7 好友个人主页.png

好友个人主页
好友个人主页

状态:新增。

5.8 群聊—非好友个人主页.png

群聊—非好友个人主页
群聊—非好友个人主页

状态:新增。

5.9 好友—聊天设置—未拉黑状态.png

好友—聊天设置—未拉黑状态
好友—聊天设置—未拉黑状态

状态:部分 Topic 设置已实现;产品设置新增。

5.10 好友—聊天设置—拉黑状态.png

好友—聊天设置—拉黑状态
好友—聊天设置—拉黑状态

状态:新增。

5.11 删除好友提示.png

删除好友提示
删除好友提示

状态:确认框纯客户端;删除接口新增。

5.12 黑名单.png

黑名单
黑名单

状态:新增。

5.13 黑名单提示(1).png

!黑名单提示(1).png)

状态:确认框纯客户端;写接口新增。

5.14 黑名单提示.png

黑名单提示
黑名单提示

状态:图片文件名与画面语义不一致;按“清除聊天记录”实施,需改造。

6. 群聊创建、资料维护与成员治理

6.1 群聊.png

群聊
群聊

状态:Tinode 群 Topic 已实现基础能力;产品群列表与配额需改造。

6.2 空白页.png

空白页
空白页

状态:纯客户端。

6.3 加入群聊.png

加入群聊
加入群聊

状态:新增邀请卡片和加入接口。

6.4 内容沟通对话3-开启进群验证与拉人状态.png

内容沟通对话3-开启进群验证与拉人状态
内容沟通对话3-开启进群验证与拉人状态

状态:新增群成员事件。

6.5 邀请进群申请.png

邀请进群申请
邀请进群申请

状态:新增。

6.6 新邀请进群申请.png

新邀请进群申请
新邀请进群申请

状态:新增。

6.7 群公告状态.png

群公告状态
群公告状态

状态:新增。

6.8 群公告状态/邀请进群申请同时存在.png

群公告状态/邀请进群申请同时存在
群公告状态/邀请进群申请同时存在

状态:纯客户端组合;数据接口新增。

6.9 群公告(对方查看状态).png

群公告(对方查看状态)
群公告(对方查看状态)

状态:新增。

6.10 群聊设置.png

群聊设置
群聊设置

状态:部分订阅设置已实现;产品菜单新增。

6.11 群资料.png

群资料
群资料

状态:需改造。

6.12 设置群头像.png

设置群头像
设置群头像

状态:上传基础已实现;用途绑定需改造。

6.13 设置昵称(1).png

!设置昵称(1).png)

状态:新增。

6.14 群简介.png

群简介
群简介

状态:同 6.11,需改造。

6.15 群标识.png

群标识
群标识

状态:角色已有基础数据;产品渲染需统一。

6.16 群二维码页面.png

群二维码页面
群二维码页面

状态:新增。

6.17 群组管理.png

群组管理
群组管理

状态:新增。

6.18 设置群管理员.png

设置群管理员
设置群管理员

状态:新增。

6.19 添加管理员.png

添加管理员
添加管理员

状态:新增。

6.20 添加管理员-设置成功.png

添加管理员-设置成功
添加管理员-设置成功

状态:新增。

6.21 添加管理员-设置成功(1).png

!添加管理员-设置成功(1).png)

状态:新增。

6.22 删除管理员-设置成功.png

删除管理员-设置成功
删除管理员-设置成功

状态:新增。

6.23 添加禁言成员.png

添加禁言成员
添加禁言成员

状态:新增。

6.24 禁言的群成员.png

禁言的群成员
禁言的群成员

状态:新增。

6.25 选择新群主.png

选择新群主
选择新群主

状态:新增。

6.26 选择新群主提示.png

选择新群主提示
选择新群主提示

状态:新增。

6.27 群文件.png

群文件
群文件

状态:新增群文件索引;底层文件存储已实现。

6.28 群文件-上传状态.png

群文件-上传状态
群文件-上传状态

状态:需改造。

7. 文件下载、收藏管理与聊天记录检索

7.1 我的收藏.png

我的收藏
我的收藏

状态:新增。

7.2 我的收藏(1).png

!我的收藏(1).png)

状态:新增。

7.3 我的收藏-文件.png

我的收藏-文件
我的收藏-文件

状态:新增。

7.4 我的收藏-文本.png

我的收藏-文本
我的收藏-文本

状态:新增。

7.5 我的收藏-语音.png

我的收藏-语音
我的收藏-语音

状态:新增。

7.6 我的收藏—链接.png

我的收藏—链接
我的收藏—链接

状态:新增。

7.7 收藏—文件(多选).png

收藏—文件(多选)
收藏—文件(多选)

状态:新增。

7.8 收藏文件—分享给好友页面.png

收藏文件—分享给好友页面
收藏文件—分享给好友页面

状态:新增。

7.9 文件-下载.png

文件-下载
文件-下载

状态:底层下载已实现租户校验;资源 ACL 需改造。

7.10 文件-下载中.png

文件-下载中
文件-下载中

状态:客户端任务管理;服务端需支持 Range。

7.11 文件-下载完成.png

文件-下载完成
文件-下载完成

状态:纯客户端完成态。

7.12 查找聊天记录-搜索关键词选中状态(点击后跳出对应聊天内容).png

查找聊天记录-搜索关键词选中状态(点击后跳出对应聊天内容)
查找聊天记录-搜索关键词选中状态(点击后跳出对应聊天内容)

状态:新增服务端搜索。

7.13 查找聊天记录-文件.png

查找聊天记录-文件
查找聊天记录-文件

状态:新增。

7.14 查找聊天记录-链接.png

查找聊天记录-链接
查找聊天记录-链接

状态:新增。

7.15 查看聊天记录-图片.png

查看聊天记录-图片
查看聊天记录-图片

状态:新增。

7.16 查看聊天记录-视频.png

查看聊天记录-视频
查看聊天记录-视频

状态:新增。

8. 实时语音与视频通话

8.1 各种通话提示状态.png

各种通话提示状态
各种通话提示状态

状态:已实现基础通话记录替换;产品文案映射需统一。

8.2 对方状态.png

对方状态
对方状态

状态:在线邀请已实现;Push 与产品鉴权需改造。

8.3 语音通话-对方待接受状态.png

语音通话-对方待接受状态
语音通话-对方待接受状态

状态:发起与超时已实现基础;好友/拉黑/租户开关校验需改造。


{"pub":{"id":"call-1","topic":"p2p...","head":{"mime":"application/json","webrtc":"started","x-im-type":"call"},"content":{"callId":"01K...","callType":"audio","audio":true,"video":false}}}

8.4 语音通话-双方语音沟通中.png

语音通话-双方语音沟通中
语音通话-双方语音沟通中

状态:WebRTC 客户端能力;信令和服务端计时已实现。

8.5 语音通话-麦克风与扬声器已关.png

语音通话-麦克风与扬声器已关
语音通话-麦克风与扬声器已关

状态:纯客户端设备控制。

8.6 语音通话-麦克风与扬声器已开.png

语音通话-麦克风与扬声器已开
语音通话-麦克风与扬声器已开

状态:纯客户端设备控制。

8.7 视频通话—等待对方接受接受邀请中.png

视频通话—等待对方接受接受邀请中
视频通话—等待对方接受接受邀请中

状态:基础通话信令已实现;隐私约束需落实。

8.8 视频通话—等待对方接受接受邀请-摄像头关闭.png

视频通话—等待对方接受接受邀请-摄像头关闭
视频通话—等待对方接受接受邀请-摄像头关闭

状态:纯客户端状态;媒体状态事件需改造。

8.9 双方视频通话中.png

双方视频通话中
双方视频通话中

状态:WebRTC 客户端能力;服务端信令已具备基础。

8.10 双方视频通话中-对方关闭摄像头状态.png

双方视频通话中-对方关闭摄像头状态
双方视频通话中-对方关闭摄像头状态

状态:现阶段纯客户端;可选媒体状态事件需改造。

8.11 视频与语音通话悬浮状态中.png

视频与语音通话悬浮状态中
视频与语音通话悬浮状态中

状态:纯客户端。

9. 企业工作台与办公协同

9.1 工作台.png

工作台
工作台

状态:新增。

9.2 部门组织框架.png

部门组织框架
部门组织框架

状态:新增。

9.3 会议通知-发起人状态.png

会议通知-发起人状态
会议通知-发起人状态

状态:新增。

9.4 会议通知-接收人状态.png

会议通知-接收人状态
会议通知-接收人状态

状态:新增。

9.5 日报.png

日报
日报

状态:新增。

9.6 日报-普通用户页面.png

日报-普通用户页面
日报-普通用户页面

状态:新增。

9.7 日报-管理员页面.png

日报-管理员页面
日报-管理员页面

状态:新增。

9.8 日报-查看详情.png

日报-查看详情
日报-查看详情

状态:新增。

9.9 月报(1).png

!月报(1).png)

状态:新增。

9.10 月报.png

月报
月报

状态:新增。

9.11 月报-详情页.png

月报-详情页
月报-详情页

状态:新增。

9.12 总经理信箱.png

总经理信箱
总经理信箱

状态:新增。

9.13 总经理信箱-文案提示.png

总经理信箱-文案提示
总经理信箱-文案提示

状态:新增配置接口。

10. 个人资料、通用设置、隐私与青少年模式

10.1 我的.png

我的
我的

状态:基础用户资料已有;产品菜单新增。

10.2 个人信息.png

个人信息
个人信息

状态:Tinode me 资料更新已有基础;目标产品接口需改造。

10.3 设置昵称.png

设置昵称
设置昵称

状态:需改造。

10.4 出生日期.png

出生日期
出生日期

状态:新增产品字段。

10.5 个性签名.png

个性签名
个性签名

状态:需改造。

10.6 二维码.png

二维码
二维码

状态:图标纯客户端;二维码协议新增。

10.7 设置(iOS).png

设置(iOS)
设置(iOS)

状态:菜单纯客户端;数据接口部分新增。

10.8 设置(安卓).png

设置(安卓)
设置(安卓)

状态:菜单纯客户端;业务协议同 10.7。

10.9 清空缓存的提示.png

清空缓存的提示
清空缓存的提示

状态:纯客户端。

10.10 版本更新页面.png

版本更新页面
版本更新页面

状态:新增 App 配置接口。

10.11 发现新版本.png

发现新版本
发现新版本

状态:纯客户端弹窗;数据来自 10.10。

10.12 隐私设置.png

隐私设置
隐私设置

状态:新增。

10.13 隐私设置-添加我的方式选项.png

隐私设置-添加我的方式选项
隐私设置-添加我的方式选项

状态:新增。

10.14 青少年模式未开启(安卓).png

青少年模式未开启(安卓)
青少年模式未开启(安卓)

状态:新增。

10.15 青少年模式提示(安卓).png

青少年模式提示(安卓)
青少年模式提示(安卓)

状态:弹窗纯客户端;文案由服务端配置。

10.16 青少年模式已开启(安卓).png

青少年模式已开启(安卓)
青少年模式已开启(安卓)

状态:新增。

10.17 关闭青少年模式(安卓).png

关闭青少年模式(安卓)
关闭青少年模式(安卓)

状态:新增。

10.18 获取推送权限(安卓).png

获取推送权限(安卓)
获取推送权限(安卓)

状态:权限引导纯客户端;设备注册需改造。

10.19 提醒(安卓).png

提醒(安卓)
提醒(安卓)

状态:纯客户端。

10.20 相机说明(安卓).png

相机说明(安卓)
相机说明(安卓)

状态:纯客户端。

10.21 麦克风说明(安卓).png

麦克风说明(安卓)
麦克风说明(安卓)

状态:纯客户端。

11. 反诈安全、举报与意见反馈

11.1 反诈弹窗(安卓).png

反诈弹窗(安卓)
反诈弹窗(安卓)

状态:新增风控决策协议。

11.2 反诈弹窗(二次提示安卓).png

反诈弹窗(二次提示安卓)
反诈弹窗(二次提示安卓)

状态:新增。

11.3 举报.png

举报
举报

状态:新增。

11.4 举报(1).png

!举报(1).png)

状态:新增。

11.5 意见反馈.png

意见反馈
意见反馈

状态:新增。

12. 联调实施清单

12.1 当前可直接联调的基础能力

  1. WebSocket /v0/channels、Wire Version 0.25 和最低版本 0.20。
  2. 第一条 hi 携带企业码并固定 Session 租户;响应包含公开租户信息、限制、ICE 配置和呼叫超时。
  3. basic/token 登录,sub/get/set/pub/leave/del/note 基础 Tinode 协议。
  4. pub 成功返回 202 + seq,Topic 消息与基础回执同步。
  5. /v0/file/u/ 和 /v0/file/s/{file_id} 的基础上传下载及租户存储隔离。

12.2 必须优先完成的服务端阻塞项

优先级改造项阻塞图片章节
P0/v1/im 统一认证中间件、响应封装、幂等键、租户 Principal全部 HTTP 产品能力
P0企业码解析、验证码、密码重置、二次认证、Token auth_version 和刷新/撤销1.1~1.11、10.7~10.8
P0普通用户禁止发布系统 Topic;系统事件可信生产通道2.5、3.1~3.5、6.4、11.1
P0消息 x-im-schema/type/client-mid 校验和服务端幂等2~4 章
P0文件资源级 ACL、Range、ETag、用途绑定和租户存储配额3.6、4.10~4.14、6.27~7.16、11.4~11.5
P1好友申请、好友关系、黑名单状态机第 3、5 章
P1群成员、角色、禁言、公告、邀请审批和配额第 6 章
P1收藏、转发和聊天记录搜索第 4、7 章
P1通话媒体状态、结果消息、Push 来电第 8 章
P2工作台、组织、会议、日报、月报、信箱第 9 章
P2隐私、青少年模式、反诈、举报、反馈第 10、11 章

12.3 前后端联调最低验收用例

编号场景预期结果
T-01A 企业 Token 连接 B 企业 Session登录失败 TENANT_MISMATCH,不产生用户/Topic 数据
T-02企业停用后使用旧 Token 登录和请求 HTTPWS/HTTP 均拒绝,客户端清除凭证并回企业入口
T-03同 client_mid 断线重发同一消息只落一条消息并返回同一 seq
T-04相同 HTTP 幂等键、相同请求体重复提交返回第一次结果;不同请求体返回 IDEMPOTENCY_CONFLICT
T-05被拉黑或删除好友后绕过按钮直接 pub服务端拒绝,对方不收到消息
T-06普通用户构造 system_event 或向系统 Topic 发布服务端拒绝,系统消息页不展示可信样式
T-07普通群成员调用管理员、禁言、转让群主接口返回 FORBIDDEN,群状态不变且写安全审计
T-08群成员数已达租户配置上限时同意两个并发申请至多一个成功,成员数不超限
T-09非消息接收者持同租户 Token 下载文件返回 FILE_FORBIDDEN,不能只通过 file_id 下载
T-10文件下载中 Token 过期后刷新并 Range 续传文件完整、checksum 正确、不重复下载已完成分片
T-11风控二次确认后重复重放 risk token只有首次有效,其余返回 Token 已消费
T-12切换企业后查看缓存、上传任务、收藏和搜索不出现上一租户数据或任务

12.4 统一错误 reason

首版客户端至少实现:TENANT_UNAVAILABLE、TENANT_MISMATCH、AUTH_FAILED、TOKEN_EXPIRED、ACCOUNT_DISABLED、RATE_LIMITED、VALIDATION_FAILED、IDEMPOTENCY_CONFLICT、RESOURCE_NOT_FOUND、FORBIDDEN、FRIEND_RELATION_REQUIRED、MESSAGE_NOT_ALLOWED、GROUP_MUTED、GROUP_MEMBER_LIMIT_EXCEEDED、TENANT_USER_QUOTA_EXCEEDED、TENANT_GROUP_QUOTA_EXCEEDED、FILE_TOO_LARGE、FILE_FORBIDDEN、FILE_UNAVAILABLE、STORAGE_QUOTA_EXCEEDED、REALNAME_REQUIRED、YOUTH_MODE_RESTRICTED、RISK_CONFIRMATION_REQUIRED、RISK_ACTION_BLOCKED。

未知 reason 使用通用失败文案并记录 request_id,不得把服务端 message 原样展示给用户。

12.5 完成定义

每个图片小节进入联调前,服务端须提供 OpenAPI/JSON Schema、错误码、权限规则和可用测试租户;前端须提供请求日志脱敏、断线/重试行为和四态页面(加载、空、成功、失败)。联调完成必须逐图勾选对应协议、至少覆盖成功、权限拒绝、重复提交、断网恢复和跨租户五类场景。