Manage Members

Overview

Group member management includes pulling the member list, muting group members, removing group members, granting permissions, and transferring the group ownership.

Getting the Group Member List

Call the getGroupMemberList API (Android/iOS and macOS/Windows) to get the list of members in a specified group. This list contains the profile of each group member, such as user ID (userID), group name card (nameCard), avatar (faceUrl), nickname (nickName), time of joining the group (joinTime), online status (isOnline), etc.
As an audio-video group (AVChatRoom) has a large number of members, the feature of pulling the list of all the members is unavailable. An Premium edition user can call getGroupMemberList to pull the latest 1,000 group members. This feature needs to be enabled in the Console, configuration path: Applications > Your App > Chat > Configuration > Group Configuration > Group feature configuration > List of online audio-video group members.
As a group might have a large number of members (for example, over 5,000), this API supports two advanced features: pulling by filter (filter) and pulling by page (nextSeq).

Pulling by Filter

When calling the getGroupMemberList API (Android/iOS and Mac/Windows), you can set filter to V2TIMGroupMemberFilter to pull the information of certain roles.
Filter
Type
V2TIM_GROUP_MEMBER_FILTER_ALL
Pull the information list of all group members
V2TIM_GROUP_MEMBER_FILTER_OWNER
Pull the information list of the group owner
V2TIM_GROUP_MEMBER_FILTER_ADMIN
Pull the information list of the group admin
V2TIM_GROUP_MEMBER_FILTER_COMMON
Pull the information list of ordinary group members
For audio-video groups, you can set filter to a custom group member mark other than V2TIMGroupMemberFilter to filter group members as needed. For more information, see Marking Group Members.
Sample code:
Android
iOS and macOS
Windows
// Use the `filter` parameter to specify only the profile of the group owner is to be pulled
int role = V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_FILTER_OWNER;
V2TIMManager.getGroupManager().getGroupMemberList("testGroup", role, 0,
new V2TIMValueCallback<V2TIMGroupMemberInfoResult>() {
@Override
public void onError(int code, String desc) {
// Messages failed to be pulled
}

@Override
public void onSuccess(V2TIMGroupMemberInfoResult v2TIMGroupMemberInfoResult) {
// Conversations pulled successfully
}
});
[[V2TIMManager sharedInstance] getGroupMemberList:@"groupA" filter:V2TIM_GROUP_MEMBER_FILTER_OWNER nextSeq:0 succ:^(uint64_t nextSeq, NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
// Conversations pulled successfully
} fail:^(int code, NSString *desc) {
// Messages failed to be pulled
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMString groupID = "testGroup";
// Use the `filter` parameter to specify only the profile of the group owner is to be pulled
uint32_t filter = V2TIMGroupMemberFilter::V2TIM_GROUP_MEMBER_FILTER_OWNER;
uint64_t nextSeq = 0;

auto callback = new ValueCallback<V2TIMGroupMemberInfoResult>{};
callback->SetCallback(
[=](const V2TIMGroupMemberInfoResult& groupMemberInfoResult) {
// Conversations pulled successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Messages failed to be pulled
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->GetGroupMemberList(groupID, filter, nextSeq, callback);

Pulling by Page

In many cases, only the first page of the group member list, not the information of all the group members, needs to be displayed on the user UI. More group members need to be pulled only when the user clicks Next Page or pulls up the list page. In this case, you can use pulling by page.
Directions for pulling by page:
1. When you call getGroupMemberList for the first time, set nextSeq to 0 (indicating to pull the group member list from the beginning). Up to 50 group member objects can be pulled at a time.
2. After the group member list is pulled successfully for the first time, the V2TIMGroupMemberInfoResult callback of getGroupMemberList will contain nextSeq (field for the next pull):
If nextSeq is 0, all the group members have been pulled.
If nextSeq is greater than 0, there are more group members that can be pulled. This doesn't mean that the next page of the member list will be pulled immediately. In common software, a paged pull is often triggered by a swipe operation.
3. When the user continues to pull up the group member list, if there are more members that can be pulled, you can continue to call the getGroupMemberList API and pass in the nextSeq parameter (the value is from the V2TIMGroupMemberInfoResult object returned by the last pull) for the next pull.
4. Repeat [step 3] until nextSeq is 0.
Sample code:
Android
iOS and macOS
Windows
{
...
long nextSeq = 0;
getGroupMemberList(nextSeq);
...
}

public void getGroupMemberList(long nextSeq) {
int filterRole = V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_FILTER_ALL;
V2TIMManager.getGroupManager().getGroupMemberList("testGroup", filterRole, nextSeq,
new V2TIMValueCallback<V2TIMGroupMemberInfoResult>() {
@Override
public void onError(int code, String desc) {
// Messages failed to be pulled
}

@Override
public void onSuccess(V2TIMGroupMemberInfoResult groupMemberInfoResult) {
if (groupMemberInfoResult.getNextSeq() != 0) {
// Make another pull
getGroupMemberList(groupMemberInfoResult.getNextSeq());
...
} else {
// Pull ends
}
}
});
}
- (void)getGroupMemberList:(uint32_t)seq {
[[V2TIMManager sharedInstance] getGroupMemberList:@"groupA" filter:V2TIM_GROUP_MEMBER_FILTER_OWNER nextSeq:seq succ:^(uint64_t nextSeq, NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
if (nextSeq != 0) {
// Make another pull
[self getGroupMemberList:nextSeq];
//...
} else {
// Pull ends
}
} fail:^(int code, NSString *desc) {
// Messages failed to be pulled
}];
}
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMString groupID = "testGroup";
uint32_t filter = V2TIMGroupMemberFilter::V2TIM_GROUP_MEMBER_FILTER_ALL;
uint64_t nextSeq = 0;

auto callback = new ValueCallback<V2TIMGroupMemberInfoResult>{};
callback->SetCallback(
[=](const V2TIMGroupMemberInfoResult& groupMemberInfoResult) {
if (groupMemberInfoResult.nextSequence != 0) {
// Make another pull
}

delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Messages failed to be pulled
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->GetGroupMemberList(groupID, filter, nextSeq, callback);

Marking Group Members

The group owner can call the markGroupMemberList API (Android/iOS and Mac/WIndows) to mark or unmark members of an audio-video group. Rules are as follows:
1. This feature is supported only on audio-video groups and Community groups, and only group owners have the permission to mark or unmark group members.
2. Up to ten custom marks can be added per audio-video group.
3. Custom marks configured through Chat SDK must be of uint32_t type and greater than or equal to 1,000.
4. Up to 100 group members can be marked at a time.
5. Only online members can be marked. When a member leaves a group or goes offline, its mark information will be cleared. When the member joins the group or goes online again, you can reset a mark for the member through a third-party callback.
After marking group members, the group owner can call getGroupMemberList to set filter to a configured custom group member mark to filter group members as needed.
Note
1. This feature is available only in Enhanced edition v6.6 or later.
2. To use this feature, you need to purchase the Premium edition.

Muting Group Members

Muting a Specified Group Member

The group owner or admin can call muteGroupMember (Android/iOS and macOS/Windows) and set muteTime (in seconds) to mute a group member. If muteTime is set to 120, the member is muted for 120 seconds. If a group member is muted, message sending will fail, and an error code will be reported. To unmute the member, set muteTime to 0.
The muting timestamp is stored in the muteUntil field (Android/iOS and macOS/Windows) of the group member information. Note that muteUntil indicates the end time for muting a group member.
After a group member is muted, all the group members (including the muted member) will receive the onMemberInfoChanged callback (Android/iOS and macOS/Windows).
Note
The group owner can mute/unmute the admin and ordinary group members. The admin can mute/unmute ordinary group members.

Muting the Entire Group

The group owner or admin can also call the muteAllGroupMembers API (Android/iOS and macOS/Windows) to mute the entire group by setting the isMute field to true/YES. The entire group can be muted for an unlimited period of time.
Muting all the group members will trigger the onGroupInfoChanged callback (Android/iOS and Mac/Windows).
This notification is disabled by default. To enable it, you can log in to the Console to modify the relevant settings. Configuration path: Applications > Your App > Chat > Configuration > Group Configuration > Group system notification configuration > Notification of group profile change > Notification of muting all change.
Note:
Only the group owner can mute the admin.
Sample code:
Android
iOS and macOS
Windows
// Mute the `userB` group member for one minute
V2TIMManager.getGroupManager().muteGroupMember("groupA", "userB", 60, new V2TIMCallback() {
@Override
public void onSuccess() {
// Muted the group member successfully
}

@Override
public void onError(int code, String desc) {
// Failed to mute the group member
}
});

// Mute all members
V2TIMManager.getGroupManager().muteAllGroupMembers("groupA", true, new V2TIMCallback() {
@Override
public void onSuccess() {
// Muted all successfully
}

@Override
public void onError(int code, String desc) {
// Failed to mute all
}
});

V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
@Override
public void onMemberInfoChanged(String groupID, List<V2TIMGroupMemberChangeInfo> v2TIMGroupMemberChangeInfoList) {
// Listen for the muting of a group member
for (V2TIMGroupMemberChangeInfo memberChangeInfo : v2TIMGroupMemberChangeInfoList) {
// ID of the muted user
String userID = memberChangeInfo.getUserID();
// Muting duration
long muteTime = memberChangeInfo.getMuteTime();
}
}

@Override
public void onAllGroupMembersMuted(String groupID, boolean isMute) {
// Listen for the muting of all
}
});
// Mute the group member `user1` for one minute
[[V2TIMManager sharedInstance] muteGroupMember:@"groupA" member:@"user1" muteTime:60 succ:^{
// Muted the group member successfully
} fail:^(int code, NSString *desc) {
// Failed to mute the group member
}];

// Mute all members
[[V2TIMManager sharedInstance] muteAllGroupMembers:@"groupA" isMute:YES succ:^{
// Muted all successfully
} fail:^(int code, NSString *desc) {
// Failed to mute all
}];

[[V2TIMManager sharedInstance] addGroupListener:self];
- (void)onMemberInfoChanged:(NSString *)groupID changeInfoList:(NSArray <V2TIMGroupMemberChangeInfo *> *)changeInfoList {
// Listen for the muting of a group member
for (V2TIMGroupMemberChangeInfo *memberChangeInfo in changeInfoList) {
// ID of the muted user
NSString *userID = memberChangeInfo.userID;
// Muting duration
uint32_t muteTime = memberChangeInfo.muteTime;
}
}

- (void)onAllGroupMembersMuted:(NSString *)groupID isMute:(BOOL)isMute {
// Listen for the muting of all
}
class Callback final : public V2TIMCallback {
public:
using SuccessCallback = std::function<void()>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

Callback() = default;
~Callback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess() override {
if (success_callback_) {
success_callback_();
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

// Mute the `userB` group member for one minute
auto callback = new Callback;
callback->SetCallback(
[=]() {
// Muted the group member successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to mute the group member
delete callback;
});
V2TIMManager::GetInstance()->GetGroupManager()->MuteGroupMember("groupA", "userB", 60, callback);

// Mute all members
V2TIMGroupInfo info;
info.groupID = "groupA";
info.allMuted = true;
info.modifyFlag = V2TIMGroupInfoModifyFlag::V2TIM_GROUP_INFO_MODIFY_FLAG_SHUTUP_ALL;
auto callback = new Callback;
callback->SetCallback(
[=]() {
// Muted all successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to mute all
delete callback;
});
V2TIMManager::GetInstance()->GetGroupManager()->SetGroupInfo(info, callback);

// Listen for the muting of a group member or all
class GroupListener final : public V2TIMGroupListener {
public:
GroupListener() = default;
~GroupListener() override = default;

void OnMemberInfoChanged(const V2TIMString& groupID,
const V2TIMGroupMemberChangeInfoVector& groupMemberChangeInfoList) override {
// Listen for the muting of a group member
for (size_t i = 0; i < groupMemberChangeInfoList.Size(); ++i) {
const V2TIMGroupMemberChangeInfo& groupMemberChangeInfo = groupMemberChangeInfoList[i];
// ID of the muted user
V2TIMString userID = groupMemberChangeInfo.userID;
// Muting duration
uint32_t muteTime = groupMemberChangeInfo.muteTime;
}
}
void onAllGroupMembersMuted(const V2TIMString& groupID,
bool isMute) override {
// Listen for the muting of all
}
// Other members …
};
// Add a group event listener. Keep `groupListener` valid before the listener is removed to ensure event callbacks are received.
GroupListener groupListener;
V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

Kicking Group Members

The SDK provides a basic kick API and an advanced kick API for all types of groups. The group owner or administrator can call the kick API to kick a specified group member out of the group.

Basic API

The group owner or admin can call kickGroupMember (Android/iOS & Mac/Windows) to kick a specified group member out of the group. After the Group member is kicked out, all members (including the kicked user) will receive the onMemberKicked (Android/iOS & Mac/Windows) callback.
Except for AVChatRoom, the kicked user can apply to join the group again or be invited to join the group after using this API. See details in Kicking group members out of a AVChatRoom.
Sample code:
Android
iOS & macOS
Windows
List<String> userIDList = new ArrayList<>();
userIDList.add("userB");
V2TIMManager.getGroupManager().kickGroupMember("groupA", userIDList, "", newV2TIMValueCallback<List<V2TIMGroupMemberOperationResult>>() {
@Override
public void onSuccess(List<V2TIMGroupMemberOperationResult> v2TIMGroupMemberOperationResults) {
// Remove group members successfully
}

@Override
public void onError(int code, String desc) {
// Failed to remove group members successfully
}
}
});

V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
@Override
public void onMemberKicked(String groupID, V2TIMGroupMemberInfo opUser,
List<V2TIMGroupMemberInfo> memberList) {
// Group member kicked notification
}
});
[[V2TIMManager sharedInstance] kickGroupMember:@"groupA" memberList:@[@"user1"] reason:@"" succ:^(NSArray<V2TIMGroupMemberOperationResult *> *resultList) {
// Remove group members successfully
} fail:^(int code, NSString *desc) {
// Failed to remove group members successfully
}];

[[V2TIMManager sharedInstance] addGroupListener:self];
- (void)onMemberKicked:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser memberList:(NSArray<V2TIMGroupMemberInfo *>*)memberList {
// Group member kicked notification
}
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}

void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMString groupID = "groupA";
V2TIMStringVector memberList;
memberList.PushBack("userB");

auto callback = new ValueCallback<V2TIMGroupMemberOperationResultVector>{};
callback->SetCallback(
[=](const V2TIMGroupMemberOperationResultVector& groupMemberOperationResultList) {
// Remove group members successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to remove group members successfully
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->KickGroupMember(groupID, memberList, {}, callback);

class GroupListener final : public V2TIMGroupListener {
public:
GroupListener() = default;
~GroupListener() override = default;

void OnMemberKicked(const V2TIMString& groupID, const V2TIMGroupMemberInfo& opUser, const V2TIMGroupMemberInfoVector& memberList) override {
// Group member kicked notification
}
};

// Note that `groupListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
GroupListener groupListener;
V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

Advanced API

Since v7.2, the SDK has made a function upgrade to kickGroupMember (Android/iOS & Mac/Windows) , adding a duration parameter to specify the duration which the user is prohibited from reapplying to join the group after being kicked out of the group.
Note:
This API is only open to Premium edition. When calling this API to kick out a group member, only those who have integrated IMSDK v6.6 and above (including the kicked user) will receive the onMemberKicked (Android/iOS & Mac/Windows) callback.
Sample code:
Android
iOS & macOS
WIndows
List<String> userIDList = new ArrayList<>();
userIDList.add("userB");
V2TIMManager.getGroupManager().kickGroupMember("groupA", userIDList, "", 100, newV2TIMValueCallback<List<V2TIMGroupMemberOperationResult>>() {
@Override
public void onSuccess(List<V2TIMGroupMemberOperationResult> v2TIMGroupMemberOperationResults) {
// Remove group members successfully
}

@Override
public void onError(int code, String desc) {
// Failed to remove group members successfully
}
});

V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
@Override
public void onMemberKicked(String groupID, V2TIMGroupMemberInfo opUser,
List<V2TIMGroupMemberInfo> memberList) {
// Group member kicked notification
}
});
[[V2TIMManager sharedInstance] kickGroupMember:@"groupA" memberList:@[@"user1"] reason:@"" duration:100 succ:^(NSArray<V2TIMGroupMemberOperationResult *> *resultList) {
// Remove group members successfully
} fail:^(int code, NSString *desc) {
// Failed to remove group members successfully
}];

[[V2TIMManager sharedInstance] addGroupListener:self];
- (void)onMemberKicked:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser memberList:(NSArray<V2TIMGroupMemberInfo *>*)memberList {
// Group member kicked notification
}
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}

void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMString groupID = "groupA";
V2TIMStringVector memberList;
memberList.PushBack("userB");

auto callback = new ValueCallback<V2TIMGroupMemberOperationResultVector>{};
callback->SetCallback(
[=](const V2TIMGroupMemberOperationResultVector& groupMemberOperationResultList) {
// Remove group members successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to remove group members successfully
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->KickGroupMember(groupID, memberList, {}, 100, callback);

class GroupListener final : public V2TIMGroupListener {
public:
GroupListener() = default;
~GroupListener() override = default;

void OnMemberKicked(const V2TIMString& groupID, const V2TIMGroupMemberInfo& opUser,
const V2TIMGroupMemberInfoVector& memberList) override {
// Group member kicked notification
}
};

// Note that `groupListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
GroupListener groupListener;
V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

Kicking from an AVChatRoom

For an audio-video group (AVChatRoom):
1. For Enhanced version earlier than v6.6, audio-video groups do not support member removal, and you can use muteGroupMember (Android/iOS and Mac/Windows) to mute a specified member to implement similar controls. For detailed directions, see Muting.
2. For Enhanced version 6.6 or later, audio-video groups support member removal. You can use the basic interface to remove group members. Once removed, members cannot rejoin the group or send messages. Both the group owner and administrators can remove members, while ordinary members do not.
3. For v7.2 or later, the AVChatRoom can also use the advanced API to kick out group members, and set a custom time to specify the time interval for kicked users to join the group again.
Caution
1. For v6.6 or later, kicking group members out of the AVChatRoom needs to purchase Premium edition.
2. If you want to kick group members from AVChatRoom, you need to log in to the Console and enable it, switch path: Applications > Your App > Chat > Configuration > Group Configuration > Group feature configuration > Audio-video group member banning.

Setting an Admin

The group owner calling setGroupMemberRole (Android/iOS and Mac/Windows) can grant admin authorization to group members in stranger social groups (Public), temporary meeting groups (Meeting), and audio-video groups (AVChatRoom).
An ordinary member set as the admin has the admin permission to perform the following operations:
Modify the basic group profile.
Remove an ordinary member from the group
Mute an ordinary member (prevent the member from speaking during a specified period of time)
Approve a request to join the group
For more information, see Group Member Roles.
Once authorized, ordinary members of audio-video groups have the same permissions as administrators, for example:
Remove a ordinary group member from the audio-video group.
After an ordinary member is set as the admin, all the members (including the ordinary member) will receive the onGrantAdministrator callback (Android/iOS and Mac/Windows).
After the ordinary member is unset as the admin, all the members (including the ordinary member) will receive the onRevokeAdministrator callback (Android/iOS and Mac/Windows).
Sample code:
Android
iOS and macOS
Windows
V2TIMManager.getGroupManager().setGroupMemberRole("groupA", "userB", V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_ROLE_ADMIN, new V2TIMCallback() {
@Override
public void onSuccess() {
// Changed the group member role successfully
}

@Override
public void onError(int code, String desc) {
// Failed to change the group member role
}
});

V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
@Override
public void onGrantAdministrator(String groupID, V2TIMGroupMemberInfo opUser,
List<V2TIMGroupMemberInfo> memberList) {
// A group member was set as the admin.
}

@Override
public void onRevokeAdministrator(String groupID, V2TIMGroupMemberInfo opUser,
List<V2TIMGroupMemberInfo> memberList) {
// A group member was unset as the admin.
}
});
[[V2TIMManager sharedInstance] setGroupMemberRole:@"groupA" member:@"user1" newRole:V2TIM_GROUP_MEMBER_ROLE_ADMIN succ:^{
// Changed the group member role successfully
} fail:^(int code, NSString *desc) {
// Failed to change the group member role
}];

[[V2TIMManager sharedInstance] addGroupListener:self];
- (void)onGrantAdministrator:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser memberList:(NSArray <V2TIMGroupMemberInfo *> *)memberList {
// A group member was set as the admin.
}

- (void)onRevokeAdministrator:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser memberList:(NSArray <V2TIMGroupMemberInfo *> *)memberList {
// A group member was unset as the admin.
}
class Callback final : public V2TIMCallback {
public:
using SuccessCallback = std::function<void()>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

Callback() = default;
~Callback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess() override {
if (success_callback_) {
success_callback_();
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMString groupID = "groupA";
V2TIMString userID = "userB";
uint32_t role = V2TIMGroupMemberRole::V2TIM_GROUP_MEMBER_ROLE_ADMIN;

auto callback = new Callback;
callback->SetCallback(
[=]() {
// Changed the group member role successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to change the group member role
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->SetGroupMemberRole(groupID, userID, role, callback);

// Listen for setting a user as the admin
class GroupListener final : public V2TIMGroupListener {
public:
GroupListener() = default;
~GroupListener() override = default;

void OnGrantAdministrator(const V2TIMString& groupID, const V2TIMGroupMemberInfo& opUser,
const V2TIMGroupMemberInfoVector& memberList) override {
// A group member was set as the admin.
}
void OnRevokeAdministrator(const V2TIMString& groupID, const V2TIMGroupMemberInfo& opUser,
const V2TIMGroupMemberInfoVector& memberList) override {
// A group member was unset as the admin.
}
// Other members …
};
// Add a group event listener. Keep `groupListener` valid before the listener is removed to ensure event callbacks are received.
GroupListener groupListener;
V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

Transferring Group Ownership

The group owner can call transferGroupOwner (Android/iOS and Mac/Windows) to transfer the ownership of a group to another group member.
After the group ownership is transferred, all the group members will receive the onGroupInfoChanged callback (Android/iOS and macOS/Windows). Here, the type of V2TIMGroupChangeInfo is V2TIMGroupChangeInfo.V2TIM_GROUP_INFO_CHANGE_TYPE_OWNER, and the value is the UserID of the new group owner.
Sample code:
Android
iOS and macOS
Windows
V2TIMManager.getGroupManager().transferGroupOwner("groupA", "userB", new V2TIMCallback() {
@Override
public void onSuccess() {
// Transferred the group ownership successfully
}

@Override
public void onError(int code, String desc) {
// Failed to transfer the group ownership
}
});
[[V2TIMManager sharedInstance] transferGroupOwner:@"groupA" member:@"user1" succ:^{
// Transferred the group ownership successfully
} fail:^(int code, NSString *desc) {
// Failed to transfer the group ownership
}];
class Callback final : public V2TIMCallback {
public:
using SuccessCallback = std::function<void()>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

Callback() = default;
~Callback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess() override {
if (success_callback_) {
success_callback_();
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMString groupID = "groupA";
V2TIMString userID = "userB";

auto callback = new Callback;
callback->SetCallback(
[=]() {
// Transferred the group ownership successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to transfer the group ownership
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->TransferGroupOwner(groupID, userID, callback);

Getting the Number of Online Group Members

Call getGroupOnlineMemberCount (Android/iOS and Mac/Windows) to get the number of online group members.
Note
1. This API is only supported in audio-video groups (AVChatRoom) before IMSDK 7.3 version.
2. You can call this API for all kinds of groups in IMSDK 7.3 and later versions.
Sample code:
Android
iOS and macOS
Windows
V2TIMManager.getGroupManager().getGroupOnlineMemberCount("group_avchatroom", new V2TIMValueCallback<Integer>() {
@Override
public void onSuccess(Integer integer) {
// Obtained the number of online members in the audio-video group (AVChatRoom) successfully
}

@Override
public void onError(int code, String desc) {
// Failed to obtain the number of online members in the audio-video group (AVChatRoom)
}
});
[[V2TIMManager sharedInstance] getGroupOnlineMemberCount:@"group_avchatroom" succ:^(NSInteger count) {
// Obtained the number of online members in the audio-video group (AVChatRoom) successfully
} fail:^(int code, NSString *desc) {
// Failed to obtain the number of online members in the audio-video group (AVChatRoom)
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMString groupID = "group_avchatroom";

auto callback = new ValueCallback<uint32_t>{};
callback->SetCallback(
[=](const uint32_t& count) {
// Obtained the number of online members in the audio-video group (AVChatRoom) successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to obtain the number of online members in the audio-video group (AVChatRoom)
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->GetGroupOnlineMemberCount(groupID, callback);