转发消息

功能描述

如果您想实现合并转发功能,需要进行以下步骤:
1. 根据原始消息列表创建一条合并消息。
2. 把合并消息发送到对端。
3. 对端收到合并消息后解析出原始消息列表。
合并消息的展示还需要标题和摘要信息,如下图所示:
合并转发
合并消息展示
点击合并消息下载合并消息列表展示










合并转发消息

创建并发送合并转发消息

我们在创建一条合并消息的时候不仅要设置合并消息列表,还要设置标题和摘要信息,实现流程如下:
1. 调用 createMergerMessage (Android / iOS & Mac / Windows) 接口创建一条合并消息,创建合并消息的时候需要设置原始消息列表,合并消息标题、合并消息摘要等信息。



属性
含义
说明
messageList
原始消息列表
合并转发的原始消息列表。
title
标题
合并消息的标题,如上图所示 “xixiyah 和 Hello 的聊天记录”。
abstractList
摘要列表
合并消息的摘要信息,如上图所示,合并消息需要预先展示原始消息的摘要信息,当用户点击 Cell 后才去展示完整消息内容。
compatibleText
兼容文本信息
低版本 SDK 如果不支持合并消息,默认会收到一条文本消息,文本消息的内容为 compatibleText。
示例代码如下:
Android
iOS & Mac
Windows
// 需要被转发的消息列表,消息列表里可以包含合并消息,不能包含群 Tips 消息
List<V2TIMMessage> msgs = new ArrayList<>();
msgs.add(message1);
msgs.add(message2);
// 合并消息标题
String title = "vinson 和 lynx 的聊天记录";
// 合并消息摘要列表
List<String> abstactList = new ArrayList<>();
msgs.add("abstract1");
msgs.add("abstract2");
msgs.add("abstract3");
// 合并消息兼容文本,低版本 SDK 如果不支持合并消息,默认会收到一条文本消息,文本消息的内容为 compatibleText
String compatibleText = "请升级最新版本查看合并消息";
// 创建合并消息
V2TIMMessage mergeMessage = V2TIMManager.getMessageManager().createMergerMessage(msgs, title, abstractList, compatibleText);
// 需要被转发的消息列表,消息列表里可以包含合并消息,不能包含群 Tips 消息
NSArray *msgs = @[message1,message2...];
// 合并消息标题
NSString *title = @"vinson 和 lynx 的聊天记录";
// 合并消息摘要列表
NSArray *abstactList = @[@"abstract1",@"abstract2",@"abstract3"];
// 合并消息兼容文本,低版本 SDK 如果不支持合并消息,默认会收到一条文本消息,文本消息的内容为 compatibleText
NSString *compatibleText = @"请升级最新版本查看合并消息";
// 创建合并消息
V2TIMMessage *mergeMessage = [[V2TIMManager sharedInstance] createMergerMessage:msgs title:title
abstractList:abstactList compatibleText:compatibleText];
// 需要被转发的消息列表,消息列表里可以包含合并消息,不能包含群 Tips 消息
V2TIMMessageVector messageList;
messageList.PushBack(message1);
messageList.PushBack(message2);
// 合并消息标题
V2TIMString title = "vinson 和 lynx 的聊天记录";
// 合并消息摘要列表
V2TIMStringVector abstractList;
abstractList.PushBack("abstract1");
abstractList.PushBack("abstract2");
abstractList.PushBack("abstract3");
// 合并消息兼容文本,低版本 SDK 如果不支持合并消息,默认会收到一条文本消息,文本消息的内容为 compatibleText
V2TIMString compatibleText = "请升级最新版本查看合并消息";
// 创建合并消息
V2TIMMessage mergerMessage = V2TIMManager::GetInstance()->GetMessageManager()->CreateMergerMessage(
messageList, title, abstractList, compatibleText);
2. 调用 sendMessage (Android / iOS & Mac / Windows) 接口发送合并消息。
示例代码如下:
Android
iOS & Mac
Windows
// 发送合并消息给用户 "denny"
V2TIMManager.getMessageManager().sendMessage(mergeMessage, "denny", null, V2TIMMessage.V2TIM_PRIORITY_NORMAL, false, null, new V2TIMSendCallback<V2TIMMessage>() {
@Override
public void onProgress(int progress) {}

@Override
public void onSuccess(V2TIMMessage v2TIMMessage) {}

@Override
public void onError(int code, String desc) {}
})
// 发送合并消息给用户 "denny"
[[V2TIMManager sharedInstance] sendMessage:mergeMessage receiver:@"denny" groupID:nil
priority:V2TIM_PRIORITY_NORMAL onlineUserOnly:NO offlinePushInfo:nil progress:nil succ:nil fail:nil];
class SendCallback final : public V2TIMSendCallback {
public:
using SuccessCallback = std::function<void(const V2TIMMessage&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
using ProgressCallback = std::function<void(uint32_t)>;

SendCallback() = default;
~SendCallback() override = default;

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

void OnSuccess(const V2TIMMessage& message) override {
if (success_callback_) {
success_callback_(message);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
void OnProgress(uint32_t progress) override {
if (progress_callback_) {
progress_callback_(progress);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
ProgressCallback progress_callback_;
};

auto callback = new SendCallback{};
callback->SetCallback([=](const V2TIMMessage& message) { delete callback; },
[=](int error_code, const V2TIMString& error_message) { delete callback; },
[=](uint32_t progress) {});

V2TIMManager::GetInstance()->GetMessageManager()->SendMessage(
mergerMessage, "denny", {}, V2TIMMessagePriority::V2TIM_PRIORITY_NORMAL, false, {}, callback);

接收合并转发消息

添加监听器

接收方调用 addAdvancedMsgListener (Android / iOS & Mac / Windows) 添加高级消息监听器。 一般建议在比较靠前的时间点调用,例如例如聊天消息界面初始化后,确保 App 能及时收到消息。
示例代码如下:
Android
iOS & Mac
Windows
V2TIMManager.getMessageManager().addAdvancedMsgListener(advancedMsgListener);
// self 为 id<V2TIMAdvancedMsgListener>
[[V2TIMManager sharedInstance] addAdvancedMsgListener:self];
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
// 成员 ...
};

// 添加高级消息的事件监听器,注意在移除监听器之前需要保持 advancedMsgListener 的生命期,以免接收不到事件回调
AdvancedMsgListener advancedMsgListener;
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(&advancedMsgListener);

解析消息

添加监听器后,接收方会在 onRecvNewMessage 中收到合并消息 V2TIMMessage。 可以先通过合并消息元素 V2TIMMergerElem (Android / iOS & Mac / Windows) 获取 titleabstractList UI 展示。 当用户点击合并消息的时候再调用 downloadMergerMessage(Android / iOS & Mac / Windows) 接口下载合并消息列表 UI 展示。
示例代码如下:
Android
iOS & Mac
Windows
@Override
public void onRecvNewMessage(V2TIMMessage msg) {
if (msg.getElemType() == V2TIMMessage.V2TIM_ELEM_TYPE_MERGER) {
// 获取合并消息 elem
V2TIMMergerElem mergerElem = msg.getMergerElem();
// 获取 title
String title = mergerElem.getTitle();
// 获取摘要列表
List<String> abstractList = mergerElem.getAbstractList();
// 用户点击合并消息的时候下载合并消息列表
mergerElem.downloadMergerMessage(new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// 下载成功,v2TIMMessages 即为合并消息列表
for (V2TIMMessage subMsg : v2TIMMessages) {
// 如果合并消息列表里面还有合并消息,可以继续解析
if (subMsg.getElemType() == V2TIMMessage.V2TIM_ELEM_TYPE_MERGER) {
V2TIMMergerElem mergerElem = subMsg.getMergerElem();
// 获取 title
String title = mergerElem.getTitle();
// 获取摘要列表
List<String> abstractList = mergerElem.getAbstractList();
// 用户点击合并消息的时候下载合并消息列表
......
}
}
}

@Override
public void onError(int code, String desc) {
// 下载失败
}
});
}
- (void)onRecvNewMessage:(V2TIMMessage *)msg {
if (msg.elemType == V2TIM_ELEM_TYPE_MERGER) {
// 获取合并消息 elem
V2TIMMergerElem *mergerElem = msg.mergerElem;
// 获取 title
NSString *title = mergerElem.title;
// 获取摘要列表
NSArray *abstractList = mergerElem.abstractList;
// 用户点击合并消息的时候下载合并消息列表
[msg.mergerElem downloadMergerMessage:^(NSArray<V2TIMMessage *> *msgs) {
// 下载成功,msgs 即为合并消息列表
for (V2TIMMessage *subMsg in msgs) {
// 如果合并消息列表里面还有合并消息,可以继续解析
if (subMsg.elemType == V2TIM_ELEM_TYPE_MERGER) {
V2TIMMergerElem *mergerElem = subMsg.mergerElem;
// 获取 title
NSString *title = mergerElem.title;
// 获取摘要列表
NSArray *abstractList = mergerElem.abstractList;
// 用户点击合并消息的时候下载合并消息列表
[msg.mergerElem downloadMergerMessage:nil fail:nil];
}
}
} fail:^(int code, NSString *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_;
};

class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
public:
// 收到新消息通知
void OnRecvNewMessage(const V2TIMMessage& message) override {
if (message.elemList.Size() == 1) {
V2TIMElem* elem = message.elemList[0];
if (elem->elemType == V2TIMElemType::V2TIM_ELEM_TYPE_MERGER) {
// 获取合并消息 elem
auto mergerElem = static_cast<V2TIMMergerElem*>(elem);
// 获取 title
V2TIMString title = mergerElem->title;
/// 合并消息摘要列表
V2TIMStringVector abstractList = mergerElem->abstractList;

// 用户点击合并消息的时候下载合并消息列表
auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) {
// 下载成功,messageList 即为合并消息列表
for (size_t i = 0; i < messageList.Size(); ++i) {
const V2TIMMessage& message = messageList[i];
if (message.elemList.Size() == 1) {
V2TIMElem* elem = message.elemList[0];
// 如果合并消息列表里面还有合并消息,可以继续解析
if (elem->elemType == V2TIMElemType::V2TIM_ELEM_TYPE_MERGER) {
// ...
}
}
}
delete callback;
},
[=](int error_code, const V2TIMString& error_message) { delete callback; });

mergerElem->DownloadMergerMessage(callback);
}
}
}
// 其他成员 ...
};

// 添加高级消息的事件监听器,注意在移除监听器之前需要保持 advancedMsgListener 的生命期,以免接收不到事件回调
AdvancedMsgListener advancedMsgListener;
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(&advancedMsgListener);

移除监听器

如果想停止接收消息,接收方可调用 removeAdvancedMsgListener (Android / iOS & Mac / Windows) 移除高级消息监听器。
示例代码如下:
Android
iOS & Mac
Windows
V2TIMManager.getMessageManager().removeAdvancedMsgListener(advancedMsgListener);
// self 为 id<V2TIMAdvancedMsgListener>
[[V2TIMManager sharedInstance] removeAdvancedMsgListener:self];
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
// 成员 ...
};

// advancedMsgListener 是 AdvancedMsgListener 的实例
V2TIMManager::GetInstance()->GetMessageManager()->RemoveAdvancedMsgListener(&advancedMsgListener);

逐条转发消息

如果您需要转发单条消息,可以先通过 createForwardMessage (Android / iOS & Mac / Windows) 接口创建一条和原消息内容完全一样的转发消息,再调用 sendMessage (Android / iOS & Mac / Windows) 接口把转发消息发送出去。
示例代码如下:
Android
iOS & Mac
Windows
// 创建转发消息,转发消息的 elem 内容和原消息完全一致
V2TIMMessage forwardMessage = V2TIMManager.getMessageManager().createForwardMessage(originMsg);
// 发送消息给用户 "denny"
V2TIMManager.getMessageManager().sendMessage(forwardMessage, "denny", null, V2TIMMessage.V2TIM_PRIORITY_NORMAL, false, null, new V2TIMSendCallback<V2TIMMessage>() {
@Override
public void onProgress(int progress) {
}

@Override
public void onSuccess(V2TIMMessage message) {
}

@Override
public void onError(int code, String desc) {
}
});
// 创建转发消息,转发消息的 elem 内容和原消息完全一致
V2TIMMessage *forwardMessage = [[V2TIMManager sharedInstance] createForwardMessage:originMsg];
// 发送消息给用户 "denny"
[[V2TIMManager sharedInstance] sendMessage:forwardMessage receiver:@"denny" groupID:nil
priority:V2TIM_PRIORITY_NORMAL onlineUserOnly:NO offlinePushInfo:nil progress:nil succ:nil fail:nil];
class SendCallback final : public V2TIMSendCallback {
public:
using SuccessCallback = std::function<void(const V2TIMMessage&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
using ProgressCallback = std::function<void(uint32_t)>;

SendCallback() = default;
~SendCallback() override = default;

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

void OnSuccess(const V2TIMMessage& message) override {
if (success_callback_) {
success_callback_(message);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
void OnProgress(uint32_t progress) override {
if (progress_callback_) {
progress_callback_(progress);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
ProgressCallback progress_callback_;
};

// 创建转发消息,转发消息的 elem 内容和原消息完全一致
V2TIMMessage forwardMessage = V2TIMManager::GetInstance()->GetMessageManager()->CreateForwardMessage(originMsg);

auto callback = new SendCallback{};
callback->SetCallback([=](const V2TIMMessage& message) { delete callback; },
[=](int error_code, const V2TIMString& error_message) { delete callback; },
[=](uint32_t progress) {});

// 发送消息给用户 "denny"
V2TIMManager::GetInstance()->GetMessageManager()->SendMessage(
forwardMessage, "denny", {}, V2TIMMessagePriority::V2TIM_PRIORITY_NORMAL, false, {}, callback);