目录

鸿蒙访客端SDK API文档

初始化SDK

//在主页面调用,以免重复初始化
    let mVisitorOptions = new VisitorOptions();
    mVisitorOptions.setKefuRestServer('${客服登录地址}')
      .setAppkey('${AppKey}')
      .setTenantId('${租户ID}')
      .setAppVersion('${app版本号}')
    VisitorClient.getInstance().init(mContext, visitorOptions)

注册

VisitorClient.getInstance()
      .getVisitorManager()
      .register(username, password)
      .then((value: string) => {
        console.info("注册成功" + value)
      })
      .catch((reason: VisitorError) => {
        console.error("注册失败" + reason.errorCode + "," + reason.description)
      });

密码登录

//调接口登录
    VisitorClient.getInstance()
      .getVisitorManager()
      .login(username, password)
      .then((value: string) => {
        console.info("登录成功" + value)
      })
      .catch((reason: VisitorError) => {
        console.error("登录失败" + reason.errorCode + "," + reason.description)
      })

Token登录

//调接口登录
    VisitorClient.getInstance()
      .getVisitorManager()
      .loginWithToken(username, token)
      .then((value: string) => {
        console.info("登录成功" + value)
      })
      .catch((reason: VisitorError) => {
        console.error("登录失败" + reason.errorCode + "," + reason.description)
      })

登录状态

//判断是否已登录,避免重复调用登录接口
    VisitorClient.getInstance().isLoggedInBefore()

退出登录

VisitorClient.getInstance()
      .getVisitorManager()
      .logout()
      .then(() => {
        console.info("退出成功")
      })
      .then(() => {
        //TODO 移除emitter事件,避免切换用户后重复执行事件
      })
      .catch((reason: VisitorError) => {
        console.error("退出失败" + reason.errorCode + "," + reason.description)
      })

长连接监听

connectListener:IMConnectListener = {
      onConnected: (): void => {
        // 长连接建立
      },
      onDisconnected: (errorCode: number): void => {
        // 长连接断开
        switch (errorCode){
          case VisitorError.USER_NOT_FOUND:
          case VisitorError.USER_LOGIN_ANOTHER_DEVICE:
          case VisitorError.USER_AUTHENTICATION_FAILED:
          case VisitorError.USER_REMOVED:
            VisitorClient.getInstance().getVisitorManager().logout()
          //TODO 跳转到登录页面
            break;
        }
      }
    } 
    //添加长连接监听
    VisitorClient.getInstance().addConnectionListener(connectListener)
    //移除长连接监听
    VisitorClient.getInstance().removeConnectionListener(connectListener)

消息监听

messageListener: MessageListener = {
      onMessage(msgs: ArrayList<Message>) {
        //收到上屏消息
      },
      onCmdMessage(msgs: ArrayList<Message>) {
        //收到cmd透传消息
      },
      onMessageStatusUpdate() {
      },
      onMessageSent() {
        //消息已发送
      }
    };
    //添加消息监听
    VisitorClient.getInstance().getVisitorManager().addMessageListener(messageListener);
    //移除消息监听
    VisitorClient.getInstance().getVisitorManager().removeMessageListener(messageListener);

绑定IM服务号

//发消息之前请点调用该API,以绑定IM服务号,可在进入聊天页面之后即调用
    VisitorClient.getInstance().getVisitorManager().bindChat(toChatUsername)

解绑IM服务号

//退出聊天页面调用该API,以解绑IM服务号
    VisitorClient.getInstance().getVisitorManager().unbindChat(toChatUsername)

修改AppKey

//newAppKey 新的AppKey
    VisitorClient.getInstance().changeAppKey(newAppKey)

修改租户ID

//newTenantId 新的租户ID
    VisitorClient.getInstance().changeTenantId(newTenantId)

消息

1.发送消息

VisitorClient.getInstance().getVisitorManager().sendMessage(message)

2.保存消息到本地

VisitorClient.getInstance().getVisitorManager().saveMessage(message)

3.删除消息

let messageId = message.messageId();
    VisitorClient.getInstance().getConversationManager().getConversation(toChatUsername).removeMessage(messageId);

4.创建文本消息

//content:文本内容;toChatUsername:IM服务号;
    Message.createTxtSendMessage(content, toChatUsername)

5.创建图片消息

//imgPath:图片路径;imgSize:图片大小(宽,高);toChatUsername:IM服务号;displayName:图片文件名称;
    let imgSize = new VisitorImageSize(480, 640);
    let message = Message.createImageSendMessage(imgPath, imgSize, toChatUsername, displayName);

6.创建语音消息

//voicePath:语音文件路径;duration:语音时长;toChatUsername:IM服务号;
    Message.createVoiceSendMessage(voicePath, duration, this.toChatUsername)

7.创建短视频消息

//videoPath:短视频文件路径;duration:视频时长;toChatUsername:IM服务号;displayName:视频文件名称;thumbLocalPath:缩略图文件路径;
    Message.createVideoSendMessage(videoPath, duration, this.toChatUsername, displayName, thumbLocalPath);

8.创建文件消息

//filePath:文件路径;fileLength:文件大小;toChatUsername:IM服务号;displayName:文件名称;
    Message.createFileSendMessage(filePath, fileLength, this.toChatUsername, displayName);

9.创建位置消息

//latitude:维度;longitude:经度;toChatUsername:IM服务号;address:地址信息;buildingName:建筑物名称;
    Message.createLocationSendMessage(latitude, longitude, this.toChatUsername, address, buildingName);

10.创建点击菜单条目后回复的选择消息

//item:ChoiceItem 点击的机器人菜单条目或者询前引导菜单条目;toChatUsername:IM服务号;transferMode:string Choice.mode 从Choice中获取的转接模式
    Message.createSendMessageForMenu(item, this.toChatUsername, transferMode)

11.创建订单消息

//发送订单消息
    let message = Message.createTxtSendMessage("订单",this.toChatUsername)
    let orderInfo:OrderInfo = {
      title:"订单消息",
      order_title:"订单号:611088888",
      desc:"短裤",
      price:"¥200",
      img_url:"https://xxx",
      item_url:"https://www.easemob.com"
    }
    message.addOrderInfo(orderInfo)
    VisitorClient.getInstance().getVisitorManager().saveMessage(message)

12.创建轨迹消息

//发送轨迹消息
    let message = Message.createTxtSendMessage("轨迹",this.toChatUsername)
    let trackInfo:TrackInfo = {
      title:"轨迹消息",
      desc:"衬衫",
      price:"¥200",
      img_url:"https://xxx",
      item_url:"https://www.easemob.com"
    }
    message.addTrackInfo(trackInfo)
            VisitorClient.getInstance().getVisitorManager().sendMessage(message)

从消息中获取坐席信息

//用于显示坐席头像、昵称
    MessageHelper.getAgentInfo(message)

会话相关

获取所有本地会话

ChatClient.getInstance().chatManager().getAllConversations();

从本地会话中获取最后一条消息

//toChatUsername:IM服务号
    VisitorClient.getInstance().getConversationManager().getConversation(toChatUsername)?.latestMessage()

从本地会话中获取最近的坐席信息

//根据业务需求,在会话列表中调用以显示最近坐席信息
let agentInfo = conversation.getAgentInfo();
      if (agentInfo) {
        this.nickName = agentInfo.userNickname ? agentInfo.userNickname : ""
        this.img = agentInfo.avatar ? agentInfo.avatar : ""
      }

从本地会话中获取未读消息数

//toChatUsername:IM服务号
    VisitorClient.getInstance().getConversationManager().getConversation(toChatUsername)?.unreadMessagesCount()

标记IM服务号对应的本地会话中所有消息为已读

//只改变本地会话中消息状态
    VisitorClient.getInstance().getConversationManager().getConversation(toChatUsername).markAllMessagesAsRead()
    //TODO 本地标记后需要调用14来通知坐席消息已读

标记本地消息为已读

//本地设置消息已读,只改变本地消息状态
    message.setUnRead(false)

标记该通会话中所有消息已读

//从消息中获取客服系统会话ID
    let sessionId = MessageHelper.getSessionIdFromMessage(message);
    //通知坐席消息已读
    VisitorClient.getInstance()
      .getVisitorManager()
      .asyncMarkAllMessagesAsRead(VisitorClient.getInstance().getTenantId(), sessionId)

获取正在进行中的会话信息

VisitorClient.getInstance().getVisitorManager().asyncGetCurrentSessionInfo()
      .then((result) => {
        //result为空,没有正在进行中的会话
        //result不为空,result.serviceSessionId就是正在进行中的会话ID
      })

从本地会话中获取缓存的消息列表

let conversation = VisitorClient.getInstance().getConversationManager().getConversation(toChatUsername);
    if(conversation){
        conversation.getAllMessages();
    }

从本地数据库加载会话的消息列表

//toChatUsername:IM服务号;startMsgId:开始的消息id,往前加载;pageSize:分页加载的消息数量;
    //startMsgId为undefined时,从最新消息往前加载
    VisitorClient.getInstance().getConversationManager().getConversation(toChatUsername).loadMessages(msgId, pageSize)

清空IM服务号对应的本地会话中的聊天记录

//toChatUsername IM服务号
    VisitorClient.getInstance().getConversationManager().clearConversation(toChatUsername)

设置访客属性

设置访客通用属性

//会设置在ext的weichat字段下
    //sendMessage之前调用
    let visitorInfo = new VisitorInfo()
      .setTrueName('真实姓名')
      .setUserNickname('昵称')
      .setPhone('188888888888')
      .setCompanyName('公司名称')
      .setEmail('88888888@qq.com')
      .setQq('88888888')
      .setDesc('访客描述')
      .setTags(['vip1'])//vip客户
    message.addVisitorInfo(visitorInfo)

设置访客自定义属性

//设置在visitorInfo访客属性对象中
    //customColumn为json字符串,可自行定义其内容
    let customColumn = "{\"custom\":\"自定义参数内容\",\"age\":18,\"test\":true}"
    visitorInfo.setCustomColumn(customColumn)

设置进线路由指定

指定坐席技能组接待

//会设置在ext的weichat字段下
    //sendMessage之前调用
    message.addQueueIdentityInfo("技能组名称")

指定坐席接待

//会设置在ext的weichat字段下
    //sendMessage之前调用
    message.addAgentIdentityInfo("qby@77909.com")

设置业务路由标识

//会设置在ext的weichat字段下
    //sendMessage之前调用
    message.addRoutingRuleFlag("testFlag")

获取欢迎语

获取企业欢迎语

//获取企业欢迎语,一般需要先调用asyncGetCurrentSessionInfo判断没有正在进行中会话时调用
    VisitorClient.getInstance().getVisitorManager().asyncGetEnterpriseWelcome()
      .then((result) => {
        if (result) {
          //创建接收消息并保存在数据库
          VisitorClient.getInstance().getVisitorManager().saveMessage(this.createReceiveTxtMessage(result))
          //TODO 更新消息列表
        }
      })

获取机器人欢迎语

//获取机器人欢迎语,一般需要先调用asyncGetCurrentSessionInfo判断没有正在进行中会话时调用
    VisitorClient.getInstance().getVisitorManager().asyncGetRobotWelcome()
      .then((result) => {
        if (result) {
          let welcomeObj: RobotWelcomeData = JSON.parse(result);
          if (welcomeObj) {
            let welcomeStr = welcomeObj.greetingText
            if (welcomeStr) {
              //欢迎语内容
              welcomeStr = welcomeStr.replaceAll("&amp;quot;", "\"");
              if (welcomeStr != "null") {
                //欢迎语类型,TODO 根据类型创建想要展示的Message并保存在数据库,UI做相应显示
                switch (welcomeObj.greetingTextType) {
                //type为0代表是文字消息的机器人欢迎语
                //type为1代表是菜单消息的机器人欢迎语
                //type为2代表是图片消息的机器人欢迎语
                //type为4代表是图文消息的机器人欢迎语
                //type为5代表是答案组消息的机器人欢迎语
                }
              }
            }
          }
        }
      })

满意度评价

1.主动获取满意度评价邀请消息

//serviceSessionId为当前客服系统会话ID,需要先调用asyncGetCurrentSessionInfo获取
    VisitorClient.getInstance().getVisitorManager().asyncGetInviteEvaluation(serviceSessionId)

2.发送评价信息

//从消息中获取满意度相关信息,例如:级别、标签列表等。
    let evaluationInfo = MessageHelper.getChatEvaluation(currentMessage)
    // visitor访客主动评价,agent坐席邀请,system强制邀请访客,点击关闭窗口或会话结束
    let evaluateWay = "agent"
    if (evaluationInfo && evaluationInfo.inviteId != undefined) {
      let inviteId = this.evaluationInfo.inviteId
      if (Number(inviteId) == 0) {
        evaluateWay = "visitor"
      }
    }
    //detail为评价的文字内容信息,currentDegree为选择星标后从evaluationInfo查到的对应level的AppraiseTags
    //selectedTags 为选中的标签信息AppraiseTagItem的集合;selectResolutionParams为选中的问题解决评价标签集合
    MessageHelper.sendEvalMessage(currentMessage, evaluateWay, detail, currentDegree,
      selectedTags,
      selectResolutionParams, {
        onSuccess() {
          //发送成功
        },
        onError(errCode, errDesc) {
          //发送失败
        }
      })

3.是否显示问题解决评价

VisitorClient.getInstance()
      .getVisitorManager()
      .asyncGetIfShowResolution()
      .then((value) => {
        //true/false
        this.showResolution = value
      })

4.获取问题解决评价引导语

VisitorClient.getInstance()
      .getVisitorManager()
      .asyncGetResolutionWord(serviceSessionId)
      .then((value) => {
        //引导语,如:请问客服是否解决了您的问题?
        if (value) {
          this.resolutionTip = value
        }
      })

5.获取问题解决评价列表

VisitorClient.getInstance()
      .getVisitorManager()
      .asyncResolutionParams(serviceSessionId)
      .then((value:ResolutionParam[] | undefined) => {
        //返回问题解决评价列表
        if (value && value.length > 1) {
          //给第一个显示的标签赋值,如:已解决
          let param0 = value[0].name
          if (param0) {
            this.solve = param0
          }
          //给第二个显示的标签赋值,如:未解决
          let param1 = value[1].name
          if (param1) {
            this.reject = param1
          }
        }
      })

6.获取邀请评价引导语

VisitorClient.getInstance().getVisitorManager().asyncGetEnquiryInviteWord(this.sessionId)
      .then((value) => {
        //邀请引导语,如:请对我的服务做出评价
        if (value) {
          this.inviteTip = value
        }
      })

留言功能

1.创建留言

let creator: CreatorBean = {
      name: this.labelName,//标题
      phone: this.phone,//电话
      email: this.email//邮箱
    }
    let leaveMsg: LeaveMsg = {
      content: this.content,//留言内容
      subject: this.theme,//留言主题
      creator: creator,
    }
    //toChatUsername:IM服务号;projectId:租户留言ID
    VisitorClient.getInstance()
      .getLeaveMsgManager()
      .asyncCreateLeaveMessage(leaveMsg, toChatUsername, projectId)

2.获取留言列表

//toChatUsername:IM服务号;projectId:租户留言ID
    VisitorClient.getInstance()
          .getLeaveMsgManager()
          .asyncGetLeaveMessages(toChatUsername, projectId)

3.创建留言评论

let attachments:ArrayList<AttachmentData> = new ArrayList()
    //评论里可添加附件,type为image、audio或file
    let attachment:AttachmentData = {
      name:"附件名称",
      url:"https://xxx",//附件url
      type:"img",
    }
    attachments.add(attachment)
    let creatorBen: CreatorBean = {
      name: "评论人姓名",
      username: VisitorClient.getInstance().currentUserName(),//当前用户ID
      type: "VISITOR"//固定为”VISITOR“,不可更改
    }
    let commentData: NewCommentData = {
      content: this.content,//评论内容
      creator: creatorBen,
      attachments: attachments.convertToArray()
    }
    //toChatUsername:IM服务号;projectId:租户留言ID;ticketId:评论的留言条目ID
    VisitorClient.getInstance()
      .getLeaveMsgManager()
      .asyncCreateLeaveMsgComment(commentData, toChatUsername, projectId, ticketId)

4.获取留言评论列表

//toChatUsername:IM服务号;projectId:租户留言ID;ticketId:评论的留言条目ID
    VisitorClient.getInstance()
          .getLeaveMsgManager()
          .asyncGetLeaveMsgComments(toChatUsername, projectId, ticketId)

自定义iframe参数 {updateVisitorInfoSrc}

//会在ext下设置{"cmd":{"updateVisitorInfoSrc":{"params":paramsObj}}}
    //action:命令,这里可随便传个值,如:”cmd“;toChatUsername:IM服务号;
    let message = Message.createCmdSendMessage(action, this.toChatUsername)
    if (message) {
      let paramsObj:VisitorInfoParams = {
        "param1": 12,
        "param2": "你好"
      };
      //paramsObj内的key/value可自行定义
      message.updateIframeParams(paramsObj)
      VisitorClient.getInstance().getVisitorManager().sendMessage(message)
    }

高级功能

显示排队人数

//初始化前设置
    //需要开通sessionCreatedNoticeEnable、sessionOpenedNoticeEnable、sessionTransferNoticeEnable、sessionAbortedNoticeEnable、sessionClosedNoticeEnable事件
    mVisitorOptions.showVisitorWaitCount()
    //聊天页面添加
    waitCountListener: VisitorWaitListener = {
      waitCount(num: number) {
        //TODO 更新排队人数
      }
    }
    VisitorClient.getInstance().getVisitorManager().addVisitorWaitListener(this.waitCountListener);

显示坐席输入状态

//初始化前设置
    //需要开通sessionOpenedNoticeEnable、sessionAbortedNoticeEnable、sessionClosedNoticeEnable事件
    mVisitorOptions.showAgentInputState()

坐席实现消息预知功能

//初始化前设置
    mVisitorOptions.showMessagePredict()

访客状态通知

//开始状态上报
    CecOfflineReportUtil.getInstance().startReport(toChatUsername)
    //结束状态上报
    CecOfflineReportUtil.getInstance().stopReport(toChatUsername)

开启/关闭本地日志(默认开启)

//初始化时调用
    let mVisitorOptions = new VisitorOptions();
    mVisitorOptions.setConsoleLog(false)
    VisitorClient.getInstance().init(mContext, visitorOptions)

取本地日志

//在控制台使用hdc命令
    hdc file recv /data/app/el2/100/base/{包名}/{AppKey}/core_log
    //例:hdc file recv /data/app/el2/100/base/com.easemob.helpdesk.huawei/1197231114210800#demo/core_log

音视频部分集成

创建CEC视频邀请消息

VisitorClient.getInstance()
        .getCallManager()
        .callVideo("邀请客服进行实时视频", toUserName, {
        onSuccess: (): void => {
            //跳转到呼叫页面
        }
    })

创建CEC视频邀请消息

//未接通时,callId为0,isConnected为false
let callId = 0
let isConnected = false
VisitorClient.getInstance()
	.getCallManager()
	.endCall(callId, this.toUserName, isConnected)

发送取消/挂断CEC视频邀请消息

//接通后,callId为坐席发来的ticket中的信息,isConnected为true
let callId = AgoraMessage.getInstance().getVideoCallTicket()?.callId as number
let isConnected = true
VisitorClient.getInstance().getCallManager().endCall(callId, this.toUserName, isConnected)

注册/移除坐席CEC呼叫访客监听

let cecOptionListener: CecOptionsListener = {
    onAgentAccept: (videoCallTicket?: VideoCallTicket, imServiceNum?: string) => {
      //弹出CEC视频邀请页面
    }
  }
  //添加坐席CEC呼叫监听,一般在主页面添加
  VisitorClient.getInstance()
    .getVisitorManager()
    .addCecOptionsListener(cecOptionListener)
  //移除坐席CEC呼叫监听
  VisitorClient.getInstance()
    .getVisitorManager()
    .removeCecOptionsListener(cecOptionListener)

注册/移除CEC视频监听

let cecVideoCallListener: CecVideoCallListener = {}
cecVideoCallListener.onAgentAccept = (videoCallTicket: VideoCallTicket) => {
  //收到坐席发来的ticket
}
cecVideoCallListener.onAgentHangup = () => {
  //结束CEC视频通话
}
//注册监听
VisitorClient
  .getInstance()
  .getCallManager()
  .registerCecVideoCallListener(cecVideoCallListener)
  
  ...
  
//取消注册
VisitorClient.getInstance()
	.getCallManager()
	.unregisterCecVideoCallListener()

关闭CEC在线会话

//visitorId为访客ID,可调用asyncGetVisitorInfo接口获取;sessionId可从消息中获取
    
    let sessionId: string = MessageHelper.getSessionIdFromMessage(message)
    VisitorClient.getInstance().getVisitorManager().asyncCloseCec(visitorId, sessionId)

注册/移除VEC视频通话监听

let vecVideoCallListener: VecVideoCallListener = {}
        vecVideoCallListener.onAgentAccept = (message: Message, videoCallTicket: VideoCallTicket) => {
          if (this.call_flag == VecCallingUtil.VEC_CALL_FLAG_RECV) {
            //已经是等待状态下,访客在等待页面,此时有坐席又发起视频邀请,无操作
          } else {
            //访客主呼,坐席接听,解析videoCallTicket,跳转到视频接通页面
          }
        }
        vecVideoCallListener.onAgentCanceled = (message: Message) => {
          //坐席取消
        }
        vecVideoCallListener.onAgentRejected = (message: Message) => {
          //坐席拒接
        }
        vecVideoCallListener.onVecCreated = (tenantId: string, rtcSessionId: string) => {
          //vec会话创建成功
        }
        vecVideoCallListener.onVecWaitTimeout = () => {
          //等待超时,挂断
        }
    VisitorClient
      .getInstance()
      .getCallManager()
      .registerVecVideoCallListener(vecVideoCallListener)

注册/移除VEC视频排队监听

let vecWaitDataListener: VecWaitListener = {
        waitData: (waitingFlag: boolean, waitingContent: string, sessionId: string): void => {
          //获取到排队人数,显示
          if (waitingContent) {
            this.content = waitingContent
          }
        }
    }
    //访客主动发起视频,注册排队监听,提示排队人数
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .registerVecWaitListener(vecWaitDataListener)
    //取消注册排队监听
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .unRegisterVecWaitListener()

获取VEC视频样式

//获取到VEC坐席渠道关联对应的设置信息;configId为从VEC渠道关联中获取ConfigID
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .asyncGetVecStyle(configId)

获取VEC视频信息

//获取到坐席头像、昵称;tenantId为租户ID
    VisitorClient.getInstance()
          .getVecVisitorManager()
          .asyncGetVecInfo(tenantId)

获取租户开通的灰度功能

//tenantId租户ID
    VisitorClient.getInstance()
            .getVisitorManager()
            .asyncGetGrayscaleOptions(tenantId)

获取屏幕共享范围设置

//是否只能共享应用内页面,默认false
    AgoraMessage.getInstance()
        .isShareDesktopInMobile()

发送VEC视频邀请消息

//vecImServiceNum:vec渠道关联对应的IM服务号
    //sessionExt:vec发起视频时携带的扩展信息,可为undefined
    VisitorClient.getInstance()
            .getCallManager()
            .callVecVideo("您正邀请客服进行视频通话", vecImServiceNum, sessionExt, {
              onSuccess: (): void => {
                //跳转到呼叫等待页面
              }
            })

发送取消/挂断VEC视频邀请消息

//callId从坐席接听回调中取,如果坐席尚未接听,传0,标识取消
    VisitorClient.getInstance()
            .getCallManager()
            .cancelVecCall(this.callId, this.toUserName)

注册/移除坐席VEC操作监听

vecOptionListener: VecOptionsListener = {
        onEnquiryInvite: (enquiryInvite, vecImServiceNum) => {
          //VEC视频结束后,根据坐席端设置,回调满意度评价邀请
        },
        onAgentInvite: (vecImServiceNum) => {
          //坐席VEC呼叫访客
          //弹出VEC视频邀请页面
        }
      }
    //添加坐席VEC呼叫访客监听
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .addVecOptionsListener(this.vecOptionListener)
    //移除坐席VEC呼叫访客监听
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .removeVecOptionsListener(vecOptionListener)

发送接听VEC视频邀请消息

VisitorClient.getInstance()
        .getCallManager()
        .acceptVecCall("访客接受视频邀请", this.toUserName)

发送拒接VEC视频邀请消息

VisitorClient.getInstance()
        .getCallManager()
        .rejectVecCall("访客拒绝接听视频", this.toUserName)

关闭VEC视频会话

//在接通视频后访客挂断时调用,visitorId为访客ID,可调用asyncGetVisitorInfo接口获取;sessionId可从消息中获取
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .asyncCloseVec(visitorId, sessionId)

访客VEC在离线状态

//开启上报,当调用bindVecChat时,sdk内部会自动调用该方法
    VecOfflineReportUtil.getInstance().startReport(this.toUserName)
    //结束上报,当调用unbindVecChat时,sdk内部会自动调用该方法
    VecOfflineReportUtil.getInstance().stopReport(this.toUserName)

注册/移除VEC中IM消息监听

this.vecMessageListener.onMessage = (msgs: ArrayList<Message>) => {
        //收到vec聊天消息列表
        //刷新VEC聊天页面,更新聊天消息未读数
      }
      this.vecMessageListener.onMessageSent = () => {
        //刷新vec聊天消息列表
      }
      this.vecMessageListener.onNewChatMessageNotify = () => {
        //新消息通知,调接口获取vec聊天消息
      }
      //添加VEC聊天监听
      VisitorClient.getInstance()
        .getVecVisitorManager()
        .addVecMessageListener(vecMessageListener)
      //取消VEC聊天监听
      VisitorClient.getInstance()
        .getVecVisitorManager()
        .removeVecMessageListener(vecMessageListener)

绑定/解绑VEC中IM服务号

//绑定VEC渠道关联中的IM服务号
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .bindVecChat(this.toUserName, this.sessionId)
    //解绑VEC渠道关联中的IM服务号
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .unbindVecChat()

请求VEC聊天消息

//在onNewChatMessageNotify中收到有新消息之后,需要调用该方法请求新消息,新消息会自动缓存在VecVisitorManager中
    VisitorClient.getInstance()
        .getVecVisitorManager()
        .requestVecMessage(mContext)

获取VEC聊天消息列表

let messages:Message[] = VisitorClient.getInstance()
        .getVecVisitorManager()
        .getMessages()
        .convertToArray()

获取VEC满意度评价设置

let enquiryData?: EnquiryInvite = AgoraMessage.getInstance()
        .getEnquiryData()

提交VEC满意度评价

//visitorId:访客ID;rtcSessionId:VEC会话ID;currentScore:当前星级;comment:备注内容;selectedTags;selectedTags:选中的标签列表;
    VisitorClient.getInstance()
                    .getVecVisitorManager()
                    .submitEvaluate(visitorId, rtcSessionId, currentScore, comment, selectedTags)