座席端SDK
适用版本agent-sdk_1.1.52
使用SDK之前,请确保你有一个可使用的SIP话机或使用WebRTC插件, 用于完成通话
DEMO获取
获取demo, 点击下载
安装
<script src="/agent-sdk/agent-sdk_1.1.52.js"></script>
or
npm install agent-sdk
快速使用
import AgentSdk from 'agent-sdk';
const op = {
el: '#ElementId',
url: 'WS地址',
agentNumber: '座席工号',
password: '座席密码',
companyShortName: '企业简称'
}
const agentSdk = new AgentSdk(op);
agentSdk.call('21000');
agentSdk.on('MakeCall', (res) => {
// 外呼发起
});
agentSdk.on('After', (res) => {
// 通话结束
});
初始化配置 SDKOptions
在new AgentSdk(options)
中,options
配置项如下:
url: string
必传
远程
websocket
服务地址companyShortName: string
必传
使用该应用的企业简称,可以在
OBC
查看。agentNumber: string
必传
登录的目标坐席工号。
agentPassword: string
必传
登录的目标坐席密码。
connectAccount: string
必传
远程队列服务账号。
connectPassword: string
必传
远程队列服务密码。
subscribePath: string
必传
远程队列服务订阅地址。
host: string
必传
远程队列服务连接
Virtual Host
地址。el: string
default: ''
接收一个元素选择器,用于指定
SDK
的UI控件的显示位置, 不传则不展示UI控件。
<div id="sdk-box"></div>
const sdk = new AgentSdk({
el: '#sdk-box',
...
});
如果配置正确, 会有如图控件出现在页面上的指定元素内。
pingInterval: number
default: 10000
ws
链接心跳间隔, 必须大于0
。timeout: number
default: 5000
请求超时时间。
maxReconnect: number
default: 10
最大重连次数, 当链接失败或链接关闭时, 会自动发起重新链接, 连续重连次数达到该值的时候会停止重连, 连接成功之后会重新计算, 配置时请注意不要超过浏览器的最大链接数量, 以下是各个浏览器的最大链接数量, 以供参考:
Chrome: 256个
FireFox: 200个
safari: 1273个
unDownloadLog: boolean
default: false
是否关闭下载日志
softPhoneFactory: Function
只有当
loginType
为3
的时候才生效指定WebRTC话机构造函数, 未指定则在全局对象
window
上查找SoftPhoneSdk
, 当座席成功登录之后, 话机会自动注册, 并用采用默认配置进行通话
import AgentSdk from 'agent-sdk';
import SoftPhoneSdk from 'soft-phone-sdk';
const agentSdk = new AgentSdk({
loginType: 3,
softPhoneFactory: SoftPhoneSdk,
...
});
const loginAndReconnect = () => {
// 获取软话机实例, 用于对话机操作
const softPhoneInstance = agentSdk.getSoftPhoneInstance();
softPhoneInstance.on('Registered', () => {
console.log('话机注册完成');
})
}
agentSdk.on('Login', () => loginAndReconnect());
agentSdk.on('Reconnect', () => loginAndReconnect());
配合WebRTC话机
当前版本SDK
内置了WebRTC
话机, 在https
环境中使用loginType: 3
, 自动就会使用WebRTC
话机
API
在const sdk = new AgentSdk(options)
中,可以通过sdk
直接调用的方法。
getVersion(): string
获取当前SDK版本号。
getLoginType(): LoginType
获取当前登录类型
init(sdkOption ?: SDKOptions)
接收一个
SDK
配置对象,将当前实例再次初始化,new AgentSdk(options)
会自动调用,当你需要重新初始化SDK
的时候可以使用, 失败会抛异常。connect()
发起
ws
连接请求,返回一个连接实例,new AgentSdk(options)
会自动调用,当你需要手动建立新连接的时候可以使用。login(loginConfig ?: LoginOptions)
使用初始化时候的配置进行登录, 或指定配置进行登陆。
LoginOptions
成员如下:
属性名 | 类型 | 含义 | 是否必填 |
---|---|---|---|
agentNumber | string | 座席工号 | 是 |
password | string | 座席密码 | 是 |
companyShortName | string | 企业简称 | 是 |
loginType | number | 登录话机类型 | 1 sip话机; 2 手机; 3 WebRTC话机 |
logout()
退出当前座席。
break()
退出并断开连接,通话期间不允许断开。
call(called: string, calledType: number = 2, caller ?: string)
指定被叫,发起呼叫,
calledType
是呼叫类型1
为坐席号,2
为手机。caller
是透传指定主叫号码hangup()
挂断当前通话,拨通与呼叫中都可以使用。
busy(busyType ?: string)
将当前座席的状态设置为忙碌
Busy
, 可以指定忙碌类型, 登录时会返回可选的忙碌类型。idle()
将当前座席的状态设置为空闲
Idle
。mute()
开启静音, 通话中可使用。
unMute()
解除静音, 开启静音后可使用。
transferCall (target: string, transferType: number)
转接当前正在进行的通话,
target
表示要转接的目标,transferType
表示转接目标的号码类型,1
座席工号,2
手机号,3
技能组ID,4
IVR模版ID。consult(consultTarget: string)
发起咨询,
consultTarget
表示要咨询的目标。consultTransfer()
咨询转接。
tripartiteCall()
会议或三方通话。
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 => {
// 链接建立成功
})
off(eventName: string, uuidOrFn: string | Function): boolean
取消一个SDK
的事件监听, 需要指定eventName
, 可以使用指定函数引用或监听的uuid
。
sdk.off('Open', uuid);
// or
sdk.off('Open', functionPointer);
setUserdata(userdata: string)
指定用户透传数据, 后续所有事件的回传数据都会携带。isConnected(): boolean
是否已链接
isLogin(): boolean
是否已登录
getSoftPhoneInstance(): object
当前使用的软话机实例, 用于对话机操作
班长座席 API
以下AIP的使用,需要当前登录座席是班长。
surveillance()
发起一次监控请求。
surveillanceStart(filter ?: SurveillanceFilter, interval: number = 2000)
开启监控, 自动发起监控请求
interval
是请求间隔, 默认两秒,filter
是监控信息的过滤, 当传递filter
时, 必须包含groupId
属性名 | 类型 | 含义 |
---|---|---|
SurveillanceFilter.groupId | string |
技能组ID |
SurveillanceFilter.agentNumber | string |
座席工号 |
SurveillanceFilter.agentName | string |
座席名称 |
SurveillanceFilter.agentState | string |
座席状态 |
SurveillanceFilter.callDirection | number |
呼入方向,0 呼入,1 呼出 |
surveillanceEnd()
关闭监控
forceIdle(target: string)
强制空闲,
target
表示目标座席工号。forceBusy(target: string)
强制忙碌,
target
表示目标座席工号。forceLogout(target: string)
强制退出,
target
表示目标座席工号。listen(target: string)
监听通话,
target
表示目标座席工号,目标必须处于通话中。forceBreak(target: string)
强制挂断通话,
target
表示目标座席工号,目标必须处于通话中。forceInsert(target: string)
强制插入通话,
target
表示目标座席工号,目标必须处于通话中。intercept(target: string)
拦截通话,
target
表示目标座席工号,目标必须处于通话中。getStateByAgentId(agentNumber: string)
获取指定座席工号的状态。
getIdleAgentByGroupId(groupId: string)
获取技能组下的空闲坐席, 通过监听IdleAgent事件拿到数据。
getGroups()
获取所有技能组, 通过监听GroupInfo事件拿到数据。
getAutoGroups()
获取可预测外呼的技能组。
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 事件会携带 |
可监听的事件名称如下:
Open
成功建立链接
回传数据类型:Frame
链接相关信息Error
建立链接失败
回传数据类型:Event
错误信息Close
链接关闭
回传数据类型:Frame
链接相关信息StateChange
状态发生改变触发
回传数据类型:string
状态值Login
登陆成功
回传数据类型:Object
属性名 | 类型 | 含义 |
---|---|---|
domain | string |
SIP话机注册域 |
sipId | string |
SIP号 |
sipPassword | string |
SIP密码 |
token | string |
登陆SDK身份标识 |
agentType | number |
座席类型 0 普通座席;1 班长 |
groupIdList | Array<string> |
座席所属技能组Id集合 |
busyType | string |
所在企业配置的可选忙碌类型 |
Logout
退出成功
回传数据类型:null
Reconnect
重链成功, 只有首次登录和退出后的登录会触发
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 |
所在企业配置的可选忙碌类型 |
Idle
制闲操作成功
回传数据类型:null
Busy
制忙操作成功
回传数据类型:null
MakeCall
发起通话成功
回传数据类型:null
MakeCallFail
发起通话失败
回传数据类型:Object
属性名 | 类型 | 含义 |
---|---|---|
cause | string |
失败原因描述 |
属性名 | 类型 | 含义 |
---|---|---|
caller | string |
主叫 |
called | string |
被叫 |
inQueueTime | number |
进入队列时间戳 |
callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
属性名 | 类型 | 含义 |
---|---|---|
caller | string |
主叫 |
called | string |
被叫 |
inQueueTime | number |
进入队列时间戳 |
callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
属性名 | 类型 | 含义 |
---|---|---|
caller | string |
主叫 |
called | string |
被叫 |
inQueueTime | number |
进入队列时间戳 |
callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
属性名 | 类型 | 含义 |
---|---|---|
caller | string |
主叫 |
called | string |
被叫 |
inQueueTime | number |
进入队列时间戳 |
callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
属性名 | 类型 | 含义 |
---|---|---|
caller | string |
主叫 |
called | string |
被叫 |
inQueueTime | number |
进入队列时间戳 |
callDirection | number |
呼叫方向(1: 呼入 2: 呼出) |
callType | string |
normal(正常呼叫),consult(咨询),transfer(转接)listen(监听),forceInsert(强插),intercept(拦截) |
TransferCall
发起转接, 只有在通话中才能发起
回传数据类型:null
TransferCalling
转接中
回传数据类型:null
TransferCallFail
转接失败
回传数据类型:null
Listen
发起监听
回传数据类型:null
Listening
监听中
回传数据类型:null
ListenFail
监听失败
回传数据类型:null
ForceBreak
强制断开通话
回传数据类型:null
ForceInsert
强制插入通话
回传数据类型:null
ForceInserting
强制插入通话中
回传数据类型:null
ForceInsertFail
强制插入通话失败
回传数据类型:null
Intercept
拦截通话
回传数据类型:null
Intercepting
拦截通话中
回传数据类型:null
InterceptFail
拦截失败
回传数据类型:null
After
话后
回传数据类型:Object
属性名 | 类型 | 含义 |
---|---|---|
caller | string |
主叫 |
called | string |
被叫 |
occCallId | 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 时不生效 |
Kick
被踢出
回传数据类型:undefined
SipError
话机异常, 当话机取消注册时触发, 同时座席会退出
回传数据类型:null
QueueInfo
队列等待消息
回传数据类型: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 |
座席名称 |
属性名 | 类型 | 含义 |
---|---|---|
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 |
座席所属技能组名称 |
属性名 | 类型 | 含义 |
---|---|---|
version | string |
当前SDK版本信息 |
message | string |
错误描述信息 |
异常处理
异常通常产生自非法的数据, 配置, 参数和方法调用的时机与顺序, 目前可能需要捕获的异常有三个场景, 捕获这些异常可以提供给使用者更多提示信息。
- 通过
sdk
句柄调用方法; sdk
自带UI
使用过程中;- 发送命令之后, 来自远端回执的异常;
- 通过
调用SDK方法中的异常捕获
const agentSdk = new AgentSdk({...}); /** * 因为call方法需要传入一个被叫, 这里没有传入, 所以会抛出一个异常 */ agentSdk.call(); /** * 捕获异常 */ try { agentSdk.call(); } catch (e) { console.log(e.message); // 被叫不能为空 }
SDK提供UI使用过程中的异常捕获
来自远端回执的异常捕获
使用
sdk
自带UI过程中和来自远端回执的异常捕获方式相同, 由于方法不被开发人员调用, 所以不能直接使用try catch
, 监听Exception
事件捕获异常。// <div id="sdk-box"></div> const agentSdk = new AgentSdk({ el: '#sdk-box', ... }); /** * 操作控件, 不填写被叫号码的情况, 直接点击呼叫按钮 * * 捕获异常 */ agentSdk.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 | 技能组黑名单 |