weihu-agent-sdk
座席端SDK
适用版本weihu-agent-sdk_1.1.47
使用SDK之前,请确保你有一个可使用的SIP话机或使用WebRTC插件, 用于完成通话
DEMO获取
获取demo, 点击下载
安装
<script src="/weihu-agent-sdk/weihu-agent-sdk_1.1.47.js"></script>
or
npm install weihu-agent-sdk
快速使用
import WeihuAgentSdk from 'weihu-agent-sdk';
const op = {
el: '#ElementId',
url: 'WS地址',
agentNumber: '座席工号',
password: '座席密码',
companyShortName: '企业简称'
}
const weihuAgentSdk = new WeihuAgentSdk(op);
weihuAgentSdk.call('21000');
weihuAgentSdk.on('MakeCall', (res) => {
// 外呼发起
});
weihuAgentSdk.on('After', (res) => {
// 通话结束
});
初始化配置 SDKOptions
在new WeihuAgentSdk(options)中,options配置项如下:
远程websocket服务地址
使用该应用的企业简称,可以在OBC查看。
登录的目标坐席工号。
登录的目标坐席密码。
远程队列服务账号。
远程队列服务密码。
远程队列服务订阅地址。
远程队列服务连接Virtual Host地址。
接收一个元素选择器,用于指定SDK的UI控件的显示位置, 不传则不展示UI控件。
<div id="sdk-box"></div>
const sdk = new WeihuAgentSdk({
el: '#sdk-box',
...
});
如果配置正确, 会有如图控件出现在页面上的指定元素内。

ws链接心跳间隔, 必须大于0。
请求超时时间。
最大重连次数, 当链接失败或链接关闭时, 会自动发起重新链接, 连续重连次数达到该值的时候会停止重连, 连接成功之后会重新计算, 配置时请注意不要超过浏览器的最大链接数量, 以下是各个浏览器的最大链接数量, 以供参考: Chrome: 256个 FireFox: 200个 safari: 1273个
是否关闭下载日志
只有当loginType为3的时候才生效
指定WebRTC话机构造函数, 未指定则在全局对象`window`上查找 `SoftPhoneSdk`, 当座席成功登录之后, 话机会自动注册, 并用采用默认配置进行通话
import WeihuAgentSdk from 'weihu-agent-sdk';
import SoftPhoneSdk from 'soft-phone-sdk';
const weihuAgentSdk = new WeihuAgentSdk({
loginType: 3,
softPhoneFactory: SoftPhoneSdk,
...
});
const loginAndReconnect = () => {
// 获取软话机实例, 用于对话机操作
const softPhoneInstance = weihuAgentSdk.getSoftPhoneInstance();
softPhoneInstance.on('Registered', () => {
console.log('话机注册完成');
})
}
weihuAgentSdk.on('Login', () => loginAndReconnect());
weihuAgentSdk.on('Reconnect', () => loginAndReconnect());
配合WebRTC话机
当前版本SDK内置了WebRTC话机, 在https环境中使用loginType: 3, 自动就会使用WebRTC话机
API
在const sdk = new WeihuAgentSdk(options)中,可以通过sdk直接调用的方法。
获取当前SDK版本号。
获取当前登录类型
接收一个SDK配置对象,将当前实例再次初始化,new WeihuAgentSdk(options)会自动调用,当你需要重新初始化SDK的时候可以使用, 失败会抛异常。
发起ws连接请求,返回一个连接实例,new WeihuAgentSdk(options)会自动调用,当你需要手动建立新连接的时候可以使用。
使用初始化时候的配置进行登录, 或指定配置进行登陆。
LoginOptions成员如下:
| 属性名 | 类型 | 含义 | 是否必填 |
|---|---|---|---|
| agentNumber | string | 座席工号 | 是 |
| password | string | 座席密码 | 是 |
| companyShortName | string | 企业简称 | 是 |
| loginType | number | 登录话机类型 | 1 sip话机; 2 手机; 3 WebRTC话机 |
退出当前座席。
退出并断开连接,通话期间不允许断开。
指定被叫,发起呼叫, calledType是呼叫类型 1为坐席号,2为手机。
挂断当前通话,拨通与呼叫中都可以使用。
将当前座席的状态设置为忙碌Busy, 可以指定忙碌类型, 登录时会返回可选的忙碌类型。
将当前座席的状态设置为空闲Idle。
开启静音, 通话中可使用。
解除静音, 开启静音后可使用。
转接当前正在进行的通话,target表示要转接的目标,transferType表示转接目标的号码类型,1座席工号, 2手机号, 3技能组ID, 4 IVR模版ID。
发起咨询,consultTarget表示要咨询的目标。
咨询转接。
会议或三方通话。
on(eventName: string, callback: Function): string
对
sdk的事件进行监听,当事件触发时调用callback, 返回一个监听的uuid用于取消监听, 支持的事件名称在EventMap部分找到。
const uuid = sdk.on('Open', data => {
// 链接建立成功
})
once(eventName: string, callback: Function): string
对
sdk的事件进行监听,当事件触发时调用callback, 返回一个监听的uuid用于取消监听, 支持的事件名称在EventMap部分找到, 与on不同的是,once绑定的事件在触发之后会自动解绑, 一次绑定只会触发一次。
const uuid = sdk.once('Open', data => {
// 链接建立成功
})
取消一个SDK的事件监听, 需要指定eventName, 可以使用指定函数引用或监听的uuid。
sdk.off('Open', uuid);
// or
sdk.off('Open', functionPointer);
setUserdata(userdata: string)
指定用户透传数据, 后续所有事件的回传数据都会携带。isConnected(): boolean
是否已链接
是否已登录
当前使用的软话机实例, 用于对话机操作
班长座席 API
以下AIP的使用,需要当前登录座席是班长。
发起一次监控请求。
开启监控, 自动发起监控请求 interval 是请求间隔, 默认两秒, filter 是监控信息的过滤, 当传递filter时, 必须包含groupId
| 属性名 | 类型 | 含义 |
|---|---|---|
| SurveillanceFilter.groupId | string |
技能组ID |
| SurveillanceFilter.agentNumber | string |
座席工号 |
| SurveillanceFilter.agentName | string |
座席名称 |
| SurveillanceFilter.agentState | string |
座席状态 |
| SurveillanceFilter.callDirection | number |
呼入方向,0 呼入,1 呼出 |
关闭监控
强制空闲,target表示目标座席工号。
强制忙碌,target表示目标座席工号。
强制退出,target表示目标座席工号。
监听通话,target表示目标座席工号,目标必须处于通话中。
强制挂断通话,target表示目标座席工号,目标必须处于通话中。
强制插入通话,target表示目标座席工号,目标必须处于通话中。
拦截通话,target表示目标座席工号,目标必须处于通话中。
获取指定座席工号的状态。
获取技能组下的空闲坐席, 通过监听IdleAgent事件拿到数据。
获取所有技能组, 通过监听GroupInfo事件拿到数据。
获取可预测外呼的技能组。
WebRTC话机相关API
当使用内置WebRTC话机时, 可以使用一下方法快速操作话机, 更多操作话机的方法请使用getSoftPhoneInstance
获取话机是否注册
发起话机注册
取消话机注册
取消话机注册, 并断开链接
事件 EventMap
可以通过sdk.on方法绑定或解绑并取得响应数据的事件名称集合。
sdk.on('Login', res => { ... })
所有事件都会包含以下公共信息:
| 属性名 | 类型 | 含义 |
|---|---|---|
| sequence | number |
请求发起时间戳 |
| eventTime | number |
事件触发时间戳 |
| nowState | string |
座席当前状态 |
| userdata | string |
用户透传数据, 使用setUserdata指定 |
| type | string |
事件标识, 固定取值event |
| event | string |
事件名称 |
| data | any |
事件数据, 具体类型查看对应事件的回传数据 |
| ivrParam | string |
一个json字符串, ivr交互参数,只有AgentRinging AgentAnswer Conversation After事件会携带 |
可监听的事件名称如下:
成功建立链接
回传数据类型: Frame 链接相关信息
建立链接失败
回传数据类型: Event 错误信息
链接关闭
回传数据类型: Frame 链接相关信息
登陆成功
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| domain | string |
SIP话机注册域 |
| sipId | string |
SIP号 |
| sipPassword | string |
SIP密码 |
| token | string |
登陆SDK身份标识 |
| agentType | number |
座席类型 0 普通座席;1 班长 |
| groupIdList | Array<string> |
座席所属技能组Id集合 |
| busyType | string |
所在企业配置的可选忙碌类型 |
退出成功
回传数据类型: null
重链成功, 只有首次登录和退出后的登录会触发Login, 在缓存token信息失效之前, 都会触发Reconnect, 用于恢复座席状态
回传数据类型: `Object`
| 属性名 | 类型 | 含义 |
|---|---|---|
| domain | string |
SIP话机注册域 |
| sipId | string |
SIP号 |
| sipPassword | string |
SIP密码 |
| token | string |
登陆SDK身份标识 |
| agentType | number |
座席类型 0 普通座席;1 班长 |
| groupIdList | Array<string> |
座席所属技能组Id集合 |
| busyType | string |
所在企业配置的可选忙碌类型 |
制闲操作成功
回传数据类型: null
制忙操作成功
回传数据类型: null
发起通话成功
回传数据类型: null
发起通话失败
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| cause | string |
失败原因描述 |
座席振铃
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| caller | string |
主叫 |
| called | string |
被叫 |
| inQueueTime | number |
进入队列时间戳 |
| callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
座席应答
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| caller | string |
主叫 |
| called | string |
被叫 |
| inQueueTime | number |
进入队列时间戳 |
| callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
被叫振铃
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| caller | string |
主叫 |
| called | string |
被叫 |
| inQueueTime | number |
进入队列时间戳 |
| callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
被叫应答
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| caller | string |
主叫 |
| called | string |
被叫 |
| inQueueTime | number |
进入队列时间戳 |
| callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
通话中
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| caller | string |
主叫 |
| called | string |
被叫 |
| inQueueTime | number |
进入队列时间戳 |
| callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
| callType | string |
normal(正常呼叫),consult(咨询),transfer(转接)listen(监听),forceInsert(强插),intercept(拦截) |
发起转接, 只有在通话中才能发起
回传数据类型: null
转接中
回传数据类型: null
转接失败
回传数据类型: null
发起监听
回传数据类型: null
监听中
回传数据类型: null
监听失败
回传数据类型: null
强制断开通话
回传数据类型: null
强制插入通话
回传数据类型: null
强制插入通话中
回传数据类型: null
强制插入通话失败
回传数据类型: null
拦截通话
回传数据类型: null
拦截通话中
回传数据类型: null
拦截失败
回传数据类型: null
After
话后 回传数据类型:
Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| caller | string |
主叫 |
| called | string |
被叫 |
| inQueueTime | number |
进入队列时间戳 |
| callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
| recordPath | string |
录音文件路径 |
| hangupDirection | number |
挂机方向,0本端,1对端 |
| beginTime | number |
开始时间 |
| ringTime | number |
振铃时间 |
| answerTime | number |
应答时间 |
| endTime | number |
结束时间 |
| cause | number |
挂机原因cause码 |
| data | number |
挂机原因说明 |
| callType | string |
normal(正常呼叫),consult(咨询),transfer(转接)listen(监听),forceInsert(强插),intercept(拦截) |
| agentAutoIdle | number |
是否开启自动空闲, 1 开启 0 关闭 |
| agentAutoIdleTime | number |
自动空闲间隔秒, agentAutoIdle为0时不生效 |
被踢出
回传数据类型: undefined
话机异常, 当话机取消注册时触发, 同时座席会退出
回传数据类型: null
队列等待消息
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| groupID | number |
技能组 |
| groupWaitNumber | number |
当前技能组等待数量 |
| isInQueue | number |
1加入队列,0移出队列 |
| handleAgentID | string |
分配的座席工号 |
| data | Array<Info> |
分配的座席工号 |
| Info.caller | string |
主叫 |
| Info.called | string |
被叫 |
| Info.groupID | number |
技能组ID |
| Info.inQueueTime | number |
加入队列时间 |
GroupInfo
技能组信息
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| groupList | Array<Group> |
座席信息集合 |
| Group.id | string |
技能组ID |
| Group.name | string |
技能组名称 |
| Group.type | number |
技能组类型 |
IdleAgent
技能组信息
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| agentList | Array<Agent> |
指定技能组下的空闲座席集合 |
| Agent.agentId | string |
座席工号 |
| Agent.agentNumber | string |
座席工号 |
| Agent.agentName | string |
座席名称 |
座席监控信息
回传数据类型: Object
| 属性名 | 类型 | 含义 |
|---|---|---|
| infoList | Array<AgentInfo> |
分配的座席工号 |
| AgentInfo.companyId | number |
座席企业ID |
| AgentInfo.agentID | number |
座席ID |
| AgentInfo.agentNumber | string |
座席工号 |
| AgentInfo.agentName | string |
座席姓名 |
| AgentInfo.nowState | string |
当前状态 |
| AgentInfo.operatingTime | number |
当前状态维持时间毫秒数 |
| AgentInfo.peerId | string |
通话对端(非通话中为空) |
| AgentInfo.groupList | Array<GroupInfo> |
座席所属技能组 |
| GroupInfo.id | string |
座席所属技能组id |
| GroupInfo.name | string |
座席所属技能组名称 |
UI操作异常事件
回传数据类型: Exception
| 属性名 | 类型 | 含义 |
|---|---|---|
| version | string |
当前SDK版本信息 |
| message | string |
错误描述信息 |
异常通常产生自非法的数据, 配置, 参数和方法调用的时机与顺序, 目前可能需要捕获的异常有三个场景, 捕获这些异常可以提供给使用者更多提示信息。
1. 通过sdk句柄调用方法;
2. sdk自带UI使用过程中;
3. 发送命令之后, 来自远端回执的异常;
const weihuAgentSdk = new WeihuAgentSdk({...});
/**
* 因为call方法需要传入一个被叫, 这里没有传入, 所以会抛出一个异常
*/
weihuAgentSdk.call();
/**
* 捕获异常
*/
try {
weihuAgentSdk.call();
} catch (e) {
console.log(e.message); // 被叫不能为空
}
使用sdk自带UI过程中和来自远端回执的异常捕获方式相同, 由于方法不被开发人员调用, 所以不能直接使用try catch, 监听Exception事件捕获异常。
// <div id="sdk-box"></div>
const weihuAgentSdk = new WeihuAgentSdk({ el: '#sdk-box', ... });
/**
* 操作控件, 不填写被叫号码的情况, 直接点击呼叫按钮
*
* 捕获异常
*/
weihuAgentSdk.on('Exception', e => {
console.log(e.message); // 被叫不能为空
})
话后状态cause说明
进入话后状态时, 会携带cause和data, 说明进入话后的原因, 以下是对照表:
| 枚举 | cause | 说明 |
|---|---|---|
| NORMAL_CLEARING | 0 | 正常结束 |
| FILE PLAYED | 0 | 正常结束 |
| NONE | 0 | 正常结束 |
| OK | 0 | 正常结束 |
| SESSION_TIME_OUT | 901 | session超时 |
| ORIGINATE_TIME_OUT | 902 | 发起呼叫超时 |
| UNALLOCATED_NUMBER | 1001 | 主叫号码不可用 |
| NO_ROUTE_TRANSIT_NET | 1002 | 被叫号码不可用 |
| NO_ROUTE_DESTINATION | 1003 | 找不到被叫 |
| NO_ROUTE | 1004 | 找不到路由 |
| CHANNEL_UNACCEPTABLE | 1006 | 通话失败 |
| CALL_AWARDED_DELIVERED | 1007 | 呼叫前转 |
| USER_BUSY | 1017 | 用户忙 |
| BUSY | 1017 | 用户忙 |
| NO_USER_RESPONSE | 1018 | 被叫无响应 |
| NO_ANSWER | 1019 | 久叫不应 |
| CAUSE480 | 1016 | 被叫未应答 |
| SUBSCRIBER_ABSENT | 1020 | 被叫号码无效 |
| CALL_REJECTED | 1021 | 拒绝应答 |
| NUMBER_CHANGED | 1022 | 号码改变 |
| REDIRECTION_TO_NEW_DESTINATION | 1023 | 重定向到新的号码 |
| EXCHANGE_ROUTING_ERROR | 1025 | 路由错误 |
| DESTINATION_OUT_OF_ORDER | 1027 | 呼叫受限 |
| INVALID_NUMBER_FORMAT | 1028 | 无效的号码格式 |
| FACILITY_REJECTED | 1029 | 被叫拒接 |
| RESPONSE_TO_STATUS_ENQUIRY | 1030 | 状态查询响应 |
| NORMAL_UNSPECIFIED | 1031 | 未指定错误 |
| NORMAL_CIRCUIT_CONGESTION | 1034 | 通信电路错误 |
| NETWORK_OUT_OF_ORDER | 1038 | 网络不可达 |
| NORMAL_TEMPORARY_FAILURE | 1041 | 临时故障 |
| SWITCH_CONGESTION | 1042 | 交换机繁忙 |
| ACCESS_INFO_DISCARDED | 1043 | 访问信息被丢弃 |
| REQUESTED_CHAN_UNAVAIL | 1044 | 请求不可用 |
| PRE_EMPTED | 1045 | 空 |
| FACILITY_NOT_SUBSCRIBED | 1050 | 设备受限 |
| OUTGOING_CALL_BARRED | 1052 | 外呼阻塞 |
| INCOMING_CALL_BARRED | 1054 | 呼入阻塞 |
| BEARERCAPABILITY_NOTAUTH | 1057 | 承载能力未经授权 |
| BEARERCAPABILITY_NOTAVAIL | 1058 | 目前暂不提供承载能力 |
| SERVICE_UNAVAILABLE | 1063 | 服务不可用 |
| UNKNOWN | 1063 | 服务不可用 |
| BEARERCAPABILITY_NOTIMPL | 1065 | 没有权限使用该功能 |
| USER_NOT_REGISTERED | 1066 | 话机未注册 |
| CHAN_NOT_IMPLEMENTED | 1067 | 找不到路由 |
| FACILITY_NOT_IMPLEMENTED | 1069 | 设备不支持所请求的服务 |
| SERVICE_NOT_IMPLEMENTED | 1079 | 未实现所请求的服务 |
| INVALID_CALL_REFERENCE | 1081 | 当前网络不支持此功能 |
| INCOMPATIBLE_DESTINATION | 1088 | 不兼容的目的地 |
| INVALID_MSG_UNSPECIFIED | 1095 | 无效消息 |
| MANDATORY_IE_MISSING | 1096 | 消息不完整 |
| MESSAGE_TYPE_NONEXIST | 1097 | 无法识别的消息类型 |
| WRONG_MESSAGE | 1098 | 当前状态下不能处理该消息 |
| IE_NONEXIST | 1099 | 未识别的参数 |
| INVALID_IE_CONTENTS | 1100 | 编码未实现 |
| WRONG_CALL_STATE | 1101 | 消息与呼叫状态不兼容 |
| RECOVERY_ON_TIMER_EXPIRE | 1102 | 呼叫超时 |
| MANDATORY_IE_LENGTH_ERROR | 1103 | 参数不存在或未实现 |
| PROTOCOL_ERROR | 1111 | 协议错误 |
| INTERWORKING | 1127 | 已完成互通呼叫 |
| NO_CALLNUM | 1128 | 未获取到码号配置 |
| SUCCESS | 0 | 成功 |
| FILE NOT FOUND | 1401 | 文件不存在 |
| PLAYBACK ERROR | 1402 | 放音失败 |
| ORIGINATOR_CANCEL | 1487 | 呼叫取消 |
| CANCEL | 1487 | 呼叫取消 |
| CRASH | 1500 | 紧急故障 |
| SYSTEM_SHUTDOWN | 1501 | 系统关闭 |
| LOSE_RACE | 1502 | 丢失呼叫 |
| MANAGER_REQUEST | 1503 | 强制挂机 |
| BLIND_TRANSFER | 1600 | 盲转 |
| ATTENDED_TRANSFER | 1601 | 咨询转 |
| ALLOTTED_TIMEOUT | 1602 | 分配超时 |
| USER_CHALLENGE | 1603 | 用户竞争 |
| MEDIA_TIMEOUT | 1604 | 媒体超时 |
| PICKED_OFF | 1605 | 被拦截 |
| PROGRESS_TIMEOUT | 1607 | 振铃超时 |
| INVALID_GATEWAY | 1608 | 网关不可用 |
| GATEWAY_DOWN | 1609 | 网关关闭 |
| INVALID_URL | 1610 | 错误的URL |
| INVALID_PROFILE | 1611 | 错误的配置 |
| NO_PICKUP | 1612 | 没有摘机 |
| SRTP_READ_ERROR | 1613 | SRTP读取错误 |
| NO_SIPGATEWAY | 1614 | 未获取到可用网关 |
| INVALID_UUID_ERROR | 1615 | 无效的uuid |
| Cannot stop record session! | 3000 | 无法停止录音 |
| No such channel! | 1004 | 呼叫不存在 |
| NONE | 0 | 空 |
| NO_SUCH_FS | 1129 | 找不到fs |
| NO_PNS | 3001 | 未找到绑定的隐私号信息 |
| NO_CALL_LOG | 3005 | 未找到回拨信息 |
| NO_PNS_ERROR | 3002 | 隐私号绑定信息有误 |
| DISPLAY_CALLER_EMPTY | 3003 | 外显号码池为空 |
| TEL_X_IS_NULL | 3004 | 隐私号小号为空 |
| INBOUND_BRIDGE_ERROR | 3100 | 呼入转接失败 |
| NO_REASON | 8888 | 未找到该错误原因 |
| EXECUTE_SERVICE_OFFLINE | 2002 | 转接到的模块不在线 |
| RS_FLOW_TIMEOUT | 2003 | 机器人配置错误 |
| RS_FLOW_BRIDGE_FAILURE | 2004 | 机器人转接失败 |
| RS_FLOW_RESPONSE_TIMEOUT | 2005 | 机器人响应超时 |
| RINGING_BUSY | 2101 | 用户占线 |
| RINGING_NOANSWER | 2102 | 无人接听 |
| LINE_BUSY | 2103 | 网络忙 |
| LINE_FAULT | 2104 | 线路故障 |
| STATUS_NOTINAREA | 2105 | 不在服务区 |
| STATUS_PAUSE | 2106 | 暂停服务 |
| STATUS_STOP | 2107 | 停机 |
| STATUS_UNABLECONNECT | 2108 | 暂时无法接通 |
| STATUS_SHUTDOWN | 2109 | 关机 |
| STATUS_STOPANDKEEP | 2110 | 停机保号 |
| STATUS_LIMITED | 2111 | 呼叫受限 |
| STATUS_WAITING | 2112 | 呼叫等待 |
| STATUS_TRANSFER | 2113 | 呼叫转移 |
| NUMBER_EMPTY | 2114 | 空号 |
| NUMBER_WRONG | 2115 | 号码错误 |
| NUMBER_INVALID | 2116 | 号码无效 |
| NUMBER_FOREIGN | 2117 | 外地号码需加零 |
| NUMBER_LOCAL | 2118 | 本地不需加零 |
| GLOBAL_BLACKLIST | 4001 | 全局黑名单 |
| GROUP_BLACKLIST | 4002 | 技能组黑名单 |