跳到主要内容

消息扩展

1.2.0 版本支持消息扩展

消息扩展功能可为消息对象(Message)增加基于 Key/Value 的状态标识。消息的扩展信息可在发送前、后设置或更新,可用于实现消息评论、礼物领取、订单状态变化等业务需求。

一条消息是否可携带或可设置扩展信息,由发送消息时 Message 的可扩展(canIncludeExpansion)属性决定,该属性必须在发送前设置,发送后无法修改。单条消息单次最多可设置 20 个扩展信息 KV 对,总计不可超过 300 个扩展信息 KV 对。在并发情况下如出现设置超过 300 个的情况,超出部分会被丢弃。

Message 消息对象添加的 Key、Value 扩展信息会被存储。如已开通历史消息云存储功能,从服务端获取的历史消息也会携带已设置的扩展信息。

提示
  • 消息扩展仅支持单聊、群聊、超级群会话类型。不支持聊天室和系统会话。

实现思路

订单状态变化为例,可通过消息扩展改变消息显示状态。以订单确认为例:

  1. 当用户购买指定产品下单后,商家需要向用户发送订单确认信息。可在发送消息时,将消息对象中的 canIncludeExpansion 属性设置为可扩展,同时设置用于标识订单状态的 Key 和 Value。例如,在用户未确认前,可用一对 Key/Value 表示该订单状态为「未确认」。
  2. 用户点击确认(或其他确认操作)该订单消息后,订单消息状态需要变更为「已确认」。此时,可通过 updateMessageExpansion 更新此条消息的扩展信息,标识为已确认状态,同时更改本地显示的消息样式。
  3. 发送方通过消息扩展状态监听,获取指定消息的状态变化,根据最新扩展信息显示最新的订单状态。

消息评论、礼物领取可参照以上实现思路:

  • 礼物领取:可通过消息扩展改变消息显示状态实现。例如,向用户发送礼物,默认为未领取状态,用户点击后可设置消息扩展为已领取状态。
  • 消息评论:可通过设置原始消息扩展信息的方式添加评论信息。

打开消息的可扩展属性(仅发送前)

构建新消息后,调用 MessagecanIncludeExpansion 方法打开或关闭某条消息的可扩展属性。必须在发送消息前设置该属性。 调用 Messageexpansion 设置扩展数据(可选)

let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";

let textMsg = new TextMessage();
textMsg.content = "文本消息";

let msg = new Message(conId, textMsg);

// 设置支持消息扩展
msg.canIncludeExpansion = true;

// 创建消息扩展数据
let map = new Map<string,string>();
map.set("k1","v1");
map.set("k2","v2");
// 设置扩展数据(可选)
msg.expansion = map;

let option :ISendMsgOption = {};

IMEngine.getInstance().sendMessage(msg,option,(msg: Message) => {
// 消息入库回调
}).then(result => {
if (EngineError.Success !== result.code) {
// 发送消息失败
return;
}
if (!result.data) {
// 消息为空
return;
}
// 发送成功的消息
let message = result.data as Message;
})
参数类型说明
canIncludeExpansionboolean该条消息是否可扩展。true:该消息允许设置扩展信息。false:该消息不允许设置扩展信息。消息发送之后不允许再更改该开关状态。
expansionMap<string, string>消息扩展信息。单次最大设置扩展信息键值对 20 对。单条消息可设置最多 300 个扩展信息。
  • Key 支持大小写英文字母、数字、 特殊字符+ = - _ 的组合方式,不支持汉字。最大 32 个字符。
  • Value 最大 4096 个字符

上例中发送的消息会携带 expansion 方法设置的扩展数据。消息发送成功后,SDK 会将消息及扩展数据存入本地数据库。

更新扩展数据

调用 IMEngineupdateMessageExpansion() 方法更新消息扩展信息。仅支持已打开可扩展属性的消息。更新消息扩展信息后,更新发起者应在成功回调里处理 UI 数据刷新,会话对端可通过消息扩展监听器收到更新的数据。

提示
  • 每次更新(或删除)消息扩展时,SDK 内部将向会话对端发送一条类型标识为 RC:MsgExMsg 的消息扩展信令消息。因此,频繁更新消息扩展会导致产生大量消息。
  • 每个终端在设置扩展信息时,如未达到上限都可以进行设置;在并发情况下,会出现设置超过 300 的情况,超出部分会被丢弃。
  • 如您的业务场景需要在应用服务端处理,也可以通过应用服务端来设置单群聊扩展
// IMEngine

/**
* 更新消息扩展信息
* ```
* 调用更新扩展的一方必须通过成功回调来处理本端的数据刷新。
* 仅被动接收扩展变更的用户(包含本用户的其他端)通过监听方法 MessageExpansionListener.onMessageExpansionUpdate 获取通知。
* 消息扩展信息是以字典形式存在。设置的时候从 expansion 中读取 key,如果原有的扩展信息中 key 不存在则添加新的 KV 对,如果 key 存在则替换成新的 value。
* 扩展信息字典中的 Key 支持大小写英文字母、数字、部分特殊符号 + = - _ 的组合方式,最大长度 32;Value 最长长度 4096,单次设置扩展数量最大为 20,消息的扩展总数不能超过 300
* ```
* @param expansion 要更新的消息扩展信息键值对
* @param messageUid 消息 messageUId
* @returns 结果
* @discussion 扩展信息只支持单聊和群组,其它会话类型不能设置扩展信息
* @version 1.2.0
*/
public updateMessageExpansion(expansion: Map<string, string>, messageUid: string): Promise<IAsyncResult<void>> ;

更新扩展数据示例代码

// 消息 UId 是固定格式的字符串,例如 : CH2C-A072-OGM5-E3HL
let msgUid = "消息 UId";

// 更新的消息扩展数据
let map = new Map<string,string>();
map.set("k1","v1");
map.set("k2","v2");

IMEngine.getInstance().updateMessageExpansion(map, msgUid).then(result => {
if (EngineError.Success !== result.code) {
// 消息扩展更新失败
return;
}
// 消息扩展更新成功
});
参数类型说明
expansionMap<string, string>要更新的消息扩展信息键值对,类型是 HashMap。
  • Key 支持大小写英文字母、数字、 特殊字符+ = - _ 的组合方式,不支持汉字。最大 32 个字符。
  • Value 最大 4096 个字符
messageUIdString消息唯一 Id,通过 Message 对象的 messageUid方法获取。

删除扩展数据

消息发送后调用 IMEngineremoveMessageExpansion 方法删除消息扩展信息中特定的键值对。仅支持已打开可扩展属性的消息。删除消息扩展信息后,发起者应在成功回调里处理删除后的数据刷新,会话对端可通过消息扩展监听器收到通知。

// IMEngine

/**
* 删除消息扩展信息中特定的键值对
* ```
* 调用删除扩展的一方必须通过成功回调来处理本端的数据刷新。
* 仅被动接收扩展变更的用户(包含本用户的其他端)通过监听方法 MessageExpansionListener.onMessageExpansionRemove 获取通知。
* ```
* @param keyArray 消息扩展信息中待删除的 key 的列表
* @param messageUid 消息 messageUId
* @returns 结果
* @discussion 扩展信息只支持单聊和群组,其它会话类型不能设置扩展信息
* @version 1.2.0
*/
public removeMessageExpansion(keyArray: Array<string>, messageUid: string): Promise<IAsyncResult<void>> ;

删除扩展数据示例代码

// 消息 UId 是固定格式的字符串,例如 : CH2C-A072-OGM5-E3HL
let msgUid = "消息 UId";

// 需要删除的 key 数组
let keyArray = new Array<string>();
keyArray.push("k1");


IMEngine.getInstance().removeMessageExpansion(keyArray, msgUid).then(result => {
if (EngineError.Success !== result.code) {
// 删除消息扩展失败
return;
}
// 删除消息扩展成功
});
参数类型说明
keyArrayArray消息扩展信息中待删除的 key 的列表,类型是 Array
messageUIdstring消息唯一 Id,通过 Message 对象的 messageUid 方法获取。

监听消息扩展数据变更

消息扩展监听

消息扩展变更的发起方调用 API 更新、删除扩展数据后,SDK 内部将向会话对端发送一条类型标识为 RC:MsgExMsg 的消息扩展信令消息。MessageExpansionListener 监听器会在 SDK 接收该信令消息后触发相应的回调方法。

// MessageExpansionListener.ts
/**
* 消息扩展监听
* @version 1.2.0
*/
interface MessageExpansionListener {
/**
* 消息扩展信息更改的回调
*
* @param expansion 消息扩展信息中更新的键值对
* @param message 消息
* @discussion 该方法的 expansion 只包含更新的键值对,不是全部的数据。如果想获取全部的键值对,请使用 message 的 expansion 属性。
*/
onMessageExpansionUpdate(expansion: Map<string, string>, message: Message);

/**
* 消息扩展信息删除的回调
* @param keyArray 消息扩展信息中删除的键值对 key 数组
* @param message 消息
*/
onMessageExpansionRemove(keyArray: Array<string>, message: Message);
}


// IMEngine.ts
/**
* 设置消息扩展监听
* @param listener 监听
* @version 1.2.0
*/
public setMessageExpansionListener(listener: MessageExpansionListener): void ;

调用 IMEnginesetMessageExpansionListener 方法设置消息扩展监听器。

let listener: MessageExpansionListener = {

onMessageExpansionUpdate: (expansion: Map<string, string>, message: Message): void => {
let jsonString = JSON.stringify(Array.from(expansion.entries()));
hilog.info(0x0000, 'IM-App', 'onMessageExpansionUpdate result expansion:%{public}s message:%{public}s',
jsonString, JSON.stringify(message));
},

onMessageExpansionRemove: (keyArray: string[], message: Message): void => {
hilog.info(0x0000, 'IM-App', 'onMessageExpansionRemove result keyArray:%{public}s message:%{public}s',
JSON.stringify(keyArray), JSON.stringify(message));
}

}

IMEngine.getInstance().setMessageExpansionListener(listener);
参数类型说明
listenerMessageExpansionListener消息扩展监听器。提供 onMessageExpansionUpdate()(消息扩展信息更改时)和 onMessageExpansionRemove()(消息扩展信息删除时)方法。