超级群频道与用户组
超级群(groupType=super;rev22 起会话类型 SUPER_GROUP(10),存量 GROUP(2)+super 仍可读)的频道与用户组:频道创建/查询/加入/退出,用户组增查与频道绑定,用于按主题或组织维度组织成员;消息按超级群会话收发(无 channelId 隔离)。
rev22 起超级群会话类型为 SUPER_GROUP(10);存量 GROUP(2)+groupType=super 仍可读,两者共用同一群会话键(g:{groupId})。
rev23 起消息可带 options.channelId 按频道投递(仅频道成员接收、历史可按频道过滤);不带 channelId 为群级消息。频道/用户组管理接口仍按 groupId 工作。
完整用法与兼容规则:超级群会话类型、超级群频道级消息、频道消息迁移、迁移与兼容 FAQ。
双语言同契约:Swift 用 async -> RcResult<T>(错误码在 RcResult.code,返回 null 的 op 用 RcResult<Void>);Objective-C 用 - (void)opWithParam:... completion:(void (^)(RcResult *))completion,回调在主线程投递。
接口一览
| 操作 | 语义 | 传输 | 返回 |
|---|---|---|---|
createSupergroupChannel | 创建超级群频道(IDL rev21 C17;客户端 REST `POST /api/apps/{appkey}/supergroup/channels`)→ SupergroupChannel。channelId 服务端生成(`ch_<uuid>`,应用内唯一);joinPolicy 由 type 推导(public→open、private→invite),与之矛盾的显式取值 1001;仅群主/管理员可调用(否则 1003),群不存在 1005,单群 100 频道上限(超限 1015)。与 Open API `supergroup.channel.create` 共享状态。 | REST(客户端) | SupergroupChannel |
listSupergroupChannels | 超级群频道列表(IDL rev21 C17;客户端 REST `GET /api/apps/{appkey}/supergroup/channels?groupId=`)→ `{groupId,channels:[SupergroupChannel],total}`。仅群成员可读(否则 1003),群不存在 1005,缺 groupId 1001。 | REST(客户端) | {groupId:string, channels:SupergroupChannel[], total:uint32} |
joinSupergroupChannel | 加入超级群频道(IDL rev21 C17;客户端 REST `POST .../supergroup/channels/{channelId}/join`,幂等)→ `{groupId,channelId,userId,joined:true,alreadyJoined}`。public 频道群成员可直接加入;private 频道需已受邀或为群主/管理员(否则 1003)。频道不存在 1005;channelId 跨群同名时可通过第二参数 `{groupId}` 消歧(未消歧 1001);非群成员 1003。 | REST(客户端) | {groupId:string, channelId:string, userId:string, joined:bool, alreadyJoined:bool} |
leaveSupergroupChannel | 离开超级群频道(IDL rev21 C17;客户端 REST `POST .../supergroup/channels/{channelId}/leave`,幂等)→ `{groupId,channelId,userId,left:true,wasMember}`;不在频道内也返回成功(wasMember=false)。频道不存在 1005、非群成员 1003。 | REST(客户端) | {groupId:string, channelId:string, userId:string, left:bool, wasMember:bool} |
bindUserGroupToChannel | 把用户组绑定到频道(IDL rev21 C17;客户端 REST `POST .../supergroup/channels/{channelId}/usergroups`,幂等)→ `{groupId,channelId,userGroupId,bound:true,reverseIndexed}`。**双向维护** SupergroupChannel.userGroupIds 与 UserGroup.channelIds(rev21 修复 rev7 仅写频道侧导致的反向索引缺失),因此 `listUserGroups`/`getUserGroupsByUser` 的 channelIds 反查可用。仅群主/管理员(否则 1003);频道/用户组不存在 1005。 | REST(客户端) | {groupId:string, channelId:string, userGroupId:string, bound:bool, reverseIndexed:bool} |
createUserGroup | 创建超级群用户组(IDL rev21 C17;客户端 REST `POST /api/apps/{appkey}/supergroup/usergroups`)→ UserGroup。userGroupId 服务端生成(`ug_<uuid>`);members 去空/去重/保序,每项必须是本群成员(否则 1003)、用户不存在 1004;仅群主/管理员(否则 1003);参数非法 1001、单群 100 用户组上限(超限 1015)。与 Open API `supergroup.usergroup.*` 共享状态。 | REST(客户端) | UserGroup |
listUserGroups | 超级群用户组列表(IDL rev21 C17;客户端 REST `GET /api/apps/{appkey}/supergroup/usergroups?groupId=`)→ `{groupId,userGroups:[UserGroup],total}`;UserGroup.channelIds 为频道反向索引(rev21 修复后可用)。仅群成员可读(否则 1003),群不存在 1005,缺 groupId 1001。 | REST(客户端) | {groupId:string, userGroups:UserGroup[], total:uint32} |
getUserGroupsByUser | 查询某用户所在的所有用户组(IDL rev21 C17;客户端 REST `GET .../supergroup/usergroups/by-user/{userId}`)→ `{userId,userGroups:[UserGroup],total}`。仅本人可查(userId ≠ 当前登录用户 1003);`options.groupId` 可限定单个群;只返回「本人确实在该群」的用户组(群已删除的不返回,不虚构)。 | REST(客户端) | {userId:string, userGroups:UserGroup[], total:uint32} |
本页 8 个操作,其中 8 个在本平台绑定中声明了方法签名。
跨端方法名
| 操作 | Android | Web | Electron | macOS | Flutter | Native (C ABI) | iOS |
|---|---|---|---|---|---|---|---|
createSupergroupChannel | createSupergroupChannel | createSupergroupChannel | createSupergroupChannel | createSupergroupChannel | createSupergroupChannel | — | func |
listSupergroupChannels | listSupergroupChannels | listSupergroupChannels | listSupergroupChannels | listSupergroupChannels | listSupergroupChannels | — | func |
joinSupergroupChannel | joinSupergroupChannel | joinSupergroupChannel | joinSupergroupChannel | joinSupergroupChannel | joinSupergroupChannel | — | func |
leaveSupergroupChannel | leaveSupergroupChannel | leaveSupergroupChannel | leaveSupergroupChannel | leaveSupergroupChannel | leaveSupergroupChannel | — | func |
bindUserGroupToChannel | bindUserGroupToChannel | bindUserGroupToChannel | bindUserGroupToChannel | bindUserGroupToChannel | bindUserGroupToChannel | — | func |
createUserGroup | createUserGroup | createUserGroup | createUserGroup | createUserGroup | createUserGroup | — | func |
listUserGroups | listUserGroups | listUserGroups | listUserGroups | listUserGroups | listUserGroups | — | func |
getUserGroupsByUser | getUserGroupsByUser | getUserGroupsByUser | getUserGroupsByUser | getUserGroupsByUser | getUserGroupsByUser | — | func |
方法名在 GA 平台之间保持一致(规则 A);Native C ABI 只覆盖部分操作,其余操作以 — 标注。
createSupergroupChannel
创建超级群频道(IDL rev21 C17;客户端 REST `POST /api/apps/{appkey}/supergroup/channels`)→ SupergroupChannel。channelId 服务端生成(`ch_
func createSupergroupChannel(params: IMPCreateSupergroupChannelParams) async -> RcResult<IMPSupergroupChannel>| 参数 | 类型 | 说明 |
|---|---|---|
params | {groupId:string, name:string, type:ChannelType, joinPolicy?:JoinPolicy} | 必填;对象:{ groupId:string, name:string, type:ChannelType, joinPolicy?:JoinPolicy } |
SupergroupChannel 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let res = await client.createSupergroupChannel(params: IMPCreateSupergroupChannelParams(groupId: "g_1001", name: "产品群", type: .public, joinPolicy: nil))
if res.code != 0 { print(res.msg ?? "") }[client createSupergroupChannelWithParams:@{ @"groupId": @"g_1001", @"name": @"产品群", @"type": @"public", @"joinPolicy": @"open" } completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
1005 | GROUP_NOT_FOUND | 客户端 / 参数 / 权限 | 404 | 否 | 群组不存在 |
1015 | MEMBERSHIP_LIMIT | 客户端 / 参数 / 权限 | 400 | 否 | 成员数量超出上限 |
listSupergroupChannels
超级群频道列表(IDL rev21 C17;客户端 REST `GET /api/apps/{appkey}/supergroup/channels?groupId=`)→ `{groupId,channels:[SupergroupChannel],total}`。仅群成员可读(否则 1003),群不存在 1005,缺 groupId 1001。
func listSupergroupChannels(groupId: String) async -> RcResult<IMPSupergroupChannelListResult>| 参数 | 类型 | 说明 |
|---|---|---|
groupId | string | 必填;群组 ID |
{groupId:string, channels:SupergroupChannel[], total:uint32} 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let channels = await client.listSupergroupChannels(groupId: "g_1001")
print(channels.code)[client listSupergroupChannelsWithGroupId:@"g_1001" completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
1005 | GROUP_NOT_FOUND | 客户端 / 参数 / 权限 | 404 | 否 | 群组不存在 |
joinSupergroupChannel
加入超级群频道(IDL rev21 C17;客户端 REST `POST .../supergroup/channels/{channelId}/join`,幂等)→ `{groupId,channelId,userId,joined:true,alreadyJoined}`。public 频道群成员可直接加入;private 频道需已受邀或为群主/管理员(否则 1003)。频道不存在 1005;channelId 跨群同名时可通过第二参数 `{groupId}` 消歧(未消歧 1001);非群成员 1003。
func joinSupergroupChannel(channelId: String, options: IMPSupergroupChannelOptions?) async -> RcResult<IMPJoinSupergroupChannelResult>| 参数 | 类型 | 说明 |
|---|---|---|
channelId | string | 必填;字段含义见类型定义 |
options | {groupId?:string} | 可选;选项对象(字段见类型列):{ groupId?:string } |
{groupId:string, channelId:string, userId:string, joined:bool, alreadyJoined:bool} 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let joined = await client.joinSupergroupChannel(channelId: "ch_1001", options: nil)
print(joined.code)[client joinSupergroupChannelWithChannelId:@"ch_1001" options:nil completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
1005 | GROUP_NOT_FOUND | 客户端 / 参数 / 权限 | 404 | 否 | 群组不存在 |
leaveSupergroupChannel
离开超级群频道(IDL rev21 C17;客户端 REST `POST .../supergroup/channels/{channelId}/leave`,幂等)→ `{groupId,channelId,userId,left:true,wasMember}`;不在频道内也返回成功(wasMember=false)。频道不存在 1005、非群成员 1003。
func leaveSupergroupChannel(channelId: String, options: IMPSupergroupChannelOptions?) async -> RcResult<IMPLeaveSupergroupChannelResult>| 参数 | 类型 | 说明 |
|---|---|---|
channelId | string | 必填;字段含义见类型定义 |
options | {groupId?:string} | 可选;选项对象(字段见类型列):{ groupId?:string } |
{groupId:string, channelId:string, userId:string, left:bool, wasMember:bool} 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let left = await client.leaveSupergroupChannel(channelId: "ch_1001", options: nil)
print(left.code)[client leaveSupergroupChannelWithChannelId:@"ch_1001" options:nil completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
1005 | GROUP_NOT_FOUND | 客户端 / 参数 / 权限 | 404 | 否 | 群组不存在 |
bindUserGroupToChannel
把用户组绑定到频道(IDL rev21 C17;客户端 REST `POST .../supergroup/channels/{channelId}/usergroups`,幂等)→ `{groupId,channelId,userGroupId,bound:true,reverseIndexed}`。**双向维护** SupergroupChannel.userGroupIds 与 UserGroup.channelIds(rev21 修复 rev7 仅写频道侧导致的反向索引缺失),因此 `listUserGroups`/`getUserGroupsByUser` 的 channelIds 反查可用。仅群主/管理员(否则 1003);频道/用户组不存在 1005。
func bindUserGroupToChannel(channelId: String, userGroupId: String, options: IMPSupergroupChannelOptions?) async -> RcResult<IMPBindUserGroupToChannelResult>| 参数 | 类型 | 说明 |
|---|---|---|
channelId | string | 必填;字段含义见类型定义 |
userGroupId | string | 必填;字段含义见类型定义 |
options | {groupId?:string} | 可选;选项对象(字段见类型列):{ groupId?:string } |
{groupId:string, channelId:string, userGroupId:string, bound:bool, reverseIndexed:bool} 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let bound = await client.bindUserGroupToChannel(channelId: "ch_1001", userGroupId: "ug_1001", options: nil)
print(bound.code)[client bindUserGroupToChannelWithChannelId:@"ch_1001" userGroupId:@"ug_1001" options:nil completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
1005 | GROUP_NOT_FOUND | 客户端 / 参数 / 权限 | 404 | 否 | 群组不存在 |
createUserGroup
创建超级群用户组(IDL rev21 C17;客户端 REST `POST /api/apps/{appkey}/supergroup/usergroups`)→ UserGroup。userGroupId 服务端生成(`ug_
func createUserGroup(params: IMPCreateUserGroupParams) async -> RcResult<IMPUserGroup>| 参数 | 类型 | 说明 |
|---|---|---|
params | {groupId:string, name:string, members?:string[]} | 必填;对象:{ groupId:string, name:string, members?:string[] } |
UserGroup 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let group = await client.createUserGroup(params: IMPCreateUserGroupParams(groupId: "g_1001", name: "产品组"))
print(group.code)[client createUserGroupWithParams:@{ @"groupId": @"g_1001", @"name": @"产品群", @"members": @[@"user2"] } completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
1004 | USER_NOT_FOUND | 客户端 / 参数 / 权限 | 404 | 否 | 用户不存在 |
1015 | MEMBERSHIP_LIMIT | 客户端 / 参数 / 权限 | 400 | 否 | 成员数量超出上限 |
listUserGroups
超级群用户组列表(IDL rev21 C17;客户端 REST `GET /api/apps/{appkey}/supergroup/usergroups?groupId=`)→ `{groupId,userGroups:[UserGroup],total}`;UserGroup.channelIds 为频道反向索引(rev21 修复后可用)。仅群成员可读(否则 1003),群不存在 1005,缺 groupId 1001。
func listUserGroups(groupId: String) async -> RcResult<IMPUserGroupListResult>| 参数 | 类型 | 说明 |
|---|---|---|
groupId | string | 必填;群组 ID |
{groupId:string, userGroups:UserGroup[], total:uint32} 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let groups = await client.listUserGroups(groupId: "g_1001")
print(groups.code)[client listUserGroupsWithGroupId:@"g_1001" completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
1005 | GROUP_NOT_FOUND | 客户端 / 参数 / 权限 | 404 | 否 | 群组不存在 |
getUserGroupsByUser
查询某用户所在的所有用户组(IDL rev21 C17;客户端 REST `GET .../supergroup/usergroups/by-user/{userId}`)→ `{userId,userGroups:[UserGroup],total}`。仅本人可查(userId ≠ 当前登录用户 1003);`options.groupId` 可限定单个群;只返回「本人确实在该群」的用户组(群已删除的不返回,不虚构)。
func getUserGroupsByUser(userId: String, options: IMPSupergroupChannelOptions?) async -> RcResult<IMPUserGroupListResult>| 参数 | 类型 | 说明 |
|---|---|---|
userId | string | 必填;用户 ID |
options | {groupId?:string} | 可选;选项对象(字段见类型列):{ groupId?:string } |
{userId:string, userGroups:UserGroup[], total:uint32} 成功返回的数据;失败时按错误码处理
示例(Swift / Objective-C)
let byUser = await client.getUserGroupsByUser(userId: "user2", options: nil)
print(byUser.code)[client getUserGroupsByUserWithUserId:@"user2" options:nil completion:^(IMPOSResult *result) {
if (result.code != 0) { NSLog(@"IM 调用失败:%ld %@", (long)result.code, result.msg); }
}];| 错误码 | 名称 | 分类 | HTTP | 可重试 | 说明 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 / 参数 / 权限 | 400 | 否 | 参数错误 |
1002 | INVALID_TOKEN | 客户端 / 参数 / 权限 | 401 | 否 | Token 无效或已过期 |
1003 | FORBIDDEN | 客户端 / 参数 / 权限 | 403 | 否 | 无权限 |
相关文档
- 功能列表:103 个操作与签名
- 状态码:错误码与重试策略
- API 参考:类与成员
- IMLib 集成指南