将 bs 客户端所有通话相关的操作和消息推送整合在这 SDK 中。
// or pnpm
npm i emicnet-bs-sdk
// 引入
import sdk from 'emicnet-bs-sdk'
// 参数及回调初始化
const { status, message } = sdk.init(params)
// message maybe is a ParamsError information
// or
sdk.init(params, ({ status, message }) => {})
参数名称 | 数据类型 | 是否必须 | 备注 |
---|---|---|---|
params | object | 是 |
参数名称 | 数据类型 | 是否必须 | 备注/说明 | 可选值 |
---|---|---|---|---|
seid | string | 是 | 超级企业 id | |
ccgeid | string | 是 | 子企业 id | |
uid | string | 是 | 坐席 id | |
token | string | 是 | 坐席登录 token | |
number | string | 是 | 坐席分机号 | |
mode | number | 是 | 坐席登录模式 | voip:2, sip:5, cb_extension: 4 |
timeout | number | 否 | 用于设置 http 请求的超时时间 | 默认值为 5, 单位为秒 |
CMUrl | string | 是 | CM 服务器地址 | |
WSUrl | string | 是 | websocket 服务器地址 |
示例代码
const { status, message } = sdk.init(params)
sdk.on('WSReady', ({ status, message }) => {})
sdk.init() 的返回值中,status === 1 代表初始化完成,不代表初始化成功。
初始化是否成功需要通过监听 sdk.on('WSReady', ({ status, message }) => {}), 判断 status 是否等于 1,status === 1 则代表 websocket 连接成功并使用传入的坐席信息通过了 websocket 服务器的验证,此时才是初始化成功。如果 status === 0,通过 message 可以得知原因。
message 的值包括 success,failed,disconnect,${ error }; success 表示连接上服务器并鉴权成功;failed 表示连接上服务器但是鉴权失败。
用于销毁当前的 SDK 实例。
sdk.destroy()
sdk.destroy() 内部的逻辑主要是释放内存和断连 websocket。
用于手动重新连接 websocket。
sdk.wsReconnect()
用于手动断开 websocket 连接。
sdk.wsDisconnect()
用于更新在 sdk.init() 中传入的 token。
sdk.refreshToken(token)
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
token | string | 是 |
用于将签入坐席。
try {
const { code, data } = await sdk.checkIn(params)
// code === 200 代表接口调用成功
// data.data.status 是 CR 给的状态码 200 表示成功
// data.data 是一个对象里面有当前坐席的状态信息
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
mode | number | 是 | |
number | string | 是 | |
switchNumber | string | 是 | |
uniqueId | string | 是 | |
callGroupId | string | 是 | |
callGroupName | string | 是 | |
deviceNumber | string | 否 | mode 为 5 或者 4 时,是必须参数 |
preStatusId | number | 否 | 默认值为 2,即空闲 |
autoAnswer | number | 否 | 默认值为 0,当为 1 时仅在mode 为 5 或者 4 时有效 |
callintype_last | number | 否 | 最后签入的呼叫类型 |
device_number_last | string | 否 | 最后签入的设备号码 |
用于签出坐席。
try {
const { code, data } = await sdk.checkOut(params)
// code === 200 代表接口调用成功
// data.data.status 是 CR 给的状态码 200 表示成功
// data.data 是一个对象里面有当前坐席的状态信息
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
forceLogout | number | 否 | 可选值为 1 和 0,当为 1 时,表示强制签出。 |
用于设置坐席为空闲状态。
try {
const { code, data } = await sdk.setReady()
// code === 200 代表接口调用成功
// data.data.status 是 CR 给的状态码 200 表示成功
// data.data 是一个对象里面有当前坐席的状态信息
} catch (error) {
// may be is a ParamsError
}
用于设置坐席为忙碌状态。
try {
const { code, data } = await sdk.setBusy(params)
// code === 200 代表接口调用成功
// data.data.status 是 CR 给的状态码 200 表示成功
// data.data 是一个对象里面有当前坐席的状态信息
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
subStatusId | number | 是 | 忙碌子状态的 id |
subStatusName | string | 是 | 忙碌子状态的 name |
statusNameLast | string | 否 | 上一状态名 |
subStatusNameLast | string | 否 | 上一子状态名 |
用于设置坐席为移动坐席或固定坐席。
try {
const { code, data } = await sdk.changeSeatMode(params)
// code === 200 代表接口调用成功
// data.data.status 是 CR 给的状态码 200 表示成功
// data.data 是一个对象里面有当前坐席的状态信息
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
mode | number | 是 | 可选值 1 和 2,1 为移动坐席,2 为固定坐席 |
用于为坐席开启夜间模式。
try {
const { code, info } = await sdk.setNightMode(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
nightMode | number | 是 | 默认值为 1 |
nightNumber | string | 否 | 夜间服务的话机号 |
在通话中时,可将坐席通话结束后的状态设置为忙碌。
try {
const { code, data } = await sdk.preSetBusy(params)
// code === 200 代表接口调用成功
// data.data.status 是 CR 给的状态码 200 表示成功
// data.data 是一个对象里面有当前坐席的状态信息
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 当前正在通话的唯一标识 |
subStatusId | number | 否 | 忙碌子状态的 id |
subStatusName | string | 否 | 忙碌子状态的 name |
在通话中时,取消 preSetBusy 操作。
try {
const { code, data } = await sdk.cancelPreSetBusy(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 当前正在通话的唯一标识 |
用于发起呼叫。
try {
const { status, data, info } = await sdk.callOut(params)
// status 是 CR 给的状态码 200 表示成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callee | string | 是 | 呼出的号码 |
在通话中时,坐席主动挂断通话。
try {
const { status, data, info } = await sdk.hungUp(params)
// status 是 CR 给的状态码 200 表示成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
mode | number | 是 | 挂机类型(0 默认常规 1 会控) |
callId | string | 是 | 当前正在通话的唯一标识 |
outlineNumber | string | 否 | mode:1 会控挂断外线必选 |
seatNumber | string | 否 | mode:1 会控挂断坐席必选 |
IsForced | number | 否 | 强制执行挂机操作(0 默认常规 1强制) |
在通话中时,坐席保持通话。
try {
const { status, data, info } = await sdk.callKeep(params)
// status 是 CR 给的状态码 200 表示成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 当前正在通话的唯一标识 |
在通话中时,坐席取消保持通话。
try {
const { status, data, info } = await sdk.callResume(params)
// status 是 CR 给的状态码 200 表示成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 当前正在通话的唯一标识 |
呼入振铃时,坐席流转该通话。
try {
const { status, data, info } = await sdk.callFlow(params)
// status 是 CR 给的状态码 200 表示成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 当前正在通话的唯一标识 |
呼入振铃时,坐席应答通话。
try {
const { status, data, info } = await sdk.callInAnswer(params)
// status 是 CR 给的状态码 200 表示成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
cid | number | 是 | 客户id(转接可选)客户呼入、预测试外呼 |
cm_name | string | 否 | 客户名称(转接可选)客户呼入、预测试外呼 |
cm_phone_type | number | 是 | 0 客户个人号码 1 家庭号码 2 单位号码 3 自定义号码 10 未知客户 |
callId | string | 是 | 当前正在通话的唯一标识 |
呼入振铃时,坐席应答通话。
try {
const { code, data, info } = await SDK.callPickup()
if (code !== 200) {
log('CALL_PICKUP error data:', data)
} else {
log('CALL_PICKUP success:', info)
}
} catch (error) {
log('CALL_PICKUP error:', error)
}
有忙时来电时,坐席应答通话。
try {
const { code, data, info } = await SDK.busyCallAnswer({ callId: this.callId })
if (code !== 200) {
log('BUSY_CALL_ANSWER error data:', data)
} else {
log('BUSY_CALL_ANSWER success:', info)
}
} catch (error) {
log('BUSY_CALL_ANSWER error:', error)
}
用于被叫是 DND 或通话中时,强插通话或在被叫 DND 时强制呼叫。
try {
const { code, data, info } = await sdk.callForceInsert(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 当前正在通话的唯一标识 |
用于可录音通话中,暂停或继续录音。
try {
const { code, data, info } = await sdk.changeCallRecordingStatus(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 当前正在通话的唯一标识 |
recordingStatus | number | 是 | 可选值为 1 和 2,1 代表暂停录音,2 代表继续录音 |
用于通话中,转接通话子流程。
try {
const { code, data, info } = await sdk.callTransferToIvr(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
ivrFlowId | string | 是 | 通话子流程 id |
ivrFlowName | number | 是 | 通话子流程 name |
encrypted_outline_number | string | 是 | 通话加密号码 |
variables | string | 否 | 依据选择的通话子流程而定 |
用于技能组有排队时,接入技能组的排队通话。
try {
const { code, data, info } = await sdk.callInsertFromQueue(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
currCallId | string | 否 | 当前正在通话的唯一标识 |
gid | string | 是 | 排队中技能组 id |
action | string | 否 | 可选值为 'hangup' 和 'hold',当前正在通话时为必传,用于标识如何处理当前的通话,'hangup' 表示挂断当前,'hold' 表示保持当前 |
用于静音通话中的对象,对象可以是坐席自身,也可以是客户以及其他与会坐席。
try {
const { code, data, info } = await sdk.callMutely(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
outlineNumber | string | 否 | 静音对象是客户时必传 |
seatNumber | string | 否 | 静音对象是与会坐席时必传 |
op_code | number | 是 | 可选值为 15 和 16,15 表示静音,16 表示取消静音 |
通话中时,用于发起多方通话。
try {
const { code, data, info } = await sdk.callMultiParty(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
seatNumberList | string | 否 | 坐席分机号;多个坐席时使用 , 隔开 |
seatNameList | string | 否 | 坐席名称;多个坐席时使用,隔开 |
用于通话中,转接通话子流程。
try {
const { code, data, info } = await SDK.setAnswerGroups({
gidList: '1,2,3',
gNameList: 'one,two,three',
})
if (code !== 200) {
log(`CHANGE_CALL_GROUP failed: code:${code} info:${info}`)
} else {
log(`CHANGE_CALL_GROUP success: code:${code} info:${info}`)
}
} catch (error) {
log('CHANGE_CALL_GROUP error:', error)
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
gidList | string | 是 | 技能组id集合(“,”逗号隔开) |
gNameList | string | 否 | 技能组名称集合(”,”逗号隔开)【客户调用】 |
通话中时,用于发起通话转接。
try {
const { code, data, info } = await sdk.callTransfer(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
op_code | number | 是 | 可选择为 5, 6, 10, 5 为转坐席,6 为转技能组,10 为转外线,11 为转总机 ,12 语音留言 |
transferNumber | string | 否 | 坐席分机号 |
gid | string | 否 | 技能组 gid |
outline_number | string | 否 | 外线号码 |
voicemailSeatNumber | string | 否 | 留言坐席 |
通话中,用于发起通话转接后取消转接。
try {
const { code, data, info } = await sdk.callTransferAbort(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
transfer_type | string | 否 | transfer_group-转技能组,transfer_seat-转坐席,transfer_outline_number-转外线 |
通话中,用于发起三方通话。
try {
const { code, data, info } = await sdk.callThreeParty(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
op_code | number | 是 | 可选择为 1, 2, 3, 1 为转坐席,2 为转技能组,3 为转外线 |
seatNumber | string | 否 | 坐席分机号 |
gid | string | 否 | 技能组 gid |
outNumber | string | 否 | 外线号码 |
通话中,用于发起取消三方通话。
try {
const { code, data, info } = await sdk.callThreePartyAbort(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
transfer_type | string | 否 | transfer_group-转技能组,transfer_seat-转坐席,transfer_outline_number-转外线 |
通话中,用于发起咨询通话。
try {
const { code, data, info } = await sdk.callConsult(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
op_code | number | 是 | 可选择为 1, 2, 3, 1 为转坐席,2 为转技能组,3 为转外线 |
seatNumber | string | 否 | 坐席分机号 |
gid | string | 否 | 技能组 gid |
outNumber | string | 否 | 外线号码 |
通话中,用于发起取消咨询通话。
try {
const { code, data, info } = await sdk.callConsultAbort(params)
// code === 200 代表接口调用成功
} catch (error) {
// may be is a ParamsError
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 排队中通话的唯一标识 |
transfer_type | string | 否 | transfer_group-转技能组,transfer_seat-转坐席,transfer_outline_number-转外线 |
班长坐席监听技能组内坐席通话的操作。
try {
const { code, data, info } = await SDK.callMonitor({
callId: this.callId,
seatId: '1111',
})
if (code !== 200) {
log(`CALL_MONITOR failed: code:${code} info:${info}`)
} else {
log(`CALL_MONITOR success: code:${code} info:${info}`)
}
} catch (error) {
log('CALL_MONITOR error:', error)
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 通话的唯一标识 |
seatId | string | 是 | 被监听坐席的 uid |
班长坐席监听技能组内坐席通话触发结束监听时调用挂断接口hungUp。
班长坐席监听技能组内坐席通话中进行强插操作进入三方通话。
try {
const { code, data, info } = await SDK.callMonitorInsert({
callId: this.callId,
})
if (code !== 200) {
log(`callMonitorInsert failed: code:${code} info:${info}`)
} else {
log(`callMonitorInsert success: code:${code} info:${info}`)
}
} catch (error) {
log('callMonitorInsert error:', error)
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 通话的唯一标识 |
班长坐席监听技能组内坐席通话中进行强拆操作结束通话。
try {
const { code, data, info } = await SDK.callMonitorBreak({
callId: this.callId,
})
if (code !== 200) {
log(`callMonitorBreak failed: code:${code} info:${info}`)
} else {
log(`callMonitorBreak success: code:${code} info:${info}`)
}
} catch (error) {
log('callMonitorBreak error:', error)
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 通话的唯一标识 |
班长坐席监听技能组内坐席通话中进行拦截操作结束坐席与客户的通话,班长与客户进入通话中。
try {
const { code, data, info } = await SDK.callMonitorIntercept({
callId: this.callId,
})
if (code !== 200) {
log(`callMonitorIntercept failed: code:${code} info:${info}`)
} else {
log(`callMonitorIntercept success: code:${code} info:${info}`)
}
} catch (error) {
log('callMonitorIntercept error:', error)
}
参数名称 | 数据类型 | 是否必须 | 备注/说明 |
---|---|---|---|
callId | string | 是 | 通话的唯一标识 |
SDK 的事件主要分为两类,一类是用于监听 SDK 内部 websocket 的状态,一类用于监听通话相关的推送。
// 监听某个事件
sdk.on('eventName', () => {
// do something
})
// 注销某个事件的监听
sdk.off('eventName')
// 注销所有事件
sdk.off()
事件名 | 用途 | 参数 | 备注/说明 |
---|---|---|---|
WSReady | 监听 sdk 内部 websocket 的状态 | { status, message,version } | status 可能的值为 0 和 1,1 代表连接成功并通过了鉴权。message 的可能的值为 failed,success,upgrade,logoff, |
WSDisconnect | 监听 sdk 内部 websocket 断联 | { status: 0, message: 'disconnect' } | |
WSError | 监听 sdk 内部 webscoket 发生错误 | { status: 0, message: error.message || error |
事件名 | 用途 | 参数 | 备注/说明 |
---|---|---|---|
callIn | 有电话呼入 | 通话信息 | |
callRing | 通话振铃 | 通话信息 | |
callEnd | 通话挂断 | 通话信息 | |
callEstablished | 通话建立 | 通话信息 | |
changeStatus | 坐席状态变更 | 坐席状态信息 | |
beCheckedOut | 坐席被踢下线 | 坐席状态信息 | |
changeCallInType | 更换话机模式 | 坐席状态信息 | |
noticePcOnline | 软电话上线通知 | 坐席状态信息 | |
changeSeatType | 坐席模式变更 | 坐席状态信息 | |
changeIsMobileSeat | 切换为移动坐席 | 坐席状态信息 | |
transferThreeParty | 三方通话 | 通话信息 | |
monitorHangup | 班长挂断 | 通话信息 | |
monitorInsertNotice | 班长强插 | 通话信息 | |
busyCallPush | 忙时来电 | 通话信息 | |
callUnholdNotice | 提示音结束后解除通话保持禁用 | 通话信息 | |
transferNoticeMonitor | 班长强插监听坐席转三方 | 通话信息 | |
transferHangup | 转接挂断 | 通话信息 | |
createSheetSuccess | 工单创建 | 工单信息 | |
sheetNotice | 工单 | 工单信息 | |
consultCallNotice | 咨询 | 通话信息 | |
transferIvrNotice | 转 IVR | 通话信息 | |
checkHoldCall | 通话保持 | 通话信息 | |
groupQueueList | 技能组排队信息 | 技能组排队信息 | |
scheduledTaskNotice | 预约外呼推送 | 预约外呼任务信息 | |
multiPartyCall | 多方通话推送 | 通话信息 | |
transferNotice | 转接 | 通话信息 | |
noticeLinuxOnline | linux 软电话上线通知 | 坐席状态信息 |