目录

鸿蒙访客端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