超级群频道消息迁移
rev23 之前,超级群消息只有“群级”一种:所有消息按 groupId 投递给全体群成员,频道只是组织单元。rev23 增加 channelId 后,新消息可以选择频道级路由。本页给出从 rev22 群级消息迁移到 rev23 频道消息的步骤、兼容规则与回滚方案。
一句话结论
存量消息不需要迁移:没有 channelId 的消息永远按群级处理。
新消息按需带上 channelId;未升级的客户端/服务端继续使用群级发送,两者可以并存。
回滚只需回退客户端(停止传 channelId);服务端无需数据迁移。
前后对比
| 维度 | rev22(群级消息) | rev23(新增频道消息) |
|---|---|---|
| 发送参数 | sendMessage(10, groupId, content) | sendMessage(10, groupId, content, { channelId }) |
| 消息体 | 无 channelId 字段 | 频道消息带 channelId;群级消息不变 |
| 收件人 | 全体群成员 | 频道有效成员(私有频道)/ 频道成员(公开频道发送自动加入) |
| 历史 | 群历史不分频道 | channelId 可过滤;不带则返回群级 + 可见频道消息 |
| 未读/回执 | 群成员维度 | 仍是群会话,但只对频道成员计未读;回执 totalMembers 取频道成员数 |
| 回调 | 载荷无 channelId | 频道消息回调载荷带 channelId |
| 兼容性 | — | additive:旧消息/旧客户端不受影响 |
兼容矩阵
| 数据 / 客户端组合 | 行为 | 建议 |
|---|---|---|
| 存量消息(无 channelId)+ 任意客户端 | 按群级消息展示与统计 | 无需处理 |
| 新频道消息 + 已升级客户端 | 按频道视图展示(IMKit channelId / 自绘过滤) | 推荐目标状态 |
| 新频道消息 + 未升级客户端 | 未知字段被忽略,消息出现在群会话中(等于群级展示) | 升级前不要把私有频道消息当敏感隔离手段 |
| 群级消息 + 任意客户端 | 保持 rev22 行为 | — |
| 未升级服务端 + 带 channelId 的请求 | 旧服务端可能忽略/拒绝该字段 | 先升级服务端再发频道消息 |
迁移步骤
- 升级服务端到包含 rev23 的版本(校验频道归属/成员;历史按频道过滤;回调带 channelId)。
- 升级各端 SDK 到包含 rev23 的版本(Web/Android/Flutter/Electron 的
options.channelId与Message.channelId)。 - 客户端读取路径先兼容:渲染时按
message.channelId区分频道视图与群级视图;无字段按群级展示。 - 写入路径按业务灰度:先让试点频道(如公告/值班频道)发送带 channelId 的消息,再逐步扩大。
- IMKit 升级到支持
channelId的版本(Web ChatView / Android ConversationIdentifier / Flutter ChatView),或自绘频道视图并手动传参。 - 回调/报表按“有 channelId 计入频道,无 channelId 计入群级”双维度统计,避免迁移期口径断层。
- 回滚:客户端停止传
channelId即可回到 rev22 行为;已写入的频道消息仍可读(按频道历史或群历史可见性规则)。
历史与展示兼容
| 场景 | 表现 | 处理建议 |
|---|---|---|
| 群级历史视图(不带 channelId) | 返回群级消息 + 调用者可见的频道消息 | 按 message.channelId 分组渲染(有值归入频道,无值归入群) |
| 频道历史视图(带 channelId) | 只返回该频道消息 | 分页 beforeSeq 仍按会话 seq 向前翻 |
| 旧客户端打开群会话 | 频道消息混在群消息里(等于群级) | 尽快升级;或在业务层隐藏频道消息标记 |
| 撤回/已读事件 | 只广播给频道成员(rev23) | 未升级客户端可能收不到频道消息的撤回/回执事件 |
常见坑
| 现象 | 原因 | 处理 |
|---|---|---|
| 发送返回 1001 | 非 conversationType=10 传了 channelId;或普通群(groupType=normal)走 Open API 带 channelId | 只有超级群会话(10)支持 channelId |
| 发送返回 1003 | 私有频道发送者不是频道成员 | 先加入频道(或使用用户组绑定),再发送 |
| 发送返回 1005 | channelId 不属于该群或已删除 | 用频道列表接口确认 groupId + channelId |
| 历史里“缺”频道消息 | 不带 channelId 只返回调用者可见消息;私有频道未加入则不返回 | 按频道视图查询,或先加入频道 |
| 未读数为 0 / 回执总人数不对 | 频道消息只对频道成员计未读,totalMembers 取频道成员数 | 以频道成员数为分母展示已读进度 |
| 旧客户端看不到频道消息 | 旧客户端未升级,忽略 channelId 字段但可读消息 | 升级客户端;或临时用群级发送 |
迁移检查清单
- 服务端 rev23 已上线;客户端 SDK 版本含
options.channelId与Message.channelId。 - 读取路径对“有/无 channelId”都正确渲染;无字段时按群级处理。
- 私有频道的发送/读取权限由服务端强制(1003),业务侧不要仅依赖前端校验。
- 回调消费方按
channelId归档;无该字段的消息仍按群级归档。 - 统计口径:频道消息 = 带 channelId;群级消息 = 不带 channelId;存量消息全部计入群级。
- IMKit 已升级或已实现自绘频道视图;频道选择器/成员页由宿主提供。
- 灰度与回滚演练:停止传 channelId 后行为回到 rev22,存量频道消息仍可读。
相关链接
- 超级群频道级消息:发送/接收/历史/回调规则
- 超级群会话类型(rev22)
- 超级群类型迁移与兼容 FAQ
- 频道操作指南
- Message 数据结构