# Class IMEngine

IM SDK 核心类

#### Version

1.0.0

- Defined in IMEngine.ts:109

##### Index

### Methods

getInstance
init
getVersion
getDeltaTime
setAppVersion
setReconnectKickEnable
setPushToken
setDatabaseStatusListener
addDatabaseStatusListener
removeDatabaseStatusListener
setLogLevel
connect
setConnectionStatusListener
addConnectionStatusListener
removeConnectionStatusListener
getCurrentConnectionStatus
getCurrentUserId
disconnect
setMessageReceivedListener
addMessageReceivedListener
removeMessageReceivedListener
setMessageRecalledListener
addMessageRecalledListener
removeMessageRecalledListener
setMessageBlockedListener
addMessageBlockedListener
removeMessageBlockedListener
sendMessage
sendMediaMessage
sendMediaMessageWithUploader
cancelSendMediaMessage
sendDirectionalMessage
sendDirectionalMediaMessage
downloadMediaMessage
downloadMediaMessageWithProgress
downloadMediaMessageWithDownloader
pauseDownloadMediaMessage
cancelDownloadMediaMessage
downloadFileWithProgress
downloadMediaFile
pauseDownloadMediaFile
cancelDownloadFile
recallMessage
registerMessageType
getMessageTypeMap
batchInsertMessage
insertMessage
getMessages
getMessageById
getMessageByUid
getHistoryMessagesById
getHistoryMessagesByTime
getRemoteHistoryMessages
getUnreadMentionedMessages
getFirstUnreadMessage
deleteHistoryMessagesByIds
deleteMessages
deleteHistoryMessagesByTime
cleanRemoteHistoryMessagesByTime
deleteRemoteMessages
setTypingStatusListener
addTypingStatusListener
removeTypingStatusListener
sendTypingStatus
setTypingStatusInterval
setMessageReceivedStatus
setMessageExtra
setMessageExpansionListener
addMessageExpansionListener
removeMessageExpansionListener
updateMessageExpansion
removeMessageExpansion
addMessageDestructionListener
removeMessageDestructionListener
messageBeginDestruct
messageStopDestruct
setPushContentShowStatus
getPushContentShowStatus
setPushReceiveStatus
getPushReceiveStatus
setConversationStatusListener
addConversationStatusListener
removeConversationStatusListener
getConversation
getConversationListByPage
getTopConversationListByPage
getBlockedConversationListByPage
getUnreadConversations
getUnreadMentionMeConversationList
getConversationsIncludingRobots
clearConversations
removeConversations
removeRemoteConversations
setReadTimestamp
setConversationsToTop
getConversationTopStatus
setConversationsNotificationLevel
getConversationNotificationLevel
saveTextMessageDraft
getTextMessageDraft
setNotificationQuietHoursLevel
getNotificationQuietHoursLevel
removeNotificationQuietHours
getTotalUnreadCount
getTotalUnreadCountByIds
getUnreadCount
clearMessagesUnreadStatus
clearMessagesUnreadStatusByTime
getUnreadCountByTypes
createLocalConversation
syncConversationReadStatus
setSyncConversationReadStatusListener
addSyncConversationReadStatusListener
removeSyncConversationReadStatusListener
addMessageReadReceiptListener
removeMessageReadReceiptListener
sendReadReceiptMessage
sendReadReceiptRequest
sendReadReceiptResponse
addMessageReadReceiptV2Listener
removeMessageReadReceiptV2Listener
sendReadReceiptResponseV2
getGroupMessageReaderList
addMessageReadReceiptV5Listener
removeMessageReadReceiptV5Listener
sendReadReceiptResponseV5
getMessageReadReceiptInfoV5
getMessageReadReceiptInfoV5ByIdentifiers
getMessagesReadReceiptUsersByPageV5
getMessagesReadReceiptByUsersV5
searchConversations
searchConversationsWithResult
searchMessages
searchMessagesInTimeRange
searchMessagesByUser
searchMessagesByConversations
searchMessagesByUsers
getPublicServiceList
getPublicService
setChatroomStatusListener
addChatroomStatusListener
removeChatroomStatusListener
joinChatroom
joinExistingChatroom
quitChatroom
getChatroomInfo
setChatroomEntries
deleteChatroomEntries
getChatroomEntries
getAllChatroomEntries
setChatroomKVStatusListener
addChatroomKVStatusListener
removeChatroomKVStatusListener
setChatroomMemberListener
addChatroomMemberListener
removeChatroomMemberListener
setChatroomNotifyEventListener
addChatroomNotifyEventListener
removeChatroomNotifyEventListener
createGroup
updateGroupInfo
getGroupsInfo
getGroupMembersByRole
getGroupMembers
checkUserInGroup
kickGroupMembers
quitGroup
dismissGroup
transferGroupOwner
addGroupManagers
removeGroupManagers
setGroupMemberInfo
searchGroupMembers
joinGroup
inviteUsersToGroup
acceptGroupInvite
refuseGroupInvite
acceptGroupApplication
refuseGroupApplication
getGroupApplications
getJoinedGroupsByRole
searchJoinedGroups
getJoinedGroups
setGroupRemark
addGroupFollows
removeGroupFollows
getGroupFollows
addGroupEventListener
removeGroupEventListener
getAllRobots
getRobotById
addRobotEventListener
removeRobotEventListener
addMessageModifiedListener
removeMessageModifiedListener
modifyMessageWithParams
refreshReferenceMessageWithParams
saveEditedMessageDraft
getEditedMessageDraft
clearEditedMessageDraft
setMessageInterceptor
updateMyUserProfileVisibility
getMyUserProfileVisibility
updateMyUserProfile
getMyUserProfile
getUserProfiles
searchUserProfileByUniqueId
subscribeEvent
unsubscribeEvent
querySubscribeEvent
querySubscribeEventByPage
getSubscribeUsersOnlineStatus
addSubscribeEventListener
removeSubscribeEventListener
addFriend
checkFriends
deleteFriends
getFriends
getFriendsInfo
searchFriendsInfo
setFriendInfo
getFriendApplications
acceptFriendApplication
refuseFriendApplication
setFriendAddPermission
getFriendAddPermission
addFriendEventListener
removeFriendEventListener

## Methods

### `Static` getInstance

- getInstance(): IMEngine

  单例对象

  #### Returns IMEngine

  #### Version

  1.0.0

  - Defined in IMEngine.ts:121

### init

- init(context: Context, appKey: string, initOption: InitOption): void

  初始化 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);

  #### Parameters

  - context: Context

    上下文，为空则初始化失败

  - appKey: string

    融云 appKey，为空则初始化失败

  - initOption: InitOption

    初始化配置，见 InitOption

  #### Returns void

  #### Version

  1.0.0

  - Defined in IMEngine.ts:151

### getVersion

- getVersion(): string

  获取 SDK 版本号

  # 示例代码

      let ver = IMEngine.getInstance().getVersion();

  #### Returns string

  版本号

  #### Version

  1.0.0

  - Defined in IMEngine.ts:164

### getDeltaTime

- getDeltaTime(): Promise<IAsyncResult<number>>

  获取本地时间与服务器时间的时间差。 通过当前本地时间减去此接口返回的时间，即当前服务器时间。

  # 示例代码

      IMEngine.getInstance().getDeltaTime().then(result => {
        if (EngineError.Success === result.code) {
          let deltaTime = result.data as number
        }
      });

  #### Returns Promise<IAsyncResult<number>>

  本地时间与服务器时间的时间差。

  #### Version

  1.3.2

  - Defined in IMEngine.ts:183

### setAppVersion

- setAppVersion(ver: string): void

  上报 APP 版本信息，服务端支持按上报的 App 版本处理自定义消息的推送内容

  # 示例代码

      let appVersion = "1.0.0";
      IMEngine.getInstance().setAppVersion(appVersion);

  #### Parameters

  - ver: string

    APP 版本，string 类型，非空，长度小于 20, 示例如 "1.1.0"

  #### Returns void

  #### Note

  当 SDK 初始化时就会用该字段，所以必须在 init 之前调用

  #### Version

  1.0.0

  - Defined in IMEngine.ts:202

### setReconnectKickEnable

- setReconnectKickEnable(enable: boolean): void

  上设置断线重连时是否踢出重连设备。

  # 说明

      用户没有开通多设备登录功能的前提下，同一个账号在一台新设备上登录的时候，会把这个账号在之前登录的设备上踢出。
      由于 SDK 有断线重连功能，存在下面情况： 用户在 A 设备登录，A 设备网络不稳定，没有连接成功，SDK 启动重连机制。 用户此时又在 B 设备登录，B 设备连接成功。 A
      设备网络稳定之后，用户在 A 设备连接成功，B 设备被踢出。 这个接口就是为这种情况加的。

  # 示例代码

      let kickEnable = true;
      IMEngine.getInstance().setReconnectKickEnable(kickEnable);

  #### Parameters

  - enable: boolean

    设置为 true 时，SDK 重连的时候发现此时已有别的设备连接成功，踢出当前重连设备，不再强行踢出别的设备

  #### Returns void

  #### Note

  当 SDK 初始化时就会用该字段，所以必须在 init 之前调用

  #### Note

  该功能需要提工单，在服务端开通此功能后，客户端调用该方法才生效

  #### Version

  1.2.0

  - Defined in IMEngine.ts:224

### setPushToken

- setPushToken(pushToken: string): void

  设置鸿蒙推送 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 排查思路

      1. 确保 APP 调用了 setPushToken()，并且确保 pushToken 是有效的
      2. 确保 InitOption statisticServer 设置了有效的服务地址（私有云必须做这一步，公有云不需要）
      3. 上述两步依旧无法解决，则提供 RongCloud 目录，里面包含了完整的日志。
      如何获取 RongCloud 目录？下面文档搜索 RongCloud 关键字
      https://docs.rongcloud.cn/harmonyOS-imlib/faq#%E9%B8%BF%E8%92%99%E6%98%AF%E5%90%A6%E6%9C%89%E6%B6%88%E6%81%AF%E6%95%B0%E6%8D%AE%E5%BA%93

  #### Parameters

  - pushToken: string

    推送 token

  #### Returns void

  #### Version

  1.0.0

  - Defined in IMEngine.ts:257

### setDatabaseStatusListener

- setDatabaseStatusListener(listener: (status: DatabaseStatus) => void): void

  设置数据库状态监听

  # 说明

      数据库打开的时机：参考 DatabaseStatusListener.onDatabaseStatusChange()

  # 示例代码

      IMEngine.getInstance().setDatabaseStatusListener((status: DatabaseStatus) => {
       hilog.info(0x0000, 'IM-App', 'setDatabaseStatusListener onChanged status:%{public}d', status);
      });

  #### Parameters

  - listener: (status: DatabaseStatus) => void

    监听

  #### Returns void

  #### Discussion

  init 之后 connect 之前调用。connect 成功之后调用不会有任何效果

  #### Version

  1.1.0

  #### Deprecated

  使用 addDatabaseStatusListener 替代，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:278

### addDatabaseStatusListener

- addDatabaseStatusListener(listener: DatabaseStatusListener): void

  增加数据库状态监听

  # 说明

      数据库打开的时机：参考 DatabaseStatusListener.onDatabaseStatusChange()

  # 示例代码

      let dbListener: DatabaseStatusListener = {
       onDatabaseStatusChange: (status: DatabaseStatus): void => {
         // status 为具体的数据库状态
       }
      }
      IMEngine.getInstance().addDatabaseStatusListener(dbListener);

  #### Parameters

  - listener: DatabaseStatusListener

    监听

  #### Returns void

  #### Discussion

  init 之后 connect 之前调用。connect 成功之后调用不会有任何效果

  #### Warning

  addDatabaseStatusListener & removeDatabaseStatusListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:310

### removeDatabaseStatusListener

- removeDatabaseStatusListener(listener: DatabaseStatusListener): void

  移除数据库状态监听

  # 示例代码

      IMEngine.getInstance().removeDatabaseStatusListener(dbListener);

  #### Parameters

  - listener: DatabaseStatusListener

    监听

  #### Returns void

  #### Warning

  addDatabaseStatusListener & removeDatabaseStatusListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:324

### setLogLevel

- setLogLevel(level: LogLevel): void

  设置控制台日志级别

  # 说明

      例如：填入 LogLevel.None ，SDK 将不再控制台输出日志
      例如：填入 LogLevel.Warn ，SDK 将会在控制台输出 Warn 和 Error 的日志

  # 示例代码

      IMEngine.getInstance().setLogLevel(LogLevel.Info)

  #### Parameters

  - level: LogLevel

    日志级别，用于过滤控制台的日志输出，初始化之后设置

  #### Returns void

  #### Version

  1.0.0

  - Defined in IMEngine.ts:342

### connect

- connect(token: string, timeout: number): Promise<IConnectResult>

  连接 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 {
         //其它业务错误码，请根据相应的错误码作出对应处理。
       }
      });

  #### Parameters

  - token: string

    从您服务器端获取的 token (用户身份令牌)

  - timeout: number

    超时时间，整型，单位秒，timeout <= 0：不设置超时时长，一直连接直到成功或失败；timeout > 0: 在对应的时间内连接未成功则返回超时错误

  #### Returns Promise<IConnectResult>

  连接结果

  #### Note

  连接成功后，SDK 将接管所有的重连处理。当因为网络原因断线的情况下，SDK 会不停重连直到连接成功为止，不需要您做额外的连接操作。

  #### See

  IConnectResult

  #### Version

  1.0.0

  - Defined in IMEngine.ts:405

### setConnectionStatusListener

- setConnectionStatusListener(listener: (status: ConnectionStatus) => void): void

  设置连接状态监听

  # 说明

      每个连接状态都有详细的描述和处理意见，参考 ConnectionStatusListener.onConnectionStatusChanged()

  # 示例代码

      IMEngine.getInstance().setConnectionStatusListener((status: ConnectionStatus) => {
       // status 为具体的连接状态
      });

  #### Parameters

  - listener: (status: ConnectionStatus) => void

    监听

  #### Returns void

  #### See

  ConnectionStatus

  #### Version

  1.0.0

  #### Deprecated

  使用 addConnectionStatusListener 替代，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:431

### addConnectionStatusListener

- addConnectionStatusListener(listener: ConnectionStatusListener): void

  增加连接监听。每个连接状态都有详细的描述和处理意见

  # 说明

      每个连接状态都有详细的描述和处理意见，参考 ConnectionStatusListener.onConnectionStatusChanged()

  # 示例代码

       let statusListener: ConnectionStatusListener = {
         onConnectionStatusChanged: (status: ConnectionStatus): void => {
           // status 为具体的连接状态
         }
       }
       IMEngine.getInstance().addConnectionStatusListener(statusListener);

  #### Parameters

  - listener: ConnectionStatusListener

    监听

  #### Returns void

  #### See

  ConnectionStatus

  #### Warning

  addConnectionStatusListener & removeConnectionStatusListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:464

### removeConnectionStatusListener

- removeConnectionStatusListener(listener: ConnectionStatusListener): void

  移除连接监听

  # 示例代码

      IMEngine.getInstance().removeConnectionStatusListener(statusListener);

  #### Parameters

  - listener: ConnectionStatusListener

    连接监听

  #### Returns void

  #### Warning

  addConnectionStatusListener & removeConnectionStatusListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:478

### getCurrentConnectionStatus

- getCurrentConnectionStatus(): Promise<IAsyncResult<ConnectionStatus>>

  获取当前连接状态

  # 示例代码

       IMEngine.getInstance().getCurrentConnectionStatus().then(result => {
         if (EngineError.Success !== result.code) {
           // 获取当前连接状态失败
           return;
         }
         if (!result.data) {
           // 获取的当前连接状态为空
           return;
         }
         let status = result.data as ConnectionStatus;
       });

  #### Returns Promise<IAsyncResult<ConnectionStatus>>

  连接状态

  #### See

  ConnectionStatus

  #### Version

  1.0.0

  - Defined in IMEngine.ts:502

### getCurrentUserId

- getCurrentUserId(): Promise<IAsyncResult<string>>

  获取当前用户 ID

  # 示例代码

       IMEngine.getInstance().getCurrentUserId().then(result => {
         if (EngineError.Success !== result.code) {
           // 获取用户 ID 失败
           return;
         }
         if (!result.data) {
           // 获取的用户 ID 为空
           return;
         }
         let userId = result.data as string;
       });

  #### Returns Promise<IAsyncResult<string>>

  连接成功后才会有值

  #### Version

  1.0.0

  - Defined in IMEngine.ts:530

### disconnect

- disconnect(isReceivePush: boolean): void

  断开连接

  # 示例代码

      let isReceivePush = true;
      IMEngine.getInstance().disconnect(isReceivePush);

  #### Parameters

  - isReceivePush: boolean

    是否接受推送

  #### Returns void

  #### Note

  SDK 在前后台切换或者网络出现异常都会自动重连，会保证连接的可靠性，除非您的 App 逻辑需要登出，否则一般不需要调用此方法进行手动断开

  #### Version

  1.0.0

  - Defined in IMEngine.ts:550

### setMessageReceivedListener

- setMessageReceivedListener(
  listener: (message: Message, info: ReceivedInfo) => void,
  ): void

  设置消息接收监听

  # 示例代码

       IMEngine.getInstance().setMessageReceivedListener((message: Message, info: ReceivedInfo) => {
         //  针对接收离线消息时，服务端会将 200 条消息打成一个包发到客户端，客户端对这包数据进行解析。该参数表示每个数据包数据逐条上抛后，还剩余的条数
         let left = info.left;
         // 消息是否离线消息
         let isOffline = info.isOffline;
         // 是否在服务端还存在未下发的消息包
         let hasPackage = info.hasPackage;
       });

  #### Parameters

  - listener: (message: Message, info: ReceivedInfo) => void

    监听

  #### Returns void

  #### Note

  刷新逻辑参考 ReceivedInfo

  #### Version

  1.0.0

  #### Deprecated

  已废弃，使用 addMessageReceivedListener() 方法，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:577

### addMessageReceivedListener

- addMessageReceivedListener(listener: MessageReceivedListener): void

  添加消息接收监听，可以添加多个监听

  # 示例代码

       let messageReceiveListener: MessageReceivedListener = {
         onMessageReceived: (message: Message, info: ReceivedInfo): void => {
           // 收到了单条消息
         },
         onOfflineMessageSyncCompleted: (): void => {
           // 离线消息已全部拉取完成
         }
       };
       IMEngine.getInstance().addMessageReceivedListener(messageReceiveListener);

  #### Parameters

  - listener: MessageReceivedListener

    监听

  #### Returns void

  #### Discussion

  刷新逻辑参考 ReceivedInfo，当回调 onOfflineMessageSyncCompleted 时，代表离线消息拉取完成

  #### Warning

  addMessageReceivedListener & removeMessageReceivedListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:610

### removeMessageReceivedListener

- removeMessageReceivedListener(listener: MessageReceivedListener): void

  移除消息接收监听

  # 示例代码

      IMEngine.getInstance().removeMessageReceivedListener(messageReceiveListener);

  #### Parameters

  - listener: MessageReceivedListener

    监听

  #### Returns void

  #### Warning

  addMessageReceivedListener & removeMessageReceivedListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:627

### setMessageRecalledListener

- setMessageRecalledListener(
  listener: (
  message: Message,
  recallMessage: RecallNotificationMessage,
  ) => void,
  ): void

  设置消息撤回监听，撤回了之后，原始消息会变成 RecallNotificationMessage 消息

  # 示例代码

      IMEngine.getInstance().setMessageRecalledListener((message: Message, recallMessage: RecallNotificationMessage) => {

      });

  #### Parameters

  - listener: (message: Message, recallMessage: RecallNotificationMessage) => void

    监听

  #### Returns void

  #### Version

  1.0.0

  #### Deprecated

  使用 addMessageRecalledListener 替代，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:646

### addMessageRecalledListener

- addMessageRecalledListener(listener: MessageRecalledListener): void

  增加消息撤回监听。撤回了之后，原始消息会变成 RecallNotificationMessage 消息

  # 示例代码

       let recalledListener : MessageRecalledListener = {
         onMessageRecalled: (message: Message, recallMessage: RecallNotificationMessage): void => {
           // 消息撤回
         }
       }
       IMEngine.getInstance().addMessageRecalledListener(recalledListener);

  #### Parameters

  - listener: MessageRecalledListener

    监听

  #### Returns void

  #### Warning

  addMessageRecalledListener & removeMessageRecalledListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:675

### removeMessageRecalledListener

- removeMessageRecalledListener(listener: MessageRecalledListener): void

  移除消息撤回监听

  # 示例代码

      IMEngine.getInstance().removeMessageRecalledListener(recalledListener);

  #### Parameters

  - listener: MessageRecalledListener

    监听

  #### Returns void

  #### Warning

  addMessageRecalledListener & removeMessageRecalledListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:689

### setMessageBlockedListener

- setMessageBlockedListener(listener: (blockInfo: MessageBlockInfo) => void): void

  设置消息敏感词拦截监听

  # 示例代码

       IMEngine.getInstance().setMessageBlockedListener((blockInfo: MessageBlockInfo) => {

       });

  #### Parameters

  - listener: (blockInfo: MessageBlockInfo) => void

    监听

  #### Returns void

  #### Discussion

  触发时间参考 MessageBlockedListener.onMessageBlocked

  #### Version

  1.0.0

  #### Deprecated

  使用 addMessageBlockedListener 替代，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:706

### addMessageBlockedListener

- addMessageBlockedListener(listener: MessageBlockedListener): void

  增加消息敏感词拦截监听

  # 示例代码

       let blockedListener : MessageBlockedListener = {
         onMessageBlocked: (blockInfo: MessageBlockInfo): void => {

         }
       }
       IMEngine.getInstance().addMessageBlockedListener(blockedListener);

  #### Parameters

  - listener: MessageBlockedListener

    监听

  #### Returns void

  #### Discussion

  触发时间参考 MessageBlockedListener.onMessageBlocked

  #### Warning

  addMessageBlockedListener & removeMessageBlockedListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:734

### removeMessageBlockedListener

- removeMessageBlockedListener(listener: MessageBlockedListener): void

  移除消息敏感词拦截监听

  # 示例代码

      IMEngine.getInstance().removeMessageBlockedListener(blockedListener);

  #### Parameters

  - listener: MessageBlockedListener

    监听

  #### Returns void

  #### Warning

  addMessageBlockedListener & removeMessageBlockedListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:748

### sendMessage

- sendMessage(
  message: Message,
  option: ISendMsgOption,
  saveCallback: (msg: Message) => void,
  ): Promise<IAsyncResult<Message>>

  发送消息

  # 说明

      如果遇到 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;
       })

  #### Parameters

  - message: Message

    消息对象

  - option: ISendMsgOption

    消息发送的配置

  - saveCallback: (msg: Message) => void

    消息入库的回调

  #### Returns Promise<IAsyncResult<Message>>

  消息发送结果

  #### Discussion

  只有入库成功才会走 savedCallback，其他的情况：非法参数、入库失败、发送不入库的消息等都不会走 savedCallback 直接走 resultCallback

  #### Note

  SDK 内置消息都有推送，自定义消息必须设置 Message.pushConfig

  #### Version

  1.0.0

  - Defined in IMEngine.ts:794

### sendMediaMessage

- sendMediaMessage(
  message: Message,
  option: ISendMsgOption,
  saveCallback: (msg: Message) => void,
  progressCallback: (msg: Message, progress: number) => void,
  ): Promise<IAsyncResult<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;
       })

  #### Parameters

  - message: Message

    消息体

  - option: ISendMsgOption

    消息发送的配置

  - saveCallback: (msg: Message) => void

    消息入库的回调

  - progressCallback: (msg: Message, progress: number) => void

    媒体文件上传进度

  #### Returns Promise<IAsyncResult<Message>>

  媒体消息发送结果

  #### Discussion

  只有入库成功才会走 savedCallback，其他的情况：非法参数、入库失败、发送不入库的消息等都不会走 savedCallback 直接走 resultCallback

  #### Note

  调用 cancelSendMediaMessage 接口成功取消发送会回调 RequestCanceled

  #### Version

  1.0.0

  - Defined in IMEngine.ts:862

### sendMediaMessageWithUploader

- sendMediaMessageWithUploader(
  message: Message,
  option: ISendMsgOption,
  saveCallback: (msg: Message) => void,
  progressCallback: (msg: Message, progress: number) => void,
  uploadCallback?: (uploader: MediaMessageTransfer) => void,
  ): Promise<IAsyncResult<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;
       })

  #### Parameters

  - message: Message

    消息体

  - option: ISendMsgOption

    消息发送的配置

  - saveCallback: (msg: Message) => void

    消息入库的回调

  - progressCallback: (msg: Message, progress: number) => void

    媒体文件上传进度

  - `Optional` uploadCallback: (uploader: MediaMessageTransfer) => void

    [可选参数]自定义媒体文件上传回调，如果此参数不传则执行SDK默认流程

  #### Returns Promise<IAsyncResult<Message>>

  媒体消息发送结果

  #### Discussion

  只有入库成功才会走 savedCallback，其他的情况：非法参数、入库失败、发送不入库的消息等都不会走 savedCallback 直接走 resultCallback

  #### Version

  1.4.0

  - Defined in IMEngine.ts:955

### cancelSendMediaMessage

- cancelSendMediaMessage(messageId: number): Promise<IAsyncResult<void>>

  取消发送媒体消息下载

  # 示例代码

       let messageId = 123;
       IMEngine.getInstance().cancelSendMediaMessage(messageId).then(result => {
         if (EngineError.Success === result.code) {
           // 取消发送媒体消息成功
         } else {
           // 取消发送媒体消息成功失败
         }
       });

  #### Parameters

  - messageId: number

    消息 Id

  #### Returns Promise<IAsyncResult<void>>

  取消发送媒体消息结果

  #### Version

  1.4.3

  - Defined in IMEngine.ts:1007

### sendDirectionalMessage

- sendDirectionalMessage(
  message: Message,
  option: ISendMsgOption,
  userIdArray: string[],
  saveCallback: (msg: Message) => void,
  ): Promise<IAsyncResult<Message>>

  发送普通定向消息

  # 说明

      此方法用于在群组中发送消息给其中的部分用户，其它用户不会收到这条消息。
      如果遇到 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;
       })

  #### Parameters

  - message: Message

    消息对象

  - option: ISendMsgOption

    消息发送的配置

  - userIdArray: string[]

    消息指定接收者

  - saveCallback: (msg: Message) => void

    消息入库的回调，

  #### Returns Promise<IAsyncResult<Message>>

  消息发送结果

  #### Discussion

  只有入库成功才会走 savedCallback，其他的情况：非法参数、入库失败、发送不入库的消息等都不会走 savedCallback 直接走 resultCallback

  #### Note

  SDK 内置消息都有推送，自定义消息必须设置 Message.pushConfig

  #### Version

  1.3.0

  - Defined in IMEngine.ts:1062

### sendDirectionalMediaMessage

- sendDirectionalMediaMessage(
  message: Message,
  option: ISendMsgOption,
  userIdArray: string[],
  saveCallback: (msg: Message) => void,
  progressCallback: (msg: Message, progress: number) => void,
  ): Promise<IAsyncResult<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;
       })

  #### Parameters

  - message: Message

    消息体

  - option: ISendMsgOption

    消息发送的配置

  - userIdArray: string[]

    消息指定接收者

  - saveCallback: (msg: Message) => void

    消息发送的配置

  - progressCallback: (msg: Message, progress: number) => void

    媒体文件上传进度

  #### Returns Promise<IAsyncResult<Message>>

  媒体消息发送结果

  #### Discussion

  只有入库成功才会走 savedCallback，其他的情况：非法参数、入库失败、发送不入库的消息等都不会走 savedCallback 直接走 resultCallback

  #### Version

  1.3.0

  - Defined in IMEngine.ts:1135

### downloadMediaMessage

- downloadMediaMessage(messageId: number): Promise<IAsyncResult<string>>

  下载媒体消息

  # 示例代码

       let messageId = 234;
       IMEngine.getInstance().downloadMediaMessage(messageId).then(result => {
         if (EngineError.Success === result.code) {
           // 本地路径
           let localPath = result.data as string;
         }
       });

  #### Parameters

  - messageId: number

    消息 id，对应的消息必须是 MediaMessageContent 子类

  #### Returns Promise<IAsyncResult<string>>

  媒体消息下载成功的本地路径，存储路径见 InitOption.mediaSavePath

  #### Note

  调用该接口下载成功后，消息的本地路径会保存数据库中；相同的消息重复下载，会直接返回本地路径

  #### Note

  SDK 下载媒体过程中，调用了 cancelDownloadMediaMessage() ，该方法会返回 EngineError.RequestCanceled

  #### Version

  1.0.0

  #### Deprecated

  使用 downloadMediaMessageWithProgress() 替代

  - Defined in IMEngine.ts:1183

### downloadMediaMessageWithProgress

- downloadMediaMessageWithProgress(
  messageId: number,
  progressListener: (messageId: number, progress: number) => void,
  ): Promise<IAsyncResult<string>>

  下载媒体消息，含下载进度

  # 示例代码

       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;
         }
       });

  #### Parameters

  - messageId: number

    消息 Id，对应的消息必须是 MediaMessageContent 子类

  - progressListener: (messageId: number, progress: number) => void

    下载进度监听，取值范围 [0 , 100]

  #### Returns Promise<IAsyncResult<string>>

  媒体消息下载成功的本地路径，存储路径见 InitOption.mediaSavePath

  #### Note

  调用该接口下载成功后，消息的本地路径会保存数据库中；相同的消息重复下载，会直接返回本地路径

  #### Note

  SDK 下载媒体过程中，调用了 cancelDownloadMediaMessage() ，该方法会返回 EngineError.RequestCanceled

  #### Version

  1.3.0

  - Defined in IMEngine.ts:1208

### downloadMediaMessageWithDownloader

- downloadMediaMessageWithDownloader(
  messageId: number,
  progressCallback: (messageId: number, progress: number) => void,
  downloadCallback?: (downloader: MediaMessageTransfer) => void,
  ): Promise<IAsyncResult<string>>

  使用自定义方法下载媒体消息

  # 示例代码

       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;
         }
       });

  #### Parameters

  - messageId: number

    消息 id，对应的消息必须是 MediaMessageContent 子类

  - progressCallback: (messageId: number, progress: number) => void
  - `Optional` downloadCallback: (downloader: MediaMessageTransfer) => void

    [可选参数]自定义媒体文件下载回调，如果此参数不传则执行SDK默认流程

  #### Returns Promise<IAsyncResult<string>>

  媒体消息下载成功的本地路径，存储路径见 InitOption.mediaSavePath

  #### Note

  调用该接口下载成功后，消息的本地路径会保存数据库中；相同的消息重复下载，会直接返回本地路径

  #### Note

  SDK 下载媒体过程中，调用了 cancelDownloadMediaMessage() ，该方法会返回 EngineError.RequestCanceled

  #### Version

  1.4.0

  - Defined in IMEngine.ts:1258

### pauseDownloadMediaMessage

- pauseDownloadMediaMessage(messageId: number): Promise<IAsyncResult<void>>

  暂停媒体消息下载

  # 示例代码

       let messageId = 123;
       IMEngine.getInstance().pauseDownloadMediaMessage(messageId).then(result => {
         if (EngineError.Success === result.code) {
           // 暂停下载成功，此时 downloadMediaMessageWithProgress 会返回 EngineError.RequestPaused
         } else {
           // 暂停下载失败
         }
       });

  #### Parameters

  - messageId: number

    消息 Id

  #### Returns Promise<IAsyncResult<void>>

  暂停下载结果

  #### Note

  暂停之后，再次调用下载方法，SDK 会继续前面的下载。

  #### Note

  如果媒体资源尺寸太小（例如是几十 KB 的小图片）可能立即就下载完了，不容易暂停成功。最好是较大的媒体资源使用该方法

  #### Version

  1.4.0

  - Defined in IMEngine.ts:1303

### cancelDownloadMediaMessage

- cancelDownloadMediaMessage(messageId: number): Promise<IAsyncResult<void>>

  取消下载媒体消息，配合 downloadMediaMessageWithProgress 方法

  # 示例代码

       let messageId = 123;
       IMEngine.getInstance().cancelDownloadMediaMessage(messageId).then(result => {
         if (EngineError.Success === result.code) {
           // 下载取消成功，此时 downloadMediaMessageWithProgress 会返回 EngineError.RequestCanceled
         } else {
           // 下载取消失败
         }
       });

  #### Parameters

  - messageId: number

    消息 Id

  #### Returns Promise<IAsyncResult<void>>

  取消下载结果

  #### Note

  取消之后，再次调用下载方法，SDK 会重新下载。

  #### Note

  如果媒体资源尺寸太小（例如是几十 KB 的小图片）不容易取消成功，可能立即就下载完了。最好是较大的媒体资源使用该方法

  #### Version

  1.3.0

  - Defined in IMEngine.ts:1330

### downloadFileWithProgress

- downloadFileWithProgress(
  remoteUrl: string,
  fileName: string,
  startCallback: (uniqueId: number) => void,
  progressListener: (uniqueId: number, progress: number) => void,
  ): Promise<IAsyncResult<string>>

  下载文件（带下载进度）

  # 说明

      如果是下载媒体消息，请调用 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;
       });

  #### Parameters

  - remoteUrl: string

    媒体的远端地址

  - fileName: string

    本地文件名

  - startCallback: (uniqueId: number) => void

    开始下载。uniqueId 下载唯一标识，可以调用 cancelDownloadFile 取消下载

  - progressListener: (uniqueId: number, progress: number) => void

    下载进度监听，取值范围 [0 , 100]

  #### Returns Promise<IAsyncResult<string>>

  媒体文件下载成功的本地路径，存储路径见 InitOption.mediaSavePath

  #### Note

  调用该接口下载成功后，消息的本地路径会保存数据库中；相同的消息重复下载，会直接返回本地路径

  #### Note

  SDK 下载媒体过程中，调用了 cancelDownloadFile() ，该方法会返回 EngineError.RequestCanceled

  #### Deprecated

  该接口已被废弃，下载媒体文件功能可使用 downloadMediaFile 接口代替。

  #### Version

  1.3.0

  - Defined in IMEngine.ts:1381

### downloadMediaFile

- downloadMediaFile(
  uniqueId: string,
  remoteUrl: string,
  fileName: string,
  startCallback: (uniqueId: string) => void,
  progressListener: (uniqueId: string, progress: number) => void,
  ): Promise<IAsyncResult<string>>

  下载媒体文件

  ## 示例代码

      // 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;
       });

  #### Parameters

  - uniqueId: string

    文件唯一标示

  - remoteUrl: string

    文件的远端地址

  - fileName: string

    本地文件名

  - startCallback: (uniqueId: string) => void
  - progressListener: (uniqueId: string, progress: number) => void

    下载进度监听，取值范围 [0 , 100]

  #### Returns Promise<IAsyncResult<string>>

  媒体文件下载成功的本地路径，存储路径见 InitOption.mediaSavePath

  #### Note

  调用该接口下载成功后，消息的本地路径会保存数据库中；相同的消息重复下载，会直接返回本地路径

  #### Note

  SDK 下载媒体过程中，调用了 cancelDownloadFile() ，该方法会返回 EngineError.RequestPaused

  #### Version

  1.4.0

  - Defined in IMEngine.ts:1446

### pauseDownloadMediaFile

- pauseDownloadMediaFile(messageId: string): Promise<IAsyncResult<string>>

  暂停下载媒体文件

  ## 示例代码

      // messageId 与 downloadMediaFile 的第一个参数对应
      let messageId = "123";
       IMEngine.getInstance().pauseDownloadMediaFile(messageId).then(result => {
         if (EngineError.Success === result.code) {
           // 暂停下载成功，此时 downloadMediaFile 会返回 EngineError.RequestCanceled
         } else {
           // 暂停下载失败
         }
       });

  #### Parameters

  - messageId: string

  #### Returns Promise<IAsyncResult<string>>

  下载的结果

  #### Note

  暂停之后，再次调用下载方法，SDK 会接着上次下载的进度断点续传。

  #### Note

  如果媒体资源尺寸太小（例如是几十 KB 的小图片）不容易取消成功，可能立即就下载完了。最好是较大的媒体资源使用该方法

  #### Version

  1.4.0

  - Defined in IMEngine.ts:1495

### cancelDownloadFile

- cancelDownloadFile(uniqueId: string | number): Promise<IAsyncResult<void>>

  取消下载文件，配合 downloadFileWithProgress 方法

  # 示例代码

       // uniqueId 必须是调用 downloadFileWithProgress 时由 SDK 生成的，此处进行了简写
       let uniqueId = "1234";

       IMEngine.getInstance().cancelDownloadFile(uniqueId).then(result => {
         if (EngineError.Success !== result.code) {
           // 取消下载失败
           return;
         }
         // 取消下载成功，此时 downloadFileWithProgress 会返回 EngineError.RequestCanceled
       })

  #### Parameters

  - uniqueId: string | number

    下载唯一标识

  #### Returns Promise<IAsyncResult<void>>

  下载的结果

  #### Note

  取消之后，再次调用下载方法，SDK 会重新下载。

  #### Note

  如果媒体资源尺寸太小（例如是几十 KB 的小图片）不容易取消成功，可能立即就下载完了。最好是较大的媒体资源使用该方法

  #### Version

  1.3.0

  - Defined in IMEngine.ts:1524

### recallMessage

- recallMessage(
  message: Message,
  ): Promise<IAsyncResult<RecallNotificationMessage>>

  撤回消息

  # 示例代码

       // 必须用发送成功的消息，此处进行了简写
       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;
       })

  #### Parameters

  - message: Message

    需要撤回的消息，发送成功的消息才能撤回（必须有有效的 MessageUid）

  #### Returns Promise<IAsyncResult<RecallNotificationMessage>>

  撤回成功后的小灰条消息

  #### Discussion

  pushContent 用 Message.pushConfig

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1557

### registerMessageType

- registerMessageType(msgClassList: List<MessageContentConstructor>): void

  注册自定义消息，初始化之后，连接之前调用

  # 说明

      自定义消息 CustomOrderMessage 示例代码见 MessageContent
      自定义媒体消息 CustomFileMessage 示例代码见 MediaMessageContent

  # 示例代码

      let clazzList: List<MessageContentConstructor> = new List();
      clazzList.add(CustomOrderMessage);
      IMEngine.getInstance().registerMessageType(clazzList);

  #### Parameters

  - msgClassList: List<MessageContentConstructor>

    自定义消息数组

  #### Returns void

  #### Note

  自定义消息需要继承 MessageContent|MediaMessageContent 并且实现无参构造方法才能注册给 SDK

  #### Note

  相同 objectName 的消息重复注册，后注册的消息会覆盖先注册的消息

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1583

### getMessageTypeMap

- getMessageTypeMap(): HashMap<string, MessageFlag>

  获取 SDK 中所有的消息 objectName 和存储标识的映射关系

  # 注意事项

      1. 映射关系集合包含 内置消息 和 自定义消息
      2. 必须在所有自定义消息注册完成之后再调用该方法，否则会导致无法正确获取自定义消息的映射关系
      3. 不要频繁调用该方法：建议 app 调用该方法之后， app 自行保存整个集合

  # 其他平台说明

      iOS 通过 RCMessagePersistentCompatible.persistentFlag 获取消息存储标识
      Android 通过 getClass().getAnnotation(MessageTag.class) 获取消息存储标识
      鸿蒙需要通过本方法获取

  # 如何获取 objectName？

      1. 发送消息时需要手动构造指定的消息体，可以直接获取到 objectName：例如创建文本消息时一定知道是文本消息的 objectName
      2. 接收消息时通过 Message 对象获取：Message.objectName
      3. 读取会话时通过 Conversation 对象获取：Conversation.objectName

  # 示例代码

      let hashMap = IMEngine.getInstance().getMessageTypeMap();

  #### Returns HashMap<string, MessageFlag>

  映射关系集合。 key ：objectName 、 value ： MessageFlag

  #### Version

  1.2.0

  - Defined in IMEngine.ts:1614

### batchInsertMessage

- batchInsertMessage(msgList: List<Message>): Promise<IAsyncResult<void>>

  消息批量入库（多用于数据迁移）

  # Message 下列属性会被入库，其他属性会被抛弃：

      conversationType   会话类型
      targetId           会话 ID
      channelId          所属会话的业务标识，长度限制 20 字符
      direction          消息方向
      senderId           发送者 ID
      receivedStatus     接收状态：direction 为 Receive 且 receivedStatus.isRead 为 false 时，会话未读数累加
      sentStatus         发送状态
      sentTime           发送时间
      content            消息内容
      objectName         消息类型，设置 content 的时候 SDK 会自动赋值对应的 objectName
      messageUid         服务端生产的消息唯一 ID，如要携带该字段需要保证入库后是唯一的
      extra              扩展信息
      canIncludeExpansion 是否支持消息扩展
      expansion           消息扩展内容

  # 示例代码

       // 必须是有效的消息集合，此处进行了简写
       let msgList : List<Message> ;
       IMEngine.getInstance().batchInsertMessage(msgList).then(result => {
         if (EngineError.Success !== result.code) {
           // 批量入库失败
           return;
         }
         // 批量入库成功
       });

  #### Parameters

  - msgList: List<Message>

    需要入库的消息，范围 [1 ~ 500]，会话类型不支持聊天室和超级群

  #### Returns Promise<IAsyncResult<void>>

  入库结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1654

### insertMessage

- insertMessage(msg: Message): Promise<IAsyncResult<Message>>

  单条消息入库

  # Message 下列属性会被入库，其他属性会被抛弃：

      conversationType   会话类型
      targetId           会话 ID
      direction          消息方向，默认为发送
      senderId           发送者 ID
      receivedStatus     接收状态：direction 为 Receive 且 receivedStatus.isRead 为 false 时，会话未读数累加
      sentStatus         发送状态，默认为发送失败
      sentTime           发送时间
      content            消息内容
      objectName         消息类型，设置 content 的时候 SDK 会自动赋值对应的 objectName
      messageUid         服务端生产的消息唯一 ID，如要携带该字段需要保证入库后是唯一的
      extra              扩展信息
      canIncludeExpansion 是否支持消息扩展
      expansion           消息扩展内容

  # 示例代码

       // 必须是有效的消息对象，此处进行了简写
       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;
       });

  #### Parameters

  - msg: Message

  #### Returns Promise<IAsyncResult<Message>>

  入库结果

  #### Version

  1.2.0

  - Defined in IMEngine.ts:1703

### getMessages

- getMessages(
  conId: ConversationIdentifier,
  option: IHistoryMessageOption,
  ): Promise<IAsyncResult<HistoryMessageResult>>

  批量获取本地和远端消息，支持单聊、群聊、系统消息。

  # 示例代码

       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;
       })

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - option: IHistoryMessageOption

    历史消息选项

  #### Returns Promise<IAsyncResult<HistoryMessageResult>>

  历史消息数据，详见 HistoryMessageResult

  #### Version

  1.5.0

  - Defined in IMEngine.ts:1743

### getMessageById

- getMessageById(messageId: number): Promise<IAsyncResult<Message>>

  通过 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;
       })

  #### Parameters

  - messageId: number

    消息的本地数据库自增 ID

  #### Returns Promise<IAsyncResult<Message>>

  消息数据

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1776

### getMessageByUid

- getMessageByUid(messageUid: string): Promise<IAsyncResult<Message>>

  通过 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;
       })

  #### Parameters

  - messageUid: string

    消息发送成功后的服务唯一 ID，固定格式的字符串，例如 ： CH2C-A072-OGM5-E3HL

  #### Returns Promise<IAsyncResult<Message>>

  消息数据

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1806

### getHistoryMessagesById

- getHistoryMessagesById(
  conId: ConversationIdentifier,
  option: IGetLocalMsgByIdOption,
  ): Promise<IAsyncResult<List<Message>>>

  获取批量本地消息，基于 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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - option: IGetLocalMsgByIdOption

    配置

  #### Returns Promise<IAsyncResult<List<Message>>>

  返回本地消息结果

  #### See

  - ConversationIdentifier
  - IGetLocalMsgByIdOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1848

### getHistoryMessagesByTime

- getHistoryMessagesByTime(
  conId: ConversationIdentifier,
  option: IGetLocalMsgByTimeOption,
  ): Promise<IAsyncResult<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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - option: IGetLocalMsgByTimeOption

    配置

  #### Returns Promise<IAsyncResult<List<Message>>>

  返回本地消息结果

  #### See

  - ConversationIdentifier
  - IGetLocalMsgByTimeOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1893

### getRemoteHistoryMessages

- getRemoteHistoryMessages(
  conId: ConversationIdentifier,
  option: IGetRemoteMsgOption,
  ): Promise<IAsyncResult<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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - option: IGetRemoteMsgOption

    配置

  #### Returns Promise<IAsyncResult<List<Message>>>

  返回远端消息结果

  #### Note

  此方法从服务器端获取之前的历史消息，但是必须先开通历史消息云存储功能

  #### See

  - ConversationIdentifier
  - IGetLocalMsgByTimeOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1940

### getUnreadMentionedMessages

- getUnreadMentionedMessages(
  conId: ConversationIdentifier,
  option: ICountOption,
  ): Promise<IAsyncResult<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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - option: ICountOption

    配置

  #### Returns Promise<IAsyncResult<List<Message>>>

  返回本地消息结果

  #### See

  - ConversationIdentifier
  - ICountOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:1984

### getFirstUnreadMessage

- getFirstUnreadMessage(
  conId: ConversationIdentifier,
  ): Promise<IAsyncResult<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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<Message>>

  消息，如果该会话没有未读，返回 null

  #### See

  ConversationIdentifier

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2020

### deleteHistoryMessagesByIds

- deleteHistoryMessagesByIds(
  messageIds: List<number>,
  ): Promise<IAsyncResult<void>>

  删除本地会话的指定一批消息

  # 示例代码

       let idList = new List<number>();
       idList.add(msg.messageId);

       IMEngine.getInstance().deleteHistoryMessagesByIds(idList).then(result => {
         if (EngineError.Success !== result.code) {
           // 删除消息失败
           return;
         }
         // 删除消息成功
       })

  #### Parameters

  - messageIds: List<number>

    消息 ID 列表

  #### Returns Promise<IAsyncResult<void>>

  删除结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2047

### deleteMessages

- deleteMessages(conId: ConversationIdentifier): Promise<IAsyncResult<void>>

  清空本地会话的消息

  # 示例代码

       let conId = new ConversationIdentifier();
       conId.conversationType = ConversationType.Private;
       conId.targetId = "TestTargetId"; // 按需填写实际的会话 id

       IMEngine.getInstance().deleteMessages(conId).then(result => {
         if (EngineError.Success !== result.code) {
           // 删除消息失败
           return;
         }
         // 删除消息成功
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### See

  ConversationIdentifier

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2076

### deleteHistoryMessagesByTime

- deleteHistoryMessagesByTime(
  conId: ConversationIdentifier,
  sentTime: number,
  ): Promise<IAsyncResult<void>>

  删除本地会话特定时间前的所有消息

  # 示例代码

       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;
         }
         // 删除消息成功
       })

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - sentTime: number

    毫秒时间戳。清除 <= sentTime 的所有历史消息，若为 0 则代表清除所有消息

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### See

  ConversationIdentifier

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2108

### cleanRemoteHistoryMessagesByTime

- cleanRemoteHistoryMessagesByTime(
  conId: ConversationIdentifier,
  sentTime: number,
  ): Promise<IAsyncResult<void>>

  删除远端会话特定时间前的消息

  # 示例代码

       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;
         }
         // 删除消息成功
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - sentTime: number

    毫秒时间戳。清除 <= sentTime 的所有历史消息，若为 0 则代表清除所有消息

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### See

  ConversationIdentifier

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2140

### deleteRemoteMessages

- deleteRemoteMessages(
  conId: ConversationIdentifier,
  msgList: List<Message>,
  isDeleteLocal: boolean,
  ): Promise<IAsyncResult<void>>

  批量删除远端消息，发送成功或者接收到的消息才可以从远端删除

  # 说明

      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;
         }
         // 删除远端消息成功
       })

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - msgList: List<Message>

    消息列表，长度范围 [1, 100]

  - isDeleteLocal: boolean

    是否删除本地消息。只有远端消息被删除成功时设置 true 才会删除本地消息。

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.1.0

  - Defined in IMEngine.ts:2190

### setTypingStatusListener

- setTypingStatusListener(
  listener: (
  conId: ConversationIdentifier,
  typingStatusList: List<TypingStatus>,
  ) => void,
  ): void

  设置输入状态的监听

  # 示例代码

      IMEngine.getInstance().setTypingStatusListener((conId: ConversationIdentifier, typingStatusList: List<TypingStatus>) => {
         // conId 具体的会话标识
         // typingStatusList 具体的输入状态
      });

  #### Parameters

  - listener: (conId: ConversationIdentifier, typingStatusList: List<TypingStatus>) => void

    监听，conId 会话标识；typingStatusList 输入状态的列表

  #### Returns void

  #### Version

  1.1.0

  #### Deprecated

  使用 addTypingStatusListener 替代，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:2215

### addTypingStatusListener

- addTypingStatusListener(listener: TypingStatusListener): void

  增加输入状态的监听

  # 示例代码

       let typingListener: TypingStatusListener = {
         onTypingStatusChange: (conId: ConversationIdentifier, typingStatusList: List<TypingStatus>): void => {
           // conId 具体的会话标识
           // typingStatusList 具体的输入状态
         }
       }
       IMEngine.getInstance().addTypingStatusListener(typingListener);

  #### Parameters

  - listener: TypingStatusListener

    监听

  #### Returns void

  #### Warning

  addTypingStatusListener & removeTypingStatusListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2245

### removeTypingStatusListener

- removeTypingStatusListener(listener: TypingStatusListener): void

  移除输入状态的监听

  # 示例代码

       IMEngine.getInstance().removeTypingStatusListener(typingListener);

  #### Parameters

  - listener: TypingStatusListener

    监听，对方调用 sendTypingStatus() 时本端会出发该监听

  #### Returns void

  #### Warning

  addTypingStatusListener & removeTypingStatusListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2259

### sendTypingStatus

- sendTypingStatus(
  conId: ConversationIdentifier,
  objectName: string,
  ): Promise<IAsyncResult<void>>

  发送输入状态，仅支持单聊

  # 说明

      常见的使用方式如下：
      在聊天页面输入文本时，可以发送 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;
         }
         // 发送成功
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - objectName: string

    正在输入的消息 ObjectName

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.1.0

  - Defined in IMEngine.ts:2292

### setTypingStatusInterval

- setTypingStatusInterval(interval: number): Promise<IAsyncResult<void>>

  设置输入状态更新时间间隔

  # 说明

      控制输入状态发送频率，在规定时间内多次调用发送输入状态方法，最终只会发送一次输入状态
      例如输入状态时间间隔为 6000 毫秒，在这段时间多次调用输入状态方法，只会发出一次输入状态，对方也只会收到一次输入状态

  # 示例代码

       let interval = 5000;
       IMEngine.getInstance().setTypingStatusInterval(interval).then(result => {
         if (EngineError.Success !== result.code) {
           // 设置输入状态间隔失败
           return;
         }
         // 设置成功
       });

  #### Parameters

  - interval: number

    时间间隔，单位毫秒，默认为 6000 毫秒。有效值 [1000，60000] 毫秒；超过范围，则设置不成功

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.1.0

  - Defined in IMEngine.ts:2322

### setMessageReceivedStatus

- setMessageReceivedStatus(
  messageId: number,
  receiveStatus: ReceivedStatus,
  ): Promise<IAsyncResult<void>>

  修改消息接收状态

  # 说明

      目前该方法仅用于设置 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;
         }
         // 设置接收状态成功
       })

  #### Parameters

  - messageId: number

    消息 Id

  - receiveStatus: ReceivedStatus

    接收状态

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2356

### setMessageExtra

- setMessageExtra(messageId: number, extra: string): Promise<IAsyncResult<void>>

  设置本地消息的附加信息

  # 说明

  用于扩展消息的使用场景。设置后可以通过 getHistoryMessages 取出带附加信息的消息。

  # 示例代码

       let messageId = 123;
       let extra = "这是要更新的 extra 字段内容";

       IMEngine.getInstance().setMessageExtra(messageId, extra).then(result => {
         if (EngineError.Success == result.code) {
           // 设置 extra 字段内容成功
         } else {
           // 设置 extra 字段内容失败
         }
       })

  #### Parameters

  - messageId: number

    消息 Id

  - extra: string

  #### Returns Promise<IAsyncResult<void>>

  返回设置成功或者失败

  #### Note

  只能用于本地使用，无法同步给远程用户

  #### Version

  1.4.1

  - Defined in IMEngine.ts:2390

### setMessageExpansionListener

- setMessageExpansionListener(listener: MessageExpansionListener): void

  设置消息扩展监听

  # 示例代码

       let listener: MessageExpansionListener = {
         onMessageExpansionUpdate: (expansion: Map<string, string>, message: Message): void => {

         },
         onMessageExpansionRemove: (keyArray: string[], message: Message): void => {

         }
       }

       IMEngine.getInstance().setMessageExpansionListener(listener);

  #### Parameters

  - listener: MessageExpansionListener

    监听

  #### Returns void

  #### Version

  1.2.0

  #### Deprecated

  使用 addMessageExpansionListener 替代

  - Defined in IMEngine.ts:2421

### addMessageExpansionListener

- addMessageExpansionListener(listener: MessageExpansionListener): void

  增加消息扩展监听

  # 示例代码

       let listener: MessageExpansionListener = {
         onMessageExpansionUpdate: (expansion: Map<string, string>, message: Message): void => {

         },
         onMessageExpansionRemove: (keyArray: string[], message: Message): void => {

         }
       }

       IMEngine.getInstance().addMessageExpansionListener(listener);

  #### Parameters

  - listener: MessageExpansionListener

    监听

  #### Returns void

  #### Warning

  addMessageExpansionListener & removeMessageExpansionListener 配对使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2445

### removeMessageExpansionListener

- removeMessageExpansionListener(listener: MessageExpansionListener): void

  移除消息扩展监听

  # 示例代码

       IMEngine.getInstance().removeMessageExpansionListener(listener);

  #### Parameters

  - listener: MessageExpansionListener

    监听

  #### Returns void

  #### Warning

  addMessageExpansionListener & removeMessageExpansionListener 配对使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2459

### updateMessageExpansion

- updateMessageExpansion(
  expansion: Map<string, string>,
  messageUid: string,
  ): Promise<IAsyncResult<void>>

  更新消息扩展信息

  # 说明

      调用更新扩展的一方必须通过成功回调来处理本端的数据刷新。
      仅被动接收扩展变更的用户（包含本用户的其他端）通过监听方法 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;
         }
         // 消息扩展更新成功
       });

  #### Parameters

  - expansion: Map<string, string>

    要更新的消息扩展信息键值对

  - messageUid: string

    消息 messageUId

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Discussion

  扩展信息只支持单聊和群组，其它会话类型不能设置扩展信息

  #### Version

  1.2.0

  - Defined in IMEngine.ts:2496

### removeMessageExpansion

- removeMessageExpansion(
  keyArray: string[],
  messageUid: string,
  ): Promise<IAsyncResult<void>>

  删除消息扩展信息中特定的键值对

  # 说明

      调用删除扩展的一方必须通过成功回调来处理本端的数据刷新。
      仅被动接收扩展变更的用户（包含本用户的其他端）通过监听方法 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;
         }
         // 删除消息扩展成功
       });

  #### Parameters

  - keyArray: string[]

    消息扩展信息中待删除的 key 的列表

  - messageUid: string

    消息 messageUId

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Discussion

  扩展信息只支持单聊和群组，其它会话类型不能设置扩展信息

  #### Version

  1.2.0

  - Defined in IMEngine.ts:2534

### addMessageDestructionListener

- addMessageDestructionListener(listener: MessageDestructionListener): void

  增加消息阅后即焚监听，仅支持单聊，仅限阅后即焚消息的接收方调用

  # 示例代码

       let destructListener: MessageDestructionListener = {
         onMessageDestructing: (message: Message, leftDuration: number): void => {

         },
         onMessageDestructionStop: (message: Message): void => {

         }
       }
       IMEngine.getInstance().addMessageDestructionListener(destructListener);

  #### Parameters

  - listener: MessageDestructionListener

    监听

  #### Returns void

  #### Warning

  国内不允许带阅后即焚功能的 App 上架

  #### Warning

  addMessageDestructionListener & removeMessageDestructionListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2566

### removeMessageDestructionListener

- removeMessageDestructionListener(listener: MessageDestructionListener): void

  移除消息阅后即焚监听，仅支持单聊，仅限阅后即焚消息的接收方调用

  # 示例代码

       IMEngine.getInstance().removeMessageDestructionListener(destructListener);

  #### Parameters

  - listener: MessageDestructionListener

    监听

  #### Returns void

  #### Version

  1.3.0

  #### Warning

  addMessageDestructionListener & removeMessageDestructionListener 配合使用，避免内存泄露

  - Defined in IMEngine.ts:2580

### messageBeginDestruct

- messageBeginDestruct(message: Message): Promise<IAsyncResult<void>>

  消息开始阅后即焚倒计时，仅支持单聊，仅限阅后即焚消息的接收方调用

  # 示例代码

       // 必须使用有效的消息体，此处进行了简写
       let msg: Message;
       IMEngine.getInstance().messageBeginDestruct(msg).then(result => {
         if (EngineError.Success !== result.code) {
           // 失败
           return;
         }
         // 成功
       });

  #### Parameters

  - message: Message

    消息体

  #### Returns Promise<IAsyncResult<void>>

  #### Warning

  国内不允许带阅后即焚功能的 App 上架

  #### Note

  调用之后，阅后即焚消息开始倒计时，触发 MessageDestructionListener.onMessageDestructing

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2603

### messageStopDestruct

- messageStopDestruct(message: Message): Promise<IAsyncResult<void>>

  消息停止阅后即焚倒计时，仅支持单聊，仅限阅后即焚消息的接收方调用

  # 说明

      调用之后，该消息终止阅后即焚
      阅后即焚倒计时停止，并触发 MessageDestructionListener.onMessageDestructionStop
      可以调用 messageBeginDestruct() 重新进行倒计时

  # 示例代码

       // 必须使用有效的消息体，此处进行了简写
       let msg: Message;
       IMEngine.getInstance().messageStopDestruct(msg).then(result => {
         if (EngineError.Success !== result.code) {
           // 失败
           return;
         }
         // 成功
       });

  #### Parameters

  - message: Message

    消息体

  #### Returns Promise<IAsyncResult<void>>

  #### Warning

  国内不允许带阅后即焚功能的 App 上架

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2635

### setPushContentShowStatus

- setPushContentShowStatus(showStatus: boolean): Promise<IAsyncResult<void>>

  设置显示推送详情

  # 说明

      通知栏显示的消息推送默认显示的是消息内容，如果消息包含敏感信息，不希望在推送通知栏上显示消息内容，可以调用此方法设置 showStatus 为 false
      注意：此功能需要从服务端开启用户设置功能。

  # 示例代码

       let showStatus = true;
       IMEngine.getInstance().setPushContentShowStatus(showStatus).then(result => {
         if (EngineError.Success !== result.code) {
           // 失败
           return;
         }
         // 成功
       });

  #### Parameters

  - showStatus: boolean

    是否显示远程推送内容，true 显示，false 不显示

  #### Returns Promise<IAsyncResult<void>>

  设置的结果

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2669

### getPushContentShowStatus

- getPushContentShowStatus(): Promise<IAsyncResult<boolean>>

  获取是否显示远程推送内容详情设置

  # 示例代码

       IMEngine.getInstance().getPushContentShowStatus().then(result => {
         if (EngineError.Success !== result.code) {
           // 获取失败
           return;
         }
         if (!result.data) {
           // 数据为空
           return;
         }
         let showStatus = result.data as boolean;
       });

  #### Returns Promise<IAsyncResult<boolean>>

  是否显示远程推送内容，true 显示，false 不显示

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2696

### setPushReceiveStatus

- setPushReceiveStatus(receiveStatus: boolean): Promise<IAsyncResult<void>>

  设置 Web 端在线时，手机端是否接收推送

  # 说明

      注意：此功能需要从服务端开启用户设置功能。

  # 示例代码

       let receiveStatus = true;
       IMEngine.getInstance().setPushReceiveStatus(receiveStatus).then(result => {
         if (EngineError.Success !== result.code) {
           // 失败
           return;
         }
         // 成功
       });

  #### Parameters

  - receiveStatus: boolean

    是否接收推送，true 接收，false 不接收

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2725

### getPushReceiveStatus

- getPushReceiveStatus(): Promise<IAsyncResult<boolean>>

  获取是否接收远程推送的设置

  # 说明

      前提: 移动端不在线，Web 、MAC/PC 终端在线，移动端是否接收远程推送。

  # 示例代码

       IMEngine.getInstance().getPushReceiveStatus().then(result => {
         if (EngineError.Success !== result.code) {
           // 获取失败
           return;
         }
         if (!result.data) {
           // 数据为空
           return;
         }
         let receiveStatus = result.data as boolean;
       });

  #### Returns Promise<IAsyncResult<boolean>>

  是否接收远程推送，true 接收，false 不接收

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2756

### setConversationStatusListener

- setConversationStatusListener(
  listener: (items: List<ConversationStatusInfo>) => void,
  ): void

  设置会话状态（置顶，消息免打扰）变化监听

  # 示例代码

       IMEngine.getInstance().setConversationStatusListener((items: List<ConversationStatusInfo>) => {

       });

  #### Parameters

  - listener: (items: List<ConversationStatusInfo>) => void

    监听

  #### Returns void

  #### Version

  1.0.0

  #### Deprecated

  使用 addConversationStatusListener 替代，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:2780

### addConversationStatusListener

- addConversationStatusListener(listener: ConversationStatusListener): void

  增加会话状态（置顶，消息免打扰）变化监听

  # 示例代码

       let statusListener : ConversationStatusListener = {
         onConversationStatusChange: (items: List<ConversationStatusInfo>): void => {

         }
       }
       IMEngine.getInstance().addConversationStatusListener(statusListener);

  #### Parameters

  - listener: ConversationStatusListener

    监听

  #### Returns void

  #### Warning

  addConversationStatusListener & removeConversationStatusListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2807

### removeConversationStatusListener

- removeConversationStatusListener(listener: ConversationStatusListener): void

  移除会话状态（置顶，消息免打扰）变化监听

  # 示例代码

       IMEngine.getInstance().removeConversationStatusListener(statusListener);

  #### Parameters

  - listener: ConversationStatusListener

    监听

  #### Returns void

  #### Warning

  addConversationStatusListener & removeConversationStatusListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:2821

### getConversation

- getConversation(
  conId: ConversationIdentifier,
  ): Promise<IAsyncResult<Conversation>>

  获取单个会话

  # 示例代码

       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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<Conversation>>

  会话数据

  #### See

  ConversationIdentifier

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2850

### getConversationListByPage

- getConversationListByPage(
  conTypeList: List<ConversationType>,
  option: IGetConversationOption,
  ): Promise<IAsyncResult<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().getConversationListByPage(conTypeList, option).then(result => {
         if (EngineError.Success !== result.code) {
           // 获取会话列表失败
           return;
         }
         if (!result.data) {
           // 会话列表为空
           return;
         }
         let conList = result.data as List<Conversation>;
       });

  #### Parameters

  - conTypeList: List<ConversationType>

    会话类型列表

  - option: IGetConversationOption

    配置

  #### Returns Promise<IAsyncResult<List<Conversation>>>

  本地会话列表数据

  #### See

  IGetConversationOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2889

### getTopConversationListByPage

- getTopConversationListByPage(
  conTypeList: List<ConversationType>,
  option: IGetConversationOption,
  ): Promise<IAsyncResult<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>;
       });

  #### Parameters

  - conTypeList: List<ConversationType>

    会话类型列表

  - option: IGetConversationOption

    配置

  #### Returns Promise<IAsyncResult<List<Conversation>>>

  本地会话列表数据

  #### See

  IGetConversationOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2935

### getBlockedConversationListByPage

- getBlockedConversationListByPage(
  conTypeList: List<ConversationType>,
  option: IGetConversationOption,
  ): Promise<IAsyncResult<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>;
       });

  #### Parameters

  - conTypeList: List<ConversationType>

    会话类型列表

  - option: IGetConversationOption

    配置

  #### Returns Promise<IAsyncResult<List<Conversation>>>

  本地会话列表数据

  #### See

  IGetConversationOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:2981

### getUnreadConversations

- getUnreadConversations(
  conTypeList: List<ConversationType>,
  ): Promise<IAsyncResult<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>;
       });

  #### Parameters

  - conTypeList: List<ConversationType>

    会话类型数组，长度范围 [1, 100]

  #### Returns Promise<IAsyncResult<List<Conversation>>>

  会话数组

  #### Version

  1.1.0

  - Defined in IMEngine.ts:3021

### getUnreadMentionMeConversationList

- getUnreadMentionMeConversationList(
  option: GetConversationsByPageOption,
  ): Promise<IAsyncResult<List<Conversation>>>

  获取本地会话中 @ 自己的未读会话列表

  # 示例代码

       let conTypeList = new List<ConversationType>();
       conTypeList.add(ConversationType.Private);
       conTypeList.add(ConversationType.Group);

       let timestamp = 0; // 按需填写实际的 timestamp
       let count = 10; // 按需填写实际需要获取的条数
       let topPriority = false; // 按需填写是否需要置顶优先

       let option: GetConversationsByPageOption = {
         conversationTypes: conTypeList,
         timestamp: timestamp,
         count: count,
         topPriority: topPriority
       }

       IMEngine.getInstance().getUnreadMentionMeConversationList(option).then(result => {
         if (EngineError.Success !== result.code) {
           // 获取未读@会话列表失败
           return;
         }
         if (!result.data) {
           // 获取未读@会话列表为空
           return;
         }
         // 未读@会话列表
         let conList = result.data as List<Conversation>;
       });

  #### Parameters

  - option: GetConversationsByPageOption

    配置

  #### Returns Promise<IAsyncResult<List<Conversation>>>

  会话列表

  #### Version

  1.9.0

  - Defined in IMEngine.ts:3068

### getConversationsIncludingRobots

- getConversationsIncludingRobots(
  option: GetConversationsByPageOption,
  ): Promise<IAsyncResult<List<Conversation>>>

  获取本地包括机器人的会话列表

  # 示例代码

       let conTypeList = new List<ConversationType>();
       conTypeList.add(ConversationType.Private);
       conTypeList.add(ConversationType.System);

       let timestamp = 0; // 按需填写实际的 timestamp
       let count = 10; // 按需填写实际需要获取的条数
       let topPriority = false; // 按需填写是否需要置顶优先

       let option: GetConversationsByPageOption = {
         conversationTypes: conTypeList,
         timestamp: timestamp,
         count: count,
         topPriority: topPriority
       }
      IMEngine.getInstance().getConversationsIncludingRobots(option).then(result => {
         if (EngineError.Success !== result.code) {
           // 获取会话列表失败
           return;
         }
         if (!result.data) {
           // 会话列表为空
           return;
         }
         let conList = result.data as List<Conversation>;
       });

  #### Parameters

  - option: GetConversationsByPageOption

    配置

  #### Returns Promise<IAsyncResult<List<Conversation>>>

  会话列表

  #### Version

  1.9.0

  - Defined in IMEngine.ts:3115

### clearConversations

- clearConversations(
  conTypeList: List<ConversationType>,
  ): Promise<IAsyncResult<void>>

  删除本地会话同时删除会话中的消息

  # 示例代码

       let conTypeList = new List<ConversationType>();
       conTypeList.add(ConversationType.Private);

       IMEngine.getInstance().clearConversations(conTypeList).then(result => {
         if (EngineError.Success !== result.code) {
           // 删除会话失败
           return;
         }
       });

  #### Parameters

  - conTypeList: List<ConversationType>

    会话类型列表

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3146

### removeConversations

- removeConversations(
  conIdList: List<ConversationIdentifier>,
  ): Promise<IAsyncResult<void>>

  批量删除本地会话，但是不会删除消息

  # 示例代码

       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;
         }
       });

  #### Parameters

  - conIdList: List<ConversationIdentifier>

    会话标识数组

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3176

### removeRemoteConversations

- removeRemoteConversations(
  conIdList: ConversationIdentifier[],
  ): Promise<IAsyncResult<void>>

  批量删除远端会话

  # 示例代码

       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;
         }
       });

  #### Parameters

  - conIdList: ConversationIdentifier[]

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.6.0

  - Defined in IMEngine.ts:3206

### setReadTimestamp

- setReadTimestamp(
  conId: ConversationIdentifier,
  timestamp: number,
  ): Promise<IAsyncResult<void>>

  设置实时会话的已读时间

  # 示例代码

       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 {
           // 设置实时会话的已读时间成功

         }
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - timestamp: number

    时间戳

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.6.0

  - Defined in IMEngine.ts:3239

### setConversationsToTop

- setConversationsToTop(
  conIdList: List<ConversationIdentifier>,
  option: ISetConversationTopOption,
  ): Promise<IAsyncResult<void>>

  批量 设置/取消 会话置顶

  # 示例代码

       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;
         }
       });

  #### Parameters

  - conIdList: List<ConversationIdentifier>

    会话标识列表

  - option: ISetConversationTopOption

    配置

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### See

  ISetConversationTopOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3276

### getConversationTopStatus

- getConversationTopStatus(
  conId: ConversationIdentifier,
  ): Promise<IAsyncResult<boolean>>

  获取会话置顶状态

  # 示例代码

       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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<boolean>>

  是否置顶

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3311

### setConversationsNotificationLevel

- setConversationsNotificationLevel(
  conIdList: List<ConversationIdentifier>,
  level: PushNotificationLevel,
  ): Promise<IAsyncResult<void>>

  批量设置会话免打扰

  # 示例代码

       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;
         }
       });

  #### Parameters

  - conIdList: List<ConversationIdentifier>

    会话标识列表

  - level: PushNotificationLevel

    会话免打扰级别

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3344

### getConversationNotificationLevel

- getConversationNotificationLevel(
  conId: ConversationIdentifier,
  ): Promise<IAsyncResult<PushNotificationLevel>>

  获取单个会话免打扰状态

  # 示例代码

       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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<PushNotificationLevel>>

  会话免打扰级别

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3379

### saveTextMessageDraft

- saveTextMessageDraft(
  conId: ConversationIdentifier,
  draft: string,
  ): Promise<IAsyncResult<void>>

  保存/清空 会话草稿

  # 示例代码

       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;
         }
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - draft: string

    草稿：传入有效值代表保存草稿；传入空字符串代表清空草稿

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Discussion

  保存成功的草稿可以通过 Conversation.draft 获取

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3409

### getTextMessageDraft

- getTextMessageDraft(
  conId: ConversationIdentifier,
  ): Promise<IAsyncResult<string>>

  获取会话草稿

  # 示例代码

       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;
       })

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<string>>

  草稿

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3441

### setNotificationQuietHoursLevel

- setNotificationQuietHoursLevel(
  option: IQuietHoursOption,
  ): Promise<IAsyncResult<void>>

  屏蔽某个时间段的消息提醒

  # 示例代码

       let option: IQuietHoursOption = {
         startTime: "00:30:00",
         duration: 300,
         level: PushNotificationLevel.Blocked
       }

       IMEngine.getInstance().setNotificationQuietHoursLevel(option).then(result => {
         if (EngineError.Success !== result.code) {
           // 设置免打扰失败
           return;
         }
       })

  #### Parameters

  - option: IQuietHoursOption

    配置，见 IQuietHoursOption

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Discussion

  此方法设置的屏蔽时间会在每天该时间段时生效。

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3471

### getNotificationQuietHoursLevel

- getNotificationQuietHoursLevel(): Promise<IAsyncResult<IQuietHoursOption>>

  查询已设置的时间段消息提醒屏蔽

  # 示例代码

       IMEngine.getInstance().getNotificationQuietHoursLevel().then(result => {
         if (EngineError.Success !== result.code) {
           // 获取免打扰失败
           return;
         }
         if (!result.data) {
           // 免打扰数据为空
           return;
         }
         let info = result.data as IQuietHoursOption;
       })

  #### Returns Promise<IAsyncResult<IQuietHoursOption>>

  具体的配置

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3498

### removeNotificationQuietHours

- removeNotificationQuietHours(): Promise<IAsyncResult<void>>

  删除已设置的全局时间段消息提醒屏蔽

  # 示例代码

       IMEngine.getInstance().removeNotificationQuietHours().then(result => {
         if (EngineError.Success !== result.code) {
           // 移除免打扰失败
           return;
         }
         // 移除免打扰成功
       });

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3521

### getTotalUnreadCount

- getTotalUnreadCount(): Promise<IAsyncResult<number>>

  获取本地会话的全部未读数

  # 示例代码

       IMEngine.getInstance().getTotalUnreadCount().then(result => {
         if (EngineError.Success !== result.code) {
           // 获取未读数失败
           return;
         }
         if (!result.data) {
           // 未读数为 null
           return;
         }
         let unreadCount = result.data as number;
       })

  #### Returns Promise<IAsyncResult<number>>

  未读数

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3548

### getTotalUnreadCountByIds

- getTotalUnreadCountByIds(
  conIds: List<ConversationIdentifier>,
  ): Promise<IAsyncResult<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;
       })

  #### Parameters

  - conIds: List<ConversationIdentifier>

    会话标识数组

  #### Returns Promise<IAsyncResult<number>>

  未读数

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3587

### getUnreadCount

- getUnreadCount(conId: ConversationIdentifier): Promise<IAsyncResult<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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<number>>

  该会话的未读数

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3619

### clearMessagesUnreadStatus

- clearMessagesUnreadStatus(
  conId: ConversationIdentifier,
  ): Promise<IAsyncResult<void>>

  清空单个会话未读数

  # 示例代码

       let conId = new ConversationIdentifier();
       conId.conversationType = ConversationType.Private;
       conId.targetId = "TestTargetId"; // 按需填写实际的会话 id

       IMEngine.getInstance().clearMessagesUnreadStatus(conId).then(result => {
         if (EngineError.Success !== result.code) {
           // 清空未读数失败
           return;
         }
         / 清空未读数成功
       })

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3647

### clearMessagesUnreadStatusByTime

- clearMessagesUnreadStatusByTime(
  conId: ConversationIdentifier,
  time: number,
  ): Promise<IAsyncResult<void>>

  清除单个会话的未读数：按照时间戳清除

  # 示例代码

       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;
         }
         // 清空未读数成功
       })

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - time: number

    时间，清理小于该时间戳的消息未读

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3678

### getUnreadCountByTypes

- getUnreadCountByTypes(
  typeList: List<ConversationType>,
  isContainBlocked: boolean,
  ): Promise<IAsyncResult<number>>

  会话未读数，是否包含免打扰会话的未读数

  # 示例代码

       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;
       });

  #### Parameters

  - typeList: List<ConversationType>

    会话类型数组

  - isContainBlocked: boolean

    是否包含免打扰；true 代表获取所有会话未读数之和； false 代表获取不包含免打扰会话的正常会话未读数之和

  #### Returns Promise<IAsyncResult<number>>

  未读数

  #### Discussion

  正常单聊会话 A 的未读数为1，免打扰单聊会话 B 的未读数为 2。true 代表获取两个单聊会话的未读数之和，其结果为 3。false 代表获取正常会话 A 的未读数，结果为 1

  #### Version

  1.0.0

  - Defined in IMEngine.ts:3714

### createLocalConversation

- createLocalConversation(
  conIds: List<ConversationIdentifier>,
  ): Promise<IAsyncResult<void>>

  创建本地会话

  # 示例代码

       let conIds = new List<ConversationIdentifier>();
       conIds.add(new ConversationIdentifier(ConversationType.Private, "会话 Id"));
       IMEngine.getInstance().createLocalConversation(conIds).then(result => {
         if (EngineError.Success !== result.code) {
           // 创建本地会话失败
           return;
         }
         // 创建本地会话成功
       });

  #### Parameters

  - conIds: List<ConversationIdentifier>

    会话标识列表

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  25.11.0

  - Defined in IMEngine.ts:3743

### syncConversationReadStatus

- syncConversationReadStatus(
  conId: ConversationIdentifier,
  timestamp: number,
  ): Promise<IAsyncResult<void>>

  同步会话已读状态

  # 说明

      用于相同账号的多端已读同步
      例如用户 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;
         }
         // 同步已读成功
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - timestamp: number

    会话中已读的最后一条消息的发送时间戳

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.2.0

  - Defined in IMEngine.ts:3787

### setSyncConversationReadStatusListener

- setSyncConversationReadStatusListener(
  listener: SyncConversationReadStatusListener,
  ): void

  设置会话已读状态监听

  # 示例代码

       let listener : SyncConversationReadStatusListener = {
         onSyncConversationReadStatus: (conId: ConversationIdentifier, timestamp: number): void => {
          // 该会话的 timestamp 之前的消息未读已清空
         }
       }
       IMEngine.getInstance().setSyncConversationReadStatusListener(listener);

  #### Parameters

  - listener: SyncConversationReadStatusListener

    监听

  #### Returns void

  #### Version

  1.2.0

  #### Deprecated

  使用 addSyncConversationReadStatusListener 替换，多次调用该方法内部会产生多个监听

  - Defined in IMEngine.ts:3810

### addSyncConversationReadStatusListener

- addSyncConversationReadStatusListener(
  listener: SyncConversationReadStatusListener,
  ): void

  增加会话已读状态监听

  # 示例代码

       let listener : SyncConversationReadStatusListener = {
         onSyncConversationReadStatus: (conId: ConversationIdentifier, timestamp: number): void => {
          // 该会话的 timestamp 之前的消息未读已清空
         }
       }
       IMEngine.getInstance().addSyncConversationReadStatusListener(listener);

  #### Parameters

  - listener: SyncConversationReadStatusListener

    监听

  #### Returns void

  #### Warning

  addSyncConversationReadStatusListener & removeSyncConversationReadStatusListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:3837

### removeSyncConversationReadStatusListener

- removeSyncConversationReadStatusListener(
  listener: SyncConversationReadStatusListener,
  ): void

  移除会话已读状态监听

  # 示例代码

       IMEngine.getInstance().removeSyncConversationReadStatusListener(listener);

  #### Parameters

  - listener: SyncConversationReadStatusListener

  #### Returns void

  #### Warning

  addSyncConversationReadStatusListener & removeSyncConversationReadStatusListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:3851

### addMessageReadReceiptListener

- addMessageReadReceiptListener(listener: MessageReadReceiptListener): void

  增加消息已读回执监听

  # 示例代码

       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);

  #### Parameters

  - listener: MessageReadReceiptListener

    监听

  #### Returns void

  #### Discussion

  业务流程请参考 ReadReceiptInfo

  #### Warning

  addMessageReadReceiptListener & removeMessageReadReceiptListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:3878

### removeMessageReadReceiptListener

- removeMessageReadReceiptListener(listener: MessageReadReceiptListener): void

  移除消息已读回执监听

  # 示例代码

       IMEngine.getInstance().removeMessageReadReceiptListener(listener);

  #### Parameters

  - listener: MessageReadReceiptListener

    监听

  #### Returns void

  #### Warning

  addMessageReadReceiptListener & removeMessageReadReceiptListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:3892

### sendReadReceiptMessage

- sendReadReceiptMessage(
  conId: ConversationIdentifier,
  timestamp: number,
  ): Promise<IAsyncResult<void>>

  单聊，发送某个会话中的消息阅读回执，由原始消息的接收方调用

  # 说明

      单聊调用该方法后，原始消息发送方会触发 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;
         }
         // 成功
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - timestamp: number

    会话中已读的最后一条消息的发送时间戳， Message.sentTime

  #### Returns Promise<IAsyncResult<void>>

  #### Discussion

  业务流程请参考 ReadReceiptInfo

  #### Version

  1.3.0

  - Defined in IMEngine.ts:3925

### sendReadReceiptRequest

- sendReadReceiptRequest(message: Message): Promise<IAsyncResult<void>>

  群聊，发送某个会话的消息已读请求，由原始消息的发送方调用

  # 说明

      群聊调用该方法后，原始消息的接收方会触发 MessageReadReceiptListener.onMessageReceiptRequest
      原始消息接收方就知道需要对该消息做已读响应。调用 sendReadReceiptResponse

  # 示例代码

       // 应该使用发送成功的消息，此处进行了简写
       let msg : Message;

       IMEngine.getInstance().sendReadReceiptRequest(msg).then(result => {
         if (EngineError.Success !== result.code) {
           // 失败
           return;
         }
         // 成功
       });

  #### Parameters

  - message: Message

    消息体，messageUid 必须有效

  #### Returns Promise<IAsyncResult<void>>

  消息已读请求的结果

  #### Discussion

  业务流程请参考 ReadReceiptInfo

  #### Version

  1.3.0

  - Defined in IMEngine.ts:3958

### sendReadReceiptResponse

- sendReadReceiptResponse(
  conId: ConversationIdentifier,
  messageArray: Message[],
  ): Promise<IAsyncResult<List<Message>>>

  群聊，发送某个会话已读响应，由原始消息的接收方调用

  # 说明

      群聊调用该方法后，原始消息的发送方会触发 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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - messageArray: Message[]

    消息体数组，消息体必须存在有效的 senderId 和 messageUid

  #### Returns Promise<IAsyncResult<List<Message>>>

  消息已读响应结果，返回的 Message 集合可以通过 Message.readReceiptInfo.hasRespond 确认该消息是否已经发送了响应

  #### Discussion

  业务流程请参考 ReadReceiptInfo

  #### Version

  1.3.0

  - Defined in IMEngine.ts:4003

### addMessageReadReceiptV2Listener

- addMessageReadReceiptV2Listener(listener: MessageReadReceiptV2Listener): void

  增加消息已读V2回执监听

  # 示例代码

       let listener: MessageReadReceiptV2Listener = {
         onMessageReceiptResponse: (conId: ConversationIdentifier, messageUid: string, readCount: number, totalCount: number): void => {

         }
       }
       IMEngine.getInstance().addMessageReadReceiptV2Listener(listener);

  #### Parameters

  - listener: MessageReadReceiptV2Listener

    监听

  #### Returns void

  #### Discussion

  业务流程请参考 ReadReceiptInfo

  #### Warning

  addMessageReadReceiptV2Listener & removeMessageReadReceiptV2Listener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.4.0

  - Defined in IMEngine.ts:4035

### removeMessageReadReceiptV2Listener

- removeMessageReadReceiptV2Listener(listener: MessageReadReceiptV2Listener): void

  移除消息已读v2回执监听

  # 示例代码

       IMEngine.getInstance().removeMessageReadReceiptV2Listener(listener);

  #### Parameters

  - listener: MessageReadReceiptV2Listener

    监听

  #### Returns void

  #### Warning

  addMessageReadReceiptV2Listener & removeMessageReadReceiptV2Listener 配合使用，避免内存泄露

  #### Version

  1.4.0

  - Defined in IMEngine.ts:4049

### sendReadReceiptResponseV2

- sendReadReceiptResponseV2(
  conId: ConversationIdentifier,
  messageArray: Message[],
  ): Promise<IAsyncResult<List<Message>>>

  群聊，发送某个会话已读响应，由原始消息的接收方调用

  # 说明

      群聊调用该方法后，原始消息的发送方会触发 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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - messageArray: Message[]

    消息体数组，消息体必须存在有效的 senderId 和 messageUid

  #### Returns Promise<IAsyncResult<List<Message>>>

  消息已读响应结果，返回的 Message 集合可以通过 Message.readReceiptInfo.hasRespond 确认该消息是否已经发送了响应

  #### Discussion

  业务流程请参考 ReadReceiptInfo

  #### Version

  1.4.0

  - Defined in IMEngine.ts:4090

### getGroupMessageReaderList

- getGroupMessageReaderList(
  conId: ConversationIdentifier,
  messageUid: string,
  successCallback: (
  totalCount: number,
  readerList: Map<string, number>,
  ) => void,
  ): Promise<IAsyncResult<number>>

  群聊，获取已读人员列表

  # 说明

      在服务端配置已读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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - messageUid: string

    消息Uid

  - successCallback: (totalCount: number, readerList: Map<string, number>) => void

  #### Returns Promise<IAsyncResult<number>>

  消息已读人数

  #### Version

  1.4.0

  - Defined in IMEngine.ts:4134

### addMessageReadReceiptV5Listener

- addMessageReadReceiptV5Listener(listener: MessageReadReceiptV5Listener): void

  增加消息已读V5回执监听

  # 示例代码

       let listener: MessageReadReceiptV5Listener = {
         onMessageReceiptResponse: (readReceiptNotifyArray: Array<ReadReceiptNotifyV5>): void => {

         }
       }
       IMEngine.getInstance().addMessageReadReceiptV5Listener(listener);

  #### Parameters

  - listener: MessageReadReceiptV5Listener

    已读 V5 监听器

  #### Returns void

  #### Discussion

  业务流程请参考 ReadReceiptInfo

  #### Warning

  addMessageReadReceiptV5Listener & removeMessageReadReceiptV5Listener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.5.0

  - Defined in IMEngine.ts:4167

### removeMessageReadReceiptV5Listener

- removeMessageReadReceiptV5Listener(listener: MessageReadReceiptV5Listener): void

  移除消息已读 v5 回执监听

  # 示例代码

       IMEngine.getInstance().removeMessageReadReceiptV5Listener(listener);

  #### Parameters

  - listener: MessageReadReceiptV5Listener

    监听

  #### Returns void

  #### Warning

  addMessageReadReceiptV5Listener & removeMessageReadReceiptV5Listener 配合使用，避免内存泄露

  #### Version

  1.5.0

  - Defined in IMEngine.ts:4181

### sendReadReceiptResponseV5

- sendReadReceiptResponseV5(
  conId: ConversationIdentifier,
  messageUidArray: string[],
  ): Promise<IAsyncResult<void>>

  发送消息已读回执 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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - messageUidArray: string[]

    消息 Uid 数组

  #### Returns Promise<IAsyncResult<void>>

  消息已读响应结果，成功返回 EngineError.Success，失败返回对应错误码。

  #### Version

  1.5.0

  - Defined in IMEngine.ts:4223

### getMessageReadReceiptInfoV5

- getMessageReadReceiptInfoV5(
  conId: ConversationIdentifier,
  messageUidArray: string[],
  ): Promise<IAsyncResult<List<ReadReceiptInfoV5>>>

  批量获取消息已读信息（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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - messageUidArray: string[]

    消息 Uid 数组

  #### Returns Promise<IAsyncResult<List<ReadReceiptInfoV5>>>

  消息已读响应结果，返回的 Message 集合

  #### Version

  1.5.0

  - Defined in IMEngine.ts:4269

### getMessageReadReceiptInfoV5ByIdentifiers

- getMessageReadReceiptInfoV5ByIdentifiers(
  identifiers: MessageIdentifier[],
  ): Promise<IAsyncResult<List<ReadReceiptInfoV5>>>

  批量获取消息已读回执 V5 信息

  #### Parameters

  - identifiers: MessageIdentifier[]

    消息会话标识

  #### Returns Promise<IAsyncResult<List<ReadReceiptInfoV5>>>

  消息已读响应结果，返回的 Message 集合

  #### Version

  1.6.0

  - Defined in IMEngine.ts:4291

### getMessagesReadReceiptUsersByPageV5

- getMessagesReadReceiptUsersByPageV5(
  conId: ConversationIdentifier,
  messageUid: string,
  option: ReadReceiptUsersOption,
  ): Promise<IAsyncResult<ReadReceiptUsersResult>>

  分页获取消息已读未读信息

  # 说明

      在服务端配置已读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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - messageUid: string

    消息Uid

  - option: ReadReceiptUsersOption

  #### Returns Promise<IAsyncResult<ReadReceiptUsersResult>>

  消息已读人数

  #### Version

  1.5.0

  - Defined in IMEngine.ts:4350

### getMessagesReadReceiptByUsersV5

- getMessagesReadReceiptByUsersV5(
  conId: ConversationIdentifier,
  messageUid: string,
  userList: string[],
  ): Promise<IAsyncResult<ReadReceiptUsersResult>>

  批量获取用户指定群组消息是否已读状态（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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - messageUid: string

    消息Uid

  - userList: string[]

    要查询的用户 userId 列表

  #### Returns Promise<IAsyncResult<ReadReceiptUsersResult>>

  #### Version

  1.5.0

  - Defined in IMEngine.ts:4406

### searchConversations

- searchConversations(
  typeList: List<ConversationType>,
  keyword: string,
  objNameList: any,
  ): Promise<IAsyncResult<List<Conversation>>>

  根据关键字搜索本地会话。

  # 示例代码

       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>;
       });

  #### Parameters

  - typeList: List<ConversationType>
  - keyword: string

    搜索的关键字，长度范围 [1, 256]

  - objNameList: any

    消息类型数组。用于搜索指定类型的消息；为空代表所有所有类型消息

  #### Returns Promise<IAsyncResult<List<Conversation>>>

  搜索到的会话列表

  #### Version

  1.1.0

  #### Deprecated

  已废弃，使用 searchConversationsWithResult() 方法

  - Defined in IMEngine.ts:4463

### searchConversationsWithResult

- searchConversationsWithResult(
  typeList: List<ConversationType>,
  keyword: string,
  objNameList: any,
  ): Promise<IAsyncResult<List<SearchConversationResult>>>

  根据关键字搜索本地会话。

  # 示例代码

       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>;
       });

  #### Parameters

  - typeList: List<ConversationType>
  - keyword: string

    搜索的关键字，长度范围 [1, 256]

  - objNameList: any

    消息类型数组。用于搜索指定类型的消息；为空代表所有所有类型消息

  #### Returns Promise<IAsyncResult<List<SearchConversationResult>>>

  搜索到的会话列表

  #### Version

  1.2.0

  - Defined in IMEngine.ts:4517

### searchMessages

- searchMessages(
  conId: ConversationIdentifier,
  keyword: string,
  objNameList: any,
  startTime: number,
  count: number,
  ): Promise<IAsyncResult<List<Message>>>

  根据关键字搜索指定消息类型的本地消息。

  # 示例代码

       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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - keyword: string

    关键字，长度范围 [1, 256]

  - objNameList: any

    消息类型数组。用于搜索指定类型的消息；为空代表搜索所有类型消息

  - startTime: number

    查询的起始发送时间，返回小于该时间的消息，毫秒时间戳；如果为 0，则查询全部。当分页时，可以传入上一批消息的最小发送时间，取值范围 [0, INT64_MAX]

  - count: number

    消息个数，传 0 时会返回所有搜索到的消息，非 0 时根据 startTime 逐页返回，取值范围 [0, 100]

  #### Returns Promise<IAsyncResult<List<Message>>>

  消息列表

  #### Version

  1.1.0

  - Defined in IMEngine.ts:4570

### searchMessagesInTimeRange

- searchMessagesInTimeRange(
  conId: ConversationIdentifier,
  keyword: string,
  option: ISearchMessageInTimeRangeOption,
  ): Promise<IAsyncResult<List<Message>>>

  根据关键字和指定时间段搜索指定会话中的消息。

  # 示例代码

       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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - keyword: string

    关键字，长度范围 [1, 256]

  - option: ISearchMessageInTimeRangeOption

    在时间区间内搜索消息的参数配置

  #### Returns Promise<IAsyncResult<List<Message>>>

  消息列表

  #### Version

  1.1.0

  - Defined in IMEngine.ts:4628

### searchMessagesByUser

- searchMessagesByUser(
  conId: ConversationIdentifier,
  userId: string,
  startTime: number,
  count: number,
  ): Promise<IAsyncResult<List<Message>>>

  根据用户 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>;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - userId: string

    用户 id

  - startTime: number

    查询的起始发送时间，返回小于该时间的消息，毫秒时间戳；如果为 0，则查询全部。当分页时，可以传入上一批消息的最小发送时间，取值范围 [0, INT64_MAX]

  - count: number

    消息个数，传 0 时会返回所有搜索到的消息；非 0 时根据 startTime 逐页返回，取值范围 [0, 100]

  #### Returns Promise<IAsyncResult<List<Message>>>

  消息列表

  #### Version

  1.1.0

  - Defined in IMEngine.ts:4678

### searchMessagesByConversations

- searchMessagesByConversations(
  conTypes: ConversationType[],
  targetIds: string[],
  channelIds: string[],
  objNameArray: string[],
  keyword: string,
  startTime: number,
  count: number,
  order: Order,
  ): Promise<IAsyncResult<List<Message>>>

  在指定的一批会话中搜索消息

  # 示例代码

       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>;
       })

  #### Parameters

  - conTypes: ConversationType[]

    会话类型数组，非空

  - targetIds: string[]

    会话 Id 数组，为空代表所有会话

  - channelIds: string[]

    频道 Id 数组，为空代表所有频道

  - objNameArray: string[]

    消息类型数组。用于搜索指定类型的消息；为空代表搜索所有类型消息

  - keyword: string

    关键字，长度范围 [1, 256]

  - startTime: number

    查询的起始发送时间，返回小于该时间的消息，毫秒时间戳；如果为 0，则查询全部。当分页时，可以传入上一批消息的最小发送时间，取值范围 [0, INT64_MAX]

  - count: number

    消息个数，传 0 时会返回所有搜索到的消息；非 0 时根据 startTime 逐页返回，取值范围 [0, 100]

  - order: Order

    返回排序。Ascending 升序，返回比 startTime 时间戳大的消息。Descending 降序，返回比 startTime 时间戳消的消息

  #### Returns Promise<IAsyncResult<List<Message>>>

  #### Version

  1.3.0

  - Defined in IMEngine.ts:4744

### searchMessagesByUsers

- searchMessagesByUsers(
  conId: ConversationIdentifier,
  sendIds: string[],
  objNameArray: string[],
  startTime: number,
  count: number,
  order: Order,
  ): Promise<IAsyncResult<List<Message>>>

  在本地指定会话中搜索多个成员指定的消息类型

  # 示例代码

       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>;
       })

  #### Parameters

  - conId: ConversationIdentifier

    会话标识

  - sendIds: string[]

    消息发送者 Id 数组，搜索由这些用户发送的消息

  - objNameArray: string[]

    消息类型数组。用于搜索指定类型的消息；为空代表搜索所有类型消息

  - startTime: number

    查询的起始发送时间，返回小于该时间的消息，毫秒时间戳；如果为 0，则查询全部。当分页时，可以传入上一批消息的最小发送时间，取值范围 [0, INT64_MAX]

  - count: number

    消息个数；非 0 时根据 startTime 逐页返回，传 0 默认取值为 100，取值范围 [0, 100]

  - order: Order

    返回排序。Ascending 升序，返回比 startTime 时间戳大的消息。Descending 降序，返回比 startTime 时间戳消的消息

  #### Returns Promise<IAsyncResult<List<Message>>>

  消息列表

  #### Version

  1.3.0

  - Defined in IMEngine.ts:4809

### getPublicServiceList

- getPublicServiceList(): Promise<IAsyncResult<List<PublicServiceInfo>>>

  获取本地订阅的所有公众号（仅支持私有云）

  # 示例代码

       IMEngine.getInstance().getPublicServiceList().then(result => {
         if (EngineError.Success !== result.code) {
           // 获取公众号失败
           return;
         }
         if (!result.data) {
           // 公众号为空
           return;
         }
         // 公众号列表
         let list = result.data as List<PublicServiceInfo>;
       });

  #### Returns Promise<IAsyncResult<List<PublicServiceInfo>>>

  #### Version

  1.1.0

  - Defined in IMEngine.ts:4856

### getPublicService

- getPublicService(
  conId: ConversationIdentifier,
  ): Promise<IAsyncResult<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;
       });

  #### Parameters

  - conId: ConversationIdentifier

    会话标识，会话类型不管为何值，SDK 均会按照 AppPublicService 处理

  #### Returns Promise<IAsyncResult<PublicServiceInfo>>

  #### Version

  1.1.0

  - Defined in IMEngine.ts:4889

### setChatroomStatusListener

- setChatroomStatusListener(listener: ChatroomStatusListener): void

  设置聊天室状态监听

  # 示例代码

       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);

  #### Parameters

  - listener: ChatroomStatusListener

    监听

  #### Returns void

  #### See

  ChatroomStatusListener

  #### Version

  1.0.0

  #### Deprecated

  使用 addChatroomStatusListener 替代

  - Defined in IMEngine.ts:4929

### addChatroomStatusListener

- addChatroomStatusListener(listener: ChatroomStatusListener): void

  增加聊天室状态监听

  # 示例代码

      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);

  #### Parameters

  - listener: ChatroomStatusListener

    监听

  #### Returns void

  #### See

  ChatroomStatusListener

  #### Warning

  addChatroomStatusListener & removeChatroomStatusListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:4966

### removeChatroomStatusListener

- removeChatroomStatusListener(listener: ChatroomStatusListener): void

  移除聊天室状态监听

  # 示例代码

      IMEngine.getInstance().removeChatroomStatusListener(listener);

  #### Parameters

  - listener: ChatroomStatusListener

    监听

  #### Returns void

  #### Warning

  addChatroomStatusListener & removeChatroomStatusListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:4980

### joinChatroom

- joinChatroom(
  roomId: string,
  msgCount: number,
  ): Promise<IAsyncResult<ChatroomJoinedInfo>>

  加入聊天室，如果聊天室不存在则创建聊天室

  # 示例代码

       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;
       });

  #### Parameters

  - roomId: string

    roomId 聊天室 ID

  - msgCount: number

    msgCount 消息个数，-1 时不拉取任何消息，0 时拉取 10 条消息，最多只能拉取 50

  #### Returns Promise<IAsyncResult<ChatroomJoinedInfo>>

  结果

  #### Version

  1.0.2

  - Defined in IMEngine.ts:5008

### joinExistingChatroom

- joinExistingChatroom(
  roomId: string,
  msgCount: number,
  ): Promise<IAsyncResult<ChatroomJoinedInfo>>

  加入已经存在的聊天室

  # 示例代码

       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;
       });

  #### Parameters

  - roomId: string

    聊天室 ID

  - msgCount: number

    消息个数，-1 时不拉取任何消息，0 时拉取 10 条消息，最多只能拉取 50

  #### Returns Promise<IAsyncResult<ChatroomJoinedInfo>>

  结果

  #### Discussion

  如果加入不存在的聊天室会报错 ChatroomNotExist

  #### Note

  聊天室的创建需要通过 AppServer 调用 IM 服务的 ServerAPI 创建

  #### Version

  1.0.0

  - Defined in IMEngine.ts:5042

### quitChatroom

- quitChatroom(roomId: string): Promise<IAsyncResult<void>>

  退出聊天室

  # 示例代码

       let roomId = "TestChatroomId"; // 按需填写实际的聊天室 id
       IMEngine.getInstance().quitChatroom(roomId).then(result => {
         if (EngineError.Success !== result.code) {
           // 退出聊天室失败
           return;
         }
       });

  #### Parameters

  - roomId: string

    聊天室 ID

  #### Returns Promise<IAsyncResult<void>>

  结果

  #### Version

  1.0.0

  - Defined in IMEngine.ts:5066

### getChatroomInfo

- getChatroomInfo(
  roomId: string,
  option: ICountOption,
  ): Promise<IAsyncResult<ChatroomInfo>>

  获取聊天室信息

  # 示例代码

       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;
       });

  #### Parameters

  - roomId: string

    聊天室 ID

  - option: ICountOption

    配置

  #### Returns Promise<IAsyncResult<ChatroomInfo>>

  聊天室信息

  #### See

  ICountOption

  #### Version

  1.0.0

  - Defined in IMEngine.ts:5103

### setChatroomEntries

- setChatroomEntries(
  roomId: string,
  entries: Map<string, string>,
  autoDelete: boolean,
  overWrite: boolean,
  ): Promise<IAsyncResult<Map<string, EngineError>>>

  设置聊天室自定义属性

  # 说明

      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>;
       });

  #### Parameters

  - roomId: string

    聊天室 ID

  - entries: Map<string, string>

    key-value 字典，长度范围 [1 ~ 10]

  - autoDelete: boolean

    用户掉线或退出时，是否自动删除该 Key、Value 值；自动删除时不会发送通知

  - overWrite: boolean

    是否强制覆盖

  #### Returns Promise<IAsyncResult<Map<string, EngineError>>>

  返回的具体结果，会明确特定 key 的具体错误

  #### Discussion

  每个聊天室支持设置最大 KV 数为 100，如果聊天室已经有 100 个 KV，则无法再增加新的 KV

  #### Version

  1.1.0

  - Defined in IMEngine.ts:5151

### deleteChatroomEntries

- deleteChatroomEntries(
  roomId: string,
  keys: List<string>,
  isForce: boolean,
  ): Promise<IAsyncResult<Map<string, EngineError>>>

  删除聊天室自定义属性

  # 示例代码

       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>;

       });

  #### Parameters

  - roomId: string

    聊天室 ID

  - keys: List<string>

    key 数组，长度范围 [1,10]

  - isForce: boolean

    是否强制删除

  #### Returns Promise<IAsyncResult<Map<string, EngineError>>>

  返回的具体结果，会明确特定 key 的具体错误

  #### Version

  1.1.0

  - Defined in IMEngine.ts:5202

### getChatroomEntries

- getChatroomEntries(
  roomId: string,
  keys: List<string>,
  ): Promise<IAsyncResult<Map<string, string>>>

  获取本地指定一批聊天室自定义属性

  # 示例代码

       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>;

       });

  #### Parameters

  - roomId: string

    聊天室 ID

  - keys: List<string>

    key 数组，长度范围 [1,100]

  #### Returns Promise<IAsyncResult<Map<string, string>>>

  对应的 kv 信息

  #### Discussion

  见 ChatroomKVStatusListener.onChatroomKVSync

  #### Version

  1.1.0

  - Defined in IMEngine.ts:5249

### getAllChatroomEntries

- getAllChatroomEntries(
  roomId: string,
  ): Promise<IAsyncResult<Map<string, string>>>

  获取本地聊天室全部自定义属性

  # 示例代码

       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>;
       });

  #### Parameters

  - roomId: string

    聊天室 ID

  #### Returns Promise<IAsyncResult<Map<string, string>>>

  对应的 kv 信息

  #### Discussion

  见 ChatroomKVStatusListener.onChatroomKVSync

  #### Version

  1.1.0

  - Defined in IMEngine.ts:5281

### setChatroomKVStatusListener

- setChatroomKVStatusListener(listener: ChatroomKVStatusListener): void

  设置聊天室 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);

  #### Parameters

  - listener: ChatroomKVStatusListener

    聊天室 KV 状态变化的监听

  #### Returns void

  #### Version

  1.1.0

  #### Deprecated

  使用 addChatroomKVStatusListener 替代

  - Defined in IMEngine.ts:5310

### addChatroomKVStatusListener

- addChatroomKVStatusListener(listener: ChatroomKVStatusListener): void

  增加聊天室 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);

  #### Parameters

  - listener: ChatroomKVStatusListener

    监听

  #### Returns void

  #### Warning

  addChatroomKVStatusListener & removeChatroomKVStatusListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:5336

### removeChatroomKVStatusListener

- removeChatroomKVStatusListener(listener: ChatroomKVStatusListener): void

  移除聊天室 KV 状态变化的监听

  # 示例代码

       IMEngine.getInstance().removeChatroomKVStatusListener(listener);

  #### Parameters

  - listener: ChatroomKVStatusListener

    监听

  #### Returns void

  #### Warning

  addChatroomKVStatusListener & removeChatroomKVStatusListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:5350

### setChatroomMemberListener

- setChatroomMemberListener(listener: ChatroomMemberActionListener): void

  设置聊天室成员变化监听

  # 示例代码

       let listener: ChatroomMemberActionListener = {
         onMemberChange: (actionModel: ChatRoomMemberActionModel): void => {

         }
       }
       IMEngine.getInstance().setChatroomMemberListener(listener);

  #### Parameters

  - listener: ChatroomMemberActionListener

    成员变化监听

  #### Returns void

  #### Version

  1.1.0

  #### Deprecated

  使用 addChatroomMemberListener 替代

  - Defined in IMEngine.ts:5369

### addChatroomMemberListener

- addChatroomMemberListener(listener: ChatroomMemberActionListener): void

  增加聊天室成员变化监听

  # 示例代码

       let listener: ChatroomMemberActionListener = {
         onMemberChange: (actionModel: ChatRoomMemberActionModel): void => {

         }
       }
       IMEngine.getInstance().addChatroomMemberListener(listener);

  #### Parameters

  - listener: ChatroomMemberActionListener

    成员变化监听

  #### Returns void

  #### Warning

  addChatroomMemberListener & removeChatroomMemberListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:5389

### removeChatroomMemberListener

- removeChatroomMemberListener(listener: ChatroomMemberActionListener): void

  移除聊天室成员变化监听

  # 示例代码

       IMEngine.getInstance().removeChatroomMemberListener(listener);

  #### Parameters

  - listener: ChatroomMemberActionListener

    成员变化监听

  #### Returns void

  #### Warning

  addChatroomMemberListener & removeChatroomMemberListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:5403

### setChatroomNotifyEventListener

- setChatroomNotifyEventListener(listener: ChatroomNotifyEventListener): void

  设置聊天室事件通知监听器

  # 示例代码

       let listener: ChatroomNotifyEventListener = {
         onChatroomNotifyMultiLoginSync: (syncEvent: ChatroomSyncEvent): void => {

         },
         onChatroomNotifyBlock: (blockEvent: ChatroomMemberBlockEvent): void => {

         },
         onChatRoomNotifyBan: (banEvent: ChatroomMemberBanEvent): void => {

         }
       }
       IMEngine.getInstance().setChatroomNotifyEventListener(listener);

  #### Parameters

  - listener: ChatroomNotifyEventListener

    监听

  #### Returns void

  #### Version

  1.1.0

  #### Deprecated

  使用 addChatroomNotifyEventListener 替代

  - Defined in IMEngine.ts:5428

### addChatroomNotifyEventListener

- addChatroomNotifyEventListener(listener: ChatroomNotifyEventListener): void

  增加聊天室事件通知监听器

  # 示例代码

       let listener: ChatroomNotifyEventListener = {
         onChatroomNotifyMultiLoginSync: (syncEvent: ChatroomSyncEvent): void => {

         },
         onChatroomNotifyBlock: (blockEvent: ChatroomMemberBlockEvent): void => {

         },
         onChatRoomNotifyBan: (banEvent: ChatroomMemberBanEvent): void => {

         }
       }
       IMEngine.getInstance().addChatroomNotifyEventListener(listener);

  #### Parameters

  - listener: ChatroomNotifyEventListener

    监听

  #### Returns void

  #### Warning

  addChatroomNotifyEventListener & removeChatroomNotifyEventListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.3.0

  - Defined in IMEngine.ts:5454

### removeChatroomNotifyEventListener

- removeChatroomNotifyEventListener(listener: ChatroomNotifyEventListener): void

  移除聊天室事件通知监听器

  # 示例代码

       IMEngine.getInstance().removeChatroomNotifyEventListener(listener);

  #### Parameters

  - listener: ChatroomNotifyEventListener

    监听

  #### Returns void

  #### Warning

  addChatroomNotifyEventListener & removeChatroomNotifyEventListener 配合使用，避免内存泄露

  #### Version

  1.3.0

  - Defined in IMEngine.ts:5468

### createGroup

- createGroup(
  groupInfo: GroupInfo,
  inviteeUserIds: string[],
  ): Promise<IAsyncResult<GroupResultWithProcessCode<string>>>

  创建群组

  # 注意

      群信息（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; // 业务错误码
           }
         }
       });

  #### Parameters

  - groupInfo: GroupInfo

    群组信息

  - inviteeUserIds: string[]

    加入群组的用户 Id 数组，一次最多允许 30 个用户加入。

  #### Returns Promise<IAsyncResult<GroupResultWithProcessCode<string>>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5555

### updateGroupInfo

- updateGroupInfo(groupInfo: GroupInfo): Promise<IAsyncResult<string[]>>

  更新群组资料

  # 注意

      群信息（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 数组
           }
         }
         // 更新群组信息成功
       });

  #### Parameters

  - groupInfo: GroupInfo

    群信息, groupId 必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  #### Returns Promise<IAsyncResult<string[]>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5630

### getGroupsInfo

- getGroupsInfo(groupIds: string[]): Promise<IAsyncResult<GroupInfo[]>>

  批量获取群组资料

      注意：只返回已存在的群组信息

  # 示例代码

       // 群 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>);
         }
       });

  #### Parameters

  - groupIds: string[]

    群 Id 数组。支持批量查询，单次查询最多支持 20 个群组。

  #### Returns Promise<IAsyncResult<GroupInfo[]>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5663

### getGroupMembersByRole

- getGroupMembersByRole(
  groupId: string,
  role: GroupMemberRole,
  option: GetGroupMembersOption,
  ): Promise<IAsyncResult<PagingQueryResult<GroupMemberInfo>>>

  分页获取指定群组的群成员列表

  # 示例代码

       // 群 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 拉取下一页
         }
       });

  #### Parameters

  - groupId: string

    群组Id。

  - role: GroupMemberRole

    查询群成员角色。

  - option: GetGroupMembersOption

    分页请求参数。包含页面标识（非必填，不填返回第一页数据）、每页条数（最大不超过 100 条）、是否正序查询（默认按加入群组时间倒序）

  #### Returns Promise<IAsyncResult<PagingQueryResult<GroupMemberInfo>>>

  操作完成后，结果通过此回调返回。注意：此接口返回分页数据的总条数。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5709

### getGroupMembers

- getGroupMembers(
  groupId: string,
  userIds: string[],
  ): Promise<IAsyncResult<GroupMemberInfo[]>>

  获取已加入指定群成员信息

  # 示例代码

       // 群 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>);
         }
       });

  #### Parameters

  - groupId: string

    群组 Id

  - userIds: string[]

    用户 Id 列表，一次最多不超过 100 个

  #### Returns Promise<IAsyncResult<GroupMemberInfo[]>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5752

### checkUserInGroup

- checkUserInGroup(
  groupId: string,
  userIds: string[],
  ): Promise<IAsyncResult<string[]>>

  检查用户是否在群组中

  # 示例代码

       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;
         }
       });

  #### Parameters

  - groupId: string

    群组 Id

  - userIds: string[]

    用户 Id 列表，一次最多不超过 100 个

  #### Returns Promise<IAsyncResult<string[]>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5781

### kickGroupMembers

- kickGroupMembers(
  groupId: string,
  userIds: string[],
  config: QuitGroupConfig,
  ): Promise<IAsyncResult<void>>

  踢出群组成员

  # 示例代码

       // 群 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) {
           // 操作失败
         }
         // 操作成功
       });

  #### Parameters

  - groupId: string

    群组 Id

  - userIds: string[]

    用户 Id 列表，一次最多不超过 100 个

  - config: QuitGroupConfig

    移除群组成员配置

  #### Returns Promise<IAsyncResult<void>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5818

### quitGroup

- quitGroup(groupId: string, config: QuitGroupConfig): Promise<IAsyncResult<void>>

  退出群组

  # 示例代码

       // 群 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) {
           // 退出失败
         }
         // 退出成功
       });

  #### Parameters

  - groupId: string

    群组 Id

  - config: QuitGroupConfig

    退出群组配置

  #### Returns Promise<IAsyncResult<void>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5856

### dismissGroup

- dismissGroup(groupId: string): Promise<IAsyncResult<void>>

  解散群组

  # 示例代码

       let groupId = "groupId";

       IMEngine.getInstance().dismissGroup(groupId).then(result => {
         if (EngineError.Success !== result.code) {
           // 解散失败
         }
         // 解散成功
       });

  #### Parameters

  - groupId: string

    群组 Id

  #### Returns Promise<IAsyncResult<void>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5881

### transferGroupOwner

- transferGroupOwner(
  groupId: string,
  newOwnerId: string,
  autoQuit: boolean,
  config: QuitGroupConfig,
  ): Promise<IAsyncResult<void>>

  转让群组

  # 示例代码

       // 群 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) {
           // 转让失败
         }
         // 转让成功
       });

  #### Parameters

  - groupId: string

    群组 Id，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - newOwnerId: string

    新群主用户 Id，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - autoQuit: boolean

    是否自动退出群组，必填，true 表示自动退出群组，false 表示不自动退出群组

  - config: QuitGroupConfig

    转让群组配置，必填，不能为空

  #### Returns Promise<IAsyncResult<void>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5921

### addGroupManagers

- addGroupManagers(
  groupId: string,
  userIds: string[],
  ): Promise<IAsyncResult<void>>

  添加群管理员

  # 示例代码

       // 群 Id
       let groupId = "groupId";
       // 管理员用户 Id 列表
       let userIds = ["user1Id", "user2Id"];
       IMEngine.getInstance().addGroupManagers(groupId, userIds).then(result => {
         if (EngineError.Success !== result.code) {
           // 添加失败
         }
         // 添加成功
       });

  #### Parameters

  - groupId: string

    群组 Id，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - userIds: string[]

    用户 Id 列表，必填，用户 Id 必须为群组成员，一次最多设置 10 个群成员为管理员，管理员上限为 10 个，群主不支持设置为管理员

  #### Returns Promise<IAsyncResult<void>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5954

### removeGroupManagers

- removeGroupManagers(
  groupId: string,
  userIds: string[],
  ): Promise<IAsyncResult<void>>

  移除群管理员

  # 示例代码

       // 群 Id
       let groupId = "groupId";
       // 管理员用户 Id 列表
       let userIds = ["user1Id", "user2Id"];

       IMEngine.getInstance().removeGroupManagers(groupId, userIds).then(result => {
         if (EngineError.Success !== result.code) {
           // 移除失败
         }
         // 移除成功
       });

  #### Parameters

  - groupId: string

    群组 Id，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - userIds: string[]

    用户 Id 列表，必填，用户 Id 必须为群组成员，一次最多操作 10 个管理员

  #### Returns Promise<IAsyncResult<void>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:5983

### setGroupMemberInfo

- setGroupMemberInfo(
  groupId: string,
  userId: string,
  nickname: string,
  extra: string,
  ): Promise<IAsyncResult<string[]>>

  设置群成员资料

      群成员信息更新模式 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 数组
           }
           // 操作成功
         }
       });

  #### Parameters

  - groupId: string

    群组 ID，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - userId: string

    群成员用户 ID，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - nickname: string

    群成员昵称，长度不超过 64 个字符，不支持纯空格

  - extra: string

    群成员附加信息，长度不超过 128 个字符，注意：传 null 代表不设置此字段

  #### Returns Promise<IAsyncResult<string[]>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6024

### searchGroupMembers

- searchGroupMembers(
  groupId: string,
  name: string,
  option: PagingQueryOption,
  ): Promise<IAsyncResult<PagingQueryResult<GroupMemberInfo>>>

  根据群成员昵称查询群成员信息

  # 示例代码

       // 群 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 拉取下一页
         }
       });

  #### Parameters

  - groupId: string

    群组 Id

  - name: string

    群成员昵称搜索关键字。注意：不能为空最长不超过 64 个字符，不支持纯空格；支持模糊搜索查询；昵称为空时，默认搜索用户名

  - option: PagingQueryOption

    分页请求参数。包含页面标识（非必填，不填返回第一页数据）、每页条数（最大不超过 200 条）、是否正序查询（默认倒序）

  #### Returns Promise<IAsyncResult<PagingQueryResult<GroupMemberInfo>>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6075

### joinGroup

- joinGroup(
  groupId: string,
  ): Promise<IAsyncResult<GroupResultWithProcessCode<void>>>

  加入群组

  # 示例代码

       // 群 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 )，表示加入群组成功。

  #### Parameters

  - groupId: string

    群组 Id

  #### Returns Promise<IAsyncResult<GroupResultWithProcessCode<void>>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6120

### inviteUsersToGroup

- inviteUsersToGroup(
  groupId: string,
  userIds: string[],
  ): Promise<IAsyncResult<GroupResultWithProcessCode<void>>>

  邀请用户加入群组

  # 示例代码

       // 群 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 )，表示需要被邀请人同意。

  #### Parameters

  - groupId: string

    群组 Id，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - userIds: string[]

    用户 Id 列表，一次最多不超过 30 个

  #### Returns Promise<IAsyncResult<GroupResultWithProcessCode<void>>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6161

### acceptGroupInvite

- acceptGroupInvite(
  groupId: string,
  inviterId: string,
  ): Promise<IAsyncResult<void>>

  用户同意加入群组

  # 示例代码

       // 群 Id
       let groupId = "groupId";
       // 发出邀请的用户 Id
       let inviterId = "inviterId";

       IMEngine.getInstance().acceptGroupInvite(groupId, inviterId).then(result => {
         if (EngineError.Success !== result.code) {
           // 用户同意加入群组失败
           return;
         }
         // 用户同意加入群组成功
       });

  #### Parameters

  - groupId: string

    群组 Id

  - inviterId: string

    发出邀请的用户 Id

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6194

### refuseGroupInvite

- refuseGroupInvite(
  groupId: string,
  inviterId: string,
  reason: string,
  ): Promise<IAsyncResult<void>>

  用户拒绝加入群组

  # 示例代码

       // 群 Id
       let groupId = "groupId";
       // 发出邀请的用户 Id
       let inviterId = "inviterId";
       // 拒绝原因
       let reason = "拒绝原因";

       IMEngine.getInstance().refuseGroupInvite(groupId, inviterId, reason).then(result => {
         if (EngineError.Success !== result.code) {
           // 用户拒绝加入群组失败
         }
         // 用户拒绝加入群组成功
       });

  #### Parameters

  - groupId: string

    群组 ID，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - inviterId: string

    邀请者 ID

  - reason: string

    拒绝原因，非必填项，拒绝时可选择是否输入拒绝原因，内容不超过 128 个字符

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6226

### acceptGroupApplication

- acceptGroupApplication(
  groupId: string,
  inviterId: string,
  applicantId: string,
  ): Promise<IAsyncResult<GroupResultWithProcessCode<void>>>

  群主或管理员同意用户加入群组

  # 示例代码

       // 群 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)。

  #### Parameters

  - groupId: string

    群组 ID，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - inviterId: string

    邀请人用户 ID，非必填，如果是邀请入群，则传邀请人 ID；如果是用户主动加群，可以为空。

  - applicantId: string

    申请入群用户 ID

  #### Returns Promise<IAsyncResult<GroupResultWithProcessCode<void>>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6269

### refuseGroupApplication

- refuseGroupApplication(
  groupId: string,
  inviterId: string,
  applicantId: string,
  reason: string,
  ): Promise<IAsyncResult<void>>

  群主或管理员拒绝用户加入群组

  # 示例代码

       // 群 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) {
           // 拒绝加入群组请求失败
         }
         // 拒绝加入群组请求成功
       });

  #### Parameters

  - groupId: string

    群组 ID，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - inviterId: string

    邀请人用户 ID，非必填，如果是邀请入群，则传邀请人 ID；如果是主动加群，可以为空。

  - applicantId: string

    申请者 ID

  - reason: string

    拒绝原因，非必填项，拒绝时可选择是否输入拒绝原因，内容不超过 128 个字符

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6313

### getGroupApplications

- getGroupApplications(
  option: PagingQueryOption,
  directions: GroupApplicationDirection[],
  status: GroupApplicationStatus[],
  ): Promise<IAsyncResult<PagingQueryResult<GroupApplicationInfo>>>

  分页获取群组请求列表

  # 示例代码

       // 分页拉取参数
       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 拉取下一页
         }
       });

  #### Parameters

  - option: PagingQueryOption

    分页请求参数。参照PagingQueryOption，包含页面标识（非必填，不填返回第一页数据）、每页条数（最大不超过 200 条）、是否正序查询（默认倒序）

  - directions: GroupApplicationDirection[]

    请求的方向数组

  - status: GroupApplicationStatus[]

    群组请求状态数组

  #### Returns Promise<IAsyncResult<PagingQueryResult<GroupApplicationInfo>>>

  操作完成后，结果通过此回调返回。按操作时间倒序排序。注意：此接口不返回分页数据的总条数。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6364

### getJoinedGroupsByRole

- getJoinedGroupsByRole(
  role: GroupMemberRole,
  option: PagingQueryOption,
  ): Promise<IAsyncResult<PagingQueryResult<GroupInfo>>>

  按角色获取已加入群组的资料

  # 示例代码

       // 通过 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 拉取下一页
         }
       });

  #### Parameters

  - role: GroupMemberRole

    群成员角色

  - option: PagingQueryOption

    查询选项，包含 页面标识（非必填，不填返回第一页数据）、每页条数（最大不超过 100 条）、是否正序查询（默认倒序）

  #### Returns Promise<IAsyncResult<PagingQueryResult<GroupInfo>>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6416

### searchJoinedGroups

- searchJoinedGroups(
  groupName: string,
  option: PagingQueryOption,
  ): Promise<IAsyncResult<PagingQueryResult<GroupInfo>>>

  按群名称搜索我加入的群组

  # 示例代码

       // 群名称
       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 拉取下一页
         }
       });

  #### Parameters

  - groupName: string

    群名称搜索关键字。不能为空最长不超过 64 个字符，不支持纯空格，支持模糊搜索查询时需要去掉前后空格。

  - option: PagingQueryOption

    分页请求参数。参照PagingQueryOption，包含页面标识（非必填，不填返回第一页数据）、每页条数（最大不超过 200 条）、是否正序查询（默认倒序）

  #### Returns Promise<IAsyncResult<PagingQueryResult<GroupInfo>>>

  操作完成后，结果通过此回调返回。注意：此接口返回分页数据的总条数。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6463

### getJoinedGroups

- getJoinedGroups(groupIds: string[]): Promise<IAsyncResult<GroupInfo[]>>

  批量获取我加入的群组

  # 示例代码

       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>);
         }
       });

  #### Parameters

  - groupIds: string[]

    群Id列表。最多不超过 20 个

  #### Returns Promise<IAsyncResult<GroupInfo[]>>

  操作完成后，结果通过此回调返回。

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6496

### setGroupRemark

- setGroupRemark(groupId: string, remark: string): Promise<IAsyncResult<void>>

  设置群组备注名

  # 示例代码

       // 群 Id
       let groupId = "groupId";
       // 群备注名
       let remark = "group remark";

       IMEngine.getInstance().setGroupRemark(groupId, remark).then(result => {
         if (EngineError.Success !== result.code) {
           // 设置失败
           return;
         }
         // 设置成功
       });

  #### Parameters

  - groupId: string

    群组 ID，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - remark: string

    群备注，字符串长度不超过 64 个字符。传 null 或 空字符串 表示移除群备注

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6526

### addGroupFollows

- addGroupFollows(groupId: string, userIds: string[]): Promise<IAsyncResult<void>>

  添加群组特别关注用户

  # 示例代码

       let groupId = "groupId";
       let userIds = ["user1Id", "user2Id"];

       IMEngine.getInstance().addGroupFollows(groupId, userIds).then(result => {
         if (EngineError.Success !== result.code) {
           // 添加失败
         }
         // 添加成功
       });

  #### Parameters

  - groupId: string

    群组 Id，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - userIds: string[]

    用户 Id 列表，单次最多关注 100 个用户

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6553

### removeGroupFollows

- removeGroupFollows(
  groupId: string,
  userIds: string[],
  ): Promise<IAsyncResult<void>>

  删除群组特别关注用户

  # 示例代码

       // 群 Id
       let groupId = "groupId";
       // 用户 Id 列表
       let userIds = ["user1Id", "user2Id"];

       IMEngine.getInstance().removeGroupFollows(groupId, userIds).then(result => {
         if (EngineError.Success !== result.code) {
           // 失败
         }
       });

  #### Parameters

  - groupId: string

    群组 Id，必填，不能为空，长度不超过 64 个字符，大小写英文字母与数字的组合，不能包含空格

  - userIds: string[]

    用户 Id 列表，单次取消关注 100 个用户

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6581

### getGroupFollows

- getGroupFollows(groupId: string): Promise<IAsyncResult<FollowInfo[]>>

  查询群组特别关注用户列表

  # 示例代码

       // 群 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);
         }
       });

  #### Parameters

  - groupId: string

    群 Id。只支持普通群。

  #### Returns Promise<IAsyncResult<FollowInfo[]>>

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6612

### addGroupEventListener

- addGroupEventListener(listener: GroupEventListener): void

  添加群组事件回调监听

  # 示例代码

       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);

  #### Parameters

  - listener: GroupEventListener

    监听

  #### Returns void

  #### Warning

  addGroupEventListener & removeGroupEventListener 配合使用，避免内存泄露

  #### Discussion

  重复 add 同一个 Listener 对象，只有第一个 Listener 会被 add

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6680

### removeGroupEventListener

- removeGroupEventListener(listener: GroupEventListener): void

  移除群组事件回调监听

  # 示例代码

       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);

  #### Parameters

  - listener: GroupEventListener

    监听

  #### Returns void

  #### Warning

  addGroupEventListener & removeGroupEventListener 配合使用，避免内存泄露

  #### Version

  1.8.0

  - Defined in IMEngine.ts:6743

### getAllRobots

- getAllRobots(): Promise<IAsyncResult<RobotInfo[]>>

  获取机器人列表

  # 示例代码

       IMEngine.getInstance().getAllRobots().then(result => {
         // code 不为 0 时，表示获取到的是本地数据
         let ret: object = result;
         if (result.data) {
           ret = Array.from(result.data);
         }
       });

  #### Returns Promise<IAsyncResult<RobotInfo[]>>

  #### Version

  25.11.0

  - Defined in IMEngine.ts:6766

### getRobotById

- getRobotById(robotId: string): Promise<IAsyncResult<RobotInfo>>

  获取机器人信息

  # 示例代码

       let robotId = "robotId";
       IMEngine.getInstance().getRobotById(robotId).then(result => {
         // code 不为 0 时，表示获取到的是本地数据
       });

  #### Parameters

  - robotId: string

    机器人 ID

  #### Returns Promise<IAsyncResult<RobotInfo>>

  #### Version

  25.11.0

  - Defined in IMEngine.ts:6787

### addRobotEventListener

- addRobotEventListener(listener: RobotEventListener): void

  添加机器人事件回调监听

  # 示例代码

       let listener: RobotEventListener = {
         onRobotSyncCompleted : (
            groupId: string,
            code: number,
            nativeArr: Array<RobotInfo>
          ): void => {

          }
       }
       IMEngine.getInstance().addRobotEventListener(listener);

  #### Parameters

  - listener: RobotEventListener

    监听

  #### Returns void

  #### Warning

  addRobotEventListener & removeRobotEventListener 配合使用，避免内存泄露

  #### Version

  25.11.0

  - Defined in IMEngine.ts:6814

### removeRobotEventListener

- removeRobotEventListener(listener: RobotEventListener): void

  移除机器人事件回调监听

  # 示例代码

       let listener: RobotEventListener = {
         onRobotSyncCompleted : (
            code: number
          ): void => {

          },
       }
       IMEngine.getInstance().removeRobotEventListener(listener);

  #### Parameters

  - listener: RobotEventListener

    监听

  #### Returns void

  #### Warning

  addRobotEventListener & removeRobotEventListener 配合使用，避免内存泄露

  #### Version

  25.11.0

  - Defined in IMEngine.ts:6835

### addMessageModifiedListener

- addMessageModifiedListener(listener: MessageModifiedListener): void

  添加消息修改事件监听

  # 示例代码

       let listener: MessageModifiedListener = {
         onMessageModified: (messages: Array<Message>) => {
           // 接收到的某条消息被修改时，会触发此回调
         },
         onModifiedMessageSyncCompleted: () => {
           // 离线的消息修改记录同步完成时，会触发此回调
         }
       }
       IMEngine.getInstance().addMessageModifiedListener(listener);

  #### Parameters

  - listener: MessageModifiedListener

    监听

  #### Returns void

  #### Version

  1.10.0

  - Defined in IMEngine.ts:6860

### removeMessageModifiedListener

- removeMessageModifiedListener(listener: MessageModifiedListener): void

  移除消息修改事件监听

  # 示例代码

       let listener: MessageModifiedListener = {
         onMessageModified: (message: Message) => {
           // 消息修改
         },
         onModifiedMessageSyncCompleted: () => {
           // 消息修改同步完成
         }
       }
       IMEngine.getInstance().removeMessageModifiedListener(listener);

  #### Parameters

  - listener: MessageModifiedListener

    监听

  #### Returns void

  #### Version

  1.10.0

  - Defined in IMEngine.ts:6881

### modifyMessageWithParams

- modifyMessageWithParams(
  params: IModifyMessageParams,
  ): Promise<IAsyncResult<void>>

  修改消息

  # 示例代码

       let content = new TextMessage();
       content.content = "content";
       let params: IModifyMessageParams = {
         messageUId: "messageUid",
         messageContent: content,
       }
       IMEngine.getInstance().modifyMessageWithParams(params).then(result => {
         // 修改消息成功
       });

  #### Parameters

  - params: IModifyMessageParams

    修改消息参数

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.10.0

  - Defined in IMEngine.ts:6903

### refreshReferenceMessageWithParams

- refreshReferenceMessageWithParams(
  params: IRefreshReferenceMessageParams,
  localMessageCallback: (msg: MessageResult[]) => void,
  remoteMessageCallback: (msg: MessageResult[]) => void,
  ): Promise<IAsyncResult<void>>

  刷新引用消息

  # 示例代码

       let conversationIdentifier = new ConversationIdentifier();
       conversationIdentifier.conversationType = ConversationType.Private;
       conversationIdentifier.targetId = "targetId";

       let referenceMessageUidList = new Array<string>();
       referenceMessageUidList.push("messageUid1");
       referenceMessageUidList.push("messageUid2");

       let params: IRefreshReferenceMessageParams = {
         conversationIdentifier: conversationIdentifier,
         messageUIds: referenceMessageUidList
       }

       IMEngine.getInstance().refreshReferenceMessageWithParams(params, (msg: Array<MessageResult>) => {
         // 被引用消息在本地，刷新 ui
       }, (msg: Array<MessageResult>) => {
         // 被引用消息在服务端，刷新 ui
       }).then(result => {
         // 接口调用失败，错误处理
       });

  #### Parameters

  - params: IRefreshReferenceMessageParams
  - localMessageCallback: (msg: MessageResult[]) => void

    被引用消息在本地获取到的引用消息结果回调

  - remoteMessageCallback: (msg: MessageResult[]) => void

    被引用消息在远端获取到的引用消息结果回调

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  1.10.0

  - Defined in IMEngine.ts:6942

### saveEditedMessageDraft

- saveEditedMessageDraft(
  draft: EditedMessageDraft,
  conversationIdentifier: ConversationIdentifier,
  ): Promise<IAsyncResult<void>>

  保存会话草稿

  # 示例代码

       let draft: EditedMessageDraft = {
         messageUid: "messageUid",
         content: "content",
       }
       let conversationIdentifier = new ConversationIdentifier();
       conversationIdentifier.conversationType = ConversationType.Private;
       conversationIdentifier.targetId = "targetId";
       IMEngine.getInstance().saveEditedMessageDraft(draft, conversationIdentifier).then(result => {
         // 设置会话草稿完成
       });

  #### Parameters

  - draft: EditedMessageDraft
  - conversationIdentifier: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.11.0

  - Defined in IMEngine.ts:6987

### getEditedMessageDraft

- getEditedMessageDraft(
  conversationIdentifier: ConversationIdentifier,
  ): Promise<IAsyncResult<EditedMessageDraft>>

  获取会话草稿

  # 示例代码

       let conversationIdentifier = new ConversationIdentifier();
       conversationIdentifier.conversationType = ConversationType.Private;
       conversationIdentifier.targetId = "targetId";
       IMEngine.getInstance().getEditedMessageDraft(conversationIdentifier).then(result => {
         // 获取会话草稿完成
       });

  #### Parameters

  - conversationIdentifier: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<EditedMessageDraft>>

  #### Version

  25.11.0

  - Defined in IMEngine.ts:7013

### clearEditedMessageDraft

- clearEditedMessageDraft(
  conversationIdentifier: ConversationIdentifier,
  ): Promise<IAsyncResult<void>>

  清除会话草稿

  # 示例代码

       let conversationIdentifier = new ConversationIdentifier();
       conversationIdentifier.conversationType = ConversationType.Private;
       conversationIdentifier.targetId = "targetId";
       IMEngine.getInstance().clearEditedMessageDraft(conversationIdentifier).then(result => {
         // 清除会话草稿完成
       });

  #### Parameters

  - conversationIdentifier: ConversationIdentifier

    会话标识

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.11.0

  - Defined in IMEngine.ts:7038

### setMessageInterceptor

- setMessageInterceptor(interceptor: MessageInterceptor): void

  设置消息拦截事件监听 MessageInterceptor 中定义的接口，sdk 超时时间为 3 秒，如果 3 秒内返回 sdk 继续处理，否则 sdk 认为消息处理失败，sdk 不会继续发送此消息。

  # 示例代码

       let interceptor: MessageInterceptor = {
         async messageWillSendAfterDB: (message: Message) => Promise<Message | null> {
           // 消息发送后入库前拦截
         },
         async messageDidReceiveBeforeDB: (message: Message) => Promise<Message | null> {
           // 消息接收后入库前拦截
         },
         async mediaMessageWillUpload: (message: Message) => Promise<Message | null> {
           // 发送媒体消息上传前拦截
         }
       }
       IMEngine.getInstance().setMessageInterceptor(interceptor);

  #### Parameters

  - interceptor: MessageInterceptor

    拦截器

  #### Returns void

  #### Version

  25.11.0

  - Defined in IMEngine.ts:7068

### updateMyUserProfileVisibility

- updateMyUserProfileVisibility(
  visibility: UserProfileVisibility,
  ): Promise<IAsyncResult<void>>

  更新我的用户信息可见性

  # 示例代码

       let visibility: UserProfileVisibility = UserProfileVisibility.UserProfileVisibilityEveryone;
       IMEngine.getInstance().updateMyUserProfileVisibility(visibility).then((result: IAsyncResult<void>) => {
         if (result.code === EngineError.Success) {
           // 更新我的用户信息可见性完成
         } else {
           // 更新我的用户信息可见性失败
         }
       });

  #### Parameters

  - visibility: UserProfileVisibility

    用户信息可见性

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7094

### getMyUserProfileVisibility

- getMyUserProfileVisibility(): Promise<IAsyncResult<UserProfileVisibility>>

  获取我的用户信息可见性

  # 示例代码

       IMEngine.getInstance().getMyUserProfileVisibility().then(result => {
         if (result.code === EngineError.Success) {
           // 获取我的用户信息可见性成功
         } else {
           // 获取我的用户信息可见性失败
         }
       });

  #### Returns Promise<IAsyncResult<UserProfileVisibility>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7117

### updateMyUserProfile

- updateMyUserProfile(profile: UserProfile): Promise<IAsyncResult<string[]>>

  更新我的用户信息

  # 示例代码

       let profile = new UserProfile();
       profile.name = "name";
       profile.portraitUri = "portraitUri";
       profile.email = "email";
       profile.birthday = "2000-01-01";
       profile.gender = UserGender.UserGenderMale;
       profile.location = "location";
       profile.role = 0;
       profile.level = 0;
       profile.userExtProfile = new HashMap<string, string>();
       profile.userExtProfile.set("key", "value");
       IMEngine.getInstance().updateMyUserProfile(profile).then((result: IAsyncResult<Array<string>>) => {
         if (result.code === EngineError.Success) {
           // 更新我的用户信息完成
         } else {
           // 更新我的用户信息失败
         }
       });

  #### Parameters

  - profile: UserProfile

    用户信息

  #### Returns Promise<IAsyncResult<string[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7152

### getMyUserProfile

- getMyUserProfile(): Promise<IAsyncResult<UserProfile>>

  获取我的用户信息

  # 示例代码

       IMEngine.getInstance().getMyUserProfile().then((result: IAsyncResult<UserProfile>) => {
         if (result.code === EngineError.Success) {
           // 获取我的用户信息完成
         } else {
           // 获取我的用户信息失败
         }
       });

  #### Returns Promise<IAsyncResult<UserProfile>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7175

### getUserProfiles

- getUserProfiles(userId: string[]): Promise<IAsyncResult<UserProfile[]>>

  批量获取用户信息

  # 示例代码

       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       IMEngine.getInstance().getUserProfiles(userIds).then((result: IAsyncResult<Array<UserProfile>>) => {
         if (result.code === EngineError.Success) {
           // 获取用户信息完成
         } else {
           // 获取用户信息失败
         }
       });

  #### Parameters

  - userId: string[]

    用户 ID

  #### Returns Promise<IAsyncResult<UserProfile[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7202

### searchUserProfileByUniqueId

- searchUserProfileByUniqueId(
  uniqueId: string,
  ): Promise<IAsyncResult<UserProfile>>

  根据唯一 ID 搜索用户信息

  # 示例代码

       let uniqueId = "uniqueId";
       IMEngine.getInstance().searchUserProfileByUniqueId(uniqueId).then((result: IAsyncResult<UserProfile>) => {
         if (result.code === EngineError.Success) {
           // 搜索用户信息完成
         } else {
           // 搜索用户信息失败
         }
       });

  #### Parameters

  - uniqueId: string

    唯一 ID

  #### Returns Promise<IAsyncResult<UserProfile>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7227

### subscribeEvent

- subscribeEvent(request: SubscribeEventRequest): Promise<IAsyncResult<String[]>>

  用户信息订阅事件

  # 示例代码

       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       let subscribeType: SubscribeType = SubscribeType.SubscribeTypeUserProfile;
       let expiry: number = 60;
       let request = new SubscribeEventRequest(subscribeType, expiry, userIds);
       IMEngine.getInstance().subscribeEvent(request).then((result: IAsyncResult<Array<String>>) => {
         if (result.code === EngineError.Success) {
           // 用户信息订阅事件完成
         } else {
           // 用户信息订阅事件失败
         }
       });

  #### Parameters

  - request: SubscribeEventRequest

    订阅事件请求

  #### Returns Promise<IAsyncResult<String[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7257

### unsubscribeEvent

- unsubscribeEvent(
  request: SubscribeEventRequest,
  ): Promise<IAsyncResult<String[]>>

  取消用户信息订阅事件

  # 示例代码

       let subscribeType: SubscribeType = SubscribeType.SubscribeTypeUserProfile;
       let expiry: number = 60;
       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       let request = new SubscribeEventRequest(subscribeType, expiry, userIds);
       IMEngine.getInstance().unsubscribeEvent(request).then((result: IAsyncResult<Array<String>>) => {
         if (result.code === EngineError.Success) {
           // 取消用户信息订阅事件完成
         } else {
           // 取消用户信息订阅事件失败
         }
       });

  #### Parameters

  - request: SubscribeEventRequest

    订阅事件请求

  #### Returns Promise<IAsyncResult<String[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7287

### querySubscribeEvent

- querySubscribeEvent(
  request: SubscribeEventRequest,
  ): Promise<IAsyncResult<SubscribeInfoEvent[]>>

  获取用户信息订阅事件

  # 示例代码

       let subscribeType: SubscribeType = SubscribeType.SubscribeTypeUserProfile;
       let expiry: number = 60;
       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       let request = new SubscribeEventRequest(subscribeType, expiry, userIds);
       IMEngine.getInstance().querySubscribeEvent(request).then((result: IAsyncResult<Array<SubscribeInfoEvent>>) => {
         if (result.code === EngineError.Success) {
           // 获取用户信息订阅事件完成
         } else {
           // 获取用户信息订阅事件失败
         }
       });

  #### Parameters

  - request: SubscribeEventRequest

    订阅事件请求

  #### Returns Promise<IAsyncResult<SubscribeInfoEvent[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7317

### querySubscribeEventByPage

- querySubscribeEventByPage(
  request: SubscribeEventRequest,
  pageSize: number,
  startIndex: number,
  ): Promise<IAsyncResult<SubscribeInfoEvent[]>>

  分页获取用户信息订阅事件

  # 示例代码

       let subscribeType: SubscribeType = SubscribeType.SubscribeTypeUserProfile;
       let expiry: number = 60;
       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       let request = new SubscribeEventRequest(subscribeType, expiry, userIds);
       let pageSize = 10;
       let startIndex = 0;
       IMEngine.getInstance().querySubscribeEventByPage(request, pageSize, startIndex).then((result: IAsyncResult<Array<SubscribeInfoEvent>>) => {
         if (result.code === EngineError.Success) {
           // 获取用户信息订阅事件完成
         } else {
           // 获取用户信息订阅事件失败
         }
       });

  #### Parameters

  - request: SubscribeEventRequest

    订阅事件请求

  - pageSize: number

    每页大小

  - startIndex: number

    起始索引

  #### Returns Promise<IAsyncResult<SubscribeInfoEvent[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7351

### getSubscribeUsersOnlineStatus

- getSubscribeUsersOnlineStatus(
  userIds: string[],
  ): Promise<IAsyncResult<SubscribeUserOnlineStatus[]>>

  获取用户在线状态

  # 示例代码

       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       IMEngine.getInstance().getSubscribeUsersOnlineStatus(userIds).then((result: IAsyncResult<Array<SubscribeUserOnlineStatus>>) => {
         if (result.code === EngineError.Success) {
           // 获取用户在线状态完成
         } else {
           // 获取用户在线状态失败
         }
       });

  #### Parameters

  - userIds: string[]

    用户 ID 列表

  #### Returns Promise<IAsyncResult<SubscribeUserOnlineStatus[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7387

### addSubscribeEventListener

- addSubscribeEventListener(listener: SubscribeEventListener): void

  添加订阅事件变化监听

  # 示例代码

       let listener: SubscribeEventListener = {
         onEventChange : (events: Array<SubscribeInfoEvent>) => {
           // 订阅事件变化
         },
         onSubscriptionSyncCompleted : (type: SubscribeType) => {
           // 订阅同步完成
         },
         onSubscriptionChangedOnOtherDevices : (events: Array<SubscribeEvent>) => {
           // 订阅在其他设备上发生变化
         }
       }
       IMEngine.getInstance().addSubscribeEventListener(listener);

  #### Parameters

  - listener: SubscribeEventListener

    订阅事件变化监听

  #### Returns void

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7420

### removeSubscribeEventListener

- removeSubscribeEventListener(listener: SubscribeEventListener): void

  移除订阅事件变化监听

  # 示例代码

       let listener: SubscribeEventListener = {
         onEventChange : (events: Array<SubscribeInfoEvent>) => {
           // 订阅事件变化
         },
         onSubscriptionSyncCompleted : (type: SubscribeType) => {
           // 订阅同步完成
         },
         onSubscriptionChangedOnOtherDevices : (events: Array<SubscribeEvent>) => {
           // 订阅在其他设备上发生变化
         }
       }
       IMEngine.getInstance().removeSubscribeEventListener(listener);

  #### Parameters

  - listener: SubscribeEventListener

    订阅事件变化监听

  #### Returns void

  #### Warning

  addSubscribeEventListener & removeSubscribeEventListener 配合使用，避免内存泄露

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7445

### addFriend

- addFriend(
  userId: string,
  directionType: FriendDirectionTypeBoth,
  extra: string,
  ): Promise<IAsyncResult<number>>

  添加好友

  # 示例代码

       let userId: string = "userId";
       let directionType: FriendDirectionType = FriendDirectionType.FriendDirectionTypeBoth;
       let extra: string = "extra";
       IMEngine.getInstance().addFriend(userId, directionType, extra).then((result: IAsyncResult<number>) => {
         if (result.code === EngineError.Success) {
           // 根据 processCode 判断具体错误原因
         } else {
           // 添加好友失败
         }
       });

  #### Parameters

  - userId: string

    用户 ID

  - directionType: FriendDirectionTypeBoth

    好友类型

  - extra: string

    额外信息

  #### Returns Promise<IAsyncResult<number>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7474

### checkFriends

- checkFriends(
  userIds: string[],
  directionType: FriendDirectionTypeBoth,
  ): Promise<IAsyncResult<FriendRelationInfo[]>>

  检查好友

  # 示例代码

       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       let friendType: FriendDirectionType = FriendDirectionType.FriendDirectionTypeBoth;
       IMEngine.getInstance().checkFriends(userIds, friendType).then((result: IAsyncResult<Array<FriendRelationInfo>>) => {
         if (result.code === EngineError.Success) {
           // result.data 为好友关系信息列表
         } else {
           // 检查好友失败
         }
       });

  #### Parameters

  - userIds: string[]

    用户 ID 列表

  - directionType: FriendDirectionTypeBoth

    好友类型

  #### Returns Promise<IAsyncResult<FriendRelationInfo[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7503

### deleteFriends

- deleteFriends(
  userIds: string[],
  directionType: FriendDirectionTypeBoth,
  ): Promise<IAsyncResult<void>>

  删除好友

  # 示例代码

       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       let directionType: FriendDirectionType = FriendDirectionType.FriendDirectionTypeBoth;
       IMEngine.getInstance().deleteFriends(userIds, directionType).then((result: IAsyncResult<void>) => {
         if (result.code === EngineError.Success) {
           // 删除好友完成
         } else {
           // 删除好友失败
         }
       });

  #### Parameters

  - userIds: string[]

    用户 ID 列表

  - directionType: FriendDirectionTypeBoth

    好友类型

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7539

### getFriends

- getFriends(
  directionType: QueryFriendsDirectionTypeBoth,
  ): Promise<IAsyncResult<FriendInfo[]>>

  获取好友

  # 示例代码

       let directionType: QueryFriendsDirectionType = QueryFriendsDirectionType.QueryFriendsDirectionTypeBoth;
       IMEngine.getInstance().getFriends(directionType).then((result: IAsyncResult<Array<FriendInfo>>) => {
         if (result.code === EngineError.Success) {
           // 获取好友完成
         } else {
           // 获取好友失败
         }
       });

  #### Parameters

  - directionType: QueryFriendsDirectionTypeBoth

    好友类型

  #### Returns Promise<IAsyncResult<FriendInfo[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7564

### getFriendsInfo

- getFriendsInfo(userIds: string[]): Promise<IAsyncResult<FriendInfo[]>>

  获取好友信息

  # 示例代码

       let userIds = new Array<string>();
       userIds.push("userId1");
       userIds.push("userId2");
       IMEngine.getInstance().getFriendsInfo(userIds).then((result: IAsyncResult<Array<FriendInfo>>) => {
         if (result.code === EngineError.Success) {
           // 获取好友信息完成
         } else {
           // 获取好友信息失败
         }
       });

  #### Parameters

  - userIds: string[]

    用户 ID 列表

  #### Returns Promise<IAsyncResult<FriendInfo[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7591

### searchFriendsInfo

- searchFriendsInfo(name: string): Promise<IAsyncResult<FriendInfo[]>>

  搜索好友

  # 示例代码

       let name: string = "name";
       IMEngine.getInstance().searchFriendsInfo(name).then((result: IAsyncResult<Array<FriendInfo>>) => {
         if (result.code === EngineError.Success) {
           // result.data 为好友信息列表
         } else {
           // 搜索好友失败
         }
       });

  #### Parameters

  - name: string

    名称

  #### Returns Promise<IAsyncResult<FriendInfo[]>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7616

### setFriendInfo

- setFriendInfo(
  userId: string,
  remark: string,
  extProfile: Map<string, string>,
  ): Promise<IAsyncResult<void>>

  设置好友信息

  # 示例代码

       let userId: string = "userId";
       let remark: string = "remark";
       let extProfile: Map<string, string> = new Map<string, string>();
       extProfile.set("key1", "value1");
       extProfile.set("key2", "value2");
       IMEngine.getInstance().setFriendInfo(userId, remark, extProfile).then((result: IAsyncResult<Array<string>>) => {
         if (result.code === EngineError.Success) {
           // 设置好友信息完成
         } else {
           // 设置好友信息失败
           if (result.data) {
             let errorKeys: Array<string> = result.data; // 失败的 key 数组
           }
         }
       });

  #### Parameters

  - userId: string

    用户 ID

  - remark: string

    备注

  - extProfile: Map<string, string>

    扩展信息键值对, 最多可设置 10 组

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7650

### getFriendApplications

- getFriendApplications(
  option: PagingQueryOption,
  requestType: FriendApplicationType[],
  requestStatus: FriendApplicationStatus[],
  ): Promise<IAsyncResult<PagingQueryResult<FriendApplicationInfo>>>

  获取好友申请

  # 示例代码

       let pageToken: string = "";
       let count: number = 10;
       let order: boolean = false;
       let pagingOption: PagingQueryOption = new PagingQueryOption(pageToken, count, order);
       let requestType: Array<FriendApplicationType> = [FriendApplicationType.FriendApplicationTypeSent, FriendApplicationType.FriendApplicationTypeReceived];
       let requestStatus: Array<FriendApplicationStatus> = [FriendApplicationStatus.FriendApplicationStatusUnHandled, FriendApplicationStatus.FriendApplicationStatusAccepted];
       IMEngine.getInstance().getFriendApplications(pagingOption, requestType, requestStatus).then((result: IAsyncResult<PagingQueryResult<FriendApplicationInfo>>) => {
         if (result.code === EngineError.Success) {
           // result.data 为好友申请信息列表
         } else {
           // 获取好友申请失败
         }
       });

  #### Parameters

  - option: PagingQueryOption

    分页请求参数

  - requestType: FriendApplicationType[]

    请求类型

  - requestStatus: FriendApplicationStatus[]

    请求状态

  #### Returns Promise<IAsyncResult<PagingQueryResult<FriendApplicationInfo>>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7682

### acceptFriendApplication

- acceptFriendApplication(userId: string): Promise<IAsyncResult<void>>

  接受好友申请

  # 示例代码

       let userId: string = "userId";
       IMEngine.getInstance().acceptFriendApplication(userId).then((result: IAsyncResult<void>) => {
         if (result.code === EngineError.Success) {
           // 接受好友申请完成
         } else {
           // 接受好友申请失败
         }
       });

  #### Parameters

  - userId: string

    用户 ID

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7716

### refuseFriendApplication

- refuseFriendApplication(userId: string): Promise<IAsyncResult<void>>

  拒绝好友申请

  # 示例代码

       let userId: string = "userId";
       IMEngine.getInstance().refuseFriendApplication(userId).then((result: IAsyncResult<void>) => {
         if (result.code === EngineError.Success) {
           // 拒绝好友申请完成
         } else {
           // 拒绝好友申请失败
         }
       });

  #### Parameters

  - userId: string

    用户 ID

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7741

### setFriendAddPermission

- setFriendAddPermission(
  permission: FriendAddPermission,
  ): Promise<IAsyncResult<void>>

  设置好友添加权限

  # 示例代码

       let permission: FriendAddPermission = FriendAddPermission.FriendAddPermissionAllowAll;
       IMEngine.getInstance().setFriendAddPermission(permission).then((result: IAsyncResult<void>) => {
         if (result.code === EngineError.Success) {
           // 设置好友添加权限完成
         } else {
           // 设置好友添加权限失败
         }
       });

  #### Parameters

  - permission: FriendAddPermission

    好友添加权限

  #### Returns Promise<IAsyncResult<void>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7766

### getFriendAddPermission

- getFriendAddPermission(): Promise<IAsyncResult<FriendAddPermission>>

  获取好友添加权限

  # 示例代码

       IMEngine.getInstance().getFriendAddPermission().then((result: IAsyncResult<FriendAddPermission>) => {
         if (result.code === EngineError.Success) {
           // 获取好友添加权限完成
         } else {
           // 获取好友添加权限失败
         }
       });

  #### Returns Promise<IAsyncResult<FriendAddPermission>>

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7789

### addFriendEventListener

- addFriendEventListener(listener: FriendEventListener): void

  设置好友添加监听

  # 示例代码

       let listener: FriendEventListener = {
         onFriendAdd : (userId: string, name: string, portraitUri: string, directionType: number, operationTime: number) => {
           // 好友添加回调
         },
         onFriendDelete : (userIds: Array<string>, directionType: number, operationTime: number) => {
           // 好友删除回调
         },
         onFriendApplicationStatusChanged = (userId: string, applicationType: number, applicationStatus: number, directionType: number, operationTime: number, extra: string | null) => {
           // 好友申请状态变更回调
         },
         onFriendCleared : (operationTime: number) => {
           // 好友清空回调
         },
         onFriendInfoChangedSync : (userId: string, remark: string | null, extProfile: Map<string, string> | null, operationTime: number) => {
           // 好友信息变更多端回调事件
         },
       };
       IMEngine.getInstance().addFriendEventListener(listener).then((result: IAsyncResult<void>) => {
         if (result.code === EngineError.Success) {
           // 设置好友添加监听完成
         } else {
           // 设置好友添加监听失败
         }
       });

  #### Parameters

  - listener: FriendEventListener

    好友事件监听

  #### Returns void

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7830

### removeFriendEventListener

- removeFriendEventListener(listener: FriendEventListener): void

  删除好友添加监听

  # 示例代码

       let listener: FriendEventListener = {
         onFriendAdd : (userId: string, name: string, portraitUri: string, directionType: number, operationTime: number) => {
           // 好友添加回调
         },
         onFriendDelete : (userIds: Array<string>, directionType: number, operationTime: number) => {
           // 好友删除回调
         },
         onFriendApplicationStatusChanged = (userId: string, applicationType: number, applicationStatus: number, directionType: number, operationTime: number, extra: string | null) => {
           // 好友申请状态变更回调
         },
         onFriendCleared : (operationTime: number) => {
           // 好友清空回调
         },
         onFriendInfoChangedSync : (userId: string, remark: string | null, extProfile: Map<string, string> | null, operationTime: number) => {
           // 好友信息变更多端回调事件
         },
       };
       IMEngine.getInstance().removeFriendEventListener(listener).then((result: IAsyncResult<void>) => {
         if (result.code === EngineError.Success) {
           // 删除好友添加监听完成
         } else {
           // 删除好友添加监听失败
         }
       });

  #### Parameters

  - listener: FriendEventListener

    好友事件监听

  #### Returns void

  #### Version

  25.12.0

  - Defined in IMEngine.ts:7867