1.1.2 • Published 5 months ago

@94ai/aisdk v1.1.2

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

概述

主体功能用于来电接听前后,订阅获取关于会话内容的消息推送,实现弹屏展示通话记录内容的相关业务。

旧版弹屏sdk会在坐席接听那刻一次性推送ai和用户聊天的全部消息

新版弹屏sdk会在话术触发转人工后,开始不断推送ai和用户聊天的消息,以及坐席接听后和用户的聊天记录,直到用户或坐席挂断通话。

一个坐席只允许一处登录,多处登录会互踢,被踢的坐席默认会定时3s尝试重新登录连接,此时如果异地登录的账号仍在线则会一直做检测能否登录,直到异地登录的账号退出,多处登录互踢的情况同理。

安装

npm设置私库源

  • 参考 《获取94ai前端sdk通用流程》 密码:dbb9
  • 执行install命令安装@94ai/aisdk
$ yarn add @94ai/aisdk
# or
$ npm i @94ai/aisdk
# or
$ pnpm add @94ai/aisdk

获取javascript文件

  • 参考 《获取94ai前端sdk通用流程》 密码:dbb9
  • 执行npx -y @94ai/aisdk -- sdk-umd,之后在当前执行命令路径下获取到94aisdk-1.1.2.umd.min.js

tip 获取旧版sdk 执行npx -y @94ai/aisdk -- sdk-umd --old,之后在当前执行命令路径下获取到94aisdk-1.1.1-old.umd.min.js

使用

初始化&销毁SDK实例

作为npm包使用

import { aiSDK } from '@94ai/aisdk' // or const { aiSDK } = require('@94ai/aisdk')

export interface UserInfo {
  userId: string,
  userType: string,
  token: string
  companyId: string
  orgId: string
  oldId: string
  chainId: string
  account:string
  userName: string
  userTypeName: string
}

export interface SDKConfig {
  corpId: string,
  secretId: string,
  agentId: string,
  onSuccess?: Function,
  onError?: Function,
  onMessage?: Function,
  onReconnect?: Function
  onSessionEnd?: Function
  onKicked?: Function
}

export interface PushData {
  /**
   * 任务 ID
   */
  taskId: string
  /**
   * 分机号
   */
  extensionNumber: string
  /**
   * 外呼 ID
   */
  callid: string
  /**
   * 外呼 ID
   */
  callId: string
  /**
   * 外呼类型
   */
  callType: CallType
  /**
   * 意向标签
   */
  intentTag: string
  /**
   * 外呼号码
   */
  number: string
  /**
   * 号码 ID
   */
  numberMD5: string
  /**
   * 分配坐席 ID
   */
  agentId: number
  /**
   * 坐席标签
   */
  agentTag: string
  /**
   * 用户标签
   */
  tag: string
  /**
   * AI 话术 ID
   */
  templateId: string
  chats: {
    /**
     * 说话内容
     */
    "content": string,
    /**
     * 说话时间
     */
    "createTime": string,
    /**
     * 说话号码
     */
    "fromNumber": string
  }[]
}

export type Context = SDKConfig & UserInfo

aiSDK.init({  // 👈 初始化SDK实例连接
  secretId: '50ab02d3a42f788e6d8f7da1c01a68d7', //必填,secretID
  corpId: '392f9b20cf5ff706', //必填,公司ID
  agentId: '1860', //必填,坐席ID
  onError(err: Error, context: Context) { // 👈 所有出错信息回调函数
    console.log(err.message)
  },
  onSuccess(context: Context) {
    console.log('注册订阅成功')
  },
  onKicked(context: Context) { // 👈  一个坐席只允许一处登录,多处登录会互踢,被踢的坐席默认会定时3s尝试重新登录连接,此时如果异地登录的账号仍在线则会一直做检测能否登录,直到异地登录的账号退出,多处登录互踢的情况同理。
    console.log('坐席异地登录,当前被踢出') // 如果不需要重连机制可以在这里执行aiSDK.destroy(),之后如果需要手动连接请再执行aiSDK.init(param)
  },
  onReconnect(context: Context) { // 👈 当出现服务异常或网络异常或被踢导致连接终断,会尝试重连,重连前会回调该函数,如果不需要重连机制也可以在这里执行aiSDK.destroy()
    console.log('尝试重连中...')
  },
  onSessionEnd(callId: string, context: Context) {  // 👈 当一个外呼会话结束会执行此回调
    console.log('当前呼叫会话callId:' + callId + '已结束' )
  },
  onMessage(message: PushData, context: Context) {
    // 来电弹屏信息回调函数  👈 根据message.callId区分不同会话,同个会话callId相同会有多次推送,一个坐席会话结束订阅推送会自动终止查询,如需提前终止查询可以执行aiSDK.stopPolling()
    console.log(message)
    console.log('')
  },
})

// 如果使用的是vue,参考如下销毁,其他框架同理
onUnmounted(() => {
  aiSDK.destory() // 👈 销毁SDK实例&连接
})

作为JavaScript使用

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>94AI-SDK Demo v1.1.1</title>
</head>
<body>
94AI-SDK Demo
<div style="padding: 10px">
  <div style="padding: 5px">secretID secretId: <input type="text" id="secretId"></div>
  <div style="padding: 5px">公司ID corpId: <input type="text" id="corpId"></div>
  <div style="padding: 5px"> 坐席ID agentId: <input type="text" id="agentId"></div>
  <button type="button" id="submit">注册</button>
  <button type="button" id="logout">退出</button>
</div>
<div id="angent-message-container"></div>
<script src="94aisdk-1.1.2.umd.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
  var angentMessageContainer = document.getElementById('angent-message-container')
  var secretId = document.getElementById('secretId')
  var corpId = document.getElementById('corpId')
  var agentId = document.getElementById('agentId')
  var secretId_storage = localStorage.getItem('secretId')
  var corpId_storage = localStorage.getItem('corpId')
  var agentId_storage = localStorage.getItem('agentId')
  // 设置默认值
  secretId.value = secretId_storage ? secretId_storage : 'db4985b726d673db5db408901b873f3e'
  corpId.value = corpId_storage ? corpId_storage : '17687fc0006b7248'
  agentId.value = agentId_storage ? agentId_storage : '1859'
  var dynamicGenerateDom = (message) => {
    var container = document.createElement('div')
    var agentIdShow = document.createElement('div')
    var agentTag = document.createElement('div')
    var callId = document.createElement('div')
    var callType = document.createElement('div')
    var number = document.createElement('div')
    var numberMD5 = document.createElement('div')
    var templateId = document.createElement('div')
    var tag = document.createElement('div')
    var taskId = document.createElement('div')
    var hr1 = document.createElement('hr')
    var hr2 = document.createElement('hr')
    var chatsLog = document.createElement('div')
    agentIdShow.innerHTML = `<span>agentId:  ${ message.agentId }</span>`
    agentTag.innerHTML = `<span>agentTag:  ${ message.agentTag }</span>`
    callId.innerHTML = `<span>callId:  ${ message.callId }</span>`
    callType.innerHTML = `<span>callType:  ${ message.callType }</span>`
    number.innerHTML = `<span>number:  ${ message.number }</span>`
    numberMD5.innerHTML = `<span>numberMD5:  ${ message.numberMD5 }</span>`
    templateId.innerHTML = `<span>templateId:  ${ message.templateId }</span>`
    tag.innerHTML = `<span>tag:  ${ message.tag }</span>`
    taskId.innerHTML = `<span>taskId:  ${ message.taskId }</span>`
    chatsLog.innerHTML = `<span>chatsLog:  ${ JSON.stringify(message.chats) }</span>`
    container.id = message.callId
    container.appendChild(agentIdShow)
    container.appendChild(agentTag)
    container.appendChild(callId)
    container.appendChild(callType)
    container.appendChild(number)
    container.appendChild(numberMD5)
    container.appendChild(templateId)
    container.appendChild(tag)
    container.appendChild(taskId)
    container.appendChild(hr1)
    container.appendChild(chatsLog)
    container.appendChild(hr2)
    angentMessageContainer.appendChild(container)
  }
  var modifyDialogueRecord = (conversation, message) => {
    conversation.children[0].innerHTML = `<span>agentId:  ${ message.agentId }</span>`
    conversation.children[1].innerHTML = `<span>agentTag:  ${ message.agentTag }</span>`
    conversation.children[2].innerHTML = `<span>callId:  ${ message.callId }</span>`
    conversation.children[3].innerHTML = `<span>callType:  ${ message.callType }</span>`
    conversation.children[4].innerHTML = `<span>number:  ${ message.number }</span>`
    conversation.children[5].innerHTML = `<span>numberMD5:  ${ message.numberMD5 }</span>`
    conversation.children[6].innerHTML = `<span>templateId:  ${ message.templateId }</span>`
    conversation.children[7].innerHTML = `<span>tag:  ${ message.tag }</span>`
    conversation.children[8].innerHTML = `<span>taskId:  ${ message.taskId }</span>`
    conversation.children[10].innerHTML = `<pre>chatsLog:  ${ JSON.stringify(message.chats, null, 4) }</pre>`
  }
  submit.onclick = () => {
    // 保存输入的id信息
    localStorage.setItem('secretId', secretId.value)
    localStorage.setItem('corpId', corpId.value)
    localStorage.setItem('agentId', agentId.value)
    var aiSDKObject = {
      // 开发环境
      secretId: secretId.value, // 必填,secretID
      corpId: corpId.value, // 必填,公司ID
      agentId: agentId.value, // 必填,坐席ID
      onError(err, context) { // 👈 所有出错信息回调函数
        console.log(err.message)
      },
      onSuccess(context) {
        console.log('注册订阅成功')
      },
      onKicked(context) { // 👈 一个坐席只允许一处登录,多处登录会互踢,被踢的坐席默认会定时3s尝试重新登录连接,此时如果异地登录的账号仍在线则会一直做检测能否登录,直到异地登录的账号退出,多处登录互踢的情况同理。
        console.log('坐席异地登录,当前被踢出') // 如果不需要重连机制可以在这里执行aiSDK.destroy(),之后如果需要手动连接请再执行aiSDK.init(param)
      },
      onReconnect(context) { // 👈 当出现服务异常或网络异常或被踢导致连接终断,会尝试重连,重连前会回调该函数,如果不需要重连机制也可以在这里执行aiSDK.destroy(),,之后如果需要手动连接请再执行aiSDK.init(param)
        console.log('尝试重连中...')
      },
      onSessionEnd(callId, context) {  // 👈 当一个【外呼会话结束】时会执行此回调,可以用来执行【销毁】 挂载到页面已结束的会话记录
        console.log('当前呼叫会话callId:' + callId + '已结束')
      },
      // 来电弹屏信息回调函数
      onMessage(message, context) {
        const conversation = document.getElementById(message.callId)
        if (conversation) {// 如果是同一会话,则更新
          modifyDialogueRecord(conversation, message)
        } else { // 如果是不同会话则创建
          dynamicGenerateDom(message)
        }
      },
      // 呼叫中
      onCalling(callbackData, context) {
        console.log('===============呼叫中start报文===============')
        console.log('callbackData:' + callbackData)
        console.log(callbackData)
        console.log('context:')
        console.log(context)
        console.log('===============呼叫中end报文===============')
      },
      // 转接人工
      onEavesdrop(callbackData, context) {
        console.log('===============转接人工start报文===============')
        console.log('callbackData:' + callbackData)
        console.log(callbackData)
        console.log('context:')
        console.log(context)
        console.log('===============转接人工end报文===============')
      },
      // 接听
      onAnswer(callbackData, context) {
        console.log('===============接听start报文===============')
        console.log('callbackData:' + callbackData)
        console.log(callbackData)
        console.log('context:')
        console.log(context)
        console.log('===============接听end报文===============')
      },
      // 挂断
      onHangup(callbackData, context) {
        console.log('===============挂断start报文===============')
        console.log('callbackData:' + callbackData)
        console.log(callbackData)
        console.log('context:')
        console.log(context)
        console.log('===============挂断end报文===============')
      }
    }
    aiSDK.init(aiSDKObject) // 初始化SDK
  }
  logout.onclick = () => {
    aiSDK.destroy()
  }
})
document.addEventListener('unload', () => {
  aiSDK.destroy()
})
</script>
</body>
</html>

secretId(必填)

类型:string

由 94AI 运营提供

corpId(必填)

类型:string

由 94AI 运营提供

sid(必填)

类型:string

管理员账号登录 94AI 决策平台,进入坐席管理列表页,查看坐席 ID

参数说明

onSuccess(context)

返回值:void

onError(err,context)

返回值:void

参数名中文名类型必填说明
err.message错误信息StringY例:秘钥错误!企业不存在或者accessToken不存在!坐席不存在!

onReconnect(context)

返回值:void

onKicked(context)

返回值:void

onSessionEnd(callId, context)

返回值:void

onMessage(msg,context)

返回值:void

参数名中文名类型必填说明
msg.agentId分配坐席 IDNumberY分配坐席 ID
msg.agentTag坐席标签StringY建议填写坐席在贵司业务系统唯一标识,用于查询对应 agentId;可以为空。
msg.callId外呼 IDStringY例:9b2eb6b8-7a27-4357-b5ec-104450086e24
msg.callType外呼类型NumberY1001:坐席-人工外呼1002:坐席-AI 外呼-不转人工1003:坐席-AI 外呼-接通转人工1004:坐席-AI 外呼-智能转人工2001:批量-预测外呼2002:批量-AI 外呼-不转人工2003:批量-AI 外呼-接通转人工2004:批量-AI 外呼-智能转人工2005:批量-语音通知
msg.number外呼号码StringY外呼号码,需要根据后台设置,控制是否脱敏
msg.numberMD5号码 IDStringY外呼号码 ID
msg.templateIdAI 话术 IDNumberY外呼的话术模板 ID,可以为空
msg.tag用户标签StringY用户标签,最多 50 个字符
msg.taskId任务 IDStringY决策系统中的任务编号
msg.chats对话记录ArrayY聊天记录,可以为空例:{"fromNumber":"0","content": "你好,请问您是王小帅吗?","createTime": "2019-01-09 14:14:19"},{"fromNumber":"7945bd83237335e5376ff44d62e4f0ae","content": "嗯","createTime": "2019-01-09 14:14:20"},{"fromNumber":"0","content": "您在九四平台有一笔贷款,本期应还金额 100 元,已经逾期 1 天了,请问您今天晚上 12 点之前能完成还款吗?","createTime": "2019-01-09 14:14:21"}

chats

参数名中文名类型必填说明
content说话内容StringY说话内容
createTime说话时间StringY说话时间,格式:2019-01-09 14:14:19
fromNumber说话号码StringY说话号码,其中 0 为机器人

Demo:

{
    "number": "13661634186",
    "callId": "1",
    "numberMD5": "md4",
    "templateId": 1,
    "agentTag": "agent tag",
    "agentId": 1,
    "callType": 1,
    "taskId": "1",
    "tag": "tag",
    "chats": [
      {
        "content": "hello world906",
        "createTime": "2021-8-5 19:39:03",
        "fromNumber": "136616325478"
      },
      {
        "content": "hello world559",
        "createTime": "2021-8-5 19:39:03",
        "fromNumber": "136616325478"
      },
      ...
    ]
  }
}