超级群频道级消息

rev23 起,超级群消息可以携带 channelId:带频道 ID 的消息按频道路由,只投递给频道成员,历史按频道过滤;不带频道 ID 的消息仍是群级消息,沿用 rev22 语义。本页说明发送/接收/历史规则、频道成员口径、回调与 IMKit 状态、错误码与限制。

版本与兼容(additive-only)

契约:Message.channelId?(since 1.6.0)、sendMessage.options.channelId?、getHistoryMessages.options.channelId?;协议口径:conversationType=10 且带 channelId 时按频道路由:仅频道成员接收、历史按 channelId 过滤、频道须属于该群;channelId 为空表示群级消息。private 频道发送者须为频道成员,public 频道群成员可发送并自动加入。

兼容:channelId 为空或空白 = 群级消息(消息体不出现该字段),存量 rev22 群级消息/历史保持不变;旧客户端忽略未知字段即可继续工作。

核心概念​

概念定义说明
群级消息不带 channelId 的超级群消息收件人 = 群成员;历史/未读/回执同 rev22
频道消息带 channelId 的超级群消息收件人 = 该频道有效成员;历史按频道过滤;消息体带 channelId
频道有效成员ChannelState.user_ids ∪ 绑定用户组成员,且仍是群成员被移出群后立即失去频道接收资格;用户组绑定实时生效
私有频道(private)发送者必须是频道有效成员非成员发送 → 1003;历史读取同样要求成员
公有频道(public)群成员可发送,发送时自动加入频道自动加入写入频道成员表;历史对群成员可读
频道归属频道必须属于该群频道不存在或属于其它群 → 1005

发送规则​

条件服务端行为错误码
conversationType=10 + channelId按频道校验 + 路由(本页语义)见下
conversationType 非 10(1/2/3/4)且带 channelId拒绝:频道只能用于超级群会话1001
channelId 为空/空白按群级消息发送(消息体不写入 channelId)—
频道不存在 / 不属于该群拒绝:频道必须属于目标群1005
私有频道 + 发送者非频道成员拒绝:私有频道只允许成员发送1003
公有频道 + 发送者是群成员但未在频道自动把发送者加入频道,再按频道成员投递—
发送者不是群成员拒绝:群成员校验先于频道校验1006
群全员禁言 / 成员禁言与群级消息相同的禁言规则1006 等

clientMsgId 幂等、内容大小(≤5KB)、敏感词/审核、@提及校验等与群级消息一致;频道过滤只改变收件人与历史可见范围。

接收、未读与回执​

能力频道消息行为备注
在线投递只推送给频道有效成员的长连接群内非频道成员不会实时收到
离线补收私有频道只补收给频道成员;公有频道消息对群成员可见补收按消息可见性过滤
会话与未读仍是群会话(conversationType=10 + groupId);只对频道成员计未读不产生独立“频道会话”行;会话 lastMessage.channelId 标识最近消息频道
已读回执totalMembers = 频道有效成员数;非成员回执不记账群级消息仍按群成员数
撤回 / 扩展 / 回应 / 流式广播范围收窄到频道成员不向群内非成员泄露频道消息
typing(输入状态)未按频道收窄:frame 没有 channelId 字段,仍是群级 typing已知限制,见下
消息搜索Open API/后台搜索按频道可见性过滤;客户端 searchMessages 暂未裁剪已知限制:私有频道内容不要依赖搜索隔离
频道列表按调用者过滤:private 频道仅成员/群主/管理员可见(rev24)见「私有频道列表可见性」

历史消息​

调用方式返回错误码
getHistoryMessages(10, groupId, { channelId })只返回该频道的消息私有频道非成员 → 1003;频道不存在/跨群 → 1005;非 10 类型 → 1001
getHistoryMessages(10, groupId)群级消息 + 调用者可见的频道消息(私有频道未加入的消息不返回)群成员校验(1006 等)
Open API message.history.get + channelId同上;带 userId 时按该用户可见性裁剪无 userId(管理端)只校验频道存在,不做可见性裁剪
存量 rev22 历史(无 channelId)视为群级消息,照常返回—

回调与外部集成​

通道channelId 行为
服务端回调(22 类)消息类回调载荷新增 channelId(仅频道消息出现;群级消息不带该字段)
机器人 / 集成回调频道消息只路由给频道内的机器人;载荷带 channelId,channelType 仍按会话类型映射
Open API message.group.publish请求体可带 channelId:超级群按频道投递;普通群带 channelId → 1001
客户端 REST 发送 / 管理端发送请求体 channelId 透传,同一套校验

IMKit 支持状态​

端IMKit 频道能力用法
WebChatView 支持 channelId(发送/历史/事件按频道收窄);rev24 提供 ChannelSwitcher(ChatView 的 showChannelSwitcher)`new ChatView({ lib, conversationType: 10, targetId, channelId, showChannelSwitcher: true })`
AndroidConversationIdentifier 支持 channelId;ChatActivity 支持 EXTRA_CHANNEL_ID;rev24 提供 ChannelListDialog + ChatFragment 频道栏`IMKit.routeToConversation(context, ConversationIdentifier(SUPER_GROUP, groupId, title, channelId))`
FlutterChatView/ChatController 支持 channelId,只渲染该频道消息;rev24 提供 ChannelList/ChannelSwitcher(SUPER_GROUP 下自动挂载)`ChatView(channelId: "ch_news", ...)`
Electron无独立 IMKit 组件;rev24 Demo 复用 Web ChannelSwitcher用 IMLib + Web 组件自绘;发送/历史传 channelId

频道 UI 组件(props/事件/主题/平台差异)见 超级群频道 UI 组件;这些是 SDK 运行时组件,不在 sdk-imkit.json 契约组件列表中。

错误码​

错误码名称含义可重试
1001INVALID_PARAMETER参数错误否
1002INVALID_TOKENToken 无效或已过期否
1003FORBIDDEN无权限否
1005GROUP_NOT_FOUND群组不存在否
1006NOT_GROUP_MEMBER未加入群组否
1015MEMBERSHIP_LIMIT成员数量超出上限否
1016USER_BANNED账号已被封禁否

限制(如实记录)​

限制说明
不产生独立频道会话会话维度仍是群会话(10 + groupId);频道只是消息路由/可见性维度,未读与回执按群会话聚合
typing 未按频道收窄输入状态 frame 没有 channelId 字段,仍是群级广播
客户端搜索未裁剪searchMessages(REST /messages/search)当前不按频道可见性过滤;私有频道不要存放依赖搜索隔离的敏感内容(Open API 搜索已过滤)
@提及校验按群成员被 @ 的用户需是群成员;频道成员关系不作为 @ 校验条件
频道级免打扰/未读角标未拆分免打扰与角标仍在群会话维度
IMKit 频道选择器/成员管理页未提供需要宿主自建频道列表/成员页;IMKit 只支持单频道会话视图
存量消息无 channelIdrev22 及更早的群级消息永远按群级处理,不会被“追认”到频道

相关链接​