Windows/macOS

群组管理

更新时间: 2024/03/12 11:23:21

网易云信 NIM SDK 提供了高级群形式的群组功能,支持用户创建、加入、退出、转让、修改、查询、解散群组,拥有完善的管理功能。

技术原理

网易云信 NIM SDK 的群组相关 API 都挂载在 nim::Team 模块中, nim::Team 提供群组操作相关接口,帮助您快速实现和使用群组的管理功能。

群组相关事件监听

在进行群组操作前,您可以提前注册监听群相关事件。监听后,在进行群组管理相关操作时,会收到对应的通知。

可以使用回调模板(OnTeamEventCallback)并调用 RegTeamEventCb 方法来监听群组事件通知。

其中群组事件的详细信息请参见 TeamEvent

示例代码:

void OnTeamEventCallback(const nim::TeamEvent& result)
{
	···
}

foo()
{
	nim::Team::RegTeamEventCb(&OnTeamEventCallback);
}

对于部分查询接口,有单独的回调模板,具体请参见nim::Team

  • 由于获取群组信息和群成员信息需要跨进程异步调用,开发者最好能在第三方 APP 中做好群组和群成员信息缓存,查询群组和群成员信息时都从本地缓存中访问。在群组或者群成员信息有变化时,SDK 会告诉注册的观察者,此时,第三方 APP 可更新缓存,并刷新界面。
  • SDK 在收到群通知之后,会对本地缓存的群信息做出对应的修改,然后触发与修改相对应的监听事件回调。
  • 群通知是接收型的消息,开发者无法手动创建和发送群通知消息。

实现流程

本章节通过群主、管理员、普通成员之间的交互为例,介绍群组管理的实现流程。

uml diagram

创建群组

  • 创建群组时邀请的用户会收到类型为 kNIMSysMsgTypeTeamInvite 的系统通知(NIMSysMsgType)。
  • 若被邀请模式(NIMTeamBeInviteMode)为需要验证(kNIMTeamBeInviteModeNeedAgree),那么创建群组后,需要用户接受邀请,才会成为群成员。

通过调用 CreateTeamAsyncEx 方法创建群组,创建者即为该群群主。

原创建群接口CreateTeamAsync已废弃。

参数说明:

参数 说明
team_info 群组信息,请参见TeamInfo 群组类型默认为 kNIMTeamTypeAdvanced 创建高级群,高级群拥有完善的成员权限体系及管理功能。为避免产生问题,不建议使用其他取值。
invitation_postscript 邀请入群的附言
ids 邀请加入的成员帐号列表
json_extension json扩展参数
目前可用于配置反垃圾相关参数
格式{"anti_spam_business_id":"{"textbid":"xxxx","picbid":"xxxx"}"}
cb 群通知的回调函数,请参见TeamEventCallback

示例代码:

void OnTeamEventCallback(const nim::TeamEvent& result)
{
	...
}
void foo()
{
	std::list<std::string> id_list;
	id_list.push_back("test1");
	id_list.push_back("test2");

	nim::TeamInfo tinfo;
	tinfo.SetName("test");
	tinfo.SetType(nim::kNIMTeamTypeAdvanced );
	nim::Team::CreateTeamAsyncEx(tinfo, id_list, "", &OnTeamEventCallback);
}

错误码:

状态码 说明
200 成功
810 邀请初始成员成功,并带上tinfo
414 成员不足
801 成员数超出限制
404 成员中有非法用户

加入群组

加入群组可以通过以下两种方式:

  • 用户接受邀请入群。
  • 用户主动申请入群。

邀请入群

邀请入群的模式可以通过 NIMTeamInviteMode 来定义,设为 kNIMTeamInviteModeManager,那么仅限群主和管理员可以邀请人进群;设为 kNIMTeamInviteModeEveryone ,那么群组内的所有人都可以邀请人进群。

通过调用 InviteAsync 方法邀请其他用户进入群组。

  • 若群组的被邀请模式 NIMTeamBeInviteModekNIMTeamBeInviteModeNotNeedAgree ,那么无需验证,其他用户可直接加入群组。
  • 若群组的被邀请模式 NIMTeamBeInviteModekNIMTeamBeInviteModeNeedAgree ,那么需要被邀请用户同意才能加入群组。

如果在被邀请成员中存在成员拥有的群组数量已达上限,则会返回失败成员的账号列表。

参数说明:

参数 说明
tid 群ID
ids 邀请入群的用户账号列表
json_extension 自定义扩展字段
invitation_postscript 邀请附言,不需要的话设置为空
cb 邀请的回调函数
  • 发起邀请后,被邀请用户会收到 NIMSysMsgType 系统通知,其通知类型为kNIMSysMsgTypeTeamInvite
  • 被邀请用户可以调用 AcceptInvitationAsync 方法接受入群邀请,接受即入群。所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamInviteAccept
  • 也可以调用 RejectInvitationAsync 方法拒绝入群邀请。拒绝后,邀请者会收到 NIMSysMsgType 系统通知,其通知类型为 kNIMSysMsgTypeTeamInviteReject

示例代码:

void OnTeamEventCallback(const nim::TeamEvent& result)
{
	···
}

void foo()
{
	const std::list<std::string> friend_list;
	friend_list.push_back("test1");
	friend_list.push_back("test2");
	nim::Team::InviteAsync("123445", friend_list, "", &OnTeamEventCallback);
}

//接受入群邀请
void TeamEventCb(const nim::TeamEvent& team_event)
{
	···
}

void foo()
{
	nim::Team::AcceptInvitationAsync("12345", "my_id", &TeamEventCb);
}

//拒绝入群邀请
void TeamEventCb(const nim::TeamEvent& team_event)
{
	···
}

void foo()
{
	nim::Team::RejectInvitationAsync("12345", "my_id", "", &TeamEventCb);
}

错误码:

状态码 说明
200 成功
810 邀请初始成员成功,并带上timetag
801 成员数超出限制
802 没有权限
803 群不存在
404 非法用户

申请入群

通过调用 ApplyJoinAsync 方法申请加入群组。

  • 若群组的加入模式 NIMTeamJoinModekNIMTeamJoinModeNoAuth,那么无需验证,其他用户可直接加入群组。
  • 若群组的加入模式 NIMTeamJoinModekNIMTeamJoinModeNeedAuth ,那么需要群主或者群管理员同意才能加入群组。
  • 若群组的加入模式 NIMTeamJoinModekNIMTeamJoinModeRejectAll ,那么该群组不接受入群申请,仅能通过邀请方式入群。

参数说明:

参数 说明
tid 群ID
reason 申请附言
json_extension 自定义扩展字段
cb 申请入群的回调函数
  • 当用户发起入群申请后,该群群主和管理员会收到 NIMSysMsgType 系统通知,其通知类型为kNIMSysMsgTypeTeamApply
  • 群主和群管理员可以调用 PassJoinApplyAsync 方法接受入群申请,接受即入群。所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamApplyPass
  • 群主和群管理员也可以调用 RejectJoinApplyAsync 方法拒绝入群申请。拒绝后,申请者会收到 NIMSysMsgType 系统通知,其通知类型为 kNIMSysMsgTypeTeamReject

示例代码:

void OnApplyJoinCb(const nim::TeamEvent& team_event)
{
	QLOG_APP(L"apply join: {0}") << team_event.res_code_;
	
	switch (team_event.res_code_)
	{
	case nim::kNIMResTeamAlreadyIn:
	{
		···
	}
	break;
	case nim::kNIMResSuccess:
	{
		···
	}
	break;
	case nim::kNIMResTeamApplySuccess:
		···
		break;
	default:
	{
		···
	}
	break;
	}
}

void foo()
{
	nim::Team::ApplyJoinAsync("12345", "", &OnApplyJoinCb);
}

//同意申请

void TeamEventCb(const nim::TeamEvent& team_event)
{
	switch (team_event.res_code_)
	{
	case nim::kNIMResTeamAlreadyIn:
	{
		···
	}
	break;
	case nim::kNIMResSuccess:
	{
		···
	}
	break;
	case nim::kNIMResTeamApplySuccess:
		···
		break;
	default:
	{
		···
	}
	break;
	}
}

void foo()
{
	nim::Team::PassJoinApplyAsync("12345", "my_id", &TeamEventCb);
}

//拒绝申请

void TeamEventCb(const nim::TeamEvent& team_event)
{
	switch (team_event.res_code_)
	{
	case nim::kNIMResTeamAlreadyIn:
	{
		···
	}
	break;
	case nim::kNIMResSuccess:
	{
		···
	}
	break;
	case nim::kNIMResTeamApplySuccess:
		···
		break;
	default:
	{
		···
	}
	break;
	}
}

void foo()
{
	nim::Team::RejectJoinApplyAsync("12345", "sender_id", "", &TeamEventCb);
}

错误码:

状态码 说明
200 成功
801 成员数超出限制
802 群验证方式为拒绝所有人申请
803 群不存在
805 群类型错误
808 申请成功
809 已在群组中

转让群组

只有群主才有转让群组的权限。

通过调用 TransferTeamAsync 方法将群组转让给其他成员。

  • 转让群后, 群主身份转移,所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamOwnerTransfer
  • 如果转让群的同时离开群, 那么相当于同时调用LeaveAsync主动退群。所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamLeave

参数说明:

参数 说明
tid 群ID
new_owner_id 转让后的群主账号
is_leave 转让群的同时是否退出该群
true:退出
false:不退出,身份变为普通群成员
json_extension 自定义扩展字段
cb 转让群主的回调函数

示例代码:

void OnTeamEventCallback(const nim::TeamEvent& result)
{
	···
}

foo()
{
	nim::Team::TransferTeamAsync("tid_", "user_id", false, &OnTeamEventCallback);
}

错误码:

状态码 说明
200 成功
802 没有权限
803 群不存在
805 群类型错误
806 群数量超出限制

退出群组

退出群组可以通过以下两种方式:

  • 群主或群组管理员将用户踢出群组。所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamKick
  • 用户主动退群。主动退群后,所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamLeave

踢人出群

  • 只有群主和管理员才能将成员踢出群组。
  • 管理员不能踢群主和其他管理员。

通过调用 KickAsync 方法将成员踢出群组。

参数说明:

参数 说明
tid 群ID
ids 被踢出的群成员账号列表
json_extension 自定义扩展字段
cb 踢人的回调函数

示例代码:

Team::KickAsync("tid", {123456, 456789}, [this](const TeamEvent& team_event) {
	// process team_event
});

错误码:

状态码 说明
200 成功
403 被踢的是管理员或群主
404 非法用户
801 群人数超出限制
802 没有权限
803 群不存在

主动退群

除群主(需先转让群主)外,其他用户均可以直接主动退群。

通过调用 LeaveAsync 方法主动退出群组。

参数说明:

参数 说明
tid 群ID
json_extension 自定义扩展字段
cb 退群的回调函数

示例代码:

void TeamEventCb(const nim::TeamEvent& team_event)
{
	···
}

void foo()
{
	nim::Team::LeaveAsync("12345", &TeamEventCb);
}

错误码:

状态码 说明
200 成功
803 群不存在
804 用户不在群组中

解散群组

解散群后, 所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamDismiss

只有群主才能解散群组。

通过调用 DismissAsync 方法解散群组。

参数说明:

参数 说明
tid 群ID
json_extension 自定义扩展字段
cb 解散群的回调函数

示例代码:

void OnTeamEventCallback(const nim::TeamEvent& result)
{
	···
}

foo()
{
	nim::Team::DismissAsync("tid_", &OnTeamEventCallback);
}

错误码:

状态码 说明
200 成功
802 没有权限
803 群不存在

修改群组信息

当用户更新群组信息后,所有群成员会收到群组通知消息(消息类型为 kNIMMessageTypeNotification ),触发事件为kNIMNotificationIdTeamUpdate

修改群信息需要权限。若该群组的群信息修改权限(NIMTeamUpdateInfoMode)为 kNIMTeamUpdateInfoModeManager,那么只有群主和管理员才能修改群组信息;若为 kNIMTeamUpdateInfoModeEveryone ,则群组内的所有人都可以修改群组信息。

通过调用 UpdateTeamInfoAsync 方法修改群组的信息。

参数说明:

参数 说明
tid 群ID
team_info 待更新的群组信息,具体请参见TeamInfo
json_extension 自定义扩展字段
cb 个更新群组信息的回调函数

示例代码:

void OnUpdateBroadCb(const nim::TeamEvent& team_event)
{
	if (team_event.res_code_ == 200)
	{
		···
	}
}

void foo()
{
	Json::Value broad;
	broad["title"] = "title";
	broad["content"] = "内容";
	broad["creator"] = "test_user";

	Json::Value broads;
	broads.append(broad);

	Json::FastWriter writer;
	nim::TeamInfo param;
	param.SetAnnouncement(writer.write(broads));
	param.SetTeamID("tid_");

	nim::Team::UpdateTeamInfoAsync("tid_", param, &OnUpdateBroadCb);
}

错误码:

状态码 说明
200 成功
802 没有权限
803 群不存在

查询群组信息

SDK 在程序启动时会对本地群信息进行同步,所以只需要调用本地缓存接口获取群即可。

SDK 支持批量获取自己加入的所有群组、根据单个群 ID 查询群组、以及远程(从服务器)获取群信息功能。

本地查询自己加入的群组列表

查询的是本地所有有效群。有效群需要满足两个条件:群有效以及我在群里。

通过调用QueryAllMyTeamsAsync方法从本地查询自己加入的所有群组列表。

示例代码如下:

Team::QueryAllMyTeamsAsync([this](int count, const std::list<std::string>& team_id_list) {
	std::string ids;
	for (auto&& tid : team_id_list) {
		ids += tid + ";";
	}
	std::cout << "[Team] QueryAllMyTeamsAsync. count: " << count << ", team_ids: " << ids << std::endl;
});

本地查询自己加入的所有群组信息

  • 默认查询的是本地所有有效群信息。有效群需要满足两个条件:群有效以及我在群里。
  • SDK 2.7.0 支持通过配置扩展参数(json_extension)条件获取缓存中有的无效群(我已不在里面的群或者解散的群),例如 "{"include_invalid" : true}"。
  • 在回调函数中,开发者通过解析群组信息 JSON 后,通过 kNIMTeamInfoKeyValidFlag 字段区分该群为存在的群还是已经解散的群,通过 kNIMTeamInfoKeyMemberValid 字段区分自己是否还在该群。

通过调用QueryAllMyTeamsInfoAsync方法从本地查询自己加入的所有群组信息。

示例代码如下:

Team::QueryAllMyTeamsInfoAsync([this](int count, const std::list<TeamInfo>& team_info_list) {
	std::cout << "count: " << count << std::endl;
	for (auto& info : team_info_list) {
		// process team_info
	}
});

查询指定群组信息

通过异步调用QueryTeamInfoAsync方法或者同步调用QueryTeamInfoBlock方法从本地查询指定群组信息。

示例代码如下:

//异步调用
Team::QueryTeamInfoAsync(params["tid"].asString(), [this](const std::string& tid, const TeamInfo& result) {
	std::cout << "[Team] QueryTeamInfoAsync. team_id: " << tid << std::endl;
});

//同步调用
TeamInfo result = Team::QueryTeamInfoBlock("tid");
std::cout << "[Team] QueryTeamInfoAsync. team_id: " << result.GetTeamID() << std::endl;
  • 异步调用 QueryTeamInfoAsync时,如果本地没有该群组信息,则自动去服务器查询。
  • 同步调用 QueryTeamInfoBlock 时,仅查询本地,不会去服务器请求。如果自己不在该群组中,接口返回的可能是过期信息,如需最新的,请调用 QueryTeamInfoOnlineAsync 方法去服务器查询。
  • 同步接口,可能会堵塞 NIM 内部线程,请谨慎使用。

批量查询指定群组信息

通过调用GetTeaminfoList方法根据群组 ID 批量查询指定群组信息。

示例代码如下:

Team::GetTeaminfoList({"tid1", "tid2", "tid3"}, [](NIMResCode error_code, const std::list<nim::TeamInfo>& team_info_list, const std::list<std::string>& fail_list){
	std::cout << "GetTeaminfoList error_code:" << error_code << std::endl;
});

群组信息 SDK 本地存储说明:

  • 解散群、退出群或者被移出群时,本地数据库会继续保留该群组信息,只是设置了无效标记,此时依然可以查询该群组信息。 如果用户手动清空全部本地数据,下次登录同步时,服务器将不同步无效的群组,用户将无法取得已退出群的群组信息。

  • 群解散后,从服务器查询群组信息时结果将返回空值。

从服务器查询指定群组

通过调用QueryTeamInfoOnlineAsync方法从服务器查询指定的群组信息。示例代码如下:

Team::QueryTeamInfoOnlineAsync("tid", [this](const TeamEvent& team_event) {
	// process team_event
});

群组检索

通过调用QueryTeamInfoByKeywordAsync方法搜索与关键字匹配的所有群信息。示例代码如下:

Team::QueryTeamInfoByKeywordAsync("keyword", [this](int count, const std::list<TeamInfo>& team_info_list) {
	std::cout << "QueryTeamInfoByKeywordAsync count: " << count << std::endl;
});
此文档是否对你有帮助?
有帮助
去反馈
  • 技术原理
  • 群组相关事件监听
  • 实现流程
  • 创建群组
  • 加入群组
  • 邀请入群
  • 申请入群
  • 转让群组
  • 退出群组
  • 踢人出群
  • 主动退群
  • 解散群组
  • 修改群组信息
  • 查询群组信息
  • 本地查询自己加入的群组列表
  • 本地查询自己加入的所有群组信息
  • 查询指定群组信息
  • 批量查询指定群组信息
  • 从服务器查询指定群组
  • 群组检索