Static
get初始化 SDK
整个 App 生命周期内,原则上 SDK 只能初始化一次
SDK 允许调用该方法重复初始化 SDK,但是我们不建议这么做
因为 SDK 重复初始化之后,之前的连接、监听等均会失效,需要将初始化后的操作重新做一遍,如重新连接,并重新设置各种监听
// 在 UIAbility 中获取 context
let context = this.context
let initOption = new InitOption();
let appKey = "从融云后台获取的 appKey";
IMEngine.getInstance().init(context, appKey, initOption);
上下文,为空则初始化失败
融云 appKey,为空则初始化失败
初始化配置,见 InitOption
获取本地时间与服务器时间的时间差。 通过当前本地时间减去此接口返回的时间,即当前服务器时间。
IMEngine.getInstance().getDeltaTime().then(result => {
if (EngineError.Success === result.code) {
let deltaTime = result.data as number
}
});
本地时间与服务器时间的时间差。
上设置断线重连时是否踢出重连设备。
用户没有开通多设备登录功能的前提下,同一个账号在一台新设备上登录的时候,会把这个账号在之前登录的设备上踢出。
由于 SDK 有断线重连功能,存在下面情况: 用户在 A 设备登录,A 设备网络不稳定,没有连接成功,SDK 启动重连机制。 用户此时又在 B 设备登录,B 设备连接成功。 A
设备网络稳定之后,用户在 A 设备连接成功,B 设备被踢出。 这个接口就是为这种情况加的。
let kickEnable = true;
IMEngine.getInstance().setReconnectKickEnable(kickEnable);
设置为 true 时,SDK 重连的时候发现此时已有别的设备连接成功,踢出当前重连设备,不再强行踢出别的设备
设置鸿蒙推送 token
1. SDK 初始化之前设置:SDK 会将推送 token 缓存,连接成功后上报
2. SDK 初始化之后连接之前设置:连接成功后 SDK 自动上报
3. SDK 连接成功后设置:SDK 立即上报
import { pushService } from '@kit.PushKit';
pushService.getToken((error: BusinessError, token: string) => {
if (token) {
IMEngine.getInstance().setPushToken(token);
}
});
推送 token
设置数据库状态监听
数据库打开的时机:参考 DatabaseStatusListener.onDatabaseStatusChange()
IMEngine.getInstance().setDatabaseStatusListener((status: DatabaseStatus) => {
hilog.info(0x0000, 'IM-App', 'setDatabaseStatusListener onChanged status:%{public}d', status);
});
监听
增加数据库状态监听
数据库打开的时机:参考 DatabaseStatusListener.onDatabaseStatusChange()
let dbListener: DatabaseStatusListener = {
onDatabaseStatusChange: (status: DatabaseStatus): void => {
// status 为具体的数据库状态
}
}
IMEngine.getInstance().addDatabaseStatusListener(dbListener);
监听
监听
设置控制台日志级别
例如:填入 LogLevel.None ,SDK 将不再控制台输出日志
例如:填入 LogLevel.Warn ,SDK 将会在控制台输出 Warn 和 Error 的日志
IMEngine.getInstance().setLogLevel(LogLevel.Info)
日志级别,用于过滤控制台的日志输出,初始化之后设置
连接 IM
调用该接口,SDK 会在 timeLimit 秒内尝试重连,直到出现下面三种情况之一
第一、连接成功,回调 IConnectResult.code === EngineError.Success
第二、超时,回调 IConnectResult.code === EngineError.ConnectionTimeout,需要手动调用该接口继续连接
第三、出现 SDK 无法处理的错误,回调 IConnectResult.code 为具体的错误码
常见的错误如下:
ClientNotInit :SDK 没有初始化,请先调用 init 接口
NaviRespTokenIncorrect :检查一下 APP 使用的 appKey 和 APP Server 使用的 appKey 是否相同
ConnectTokenIncorrect :检查一下 APP 使用的 appKey 和 APP Server 使用的 appKey 是否相同
ConnectOneTimePasswordUsed :重新请求 Token
ConnectPlatformError :重新请求 Token
ConnectTokenExpired :重新请求 Token
ConnectAppBlockOrDelete : 给用户提示 AppKey 已经封禁或删除
ConnectUserBlocked :给用户提示被封禁
DisconnectUserKicked :给用户提示被提掉线
DisconnectUserBlocked :给用户提示被封禁
ConnectUserDeleteAccount :给用户提示已销号
let token = "IMToken";
let timeout = 5;
IMEngine.getInstance().connect(token, timeout).then(result => {
if (EngineError.Success === result.code) {
// 连接成功
let userId = result.userId;
return;
}
if (EngineError.ConnectTokenExpired === result.code) {
// Token 过期,从 APP 服务请求新 token,获取到新 token 后重新 connect()
} else if (EngineError.ConnectionTimeout === result.code) {
// 连接超时,弹出提示,可以引导用户等待网络正常的时候再次点击进行连接
} else {
//其它业务错误码,请根据相应的错误码作出对应处理。
}
});
从您服务器端获取的 token (用户身份令牌)
超时时间,整型,单位秒,timeout <= 0:不设置超时时长,一直连接直到成功或失败;timeout > 0: 在对应的时间内连接未成功则返回超时错误
连接结果
设置连接状态监听
每个连接状态都有详细的描述和处理意见,参考 ConnectionStatusListener.onConnectionStatusChanged()
IMEngine.getInstance().setConnectionStatusListener((status: ConnectionStatus) => {
// status 为具体的连接状态
});
监听
增加连接监听。每个连接状态都有详细的描述和处理意见
每个连接状态都有详细的描述和处理意见,参考 ConnectionStatusListener.onConnectionStatusChanged()
let statusListener: ConnectionStatusListener = {
onConnectionStatusChanged: (status: ConnectionStatus): void => {
// status 为具体的连接状态
}
}
IMEngine.getInstance().addConnectionStatusListener(statusListener);
监听
连接监听
获取当前连接状态
IMEngine.getInstance().getCurrentConnectionStatus().then(result => {
if (EngineError.Success !== result.code) {
// 获取当前连接状态失败
return;
}
if (!result.data) {
// 获取的当前连接状态为空
return;
}
let status = result.data as ConnectionStatus;
});
连接状态
获取当前用户 ID
IMEngine.getInstance().getCurrentUserId().then(result => {
if (EngineError.Success !== result.code) {
// 获取用户 ID 失败
return;
}
if (!result.data) {
// 获取的用户 ID 为空
return;
}
let userId = result.data as string;
});
连接成功后才会有值
设置消息接收监听
IMEngine.getInstance().setMessageReceivedListener((message: Message, info: ReceivedInfo) => {
// 针对接收离线消息时,服务端会将 200 条消息打成一个包发到客户端,客户端对这包数据进行解析。该参数表示每个数据包数据逐条上抛后,还剩余的条数
let left = info.left;
// 消息是否离线消息
let isOffline = info.isOffline;
// 是否在服务端还存在未下发的消息包
let hasPackage = info.hasPackage;
});
监听
添加消息接收监听,可以添加多个监听
let messageReceiveListener: MessageReceivedListener = {
onMessageReceived: (message: Message, info: ReceivedInfo): void => {
// 收到了单条消息
},
onOfflineMessageSyncCompleted: (): void => {
// 离线消息已全部拉取完成
}
};
IMEngine.getInstance().addMessageReceivedListener(messageReceiveListener);
监听
监听
设置消息撤回监听,撤回了之后,原始消息会变成 RecallNotificationMessage 消息
IMEngine.getInstance().setMessageRecalledListener((message: Message, recallMessage: RecallNotificationMessage) => {
});
监听
增加消息撤回监听。撤回了之后,原始消息会变成 RecallNotificationMessage 消息
let recalledListener : MessageRecalledListener = {
onMessageRecalled: (message: Message, recallMessage: RecallNotificationMessage): void => {
// 消息撤回
}
}
IMEngine.getInstance().addMessageRecalledListener(recalledListener);
监听
监听
设置消息敏感词拦截监听
IMEngine.getInstance().setMessageBlockedListener((blockInfo: MessageBlockInfo) => {
});
监听
增加消息敏感词拦截监听
let blockedListener : MessageBlockedListener = {
onMessageBlocked: (blockInfo: MessageBlockInfo): void => {
}
}
IMEngine.getInstance().addMessageBlockedListener(blockedListener);
监听
监听
发送消息
如果遇到 DatabaseNotOpened = 34301 ,原因是在 IM 连接成功前发送了消息
IM 连接成功后 SDK 才会打开对应用户的消息数据库
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
let textMsg = new TextMessage();
textMsg.content = "文本消息的内容";
let msg = new Message(conId, textMsg);
let option: ISendMsgOption = {};
IMEngine.getInstance().sendMessage(msg, option, (msg: Message) => {
// 消息入库回调
}).then(result => {
if (EngineError.Success !== result.code) {
// 发送消息失败
return;
}
if (!result.data) {
// 消息数据为空
return;
}
let msg = result.data as Message;
})
消息对象
消息发送的配置
消息入库的回调
消息发送结果
发送媒体消息
如果遇到 DatabaseNotOpened = 34301 ,原因是在 IM 连接成功前发送了消息
IM 连接成功后 SDK 才会打开对应用户的消息数据库
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
let imgMsg = new ImageMessage();
// 使用沙盒路径创建图片消息。系统路径的图片 SDK 无法访问(例如相册的图片路径 SDK 就无法访问)
imgMsg.localPath = localPath;
let msg = new Message(conId, imgMsg);
let option: ISendMsgOption = {};
IMEngine.getInstance().sendMediaMessage(msg, option, (msg: Message) => {
// 消息保存到数据库
}, (msg: Message, progress: number) => {
// 媒体上传进度 [1 ~ 100]
}).then(result => {
if (EngineError.Success !== result.code) {
//发送消息失败
return;
}
if (!result.data) {
// 消息为空
return;
}
let msg = result.data as Message;
})
消息体
消息发送的配置
消息入库的回调
媒体文件上传进度
媒体消息发送结果
使用自定义上传发送媒体消息
如果遇到 DatabaseNotOpened = 34301 ,原因是在 IM 连接成功前发送了消息
IM 连接成功后 SDK 才会打开对应用户的消息数据库
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
let imgMsg = new ImageMessage();
// 使用沙盒路径创建图片消息。系统路径的图片 SDK 无法访问(例如相册的图片路径 SDK 就无法访问)
imgMsg.localPath = localPath;
let msg = new Message(conId, imgMsg);
let option: ISendMsgOption = {};
IMEngine.getInstance().sendMediaMessageWithUploader(msg, option, (msg: Message) => {
// 消息保存到数据库
}, (msg: Message, progress: number) => {
// 媒体上传进度 [1 ~ 100]
}, (uploader: MediaMessageTransfer) => {
// app 需要在该回调里面做上传业务,并把上传进度,上传结果通知 sdk
// 此处 for 循环模拟上传进度。实际应该是 app 真实的上传进度
for (let index = 1; index < 101; index++) {
// 这里的进度取值范围必须是 [1 ~ 100]
uploader.updateProgress(index);
}
// 模拟 app 是否上传媒体成功
let appUploadSuccess = true;
if (appUploadSuccess) {
// app 上传媒体成功了,调用 uploader.success 通知 sdk 上传成功了,sdk 就会将该消息带着远端 url 直接发送出去
uploader.success("https://exmaple.com/123.jpg");
}else {
// 如果 app 上传失败,调用 uploader.error 通知 sdk 上传失败了,sdk 会触发失败回调
uploader.error();
}
}).then(result => {
if (EngineError.Success !== result.code) {
//发送消息失败
return;
}
if (!result.data) {
// 消息为空
return;
}
let msg = result.data as Message;
})
消息体
消息发送的配置
消息入库的回调
媒体文件上传进度
Optional
uploadCallback: (uploader: MediaMessageTransfer) => void[可选参数]自定义媒体文件上传回调,如果此参数不传则执行SDK默认流程
媒体消息发送结果
取消发送媒体消息下载
let messageId = 123;
IMEngine.getInstance().cancelSendMediaMessage(messageId).then(result => {
if (EngineError.Success === result.code) {
// 取消发送媒体消息成功
} else {
// 取消发送媒体消息成功失败
}
});
消息 Id
取消发送媒体消息结果
发送普通定向消息
此方法用于在群组中发送消息给其中的部分用户,其它用户不会收到这条消息。
如果遇到 DatabaseNotOpened = 34301 ,原因是在 IM 连接成功前发送了消息
IM 连接成功后 SDK 才会打开对应用户的消息数据库
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "群组 id";
let textMsg = new TextMessage();
textMsg.content = "文本消息的内容";
let msg = new Message(conId, textMsg);
let option: ISendMsgOption = {};
// 填入实际的用户 id
let userIdArray = ["userId1", "userId2"];
IMEngine.getInstance().sendDirectionalMessage(msg, option, userIdArray, (msg: Message) => {
// 消息入库回调
}).then(result => {
if (EngineError.Success !== result.code) {
// 发送消息失败
return;
}
if (!result.data) {
// 消息数据为空
return;
}
let msg = result.data as Message;
})
消息对象
消息发送的配置
消息指定接收者
消息入库的回调,
消息发送结果
发送媒体定向消息
此方法用于在群组中发送消息给其中的部分用户,其它用户不会收到这条消息。
如果遇到 DatabaseNotOpened = 34301 ,原因是在 IM 连接成功前发送了消息
IM 连接成功后 SDK 才会打开对应用户的消息数据库
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "群组 id";
let imgMsg = new ImageMessage();
// 使用沙盒路径创建图片消息。系统路径的图片 SDK 无法访问(例如相册的图片路径 SDK 就无法访问)
imgMsg.localPath = localPath;
let msg = new Message(conId, imgMsg);
let option: ISendMsgOption = {};
// 填入实际的用户 id
let userIdArray = ["userId1", "userId2"];
IMEngine.getInstance().sendDirectionalMediaMessage(msg, option, userIdArray, (msg: Message) => {
// 消息保存到数据库
}, (msg: Message, progress: number) => {
// 媒体上传进度 [1 ~ 100]
}).then(result => {
if (EngineError.Success !== result.code) {
//发送消息失败
return;
}
if (!result.data) {
// 消息为空
return;
}
let msg = result.data as Message;
})
消息体
消息发送的配置
消息指定接收者
消息发送的配置
媒体文件上传进度
媒体消息发送结果
下载媒体消息
let messageId = 234;
IMEngine.getInstance().downloadMediaMessage(messageId).then(result => {
if (EngineError.Success === result.code) {
// 本地路径
let localPath = result.data as string;
}
});
消息 id,对应的消息必须是 MediaMessageContent 子类
媒体消息下载成功的本地路径,存储路径见 InitOption.mediaSavePath
下载媒体消息,含下载进度
let messageId = 123;
IMEngine.getInstance().downloadMediaMessageWithProgress(messageId, (messageId: number, progress: number) => {
// 下载进度,取值范围 [0 , 100]
}).then(result => {
if (EngineError.Success === result.code) {
// 本地路径
let localPath = result.data as string;
}
});
消息 Id,对应的消息必须是 MediaMessageContent 子类
下载进度监听,取值范围 [0 , 100]
媒体消息下载成功的本地路径,存储路径见 InitOption.mediaSavePath
使用自定义方法下载媒体消息
let messageId = 234;
IMEngine.getInstance().downloadMediaMessageWithDownloader(
messageId,
(messageId: number, progress: number) => {
// 下载进度,取值范围 [0 , 100]
},
(downloader: MediaMessageTransfer) => {
downloadImg(imgMsg.getPicFilePath(), new downloadListener() {
public onSuccess(localPath: string): void {
downloader.success(localPath);
}
}
}
).then(result => {
if (EngineError.Success === result.code) {
// 本地路径
let localPath = result.data as string;
}
});
消息 id,对应的消息必须是 MediaMessageContent 子类
Optional
downloadCallback: (downloader: MediaMessageTransfer) => void[可选参数]自定义媒体文件下载回调,如果此参数不传则执行SDK默认流程
媒体消息下载成功的本地路径,存储路径见 InitOption.mediaSavePath
暂停媒体消息下载
let messageId = 123;
IMEngine.getInstance().pauseDownloadMediaMessage(messageId).then(result => {
if (EngineError.Success === result.code) {
// 暂停下载成功,此时 downloadMediaMessageWithProgress 会返回 EngineError.RequestPaused
} else {
// 暂停下载失败
}
});
消息 Id
暂停下载结果
取消下载媒体消息,配合 downloadMediaMessageWithProgress 方法
let messageId = 123;
IMEngine.getInstance().cancelDownloadMediaMessage(messageId).then(result => {
if (EngineError.Success === result.code) {
// 下载取消成功,此时 downloadMediaMessageWithProgress 会返回 EngineError.RequestCanceled
} else {
// 下载取消失败
}
});
消息 Id
取消下载结果
下载文件(带下载进度)
如果是下载媒体消息,请调用 downloadMediaMessageWithProgress 方法,下载成功 SDK 会更新媒体消息的本地路径
不是媒体消息的媒体文件需要下载时,才调用 downloadFileWithProgress
会将 file_name 最后一个 . 之前的特殊替换为下划线。如 abc@123.png 会被替换为 abc_123.png。
如果多次请求 file_name 相同,后一次下载会加入序号,如 abc.png,abc(1).png,abc(2).png。
let remoteUrl = "https://expamle.com/1.jpg";
let fileName = "1.jpg";
IMEngine.getInstance().downloadFileWithProgress(remoteUrl, fileName, (uniqueId: number) => {
// 开始下载,下载唯一标识 uniqueId
}, (uniqueId: number, progress: number) => {
// 下载进度
}).then(result => {
if (EngineError.Success !== result.code) {
// 下载失败
return;
}
if (!result.data) {
// 下载的本地路径为空
return;
}
// 本地路径
let localPath = result.data as string;
});
媒体的远端地址
本地文件名
开始下载。uniqueId 下载唯一标识,可以调用 cancelDownloadFile 取消下载
下载进度监听,取值范围 [0 , 100]
媒体文件下载成功的本地路径,存储路径见 InitOption.mediaSavePath
下载媒体文件
// uniqueId 是下载媒体文件任务的标识,可以用来发起下载、暂停下载和取消下载。
// 与 pauseDownloadMediaFile 和 cancelDownloadFile 中的 uniqueId 保持一致。
let uniqueId = "123"
let remoteUrl = "https://expamle.com/1.jpg";
let fileName = "1.jpg";
IMEngine.getInstance().downloadMediaFile(uniqueId, remoteUrl, fileName,
(uniqueId: string) => {
// 开始下载,下载唯一标识 uniqueId
},
(uniqueId: string, progress: number) => {
// 下载进度
}).then(result => {
if (EngineError.Success !== result.code) {
// 下载失败
return;
}
if (!result.data) {
// 下载的本地路径为空
return;
}
// 本地路径
let localPath = result.data as string;
});
文件唯一标示
文件的远端地址
本地文件名
下载进度监听,取值范围 [0 , 100]
媒体文件下载成功的本地路径,存储路径见 InitOption.mediaSavePath
暂停下载媒体文件
// messageId 与 downloadMediaFile 的第一个参数对应
let messageId = "123";
IMEngine.getInstance().pauseDownloadMediaFile(messageId).then(result => {
if (EngineError.Success === result.code) {
// 暂停下载成功,此时 downloadMediaFile 会返回 EngineError.RequestCanceled
} else {
// 暂停下载失败
}
});
下载的结果
取消下载文件,配合 downloadFileWithProgress 方法
// uniqueId 必须是调用 downloadFileWithProgress 时由 SDK 生成的,此处进行了简写
let uniqueId = "1234";
IMEngine.getInstance().cancelDownloadFile(uniqueId).then(result => {
if (EngineError.Success !== result.code) {
// 取消下载失败
return;
}
// 取消下载成功,此时 downloadFileWithProgress 会返回 EngineError.RequestCanceled
})
下载唯一标识
下载的结果
撤回消息
// 必须用发送成功的消息,此处进行了简写
let message : Message;
IMEngine.getInstance().recallMessage(message).then(result => {
if (EngineError.Success !== result.code) {
// 消息撤回失败
return;
}
if (!result.data) {
// 撤回小灰条消息为空
return;
}
// 撤回小灰条消息
let recallNtfMsg = result.data as RecallNotificationMessage;
})
需要撤回的消息,发送成功的消息才能撤回(必须有有效的 MessageUid)
撤回成功后的小灰条消息
注册自定义消息,初始化之后,连接之前调用
自定义消息 CustomOrderMessage 示例代码见 MessageContent
自定义媒体消息 CustomFileMessage 示例代码见 MediaMessageContent
let clazzList: List<MessageContentConstructor> = new List();
clazzList.add(CustomOrderMessage);
IMEngine.getInstance().registerMessageType(clazzList);
自定义消息数组
获取 SDK 中所有的消息 objectName 和存储标识的映射关系
1. 映射关系集合包含 内置消息 和 自定义消息
2. 必须在所有自定义消息注册完成之后再调用该方法,否则会导致无法正确获取自定义消息的映射关系
3. 不要频繁调用该方法:建议 app 调用该方法之后, app 自行保存整个集合
iOS 通过 RCMessagePersistentCompatible.persistentFlag 获取消息存储标识
Android 通过 getClass().getAnnotation(MessageTag.class) 获取消息存储标识
鸿蒙需要通过本方法获取
1. 发送消息时需要手动构造指定的消息体,可以直接获取到 objectName:例如创建文本消息时一定知道是文本消息的 objectName
2. 接收消息时通过 Message 对象获取:Message.objectName
3. 读取会话时通过 Conversation 对象获取:Conversation.objectName
let hashMap = IMEngine.getInstance().getMessageTypeMap();
映射关系集合。 key :objectName 、 value : MessageFlag
消息批量入库(多用于数据迁移)
conversationType 会话类型
targetId 会话 ID
channelId 所属会话的业务标识,长度限制 20 字符
direction 消息方向
senderId 发送者 ID
receivedStatus 接收状态:direction 为 Receive 且 receivedStatus.isRead 为 false 时,会话未读数累加
sentStatus 发送状态
sentTime 发送时间
content 消息内容
objectName 消息类型,设置 content 的时候 SDK 会自动赋值对应的 objectName
messageUid 服务端生产的消息唯一 ID,如要携带该字段需要保证入库后是唯一的
extra 扩展信息
// 必须是有效的消息集合,此处进行了简写
let msgList : List<Message> ;
IMEngine.getInstance().batchInsertMessage(msgList).then(result => {
if (EngineError.Success !== result.code) {
// 批量入库失败
return;
}
// 批量入库成功
});
需要入库的消息,范围 [1 ~ 500],会话类型不支持聊天室和超级群
入库结果
单条消息入库
conversationType 会话类型
targetId 会话 ID
direction 消息方向,默认为发送
senderId 发送者 ID
receivedStatus 接收状态:direction 为 Receive 且 receivedStatus.isRead 为 false 时,会话未读数累加
sentStatus 发送状态,默认为发送失败
sentTime 发送时间
content 消息内容
objectName 消息类型,设置 content 的时候 SDK 会自动赋值对应的 objectName
messageUid 服务端生产的消息唯一 ID,如要携带该字段需要保证入库后是唯一的
extra 扩展信息
// 必须是有效的消息对象,此处进行了简写
let msg : Message;
IMEngine.getInstance().insertMessage(msg).then(result => {
if (EngineError.Success !== result.code) {
// 入库失败
return;
}
if (!result.data) {
// 入库的消息体为空
return;
}
// 入库成功的消息,含有效的 messageId
let dbMsg = result.data as Message;
});
入库结果
批量获取本地和远端消息,支持单聊、群聊、系统消息。
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let option: IHistoryMessageOption = {
sendTime: 0,
count: 100,
order: Order.Ascending
}
IMEngine.getInstance().getMessages(conId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取历史消息失败
return;
}
if (!result.data) {
// 获取历史消息为空
return;
}
// 获取到有效的历史消息
let dbMsg = result.data as HistoryMessageResult;
})
会话标识
历史消息选项
历史消息数据,详见 HistoryMessageResult
通过 messageId 获取单条消息
let messageId = 123;
IMEngine.getInstance().getMessageById(messageId).then(result => {
if (EngineError.Success !== result.code) {
// 获取本地消息失败
return;
}
if (!result.data) {
// 获取本地消息为空
return;
}
// 获取到有效的本地消息
let dbMsg = result.data as Message;
})
消息的本地数据库自增 ID
消息数据
通过 messageUid 获取单条消息
let messageUid = "CH2C-A072-OGM5-E3HL";
IMEngine.getInstance().getMessageByUid(messageUid).then(result => {
if (EngineError.Success !== result.code) {
// 获取本地消息失败
return;
}
if (!result.data) {
// 获取本地消息为空
return;
}
// 获取到有效的本地消息
let dbMsg = result.data as Message;
})
消息发送成功后的服务唯一 ID,固定格式的字符串,例如 : CH2C-A072-OGM5-E3HL
消息数据
获取批量本地消息,基于 messageId 获取
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let option: IGetLocalMsgByIdOption = {
messageId: 100,
beforeCount: 5,
afterCount: 5
}
IMEngine.getInstance().getHistoryMessagesById(conId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息体集合
let msgList = result.data as List<Message>;
});
会话标识
配置
返回本地消息结果
获取批量本地消息,基于 time 获取
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let option: IGetLocalMsgByTimeOption = {
time: Date.now(),
beforeCount: 5,
afterCount: 5
};
IMEngine.getInstance().getHistoryMessagesByTime(conId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息列表
let msgList = result.data as List<Message>;
});
会话标识
配置
返回本地消息结果
获取批量远端消息
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let option: IGetRemoteMsgOption = {
time: Date.now(),
count: 10,
order: Order.Descending,
isCheckDup: true
}
IMEngine.getInstance().getRemoteHistoryMessages(conId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取聊天室消息失败
return;
}
if (!result.data) {
// 消息数据为空
return;
}
// 消息列表
let msgList = result.data as List<Message>;
});
会话标识
配置
返回远端消息结果
获取本地会话中 @ 自己的未读消息列表
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let option: ICountOption = {
count: 10,
order: Order.Descending
};
IMEngine.getInstance().getUnreadMentionedMessages(conId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息列表
let msgList = result.data as List<Message>;
});
会话标识
配置
返回本地消息结果
获取会话里第一条未读消息
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().getFirstUnreadMessage(conId).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
let msg = result.data as Message;
});
会话标识
消息,如果该会话没有未读,返回 null
删除本地会话的指定一批消息
let idList = new List<number>();
idList.add(msg.messageId);
IMEngine.getInstance().deleteHistoryMessagesByIds(idList).then(result => {
if (EngineError.Success !== result.code) {
// 删除消息失败
return;
}
// 删除消息成功
})
消息 ID 列表
删除结果
清空本地会话的消息
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().deleteMessages(conId).then(result => {
if (EngineError.Success !== result.code) {
// 删除消息失败
return;
}
// 删除消息成功
});
会话标识
结果
删除本地会话特定时间前的所有消息
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let sentTime = Date.now();
IMEngine.getInstance().deleteHistoryMessagesByTime(conId, time).then(result => {
if (EngineError.Success !== result.code) {
// 删除消息失败
return;
}
// 删除消息成功
})
会话标识
毫秒时间戳。清除 <= sentTime 的所有历史消息,若为 0 则代表清除所有消息
结果
删除远端会话特定时间前的消息
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let sentTime = Date.now();
IMEngine.getInstance().cleanRemoteHistoryMessagesByTime(conId, time).then(result => {
if (EngineError.Success !== result.code) {
// 删除消息失败
return;
}
// 删除消息成功
});
会话标识
毫秒时间戳。清除 <= sentTime 的所有历史消息,若为 0 则代表清除所有消息
结果
批量删除远端消息,发送成功或者接收到的消息才可以从远端删除
msgList 里面 Message 下列属性是必须的
uid: 服务端生产的消息唯一 id
direction: 消息方向
sentTime: 发送时间,不能小于等于 0
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 ID";
let msgList = new List<Message>();
for (let i = 0; i < 10; i++) {
// msg 必须是发送成功的消息,此处进行简写
let msg : Message;
msgList.add(msg);
}
// 是否删除本地消息
let isDeleteLocal = true;
IMEngine.getInstance().deleteRemoteMessages(conId, msgList, isDeleteLocal).then(result => {
if (EngineError.Success !== result.code) {
// 删除远端消息失败
return;
}
// 删除远端消息成功
})
会话标识
消息列表,长度范围 [1, 100]
是否删除本地消息。只有远端消息被删除成功时设置 true 才会删除本地消息。
设置输入状态的监听
IMEngine.getInstance().setTypingStatusListener((conId: ConversationIdentifier, typingStatusList: List<TypingStatus>) => {
// conId 具体的会话标识
// typingStatusList 具体的输入状态
});
监听,conId 会话标识;typingStatusList 输入状态的列表
增加输入状态的监听
let typingListener: TypingStatusListener = {
onTypingStatusChange: (conId: ConversationIdentifier, typingStatusList: List<TypingStatus>): void => {
// conId 具体的会话标识
// typingStatusList 具体的输入状态
}
}
IMEngine.getInstance().addTypingStatusListener(typingListener);
监听
监听,对方调用 sendTypingStatus() 时本端会出发该监听
发送输入状态,仅支持单聊
常见的使用方式如下:
在聊天页面输入文本时,可以发送 TextMessageObjectName ,对方收到后可以展示"正在输入中"
在录音时,可以发送 HQVoiceMessageObjectName ,对方收到后可以展示"正在说话"
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 ID";
let objectName = TextMessageObjectName;
IMEngine.getInstance().sendTypingStatus(conId, objectName).then(result => {
if (EngineError.Success !== result.code) {
// 发送失败
return;
}
// 发送成功
});
会话标识
正在输入的消息 ObjectName
设置输入状态更新时间间隔
控制输入状态发送频率,在规定时间内多次调用发送输入状态方法,最终只会发送一次输入状态
例如输入状态时间间隔为 6000 毫秒,在这段时间多次调用输入状态方法,只会发出一次输入状态,对方也只会收到一次输入状态
let interval = 5000;
IMEngine.getInstance().setTypingStatusInterval(interval).then(result => {
if (EngineError.Success !== result.code) {
// 设置输入状态间隔失败
return;
}
// 设置成功
});
时间间隔,单位毫秒,默认为 6000 毫秒。有效值 [1000,60000] 毫秒;超过范围,则设置不成功
修改消息接收状态
目前该方法仅用于设置 isListened 来标记高清语音消息是否已被听过
let messageId = 123;
let receivedStatus = new ReceivedStatus();
receivedStatus.isRead = false;
receivedStatus.isListened = false;
IMEngine.getInstance().setMessageReceivedStatus(messageId, receivedStatus).then(result => {
if (EngineError.Success !== result.code) {
// 设置接收状态失败
return;
}
// 设置接收状态成功
})
消息 Id
接收状态
结果
设置本地消息的附加信息
用于扩展消息的使用场景。设置后可以通过 getHistoryMessages 取出带附加信息的消息。
let messageId = 123;
let extra = "这是要更新的 extra 字段内容";
IMEngine.getInstance().setMessageExtra(messageId, extra).then(result => {
if (EngineError.Success == result.code) {
// 设置 extra 字段内容成功
} else {
// 设置 extra 字段内容失败
}
})
消息 Id
返回设置成功或者失败
设置消息扩展监听
let listener: MessageExpansionListener = {
onMessageExpansionUpdate: (expansion: Map<string, string>, message: Message): void => {
},
onMessageExpansionRemove: (keyArray: string[], message: Message): void => {
}
}
IMEngine.getInstance().setMessageExpansionListener(listener);
监听
增加消息扩展监听
let listener: MessageExpansionListener = {
onMessageExpansionUpdate: (expansion: Map<string, string>, message: Message): void => {
},
onMessageExpansionRemove: (keyArray: string[], message: Message): void => {
}
}
IMEngine.getInstance().addMessageExpansionListener(listener);
监听
监听
更新消息扩展信息
调用更新扩展的一方必须通过成功回调来处理本端的数据刷新。
仅被动接收扩展变更的用户(包含本用户的其他端)通过监听方法 MessageExpansionListener.onMessageExpansionUpdate 获取通知。
消息扩展信息是以字典形式存在。设置的时候从 expansion 中读取 key,如果原有的扩展信息中 key 不存在则添加新的 KV 对,如果 key 存在则替换成新的 value。
扩展信息字典中的 Key 支持大小写英文字母、数字、部分特殊符号 + = - _ 的组合方式,最大长度 32;Value 最长长度 4096,单次设置扩展数量最大为 20,消息的扩展总数不能超过 300
// 消息 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;
}
// 消息扩展更新成功
});
要更新的消息扩展信息键值对
消息 messageUId
结果
删除消息扩展信息中特定的键值对
调用删除扩展的一方必须通过成功回调来处理本端的数据刷新。
仅被动接收扩展变更的用户(包含本用户的其他端)通过监听方法 MessageExpansionListener.onMessageExpansionRemove 获取通知。
// 消息 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;
}
// 删除消息扩展成功
});
消息扩展信息中待删除的 key 的列表
消息 messageUId
结果
增加消息阅后即焚监听,仅支持单聊,仅限阅后即焚消息的接收方调用
let destructListener: MessageDestructionListener = {
onMessageDestructing: (message: Message, leftDuration: number): void => {
},
onMessageDestructionStop: (message: Message): void => {
}
}
IMEngine.getInstance().addMessageDestructionListener(destructListener);
监听
移除消息阅后即焚监听,仅支持单聊,仅限阅后即焚消息的接收方调用
IMEngine.getInstance().removeMessageDestructionListener(destructListener);
监听
消息开始阅后即焚倒计时,仅支持单聊,仅限阅后即焚消息的接收方调用
// 必须使用有效的消息体,此处进行了简写
let msg: Message;
IMEngine.getInstance().messageBeginDestruct(msg).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
消息体
消息停止阅后即焚倒计时,仅支持单聊,仅限阅后即焚消息的接收方调用
调用之后,该消息终止阅后即焚
阅后即焚倒计时停止,并触发 MessageDestructionListener.onMessageDestructionStop
可以调用 messageBeginDestruct() 重新进行倒计时
// 必须使用有效的消息体,此处进行了简写
let msg: Message;
IMEngine.getInstance().messageStopDestruct(msg).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
消息体
设置显示推送详情
通知栏显示的消息推送默认显示的是消息内容,如果消息包含敏感信息,不希望在推送通知栏上显示消息内容,可以调用此方法设置 showStatus 为 false
注意:此功能需要从服务端开启用户设置功能。
let showStatus = true;
IMEngine.getInstance().setPushContentShowStatus(showStatus).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
是否显示远程推送内容,true 显示,false 不显示
设置的结果
获取是否显示远程推送内容详情设置
IMEngine.getInstance().getPushContentShowStatus().then(result => {
if (EngineError.Success !== result.code) {
// 获取失败
return;
}
if (!result.data) {
// 数据为空
return;
}
let showStatus = result.data as boolean;
});
是否显示远程推送内容,true 显示,false 不显示
设置 Web 端在线时,手机端是否接收推送
注意:此功能需要从服务端开启用户设置功能。
let receiveStatus = true;
IMEngine.getInstance().setPushReceiveStatus(receiveStatus).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
是否接收推送,true 接收,false 不接收
结果
获取是否接收远程推送的设置
前提: 移动端不在线,Web 、MAC/PC 终端在线,移动端是否接收远程推送。
IMEngine.getInstance().getPushReceiveStatus().then(result => {
if (EngineError.Success !== result.code) {
// 获取失败
return;
}
if (!result.data) {
// 数据为空
return;
}
let receiveStatus = result.data as boolean;
});
是否接收远程推送,true 接收,false 不接收
设置会话状态(置顶,消息免打扰)变化监听
IMEngine.getInstance().setConversationStatusListener((items: List<ConversationStatusInfo>) => {
});
监听
增加会话状态(置顶,消息免打扰)变化监听
let statusListener : ConversationStatusListener = {
onConversationStatusChange: (items: List<ConversationStatusInfo>): void => {
}
}
IMEngine.getInstance().addConversationStatusListener(statusListener);
监听
监听
获取单个会话
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().getConversation(conId).then(result => {
if (EngineError.Success !== result.code) {
// 获取回话失败
return;
}
if (!result.data) {
// 会话为空
return;
}
let con = result.data as Conversation;
});
会话标识
会话数据
分页获取本地会话列表
let conTypeList = new List<ConversationType>();
conTypeList.add(ConversationType.Private);
conTypeList.add(ConversationType.Group);
let option: IGetConversationOption = {
time: Date.now(),
count: 10
}
IMEngine.getInstance().getConversationListByPage(conTypeList, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取会话列表失败
return;
}
if (!result.data) {
// 会话列表为空
return;
}
let conList = result.data as List<Conversation>;
});
会话类型列表
配置
本地会话列表数据
分页获取本地置顶会话列表
let conTypeList = new List<ConversationType>();
conTypeList.add(ConversationType.Private);
conTypeList.add(ConversationType.Group);
let option: IGetConversationOption = {
time: Date.now(),
count: 10
}
IMEngine.getInstance().getTopConversationListByPage(conTypeList, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取会话列表失败
return;
}
if (!result.data) {
// 会话列表为空
return;
}
let conList = result.data as List<Conversation>;
});
会话类型列表
配置
本地会话列表数据
分页获取本地免打扰会话列表
let conTypeList = new List<ConversationType>();
conTypeList.add(ConversationType.Private);
conTypeList.add(ConversationType.Group);
let option: IGetConversationOption = {
time: Date.now(),
count: 10
}
IMEngine.getInstance().getBlockedConversationListByPage(conTypeList, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取会话列表失败
return;
}
if (!result.data) {
// 会话列表为空
return;
}
let conList = result.data as List<Conversation>;
});
会话类型列表
配置
本地会话列表数据
获取本地未读会话列表,该接口仅支持单聊、群聊、系统三种会话类型,不支持聊天室、超级群。
let conTypeList = new List<ConversationType>();
conTypeList.add(ConversationType.Private);
conTypeList.add(ConversationType.Group);
IMEngine.getInstance().getUnreadConversations(conTypeList).then(result => {
if (EngineError.Success !== result.code) {
// 获取未读会话列表失败
return;
}
if (!result.data) {
// 获取未读会话列表为空
return;
}
// 未读会话列表
let conList = result.data as List<Conversation>;
});
会话类型数组,长度范围 [1, 100]
会话数组
删除本地会话同时删除会话中的消息
let conTypeList = new List<ConversationType>();
conTypeList.add(ConversationType.Private);
IMEngine.getInstance().clearConversations(conTypeList).then(result => {
if (EngineError.Success !== result.code) {
// 删除会话失败
return;
}
});
会话类型列表
结果
批量删除本地会话,但是不会删除消息
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let list = new List<ConversationIdentifier>();
list.add(conId);
IMEngine.getInstance().removeConversations(conIdList).then(result => {
if (EngineError.Success !== result.code) {
// 删除会话失败
return;
}
});
会话标识数组
结果
批量删除远端会话
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let conIds : Array<ConversationIdentifier> = [];
conIds.push(conId);
IMEngine.getInstance().removeRemoteConversations(conIds).then(result => {
if (EngineError.Success !== result.code) {
// 删除会话失败
return;
}
});
结果
设置实时会话的已读时间
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let timestamp = 1234567; // 按需填写实际的 timestamp
IMEngine.getInstance().setReadTimestamp(conId, timestamp).then(result => {
if (EngineError.Success !== result.code) {
// 设置实时会话的已读时间失败
} else {
// 设置实时会话的已读时间成功
}
});
会话标识
时间戳
结果
批量 设置/取消 会话置顶
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let list = new List<ConversationIdentifier>();
list.add(conId);
let option: ISetConversationTopOption = {
isTop: true, // 是否置顶
isNeedCreate: true // 没有会话时是否创建该会话
}
IMEngine.getInstance().setConversationsToTop(conIdList, option).then(result => {
if (EngineError.Success !== result.code) {
// 设置置顶失败
return;
}
});
会话标识列表
配置
结果
获取会话置顶状态
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().getConversationTopStatus(conId).then(result => {
if (EngineError.Success !== result.code) {
// 获取置顶状态失败
return;
}
if (!result.data) {
// 置顶状态为空
return;
}
let isTop = result.data as boolean;
});
会话标识
是否置顶
批量设置会话免打扰
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let list = new List<ConversationIdentifier>();
list.add(conId);
let level = PushNotificationLevel.Blocked;
IMEngine.getInstance().setConversationsNotificationLevel(conIdList, level).then(result => {
if (EngineError.Success !== result.code) {
// 设置免打扰失败
return;
}
});
会话标识列表
会话免打扰级别
结果
获取单个会话免打扰状态
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().getConversationNotificationLevel(conId).then(result => {
if (EngineError.Success !== result.code) {
// 获取免打扰状态失败
return;
}
if (!result.data) {
// 免打扰状态为空
return;
}
let level = result.data as PushNotificationLevel;
});
会话标识
会话免打扰级别
保存/清空 会话草稿
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let draft = "draft From 鸿蒙";
IMEngine.getInstance().saveTextMessageDraft(conId, draft).then(result => {
if (EngineError.Success !== result.code) {
// 保存草稿失败
return;
}
});
会话标识
草稿:传入有效值代表保存草稿;传入空字符串代表清空草稿
结果
获取会话草稿
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().getTextMessageDraft(conId).then(result => {
if (EngineError.Success !== result.code) {
// 获取草稿失败
return;
}
if (!result.data) {
// 草稿为空
return;
}
let draft = result.data as string;
})
会话标识
草稿
屏蔽某个时间段的消息提醒
let option: IQuietHoursOption = {
startTime: "00:30:00",
duration: 300,
level: PushNotificationLevel.Blocked
}
IMEngine.getInstance().setNotificationQuietHoursLevel(option).then(result => {
if (EngineError.Success !== result.code) {
// 设置免打扰失败
return;
}
})
配置,见 IQuietHoursOption
结果
查询已设置的时间段消息提醒屏蔽
IMEngine.getInstance().getNotificationQuietHoursLevel().then(result => {
if (EngineError.Success !== result.code) {
// 获取免打扰失败
return;
}
if (!result.data) {
// 免打扰数据为空
return;
}
let info = result.data as IQuietHoursOption;
})
具体的配置
删除已设置的全局时间段消息提醒屏蔽
IMEngine.getInstance().removeNotificationQuietHours().then(result => {
if (EngineError.Success !== result.code) {
// 移除免打扰失败
return;
}
// 移除免打扰成功
});
结果
获取本地会话的全部未读数
IMEngine.getInstance().getTotalUnreadCount().then(result => {
if (EngineError.Success !== result.code) {
// 获取未读数失败
return;
}
if (!result.data) {
// 未读数为 null
return;
}
let unreadCount = result.data as number;
})
未读数
获取本地批量会话的未读数之和
let conIdList = new List<ConversationIdentifier>();
let conId1 = new ConversationIdentifier();
conId1.conversationType = ConversationType.Private;
conId1.targetId = "会话 id";
conIdList.add(conId1)
let conId2 = new ConversationIdentifier();
conId2.conversationType = ConversationType.Private;
conId2.targetId = "会话 id";
conIdList.add(conId2)
IMEngine.getInstance().getTotalUnreadCountByIds(conIdList).then(result => {
if (EngineError.Success !== result.code) {
// 获取未读数失败
return;
}
if (!result.data) {
// 未读数为 null
return;
}
let unreadCount = result.data as number;
})
会话标识数组
未读数
获取单个会话的未读数
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().getUnreadCount(conId).then(result => {
if (EngineError.Success !== result.code) {
// 获取未读数失败
return;
}
if (!result.data) {
// 未读数为 null
return;
}
let unreadCount = result.data as number;
});
会话标识
该会话的未读数
清空单个会话未读数
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
IMEngine.getInstance().clearMessagesUnreadStatus(conId).then(result => {
if (EngineError.Success !== result.code) {
// 清空未读数失败
return;
}
/ 清空未读数成功
})
会话标识
结果
清除单个会话的未读数:按照时间戳清除
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let time = Date.now();
IMEngine.getInstance().clearMessagesUnreadStatusByTime(conId, time).then(result => {
if (EngineError.Success !== result.code) {
// 清空未读数失败
return;
}
// 清空未读数成功
})
会话标识
时间,清理小于该时间戳的消息未读
结果
会话未读数,是否包含免打扰会话的未读数
let typeList = new List<ConversationType>();
typeList.add(ConversationType.Private);
typeList.add(ConversationType.Group);
let isContainBlocked = false;
IMEngine.getInstance().getUnreadCountByTypes(conTypeList, isContainBlocked).then(result => {
if (EngineError.Success !== result.code) {
// 获取未读数失败
return;
}
if (!result.data) {
// 未读数为 null
return;
}
let unreadCount = result.data as number;
});
会话类型数组
是否包含免打扰;true 代表获取所有会话未读数之和; false 代表获取不包含免打扰会话的正常会话未读数之和
未读数
同步会话已读状态
用于相同账号的多端已读同步
例如用户 A 同时登录鸿蒙和 Android,两端同时收到消息,同时未读数增加
Android 调用该方法将某个会话同步已读之后, 鸿蒙会触发 SyncConversationReadStatusListener
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 Id";
// 会话中已读的最后一条消息的发送时间戳,此处用了当前时间
let time = Date.now();
IMEngine.getInstance().syncConversationReadStatus(conId,time).then(result => {
if (EngineError.Success !== result.code) {
// 同步已读失败
return;
}
// 同步已读成功
});
会话标识
会话中已读的最后一条消息的发送时间戳
结果
设置会话已读状态监听
let listener : SyncConversationReadStatusListener = {
onSyncConversationReadStatus: (conId: ConversationIdentifier, timestamp: number): void => {
// 该会话的 timestamp 之前的消息未读已清空
}
}
IMEngine.getInstance().setSyncConversationReadStatusListener(listener);
监听
增加会话已读状态监听
let listener : SyncConversationReadStatusListener = {
onSyncConversationReadStatus: (conId: ConversationIdentifier, timestamp: number): void => {
// 该会话的 timestamp 之前的消息未读已清空
}
}
IMEngine.getInstance().addSyncConversationReadStatusListener(listener);
监听
增加消息已读回执监听
let listener: MessageReadReceiptListener = {
onMessageReadReceiptReceived: (message: Message): void => {
},
onMessageReceiptRequest: (conId: ConversationIdentifier, messageUid: string): void => {
},
onMessageReceiptResponse: (conId: ConversationIdentifier, messageUid: string, respondUserIdList: Map<string, number>): void => {
}
}
IMEngine.getInstance().addMessageReadReceiptListener(listener);
监听
监听
单聊,发送某个会话中的消息阅读回执,由原始消息的接收方调用
单聊调用该方法后,原始消息发送方会触发 MessageReadReceiptListener.onMessageReadReceiptReceived
原始消息发送方本地对应单聊会话的已读消息 sentStatus 均为 SentStatus.Read
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let time = Date.now();
IMEngine.getInstance().sendReadReceiptMessage(conId, time).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
会话标识
会话中已读的最后一条消息的发送时间戳, Message.sentTime
群聊,发送某个会话的消息已读请求,由原始消息的发送方调用
群聊调用该方法后,原始消息的接收方会触发 MessageReadReceiptListener.onMessageReceiptRequest
原始消息接收方就知道需要对该消息做已读响应。调用 sendReadReceiptResponse
// 应该使用发送成功的消息,此处进行了简写
let msg : Message;
IMEngine.getInstance().sendReadReceiptRequest(msg).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
消息体,messageUid 必须有效
消息已读请求的结果
群聊,发送某个会话已读响应,由原始消息的接收方调用
群聊调用该方法后,原始消息的发送方会触发 MessageReadReceiptListener.onMessageReceiptResponse
原始消息的发送方就知道自己该消息有哪些人已读了
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgArray = new Array<Message>();
let msg : Message;
msgArray.push(msg);
IMEngine.getInstance().sendReadReceiptResponse(conId, msgArray).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (!result.data) {
// 成功的消息体列表为空
return;
}
// 发送响应成功的消息列表
let msgList = result.data as List<Message>;
});
会话标识
消息体数组,消息体必须存在有效的 senderId 和 messageUid
消息已读响应结果,返回的 Message 集合可以通过 Message.readReceiptInfo.hasRespond 确认该消息是否已经发送了响应
增加消息已读V2回执监听
let listener: MessageReadReceiptV2Listener = {
onMessageReceiptResponse: (conId: ConversationIdentifier, messageUid: string, readCount: number, totalCount: number): void => {
}
}
IMEngine.getInstance().addMessageReadReceiptV2Listener(listener);
监听
监听
群聊,发送某个会话已读响应,由原始消息的接收方调用
群聊调用该方法后,原始消息的发送方会触发 MessageReadReceiptV2Listener.onMessageReceiptResponse
原始消息的发送方就知道自己该消息有多少人已读了
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgArray = new Array<Message>();
let msg : Message;
msgArray.push(msg);
IMEngine.getInstance().sendReadReceiptResponseV2(conId, msgArray).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (!result.data) {
// 成功的消息体列表为空
return;
}
// 发送响应成功的消息列表
let msgList = result.data as List<Message>;
});
会话标识
消息体数组,消息体必须存在有效的 senderId 和 messageUid
消息已读响应结果,返回的 Message 集合可以通过 Message.readReceiptInfo.hasRespond 确认该消息是否已经发送了响应
群聊,获取已读人员列表
在服务端配置已读V2后,原始消息的发送方调用该方法后,就知道自己该消息有哪些人已读了
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgUid = "123456"; // 按需填写实际的Message Uid
IMEngine.getInstance().getGroupMessageReaderList(conId, msgUid, (totalCount: number, readerList: Map<string, number>) => {
// 处理已读人员信息
}).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功,获取已读人数
let readCount = result.data;
});
会话标识
消息Uid
消息已读人数
增加消息已读V5回执监听
let listener: MessageReadReceiptV5Listener = {
onMessageReceiptResponse: (readReceiptNotifyArray: Array<ReadReceiptNotifyV5>): void => {
}
}
IMEngine.getInstance().addMessageReadReceiptV5Listener(listener);
已读 V5 监听器
监听
发送消息已读回执 V5,由原始消息的接收方调用
调用该方法后,原始消息的发送方会触发 MessageReadReceiptV5Listener.onMessageReceiptResponse
原始消息的发送方就知道自己该消息有多少人已读了
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgUidArray = new Array<String>();
let messageUid1 = "MessageUid1"; // 按需填写实际的 MessageUid
let messageUid2 = "MessageUid2"; // 按需填写实际的 MessageUid
msgUidArray.push(messageUid1);
msgUidArray.push(messageUid2);
IMEngine.getInstance().sendReadReceiptResponseV5(conId, msgUidArray).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (!result.data) {
// 成功的消息体列表为空
return;
}
// 发送响应成功的消息列表
let msgList = result.data as List<Message>;
});
会话标识
消息 Uid 数组
消息已读响应结果,成功返回 EngineError.Success,失败返回对应错误码。
批量获取消息已读信息(V5)
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgUidArray = new Array<string>();
let messageUid1 = "MessageUid1"; // 按需填写实际的 MessageUid
let messageUid2 = "MessageUid2"; // 按需填写实际的 MessageUid
msgUidArray.push(messageUid1);
msgUidArray.push(messageUid2);
IMEngine.getInstance().getMessageReadReceiptInfoV5(conId, msgUidArray).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (!result.data) {
// 成功的消息体列表为空
return;
}
// 发送响应成功的消息列表
let msgList = result.data as List<ReadReceiptInfoV5>;
});
会话标识
消息 Uid 数组
消息已读响应结果,返回的 Message 集合
批量获取消息已读回执 V5 信息
消息会话标识
消息已读响应结果,返回的 Message 集合
分页获取消息已读未读信息
在服务端配置已读V5后,原始消息的发送方调用该方法后,就知道自己该消息有哪些人已读了
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgUid = "123456"; // 按需填写实际的Message Uid
let pageToken = "yourPageToken";
let count = 100;
let readStatus = ReadStatus.All;
let order = Order.Descending;
IMEngine.getInstance().getMessagesReadReceiptUsersByPageV5(
conId,
msgUid,
pageToken,
count,
readStatus,
order,
).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功,获取已读人数
let readReceiptUserResult = result.data;
});
会话标识
消息Uid
消息已读人数
批量获取用户指定群组消息是否已读状态(V5)
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgUid = "123456"; // 按需填写实际的Message Uid
// 需要具体的消息,此处进行了简写
let userIdArray = new Array<string>();
let userId1 = "userId1"; // 按需填写实际的 userId
let userId2 = "userId2"; // 按需填写实际的 userId
userIdArray.push(userId1);
userIdArray.push(userId2);
IMEngine.getInstance().getMessagesReadReceiptByUsersV5(
conId,
msgUid,
userIdArray,
).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功,获取已读人数
let readReceiptUserResult = result.data;
});
会话标识
消息Uid
要查询的用户 userId 列表
根据关键字搜索本地会话。
let conTypeList = new List<ConversationType>();
conTypeList.add(ConversationType.Private);
conTypeList.add(ConversationType.Group);
let keyword = "需要搜索的关键字";
let objNameList = new List<string>();
// 例如文本消息传入文本消息的 objectName: RC:TxtMsg
objNameList.add(TextMessageObjectName);
IMEngine.getInstance().searchConversations(conTypeList, keyword, objNameList).then(result => {
if (EngineError.Success !== result.code) {
// 搜索会话失败
return;
}
if (!result.data) {
// 搜索的会话为空
return;
}
// 搜索到的会话列表
let conList = result.data as List<Conversation>;
});
搜索的关键字,长度范围 [1, 256]
消息类型数组。用于搜索指定类型的消息;为空代表所有所有类型消息
搜索到的会话列表
根据关键字搜索本地会话。
let conTypeList = new List<ConversationType>();
conTypeList.add(ConversationType.Private);
conTypeList.add(ConversationType.Group);
let keyword = "关键字";
IMEngine.getInstance().searchConversationsWithResult(conTypeList, keyword, null).then(result => {
if (EngineError.Success !== result.code) {
// 搜索会话失败
return;
}
if (!result.data) {
// 搜索的会话内容为空
return;
}
// 搜索的结果
let searchResultList = result.data as List<SearchConversationResult>;
});
搜索的关键字,长度范围 [1, 256]
消息类型数组。用于搜索指定类型的消息;为空代表所有所有类型消息
搜索到的会话列表
根据关键字搜索指定消息类型的本地消息。
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 ID";
let keyword = "需要搜索的关键字";
let objNameList = new List<string>();
objNameList.add(TextMessageObjectName);
let startTime = Date.now();
let count = 10;
IMEngine.getInstance().searchMessages(conId, keyword, objNameList, startTime, count).then(result => {
if (EngineError.Success !== result.code) {
// 搜索消息失败
return;
}
if (!result.data) {
// 搜索消息为空
return;
}
// 搜索到的消息
let msgList = result.data as List<Message>;
});
会话标识
关键字,长度范围 [1, 256]
消息类型数组。用于搜索指定类型的消息;为空代表搜索所有类型消息
查询的起始发送时间,返回小于该时间的消息,毫秒时间戳;如果为 0,则查询全部。当分页时,可以传入上一批消息的最小发送时间,取值范围 [0, INT64_MAX]
消息个数,传 0 时会返回所有搜索到的消息,非 0 时根据 startTime 逐页返回,取值范围 [0, 100]
消息列表
根据关键字和指定时间段搜索指定会话中的消息。
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 ID";
let keyword = "需要搜索的关键字";
// 查找当前时间 24 小时内的消息
let option: ISearchMessageInTimeRangeOption = {
startTime: Date.now() - 24 * 60 * 60 * 1000,
endTime: Date.now(),
offset: 0,
limit: 10
}
IMEngine.getInstance().searchMessagesInTimeRange(conId, keyword, option).then(result => {
if (EngineError.Success !== result.code) {
// 搜索消息失败
return;
}
if (!result.data) {
// 搜素消息为空
return;
}
// 搜索的消息列表
let msgList = result.data as List<Message>;
});
会话标识
关键字,长度范围 [1, 256]
在时间区间内搜索消息的参数配置
消息列表
根据用户 id 搜索指定会话中的本地消息。
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 ID";
let userId = "用户 ID";
let startTime = Date.now();
let count = 10;
IMEngine.getInstance().searchMessagesByUser(conId, userId, startTime, count).then(result => {
if (EngineError.Success !== result.code) {
// 搜索消息失败
return;
}
if (!result.data) {
// 搜素消息为空
return;
}
// 搜索的消息列表
let msgList = result.data as List<Message>;
});
会话标识
用户 id
查询的起始发送时间,返回小于该时间的消息,毫秒时间戳;如果为 0,则查询全部。当分页时,可以传入上一批消息的最小发送时间,取值范围 [0, INT64_MAX]
消息个数,传 0 时会返回所有搜索到的消息;非 0 时根据 startTime 逐页返回,取值范围 [0, 100]
消息列表
在指定的一批会话中搜索消息
let conTypeArray = new Array<ConversationType>();
conTypeArray.push(ConversationType.Private);
let targetIdArray: Array<string> | null = null;
let channelIdArray: Array<string> | null = null;
let objNameArray: Array<string> | null = null;
let keyword = "关键字";
let startTime = Date.now();
let count = 10;
let order = Order.Ascending;
IMEngine.getInstance().searchMessagesByConversations(
conTypeArray,
targetIdArray,
channelIdArray,
objNameArray,
keyword,
startTime,
count, order
).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (!result.data) {
// 数据为空
return;
}
let msgList = result.data as List<Message>;
})
会话类型数组,非空
会话 Id 数组,为空代表所有会话
频道 Id 数组,为空代表所有频道
消息类型数组。用于搜索指定类型的消息;为空代表搜索所有类型消息
关键字,长度范围 [1, 256]
查询的起始发送时间,返回小于该时间的消息,毫秒时间戳;如果为 0,则查询全部。当分页时,可以传入上一批消息的最小发送时间,取值范围 [0, INT64_MAX]
消息个数,传 0 时会返回所有搜索到的消息;非 0 时根据 startTime 逐页返回,取值范围 [0, 100]
返回排序。Ascending 升序,返回比 startTime 时间戳大的消息。Descending 降序,返回比 startTime 时间戳消的消息
在本地指定会话中搜索多个成员指定的消息类型
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
let userIdArray = ["UserId1","UserId2"];
let objNameArray: Array<string> | null = null;
let startTime = Date.now();
let count = 10;
let order = Order.Ascending;
IMEngine.getInstance().searchMessagesByUsers(conId, userIdArray, objNameArray, startTime, count, order).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (!result.data) {
// 数据为空
return;
}
// 搜索到的消息列表
let msgList = result.data as List<Message>;
})
会话标识
消息发送者 Id 数组,搜索由这些用户发送的消息
消息类型数组。用于搜索指定类型的消息;为空代表搜索所有类型消息
查询的起始发送时间,返回小于该时间的消息,毫秒时间戳;如果为 0,则查询全部。当分页时,可以传入上一批消息的最小发送时间,取值范围 [0, INT64_MAX]
消息个数;非 0 时根据 startTime 逐页返回,传 0 默认取值为 100,取值范围 [0, 100]
返回排序。Ascending 升序,返回比 startTime 时间戳大的消息。Descending 降序,返回比 startTime 时间戳消的消息
消息列表
获取本地订阅的所有公众号(仅支持私有云)
IMEngine.getInstance().getPublicServiceList().then(result => {
if (EngineError.Success !== result.code) {
// 获取公众号失败
return;
}
if (!result.data) {
// 公众号为空
return;
}
// 公众号列表
let list = result.data as List<PublicServiceInfo>;
});
获取本地订阅的指定公众号
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.AppPublicService;
conId.targetId = this.targetId;
IMEngine.getInstance().getPublicService(conId).then(result => {
if (EngineError.Success !== result.code) {
// 获取公众号失败
return;
}
if (!result.data) {
// 公众号为空
return;
}
// 公众号信息
let info = result.data as PublicServiceInfo;
});
会话标识,会话类型不管为何值,SDK 均会按照 AppPublicService 处理
设置聊天室状态监听
let listener: ChatroomStatusListener = {
onChatroomJoining(roomId: string): void {
},
onChatroomJoined(roomId: string, info: ChatroomJoinedInfo): void {
},
onChatroomJoinFailed(roomId: string, code: EngineError): void {
},
onChatroomQuited(roomId: string): void {
},
onChatroomDestroyed(roomId: string, type: ChatroomDestroyType): void {
},
}
IMEngine.getInstance().setChatroomStatusListener(listener);
监听
增加聊天室状态监听
let listener: ChatroomStatusListener = {
onChatroomJoining(roomId: string): void {
hilog.info(0x0000, 'IM-App', 'onChatroomJoining roomId:%{public}s', roomId);
},
onChatroomJoined(roomId: string, info: ChatroomJoinedInfo): void {
hilog.info(0x0000, 'IM-App', 'onChatroomJoined roomId:%{public}s info:%{public}s', roomId, JSON.stringify(info));
},
onChatroomJoinFailed(roomId: string, code: EngineError): void {
hilog.info(0x0000, 'IM-App', 'onChatroomJoined roomId:%{public}s code:%{public}d', roomId, code);
},
onChatroomQuited(roomId: string): void {
hilog.info(0x0000, 'IM-App', 'onChatroomQuited roomId:%{public}s', roomId);
},
onChatroomDestroyed(roomId: string, type: ChatroomDestroyType): void {
hilog.info(0x0000, 'IM-App', 'onChatroomDestroyed roomId:%{public}s type:%{public}d', roomId, type);
},
}
IMEngine.getInstance().addChatroomStatusListener(listener);
监听
监听
加入聊天室,如果聊天室不存在则创建聊天室
let roomId = "TestChatroomId"; // 按需填写实际的聊天室 id
let msgCount = 5;
IMEngine.getInstance().joinChatroom(roomId, msgCount).then(result => {
if (EngineError.Success !== result.code) {
// 加入聊天室失败
return;
}
if (!result.data) {
// 聊天室加入信息失败
return;
}
let joinedInfo = result.data as ChatroomJoinedInfo;
});
roomId 聊天室 ID
msgCount 消息个数,-1 时不拉取任何消息,0 时拉取 10 条消息,最多只能拉取 50
结果
加入已经存在的聊天室
let roomId = "TestChatroomId"; // 按需填写实际的聊天室 id
let msgCount = 5;
IMEngine.getInstance().joinExistingChatroom(roomId, msgCount).then(result => {
if (EngineError.Success !== result.code) {
// 加入聊天室失败
return;
}
if (!result.data) {
// 聊天室加入信息失败
return;
}
let joinedInfo = result.data as ChatroomJoinedInfo;
});
聊天室 ID
消息个数,-1 时不拉取任何消息,0 时拉取 10 条消息,最多只能拉取 50
结果
退出聊天室
let roomId = "TestChatroomId"; // 按需填写实际的聊天室 id
IMEngine.getInstance().quitChatroom(roomId).then(result => {
if (EngineError.Success !== result.code) {
// 退出聊天室失败
return;
}
});
聊天室 ID
结果
获取聊天室信息
let roomId = "TestChatroomId"; // 按需填写实际的聊天室 id
let option: ICountOption = {
count: 10,
order: Order.Descending
}
IMEngine.getInstance().getChatroomInfo(roomId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取聊天室信息失败
return;
}
if (!result.data) {
// 聊天室信息为空
return;
}
let chatroomInfo = result.data as ChatroomInfo;
});
聊天室 ID
配置
聊天室信息
设置聊天室自定义属性
entries 最大限制为 10
key : 聊天室属性名称,长度范围 [1~128],支持大小写英文字母、数字、部分特殊符号 + = - _ 的组合方式
value : 聊天室属性对应的值,长度范围 [1~4096]
let roomId = "聊天室 ID";
let map = new Map<string, string>();
map.set("key1","value1");
map.set("key2","value2");
let autoDelete = true;
let overWrite = true;
IMEngine.getInstance().setChatroomEntries(roomId, map, autoDelete, overWrite).then(result => {
if (EngineError.Success !== result.code) {
// 设置 KV 失败
return;
}
if (!result.data) {
// 所有 KV 都设置成功
return;
}
// 设置失败的 key 和对应的失败错误码,视情况决定是否重新设置失败的 KV
let errorMap = result.data as Map<string, EngineError>;
});
聊天室 ID
key-value 字典,长度范围 [1 ~ 10]
用户掉线或退出时,是否自动删除该 Key、Value 值;自动删除时不会发送通知
是否强制覆盖
返回的具体结果,会明确特定 key 的具体错误
删除聊天室自定义属性
let roomId = "聊天室 ID";
let list = new List<string>();
list.add("key1");
list.add("key2");
let isForce = true;
IMEngine.getInstance().deleteChatroomEntries(roomId, list, isForce).then(result => {
if (EngineError.Success !== result.code) {
// 删除 KV 失败
return;
}
if (!result.data) {
// 删除 KV 成功
return;
}
// 删除失败的 K 和对应的错误,视情况决定是否重新删除失败的 KV
let errorMap = result.data as Map<string,EngineError>;
});
聊天室 ID
key 数组,长度范围 [1,10]
是否强制删除
返回的具体结果,会明确特定 key 的具体错误
获取本地指定一批聊天室自定义属性
let roomId = "聊天室 ID";
let list = new List<string>();
list.add("key1");
list.add("key2");
IMEngine.getInstance().getChatroomEntries(roomId, list).then(result => {
if (EngineError.Success !== result.code) {
// 获取 KV 失败
return;
}
if (!result.data) {
// KV 为空
return;
}
// KV map
let kvMap = result.data as Map<string,string>;
});
聊天室 ID
key 数组,长度范围 [1,100]
对应的 kv 信息
获取本地聊天室全部自定义属性
let roomId = "聊天室 ID";
IMEngine.getInstance().getAllChatroomEntries(roomId).then(result => {
if (EngineError.Success !== result.code) {
// 获取 KV 失败
return;
}
if (!result.data) {
// KV 为空
return;
}
// KV map
let kvMap = result.data as Map<string,string>;
});
聊天室 ID
对应的 kv 信息
设置聊天室 KV 状态变化的监听
let listener: ChatroomKVStatusListener = {
onChatroomKVSync: (roomId: string): void => {
},
onChatroomKVUpdate: (roomId: string, entries: Map<string, string>): void => {
},
onChatroomKVRemove: (roomId: string, entries: Map<string, string>): void => {
}
}
IMEngine.getInstance().setChatroomKVStatusListener(listener);
聊天室 KV 状态变化的监听
增加聊天室 KV 状态变化的监听
let listener: ChatroomKVStatusListener = {
onChatroomKVSync: (roomId: string): void => {
},
onChatroomKVUpdate: (roomId: string, entries: Map<string, string>): void => {
},
onChatroomKVRemove: (roomId: string, entries: Map<string, string>): void => {
}
}
IMEngine.getInstance().addChatroomKVStatusListener(listener);
监听
监听
设置聊天室成员变化监听
let listener: ChatroomMemberActionListener = {
onMemberChange: (actionModel: ChatRoomMemberActionModel): void => {
}
}
IMEngine.getInstance().setChatroomMemberListener(listener);
成员变化监听
增加聊天室成员变化监听
let listener: ChatroomMemberActionListener = {
onMemberChange: (actionModel: ChatRoomMemberActionModel): void => {
}
}
IMEngine.getInstance().addChatroomMemberListener(listener);
成员变化监听
成员变化监听
设置聊天室事件通知监听器
let listener: ChatroomNotifyEventListener = {
onChatroomNotifyMultiLoginSync: (syncEvent: ChatroomSyncEvent): void => {
},
onChatroomNotifyBlock: (blockEvent: ChatroomMemberBlockEvent): void => {
},
onChatRoomNotifyBan: (banEvent: ChatroomMemberBanEvent): void => {
}
}
IMEngine.getInstance().setChatroomNotifyEventListener(listener);
监听
增加聊天室事件通知监听器
let listener: ChatroomNotifyEventListener = {
onChatroomNotifyMultiLoginSync: (syncEvent: ChatroomSyncEvent): void => {
},
onChatroomNotifyBlock: (blockEvent: ChatroomMemberBlockEvent): void => {
},
onChatRoomNotifyBan: (banEvent: ChatroomMemberBanEvent): void => {
}
}
IMEngine.getInstance().addChatroomNotifyEventListener(listener);
监听
监听
创建群组
群信息(GroupInfo)支持设置的属性:<br>
1,群ID(id),最大长度 64 个字符。支持大小写英文字母与数字的组合<br>
2,群名称(name),最长不超过 64 个字符<br>
3,群头像(portraitUri),长度不超过 128 个字符<br>
4,群简介(introduction),最大长度不超过 512 个字符<br>
5,群公告(notice),最大长度不超过 1024 个字符<br>
6,群扩展信息(extProfile),默认最多可设置 10 个,需要通过开发者后台或 API 设置后才能使用,否则设置失败<br>
7,主动加入群权限模式(joinPermission)<br>
8,将群成员移出群组设置模式(removeMemberPermission)<br>
9,邀请他人入群模式(invitePermission)<br>
10,被邀请入群模式(inviteHandlePermission)<br>
11,群信息更新模式(groupInfoEditPermission)<br>
12,群成员信息更新模式(memberInfoEditPermission)<br>
其中:群ID(id)、群名称(name)必填,否则接口调用失败。<br>
`processCode` 参数说明:<br>
当群组的 `inviteHandlePermission` 为被邀请人需要同意才能进群时,`processCode` 返回 `GroupNeedInviteeAccept` ( 25427 ),表示需要被邀请人同意后才能进入群组。<br>
当群组的 `inviteHandlePermission` 为不需被邀请人同意时,`processCode` 返回 Success ( 0 ),被邀请人会直接加入群组。<br>
// 群 Id。必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
let groupId = "groupId";
// 群名称。必填,不能为空,长度不超过 64 个字符
let groupName = "groupName";
let portraitUri = "";
let introduction = "这是一个测试群";
let notice = "";
let joinPermission = 0; // 需要群主验证
let removeMemberPermission = 0; // 群主
let invitePermission = 0; // 群主
let inviteHandlePermission = 0; // 不需要被邀请人同意
let groupInfoEditPermission = 0; // 群主
let memberInfoEditPermission = 0; // 群主+管理员+自己
let hashMap = new HashMap<string, string>();
hashMap.set("kye1", "value1");
hashMap.set("ley2", "value2");
let groupInfo = new GroupInfo();
groupInfo.setGroupId(groupId);
groupInfo.setGroupName(groupName);
groupInfo.setPortraitUri(portraitUri);
groupInfo.setIntroduction(introduction);
groupInfo.setNotice(notice);
groupInfo.setJoinPermission(joinPermission);
groupInfo.setRemoveMemberPermission(removeMemberPermission);
groupInfo.setInvitePermission(invitePermission);
groupInfo.setInviteHandlePermission(inviteHandlePermission);
groupInfo.setGroupInfoEditPermission(groupInfoEditPermission);
groupInfo.setMemberInfoEditPermission(memberInfoEditPermission);
groupInfo.setExtProfile(hashMap);
// 设置加入群组的用户Id,非必填,一次最多允许 30 个用户加入。
let userIds = ["user1Id", "user2Id"];
IMEngine.getInstance().createGroup(groupInfo, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 创建群组失败
if (result.data) {
let ret: GroupResultWithProcessCode<string> = result.data;
if (ret.dataArray) {
let array: Array<string> = ret?.dataArray; // 失败的 key 数组
}
}
} else {
// 创建群组成功
if (result.data) {
let ret: GroupResultWithProcessCode<string> = result.data;
let processCode = ret.processCode; // 业务错误码
}
}
});
群组信息
加入群组的用户 Id 数组,一次最多允许 30 个用户加入。
更新群组资料
群信息(GroupInfo)支持设置的属性:<br>
1,群ID(id),最大长度 64 个字符。支持大小写英文字母与数字的组合<br>
2,群名称(name),最长不超过 64 个字符<br>
3,群头像(portraitUri),长度不超过 128 个字符<br>
4,群简介(introduction),最大长度不超过 512 个字符<br>
5,群公告(notice),最大长度不超过 1024 个字符<br>
6,群扩展信息(extProfile),默认最多可设置 10 个,需要通过开发者后台或 API 设置后才能使用,否则设置失败<br>
7,主动加入群权限模式(joinPermission)<br>
8,将群成员移出群组设置模式(removeMemberPermission)<br>
9,邀请他人入群模式(invitePermission)<br>
10,被邀请入群模式(inviteHandlePermission)<br>
11,群信息更新模式(groupInfoEditPermission)<br>
12,群成员信息更新模式(memberInfoEditPermission)<br>
其中:群ID(id)、群名称(name)必填,否则接口调用失败。<br>
// 群 Id
let groupId = "groupId";
let groupName = "groupName";
let portraitUri = "";
let introduction = "这是一个测试群";
let notice = "";
let joinPermission = 0; // 需要群主验证
let removeMemberPermission = 0; // 群主
let invitePermission = 0; // 群主
let inviteHandlePermission = 0; // 不需要被邀请人同意
let groupInfoEditPermission = 0; // 群主
let memberInfoEditPermission = 0; // 群主+管理员+自己
let hashMap = new HashMap<string, string>();
hashMap.set("kye1", "value1");
hashMap.set("key2", "value2");
let groupInfo = new GroupInfo();
groupInfo.setGroupId(groupId);
groupInfo.setGroupName(groupName);
groupInfo.setPortraitUri(portraitUri);
groupInfo.setIntroduction(introduction);
groupInfo.setNotice(notice);
groupInfo.setJoinPermission(joinPermission);
groupInfo.setRemoveMemberPermission(removeMemberPermission);
groupInfo.setInvitePermission(invitePermission);
groupInfo.setInviteHandlePermission(inviteHandlePermission);
groupInfo.setGroupInfoEditPermission(groupInfoEditPermission);
groupInfo.setMemberInfoEditPermission(memberInfoEditPermission);
groupInfo.setExtProfile(hashMap);
IMEngine.getInstance().updateGroupInfo(groupInfo).then(result => {
if (EngineError.Success !== result.code) {
// 更新群组信息失败
if (result.data) {
let array: Array<string> = result.data; // 具体失败的 key 数组
}
}
// 更新群组信息成功
});
群信息, groupId 必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
批量获取群组资料
注意:只返回已存在的群组信息
// 群 Id 列表
let groupIds = ["group1Id", "group2Id"];
IMEngine.getInstance().getGroupsInfo(groupIds).then(result => {
if (EngineError.Success !== result.code) {
// 获取群信息失败
return;
}
// 获取群信息成功
let ret : Object = result;
if (result.data) {
ret = Array.from(result.data as Array<GroupInfo>);
}
});
群 Id 数组。支持批量查询,单次查询最多支持 20 个群组。
操作完成后,结果通过此回调返回。
分页获取指定群组的群成员列表
// 群 Id
let groupId = "groupId";
// 通过 role 参数指定拉取全部群成员角色类型的群成员信息
let role = GroupMemberRole.Undef; // 未定义角色(使用此枚举代表查询全部类型群成员)
// 分页拉取参数
let pageToken = "";
// 设置分页大小,取值范围为 [1~100]。
let count = 10;
// 按加入群组时间正序、倒序获取。true:正序;false:倒序。
let order = false;
// 分页请求参数
let paging_option = new PagingQueryOption(pageToken, count, order)
IMEngine.getInstance().getGroupMembersByRole(groupId, role, paging_option).then(result => {
if (EngineError.Success !== result.code) {
// 拉取失败
return;
}
// 拉取成功
if (result.data) {
let ret: PagingQueryResult<GroupMemberInfo> = result.data;
let pageToken: string = ret.pageToken;
let totalCount: number = ret.totalCount;
let data = Array.from(ret.data as Array<GroupMemberInfo>);
// 使用返回的 pageToken 拉取下一页
}
});
群组Id。
查询群成员角色。
分页请求参数。包含页面标识(非必填,不填返回第一页数据)、每页条数(最大不超过 100 条)、是否正序查询(默认按加入群组时间倒序)
操作完成后,结果通过此回调返回。注意:此接口返回分页数据的总条数。
获取已加入指定群成员信息
// 群 Id
let groupId = "groupId";
// 设置查询用户 Id 列表
let userIds = ["user1Id", "user2Id"];
IMEngine.getInstance().getGroupMembers(groupId, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 拉取失败
return;
}
// 拉取成功
let ret: object = result;
if (result.data) {
ret = Array.from(result.data as Array<GroupMemberInfo>);
}
});
群组 Id
用户 Id 列表,一次最多不超过 100 个
操作完成后,结果通过此回调返回。
检查用户是否在群组中
let groupId = "test_group";
let userIds = ["user1", "user2"];
IMEngine.getInstance().checkUserInGroup(groupId, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (result.data) {
let ret: Array<string> = result.data;
}
});
群组 Id
用户 Id 列表,一次最多不超过 100 个
操作完成后,结果通过此回调返回。
踢出群组成员
// 群 Id
let groupId = "groupId";
// 用户 Id 列表
let userIds = ["user1Id", "user2Id"];
// 是否移除群成员禁言状态(默认为 true)
let removeMute = true;
// 是否移除白名单(默认为 true)
let removeWhiteList = true;
// 是否移除群组特别关注的用户(默认为 true)
let removeFavoriteMembers = true;
let config = new QuitGroupConfig(removeMute, removeWhiteList, removeFavoriteMembers);
IMEngine.getInstance().kickGroupMembers(groupId, userIds, config).then(result => {
if (EngineError.Success !== result.code) {
// 操作失败
}
// 操作成功
});
群组 Id
用户 Id 列表,一次最多不超过 100 个
移除群组成员配置
操作完成后,结果通过此回调返回。
退出群组
// 群 Id
let groupId = "groupId";
// 是否移除群成员禁言状态 (默认为 true)
let removeMute = true;
// 是否移除白名单(默认为 true)
let removeWhiteList = true;
// 是否移除群组特别关注的用户(默认为 true)
let removeFavoriteMembers = true;
let config = new QuitGroupConfig(removeMute, removeWhiteList, removeFavoriteMembers);
IMEngine.getInstance().quitGroup(groupId, config).then(result => {
if (EngineError.Success !== result.code) {
// 退出失败
}
// 退出成功
});
群组 Id
退出群组配置
操作完成后,结果通过此回调返回。
解散群组
let groupId = "groupId";
IMEngine.getInstance().dismissGroup(groupId).then(result => {
if (EngineError.Success !== result.code) {
// 解散失败
}
// 解散成功
});
群组 Id
操作完成后,结果通过此回调返回。
转让群组
// 群 Id
let groupId = "groupId";
// 转让后的群主用户 Id
let newOwnerId = "userId";
// 转让后退出群组
let autoQuit = true;
// 是否移除群成员禁言状态(默认为 true)
let removeMute = true;
// 是否移除白名单(默认为 true)
let removeWhiteList = true;
// 是否移除群组特别关注的用户(默认为 true)
let removeFavoriteMembers = true;
let config = new QuitGroupConfig(removeMute, removeWhiteList, removeFavoriteMembers);
IMEngine.getInstance().transferGroupOwner(groupId, newOwnerId, autoQuit, config).then(result => {
if (EngineError.Success !== result.code) {
// 转让失败
}
// 转让成功
});
群组 Id,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
新群主用户 Id,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
是否自动退出群组,必填,true 表示自动退出群组,false 表示不自动退出群组
转让群组配置,必填,不能为空
操作完成后,结果通过此回调返回。
添加群管理员
// 群 Id
let groupId = "groupId";
// 管理员用户 Id 列表
let userIds = ["user1Id", "user2Id"];
IMEngine.getInstance().addGroupManagers(groupId, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 添加失败
}
// 添加成功
});
群组 Id,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
用户 Id 列表,必填,用户 Id 必须为群组成员,一次最多设置 10 个群成员为管理员,管理员上限为 10 个,群主不支持设置为管理员
操作完成后,结果通过此回调返回。
移除群管理员
// 群 Id
let groupId = "groupId";
// 管理员用户 Id 列表
let userIds = ["user1Id", "user2Id"];
IMEngine.getInstance().removeGroupManagers(groupId, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 移除失败
}
// 移除成功
});
群组 Id,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
用户 Id 列表,必填,用户 Id 必须为群组成员,一次最多操作 10 个管理员
操作完成后,结果通过此回调返回。
设置群成员资料
群成员信息更新模式 memberInfoEditPermission ,决定是否可以修改群成员资料
// 群 Id
let groupId = "test_group";
// 群成员用户 Id
let userId = "userId";
// 群成员昵称
let nickname = "name";
// 群成员附加信息
let extra = "extra";
IMEngine.getInstance().setGroupMemberInfo(groupId, userId, nickname, extra).then(result => {
if (EngineError.Success !== result.code) {
// 操作失败
if (result.data) {
let array: Array<string> = result.data; // 失败的 key 数组
}
// 操作成功
}
});
群组 ID,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
群成员用户 ID,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
群成员昵称,长度不超过 64 个字符,不支持纯空格
群成员附加信息,长度不超过 128 个字符,注意:传 null 代表不设置此字段
根据群成员昵称查询群成员信息
// 群 Id
let groupId = "groupId";
// 群成员昵称,不能为空最长不超过 64 个字符
let nickname = "name";
// 分页拉取参数
let pageToken = null; // 首次查询可以传 null
// 设置分页大小,取值范围为 [1~200]。
let count = 10;
// 按加入群组时间正序、倒序获取。true:正序;false:倒序。
let order = false;
// 分页请求参数
let paging_option = new PagingQueryOption(pageToken, count, order)
IMEngine.getInstance().searchGroupMembers(groupId, nickname, paging_option).then(result => {
if (EngineError.Success !== result.code) {
// 拉取失败
return;
}
// 拉取成功
if (result.data) {
let ret: PagingQueryResult<GroupMemberInfo> = result.data;
let pageToken: string = ret.pageToken;
let totalCount: number = ret.totalCount;
let data = Array.from(ret.data as Array<GroupMemberInfo>);
// 使用返回的 pageToken 拉取下一页
}
});
群组 Id
群成员昵称搜索关键字。注意:不能为空最长不超过 64 个字符,不支持纯空格;支持模糊搜索查询;昵称为空时,默认搜索用户名
分页请求参数。包含页面标识(非必填,不填返回第一页数据)、每页条数(最大不超过 200 条)、是否正序查询(默认倒序)
加入群组
// 群 Id
let groupId = "groupId";
IMEngine.getInstance().joinGroup(groupId).then(result => {
if (EngineError.Success !== result.code) {
// 加入群组请求
return;
}
if (result.data) {
// 加入群组请求成功时需要处理 processCode
let ret: GroupResultWithProcessCode<void> = result.data;
let processCode = ret.processCode;
}
});
- 当群组的 `joinPermission` 为需要群主或管理员审批时,`code` 返回 `GroupJoinGroupNeedManagerAccept` ( 25424 ),表示需要等待群主或管理员的审批。
- 当群组的 `joinPermission` 为不用验证时,`code` 返回 Success ( 0 ),表示加入群组成功。
群组 Id
邀请用户加入群组
// 群 Id
let groupId = "groupId";
// 用户 Id 列表
let userIds = ["user1Id", "user2Id"];
IMEngine.getInstance().inviteUsersToGroup(groupId, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 邀请加入群组请求失败
return;
}
if (result.data) {
// 邀请加入群组请求成功需要处理 processCode
let ret: GroupResultWithProcessCode<void> = result.data;
let processCode = ret.processCode;
}
});
谁可以邀请他人入群方式 {@link GroupOperationPermission},决定是否可以邀请他人
邀请加入群组处理方式 {@link GroupInviteHandlePermission},决定是否可以加入群组
- 当该群组主动加入权限 joinPermission 为需群主或管理员审批时,code 返回 GroupJoinGroupNeedManagerAccept( 25424 ),表示需要等待群主或管理员审批。同时群主或管理员会收到群组申请的事件回调。
- 当该群组主动加入权限 joinPermission 为不用验证,被邀请加入群组权限 inviteHandlePermission 为需要被邀请人同意时,code 返回 GroupNeedInviteeAccept( 25427 ),表示需要被邀请人同意。
群组 Id,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
用户 Id 列表,一次最多不超过 30 个
用户同意加入群组
// 群 Id
let groupId = "groupId";
// 发出邀请的用户 Id
let inviterId = "inviterId";
IMEngine.getInstance().acceptGroupInvite(groupId, inviterId).then(result => {
if (EngineError.Success !== result.code) {
// 用户同意加入群组失败
return;
}
// 用户同意加入群组成功
});
群组 Id
发出邀请的用户 Id
用户拒绝加入群组
// 群 Id
let groupId = "groupId";
// 发出邀请的用户 Id
let inviterId = "inviterId";
// 拒绝原因
let reason = "拒绝原因";
IMEngine.getInstance().refuseGroupInvite(groupId, inviterId, reason).then(result => {
if (EngineError.Success !== result.code) {
// 用户拒绝加入群组失败
}
// 用户拒绝加入群组成功
});
群组 ID,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
邀请者 ID
拒绝原因,非必填项,拒绝时可选择是否输入拒绝原因,内容不超过 128 个字符
群主或管理员同意用户加入群组
// 群 Id
let groupId = "test_group";
// 发出邀请的用户 Id
let inviterId = "inviterId";
// 申请入群用户 Id
let applicantId = "applicantId";
IMEngine.getInstance().acceptGroupApplication(groupId, inviterId, applicantId).then(result => {
if (EngineError.Success !== result.code) {
// 同意加入群组请求失败
return;
}
if (result.data) {
// 同意加入群组请求成功需要处理 processCode
let ret: GroupResultWithProcessCode<void> = result.data;
let processCode = ret.processCode;
}
});
- 当群组的 `inviteHandlePermission` 为需要被邀请人同意时,若 `code` 返回 `GroupNeedInviteeAccept` (25427),表示需等待被邀请人同意方可加入群组。
- 当群组的 `inviteHandlePermission` 为无需被邀请人同意时,若 `code` 返回 `Success` (0),表示被邀请人已成功加入群组。
以上仅适用于邀请加入群组的情况,当用户主动申请加入群组时,`code` 始终为 `Success` (0)。
群组 ID,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
邀请人用户 ID,非必填,如果是邀请入群,则传邀请人 ID;如果是用户主动加群,可以为空。
申请入群用户 ID
群主或管理员拒绝用户加入群组
// 群 Id
let groupId = "groupId";
// 发出邀请的用户 Id
let inviterId = "inviterId";
// 申请入群用户 Id
let applicantId = "applicantId";
// 拒绝原因
let reason = "拒绝原因";
IMEngine.getInstance().refuseGroupApplication(groupId, inviterId, applicantId, reason).then(result => {
if (EngineError.Success !== result.code) {
// 拒绝加入群组请求失败
}
// 拒绝加入群组请求成功
});
群组 ID,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
邀请人用户 ID,非必填,如果是邀请入群,则传邀请人 ID;如果是主动加群,可以为空。
申请者 ID
拒绝原因,非必填项,拒绝时可选择是否输入拒绝原因,内容不超过 128 个字符
分页获取群组请求列表
// 分页拉取参数
let pageToken = null;
// 设置分页大小,取值范围为 [1~100]。
let count = 10;
// 按操作时间正序、倒序获取。true:正序;false:倒序。
let order = false;
// 分页请求参数
let paging_option = new PagingQueryOption(pageToken, count, order)
// 查询发出的申请 + 收到的申请类型的请求
let directionArray:Array<GroupApplicationDirection> = [GroupApplicationDirection.ApplicationSent, GroupApplicationDirection.ApplicationReceived];
// 查询管理员待处理 + 管理员拒绝 + 已加入类型的申请
let statusArray: Array<GroupApplicationStatus> = [GroupApplicationStatus.ManagerUnHandled, GroupApplicationStatus.ManagerRefused, GroupApplicationStatus.Joined];
IMEngine.getInstance().getGroupApplications(paging_option, directionArray, statusArray).then(result => {
if (EngineError.Success !== result.code) {
// 拉取失败
return
}
// 拉取成功
if (result.data) {
let data : PagingQueryResult<GroupApplicationInfo> = result.data;
let pageToken: string = data?.pageToken;
let totalCount: number = data?.totalCount;
let infoArr: Array<GroupApplicationInfo> = Array.from(data?.data);
// 使用返回的 pageToken 拉取下一页
}
});
分页请求参数。参照PagingQueryOption,包含页面标识(非必填,不填返回第一页数据)、每页条数(最大不超过 200 条)、是否正序查询(默认倒序)
请求的方向数组
群组请求状态数组
操作完成后,结果通过此回调返回。按操作时间倒序排序。注意:此接口不返回分页数据的总条数。
按角色获取已加入群组的资料
// 通过 role 参数指定拉取全部群成员角色类型的群
let role : GroupMemberRole = GroupMemberRole.Undef; // 按需使用角色枚举值
// 分页拉取参数
let pageToken = null;
// 设置分页大小,取值范围为 [1~100]。
let count = 10;
// 按加入群组时间正序、倒序获取。true:正序;false:倒序
let order = false;
// 分页请求参数
let paging_option = new PagingQueryOption(pageToken, count, order);
IMEngine.getInstance().getJoinedGroupsByRole(role, paging_option).then(result => {
if (EngineError.Success !== result.code) {
// 拉取失败
return
}
// 拉取成功
if (result.data) {
let data: PagingQueryResult<GroupInfo> = result.data;
let pageToken: string = data?.pageToken;
let totalCount: number = data?.totalCount;
let arr: Array<GroupInfo> = Array.from(data?.data as Array<GroupInfo>);
// 使用返回的 pageToken 拉取下一页
}
});
群成员角色
查询选项,包含 页面标识(非必填,不填返回第一页数据)、每页条数(最大不超过 100 条)、是否正序查询(默认倒序)
按群名称搜索我加入的群组
// 群名称
let groupName = "test group";
// 分页拉取参数
let pageToken = null;
// 设置分页大小,取值范围为 [1~200]。
let count = 10;
// 按加入群组时间正序、倒序获取。true:正序;false:倒序。
let order = false;
// 分页请求参数
let paging_option = new PagingQueryOption(pageToken, count, order)
IMEngine.getInstance().searchJoinedGroups(groupName, paging_option).then(result => {
if (EngineError.Success !== result.code) {
// 拉取失败
return;
}
// 拉取成功
if (result.data) {
let data: PagingQueryResult<GroupInfo> = result.data;
let pageToken: string = data?.pageToken;
let totalCount: number = data?.totalCount;
let arr: Array<GroupInfo> = Array.from(data?.data as Array<GroupInfo>);
// 使用返回的 pageToken 拉取下一页
}
});
群名称搜索关键字。不能为空最长不超过 64 个字符,不支持纯空格,支持模糊搜索查询时需要去掉前后空格。
分页请求参数。参照PagingQueryOption,包含页面标识(非必填,不填返回第一页数据)、每页条数(最大不超过 200 条)、是否正序查询(默认倒序)
操作完成后,结果通过此回调返回。注意:此接口返回分页数据的总条数。
批量获取我加入的群组
let groupIds = ["group1Id", "group2Id"];
IMEngine.getInstance().getJoinedGroups(groupIds).then(result => {
if (EngineError.Success !== result.code) {
// 获取失败
return;
}
// 获取成功
let ret: object = result;
if (result.data) {
ret = Array.from(result.data as Array<GroupInfo>);
}
});
群Id列表。最多不超过 20 个
操作完成后,结果通过此回调返回。
设置群组备注名
// 群 Id
let groupId = "groupId";
// 群备注名
let remark = "group remark";
IMEngine.getInstance().setGroupRemark(groupId, remark).then(result => {
if (EngineError.Success !== result.code) {
// 设置失败
return;
}
// 设置成功
});
群组 ID,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
群备注,字符串长度不超过 64 个字符。传 null 或 空字符串 表示移除群备注
添加群组特别关注用户
let groupId = "groupId";
let userIds = ["user1Id", "user2Id"];
IMEngine.getInstance().addGroupFollows(groupId, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 添加失败
}
// 添加成功
});
群组 Id,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
用户 Id 列表,单次最多关注 100 个用户
删除群组特别关注用户
// 群 Id
let groupId = "groupId";
// 用户 Id 列表
let userIds = ["user1Id", "user2Id"];
IMEngine.getInstance().removeGroupFollows(groupId, userIds).then(result => {
if (EngineError.Success !== result.code) {
// 失败
}
});
群组 Id,必填,不能为空,长度不超过 64 个字符,大小写英文字母与数字的组合,不能包含空格
用户 Id 列表,单次取消关注 100 个用户
查询群组特别关注用户列表
// 群 Id
let groupId = "groupId";
IMEngine.getInstance().getGroupFollows(groupId).then(result => {
if (EngineError.Success !== result.code) {
// 查询失败
return;
}
// 查询成功
let ret : Object = result;
if (result.data) {
ret = Array.from(result.data);
}
});
群 Id。只支持普通群。
添加群组事件回调监听
let listener: GroupEventListener = {
onGroupOperation : (
groupId: string,
operatorInfo: GroupMemberInfo,
groupInfo: GroupInfo,
operation: GroupOperation,
memberInfos: Array<GroupMemberInfo>,
operationTime: number
): void => {
},
onGroupInfoChanged : (
operatorInfo: GroupMemberInfo,
fullGroupInfo: GroupInfo,
properties: Array<string>,
operationTime: number
): void => {
},
onGroupMemberInfoChanged : (
groupId: string,
operatorInfo: GroupMemberInfo,
memberInfo: GroupMemberInfo,
operationTime: number
): void => {
},
onGroupApplicationEvent : (
info: GroupApplicationInfo
): void => {
},
onGroupRemarkChangedSync : (
groupId: string,
operationType: GroupOperationType,
groupRemark: string,
operationTime: number
): void => {
},
onGroupFollowsChangedSync : (
groupId: string,
operationType: GroupOperationType,
userIds: Array<string>,
operationTime: number
): void => {
}
}
IMEngine.getInstance().addGroupEventListener(listener);
监听
移除群组事件回调监听
let listener: GroupEventListener = {
onGroupOperation : (
groupId: string,
operatorInfo: GroupMemberInfo,
groupInfo: GroupInfo,
operation: GroupOperation,
memberInfos: Array<GroupMemberInfo>,
operationTime: number
): void => {
},
onGroupInfoChanged : (
operatorInfo: GroupMemberInfo,
fullGroupInfo: GroupInfo,
properties: Array<string>,
operationTime: number
): void => {
},
onGroupMemberInfoChanged : (
groupId: string,
operatorInfo: GroupMemberInfo,
memberInfo: GroupMemberInfo,
operationTime: number
): void => {
},
onGroupApplicationEvent : (
info: GroupApplicationInfo
): void => {
},
onGroupRemarkChangedSync : (
groupId: string,
operationType: GroupOperationType,
groupRemark: string,
operationTime: number
): void => {
},
onGroupFollowsChangedSync : (
groupId: string,
operationType: GroupOperationType,
userIds: Array<string>,
operationTime: number
): void => {
}
}
IMEngine.getInstance().removeGroupEventListener(listener);
监听
IM SDK 核心类
Version
1.0.0