消息免打扰

功能描述

通过设置单聊、群聊或者全局的消息接收选项,可以实现类似 WhatsApp 中消息免打扰的功能。
说明:
单聊和群聊消息接收选项仅增强版 SDK 5.3.425 及以上版本支持。
全局消息接收选项仅增强版 SDK 7.4.4643 及以上版本支持。
SDK 提供三种类型的消息接收选项,在 V2TIMReceiveMessageOpt 中定义如下:
消息接收选项
支持类型
功能描述
V2TIM_RECEIVE_MESSAGE
单聊、群聊、全局
在线时正常接收消息,离线时接收离线推送通知
V2TIM_NOT_RECEIVE_MESSAGE
单聊、群聊
在线和离线都不接收消息
V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE
单聊、群聊、
全局
在线时正常接收消息,离线时不接收离线推送通知
V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE_EXCEPT_AT
群聊
在线接收消息,离线只接收 at 消息的推送
V2TIM_NOT_RECEIVE_MESSAGE_EXCEPT_AT
话题
在线和离线只接收 at 消息
设置不同的 V2TIMReceiveMessageOpt 可以实现不同的消息免打扰效果:
免打扰效果
消息接收选项
说明
完全不接收消息
V2TIM_NOT_RECEIVE_MESSAGE
任何消息都收不到,会话列表也不会更新。
接收消息但不提醒
V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE
此时建议在会话列表界面显示小圆点(不显示未读数):
1、收到新消息,会话列表需要更新,通过会话 V2TIMConversation 中的 unreadCount 获取到消息未读数。
2、如果未读数大于零,UI 显示小红点而非未读数。
接收消息但只提醒 at 消息
V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE_EXCEPT_AT
指定时间窗口内,登录账号的所有消息在线可以收到,离线不进行推送。
只接收 at 消息
V2TIM_NOT_RECEIVE_MESSAGE_EXCEPT_AT
在线和离线只接收话题的 at 消息。
说明:
以上实现效果中如果涉及V2TIMConversationunreadCount,只能在好友工作群(Work)、陌生人社交群(Public)和社群(Community)中使用,直播群(AVChatRoom)、临时会议群(Meeting)暂不支持。群组类型详见 群组介绍

设置单聊的消息接收选项

您可以调用 setC2CReceiveMessageOpt(Android / iOS & Mac / Windows) 设置单聊的消息接收选项。 您可通过参数 userIDList 设置一批用户,但一次最大允许设置 30 个用户。
注意
该接口调用频率被限制为单个用户 1 秒内最多调用 5 次。
示例代码如下:
Android
iOS & Mac
Windows
// 设置在线和离线都不接收消息

List<String> userList = new ArrayList<>();
userList.add("user1");
userList.add("user2");

V2TIMManager.getMessageManager().setC2CReceiveMessageOpt(userList, V2TIMMessage.V2TIM_NOT_RECEIVE_MESSAGE, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// 设置在线和离线都不接收消息

NSArray* array = [NSArray arrayWithObjects:@"user1", @"user2", nil]];
[[V2TIMManager sharedInstance] setC2CReceiveMessageOpt:array opt:V2TIM_NOT_RECEIVE_MESSAGE succ:^{
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
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_;
};

V2TIMStringVector userIDList;
userIDList.PushBack("user1");
userIDList.PushBack("user2");
V2TIMReceiveMessageOpt opt = V2TIMReceiveMessageOpt::V2TIM_NOT_RECEIVE_MESSAGE;

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 设置成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 设置失败
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SetC2CReceiveMessageOpt(userIDList, opt, callback);

获取单聊的消息接收选项

您可以通过调用 getC2CReceiveMessageOpt(Android / iOS & Mac / Windows) 获取单聊的消息接收选项。
示例代码如下:
Android
iOS & Mac
Windows
List<String> userList = new ArrayList<>();
userList.add("user1");
userList.add("user2");

V2TIMManager.getMessageManager().getC2CReceiveMessageOpt(userList, new V2TIMValueCallback<List<V2TIMReceiveMessageOptInfo>>() {
@Override
public void onSuccess(List<V2TIMReceiveMessageOptInfo> v2TIMReceiveMessageOptInfos) {
for (int i = 0; i < v2TIMReceiveMessageOptInfos.size(); i++){
V2TIMReceiveMessageOptInfo info = v2TIMReceiveMessageOptInfos.get(i);
Log.i("imsdk", "userId: " + info.getUserID() ", receiveOpt: " + info.getC2CReceiveMessageOpt());
}
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
NSArray* array = [NSArray arrayWithObjects:@"user1", @"user2", nil]];
[[V2TIMManager sharedInstance] getC2CReceiveMessageOpt:array succ:^(NSArray<V2TIMReceiveMessageOptInfo *> *optList) {
for (int i = 0; i < optList.count; i++) {
V2TIMReceiveMessageOptInfo* info = optList[i];
NSLog(@"userId: %@, receiveOpt: %@", info.userID, info.receiveOpt);
}
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
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_;
};

V2TIMStringVector userIDList;
userIDList.PushBack("user1");
userIDList.PushBack("user2");

auto callback = new ValueCallback<V2TIMReceiveMessageOptInfoVector>{};
callback->SetCallback(
[=](const V2TIMReceiveMessageOptInfoVector& receiveMessageOptInfoList) {
for (size_t i = 0; i < receiveMessageOptInfoList.Size(); ++i) {
const V2TIMReceiveMessageOptInfo& opt = receiveMessageOptInfoList[i];
V2TIMString userID = opt.userID;
V2TIMReceiveMessageOpt receiveOpt = opt.receiveOpt;
}

delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取失败
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetC2CReceiveMessageOpt(userIDList, callback);

设置群聊的消息接收选项

您可以调用 setGroupReceiveMessageOpt(Android / iOS & Mac / Windows) 设置群聊的消息接收选项。
示例代码如下:
Android
iOS & Mac
Windows
// 设置在线和离线都不接收消息

String groupID = "groupID";
V2TIMManager.getMessageManager().setGroupReceiveMessageOpt(groupID, V2TIMMessage.V2TIM_NOT_RECEIVE_MESSAGE, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// 设置在线和离线都不接收消息

NSString *groupID = @"groupID";
[[V2TIMManager sharedInstance] setGroupReceiveMessageOpt:groupID opt:V2TIM_NOT_RECEIVE_MESSAGE succ:^{
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
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 = "groupID";
V2TIMReceiveMessageOpt opt = V2TIMReceiveMessageOpt::V2TIM_NOT_RECEIVE_MESSAGE;

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 设置成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 设置失败
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SetGroupReceiveMessageOpt(groupID, opt, callback);

获取群聊的消息接收选项

您可以调用 getGroupsInfo(Android / iOS & Mac / Windows) 获得群资料 V2TIMGroupInfo 对象列表,对象的 recvOpt 字段表示群组的消息接收选项。
示例代码如下:
Android
iOS & Mac
Windows
List<String> groupIDList = new ArrayList<>();
groupIDList.add("groupID1");
groupIDList.add("groupID2");
V2TIMManager.getGroupManager().getGroupsInfo(groupIDList, new V2TIMValueCallback<List<V2TIMGroupInfoResult>>() {
@Override
public void onSuccess(List<V2TIMGroupInfoResult> v2TIMGroupProfileResults) {
for (V2TIMGroupInfoResult result : v2TIMGroupProfileResults) {
V2TIMGroupInfo info = result.getGroupInfo();
Log.i("imsdk", "recvOpt: " + info.getRecvOpt());
}
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
NSArray* array = [NSArray arrayWithObjects:@"groupID1", @"groupID2", nil]];
[[V2TIMManager sharedInstance] getGroupsInfo:array succ:^(NSArray<V2TIMGroupInfoResult *> * groupResultList) {
for (V2TIMGroupInfoResult *result in groupResultList){
V2TIMGroupInfo *info = result.info;
NSLog(@"recvOpt, %d", (int)info.recvOpt);
}
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
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_;
};

V2TIMStringVector groupIDList;
groupIDList.PushBack("groupID1");
groupIDList.PushBack("groupID2");

auto callback = new ValueCallback<V2TIMGroupInfoResultVector>{};
callback->SetCallback(
[=](const V2TIMGroupInfoResultVector& groupInfoResultList) {
for (size_t i = 0; i < groupInfoResultList.Size(); ++i) {
const V2TIMGroupInfo& info = groupInfoResultList[i].info;
V2TIMReceiveMessageOpt recvOpt = info.recvOpt;
}

delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取失败
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->GetGroupsInfo(groupIDList, callback);

设置全局的消息接收选项

您可以调用 setAllReceiveMessageOpt(Android / iOS & Mac / Windows) 设置登录账号的全局消息接收选项,支持设置每天重复生效,也支持指定时间段内生效。
示例代码如下:
Android
iOS & Mac
Windows
// 设置登录账号每天晚上 10 点到早上 6 点,在线正常接收消息,离线不会有推送通知

V2TIMManager.getMessageManager().setAllReceiveMessageOpt(V2TIMMessage.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE, 22, 0, 0, 8*60*60, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.d("imsdk", "setAllReceiveMessageOpt onSuccess");
}
@Override
public void onError(int code, String desc) {
Log.d("imsdk", "setAllReceiveMessageOpt onError code = " + code + ", desc = " + desc);
}});


// 假设今天晚上 10 点的 UTC 时间是 12345678。
// 设置登录账号从今天晚上 10 点开始,连续三天时间,在线正常接收消息,离线不会有推送通知
V2TIMManager.getMessageManager().setAllReceiveMessageOpt(V2TIMMessage.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE, 12345678, 3*24*60*60, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.d("imsdk", "setAllReceiveMessageOpt onSuccess");
}
@Override
public void onError(int code, String desc) {
Log.d("imsdk", "setAllReceiveMessageOpt onError code = " + code + ", desc = " + desc);
}});
// 设置登录账号每天晚上 10 点到早上 6 点,在线正常接收消息,离线不会有推送通知

[[V2TIMManager sharedInstance] setAllReceiveMessageOpt:V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE startHour:22 startMinute:0 startSecond:0 duration:8*60*60 succ:^{
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];


// 假设今天晚上 10 点的 UTC 时间是 12345678。
// 设置登录账号从今天晚上 10 点开始,连续三天时间,在线正常接收消息,离线不会有推送通知
[[V2TIMManager sharedInstance] setAllReceiveMessageOpt:V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE startTimeStamp:12345678 duration:3*24*60*60 succ:^{
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
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_;
};

V2TIMReceiveMessageOpt opt = V2TIMReceiveMessageOpt::V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE;

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 设置成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 设置失败
delete callback;
});

// 设置登录账号每天晚上 10 点到早上 6 点,在线正常接收消息,离线不会有推送通知
V2TIMManager::GetInstance()->GetMessageManager()->SetAllReceiveMessageOpt(opt, 22, 0, 0, 8*60*60, callback);


// 假设今天晚上 10 点的 UTC 时间是 12345678。
// 设置登录账号从今天晚上 10 点开始,连续三天时间,在线正常接收消息,离线不会有推送通知
V2TIMManager::GetInstance()->GetMessageManager()->SetAllReceiveMessageOpt(opt, 12345678, 3*24*60*60, callback);

获取全局的消息接收选项

您可以调用 getAllReceiveMessageOpt(Android / iOS & Mac / Windows) 获得全局消息接收选项 V2TIMReceiveMessageOptInfo (Android / iOS & Mac / Windows) 对象,表示登录账号的全局消息接收选项信息。
示例代码如下:
Android
iOS & Mac
Windows
V2TIMManager.getMessageManager().getAllReceiveMessageOpt(new V2TIMValueCallback<V2TIMReceiveMessageOptInfo>() {
@Override
public void onSuccess(V2TIMReceiveMessageOptInfo v2TIMReceiveMessageOptInfo) {
String result = "startHour = " + v2TIMReceiveMessageOptInfo.getStartHour() +
", startMinute = " + v2TIMReceiveMessageOptInfo.getStartMinute() +
", startSecond = " + v2TIMReceiveMessageOptInfo.getStartSecond() +
", startTimeStamp = " + v2TIMReceiveMessageOptInfo.getStartTimeStamp() +
", duration = " + v2TIMReceiveMessageOptInfo.getDuration() +
", opt = " + v2TIMReceiveMessageOptInfo.getAllReceiveMessageOpt();
Log.d("imsdk", "getAllReceiveMessageOpt onSuccess = " + result);
}
@Override
public void onError(int code, String desc) {
Log.d("imsdk", "getAllReceiveMessageOpt onError code = " + code + ", desc = " + desc);
}});
[V2TIMManager.sharedInstance getAllReceiveMessageOpt:^(V2TIMReceiveMessageOptInfo *optInfo) {
NSLog(@"optInfo %@", optInfo);
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
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_;
};

auto callback = new ValueCallback<V2TIMReceiveMessageOptInfo>{};
callback->SetCallback(
[=](const V2TIMReceiveMessageOptInfo& receiveMessageOptInfo) {
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取失败
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetAllReceiveMessageOpt(callback);