电话条对接-高阶版

当前电话条共有两个版本,易用版&高级版,易用版我们提供已集成好的界面和能力,您引入代码初始化后即可使用,但是灵活性较差。 高级版方法都为原子化方法,需要您这边具体一定的开发能力以及留有较多的开发时间。 如您为初次使用,建议先集成测试易用版看是否能满足您的需求。

一、场景说明

使用电话条对接,可以将云客服的电话条功能外呼、挂断、转接咨询等能力集成到您自己的业务系统中,在您自己的业务系统使用此功能。 注意:WEBRTC登陆方式请尽可能使用Chrome浏览器并使用HTTPS协议。

二、对接步骤

1、安装

NPM
npm install ue-softphone-sdk import ueSoftPhone from 'ue-softphone-sdk' var ue = new ueSoftPhone ({ // 参数 })
JS方式安装
固定链接(国内资源)
版本号链接(国际资源)

2、电话条初始化方法

var ue = new ueSoftPhone (Object object)
参数:
属性类型可选值默认值必填说明
accountNamestring——是座席账号,如6000@ykf
passwordstring——与passwordPk任选其一座席密码
passwordPkstring--与password任选其一加密后的座席密码,加密逻辑请参考本文档最下方
loginTypestringPSTN / SIP / WEBRTCPSTN否登陆类型 1.手机、2.SIP话机、3.WEBRTC
serverstring___否callApiUrl
isOpenNetworkbooleantrue开启,false关闭false否是否开启网络检测
pushCallinRingStatistics booleantrue开启,false关闭false否坐席callin来电振铃,是否推送ivr按键信息,排队时间,3天内来电次数
pushHangupStatisticsbooleantrue开启,false关闭false否坐席hangup挂机事件事件,是否推送坐席当日通话时长、当日通话次数。
isOpenCallQueuebooleantrue开启,false关闭false否是否开启呼叫队列,查看实时排队情况
volumeobjectinterval: 100-5000 默认值500false否是否开启音量检测。interval为音量检测的间隔
debugboolean—false否是否开启控制台日志
successfunction——否座席初始化成功的回调函数
errorfunction——否座席初始化异常的回调函数
monitorbooleanfalse否是否开启监控信息推送
hangupTonestringdefault 三声滴挂,default2 一声滴挂default否挂机铃声选用
初始化请求参数示例:
window.ue = new ueSoftPhone({ accountName: '8088@useasy', password: '123456Aa', loginType: 'WEBRTC', success(res) { console.log(787877,res); }, error:function(res) { console.log('error',res); } })

3、监听通话事件

ue.listenCallEvent(Object object)
ue.listenCallEvent({ success(res) { console.log(res,'监听通话成功',); }, message: (res) => { console.log(res, '接收通话事件成功') }, event: (res) => { console.log(res, 'socket互踢') } })
参数:
属性类型可选值默认值必填说明
successfunction——否事件绑定通道建立成功回调
messagefunction——否通话事件回调 具体看res.data参数说明
errorfunction——否事件绑定异常回调 主要是底层链接ws的异常回调
eventfunction——否捕获相同坐席登录多个的回调
object.message
回调函数参数Object res
属性类型说明
subTypestring—
dataobject—
Object res.data
名称类型说明
accountIdstring账户编号
agentNumberstring座席编号
statestring状态编号,0:空闲、1:忙碌、2:呼叫中、3:振铃、4:通话中、5:整理、6:保持、7:静音、8:未连接、9:失效、10:咨询、 11:三方、 12:咨询(被咨询方)、 13:三方(被咨询方)100之后为自定义
stateNamestring状态名称
callTypestring通话类型,呼入:callin,外呼:callout,双向呼叫:twoWayCall,外呼任务:callTask,自动外呼:autoCallout
queueNumberstring技能组编号
customerNumberstring客户号码
customerCitystring客户城市
customerProvincestring客户号码所在省
taskIdstring任务id
eventTimestring事件发生时间
defaultStatestring默认登录状态
defaultStateNamestring默认登录状态名称
callIdstring通话ID
eventTypestring通话事件:呼叫:calling,振铃:ring,接通:link,挂机:hangup
disNumberstring外显号
serviceNumberstring服务号
extrasstring扩展参数
ivrKeystringivr按键信息,如1_2,多个按键之间以_分隔开,仅限于callin事件且pushCallinRingStatistics为true的情况下推送
queueDurationint排队时间,单位为秒。仅限于callin事件且pushCallinRingStatistics为true的情况下推送
threeDayCallinTimesint三天内来电次数。仅限于callin事件且pushCallinRingStatistics为true的情况下推送
dailyCallDurationint当日通话时长,单位为秒。仅限于hangup事件且初始化时pushHangupStatistics为true情况下推送
dailyCallTimesint当日通话次数。仅限于hangup事件且初始化时pushHangupStatistics为true情况下推送
dailyConnectTimesint当日接通次数。仅限于hangup事件且初始化时pushHangupStatistics为true情况下推送

4、监听网络检测事件

ue.listenCallNetork(监听网络检测事件) ue.listenCallNetork({ message(res) { console.log(res); } })
message返回值
{ delay: 网络检测数值 }
属性类型说明
successfunction事件绑定成功回调
errorfunction事件绑定异常回调
messagefunction网络检测事件回调,检测值res以json返回

5、监听呼叫队列

可使用此方法监听呼叫队列listenCallQueueEvent
// 监听呼叫队列socket ue.listenCallQueueEvent({ success(res) { console.log('监听呼叫队列socket成功',res); }, message(res) { console.log(res, '获取呼叫队列数据成功') } })
初始化队列数据
{ "success": true, "message": "200 ok!", "code": "200", "data": [ { "accountId": "1090", "queueNumber": "10000187", "queueName": "新需求", "onlineCount": 1, "idleCount": 1, "callingCount": 0, "currentWait": 0, "online": [ "8006" ], "groupLeader": [], "idle": [ "8006" ], "calling": [], "currentQueue": [] }, { "accountId": "1090", "queueNumber": "10000188", "queueName": "杨测试", "onlineCount": 1, "idleCount": 1, "callingCount": 0, "currentWait": 0, "online": [ "8006" ], "groupLeader": [], "idle": [ "8006" ], "calling": [], "currentQueue": [] }, { "accountId": "1090", "queueNumber": "10000210", "queueName": "ftest", "onlineCount": 1, "idleCount": 1, "callingCount": 0, "currentWait": 0, "online": [ "8006" ], "groupLeader": [], "idle": [ "8006" ], "calling": [], "currentQueue": [] }, { "accountId": "1090", "queueNumber": "10000218", "queueName": "8073", "onlineCount": 1, "idleCount": 1, "callingCount": 0, "currentWait": 1, "online": [ "8006" ], "groupLeader": [], "idle": [ "8006" ], "calling": [], "currentQueue": [ { "ivrId": null, "callId": "740036808283537408", "queueNumber": "10000218", "trunkNumber": "02120775542", "customerNumber": "13520558188", "displayNumber": "", "queueStartTime": "2023-11-23 16:54:26", "waitDuration": 5938869, "queueName": "8073" } ] }, { "accountId": "1090", "queueNumber": "10000579", "queueName": "8006", "onlineCount": 1, "idleCount": 1, "callingCount": 0, "currentWait": 0, "online": [ "8006" ], "groupLeader": [], "idle": [ "8006" ], "calling": [], "currentQueue": [] } ] }
获取socket 呼叫队列
{ "subtype": "queue", "data": { "accountId": "1090", "queueNumber": "10000210", "queueName": "ftest", "onlineCount": 1, "idleCount": 1, "callingCount": 0, "currentWait": 0, "online": [ "8006", "8010" ], "groupLeader": [ "8010" ], "idle": [ "8006" ], "calling": [], "currentQueue": [] } }

6、监听通话音量(webtrc模式可用)

可使用此方法监听通话音量listenCallVolume
开启音量检测
ue.listenCallVolume({ success(res) { console.log('监听音量检测-->success',res); }, message(res) { console.log('监听音量检测-->message',res); }, error(res) { console.log('监听音量检测-->error',res); } })
关闭音量检测
window.ue.stopListenVolume({ success(res) { console.log(res,'关闭音量监听成功') }, error(error) { console.log(error,'关闭音量监听失败') } })

7、获取监控信息

可使用此方法获取监控信息ue.listenMonitor
ue.listenMonitor({ success(res) { console.log('座席监控信息success', res); }, message(res) { // 返回参数说明 type: summary: 监控总览, agent: 座席监控, queue: 服务组监控 console.log(res, '座席监控信息message', res.type); }, error(res) { console.log(res, '座席监控信息error'); } });

8、获取机器人转人工随路数据

ue.listenCallEvent(Object object)
ue.listenCallEvent({ success(res) { console.log(res,'监听通话成功',); }, message: (res) => { console.log(res, '接收通话事件成功') }, event: (res) => { console.log(res, 'socket互踢') } })
参数:
属性类型可选值默认值必填说明
successfunction——否事件绑定通道建立成功回调
messagefunction——否通话事件回调 具体看res.data参数说明
errorfunction——否事件绑定异常回调 主要是底层链接ws的异常回调
eventfunction——否捕获相同坐席登录多个的回调
object.message
回调函数参数Object res
属性类型说明
subTypestringrobotEvent
dataobject—
Object res.date.msg
属性类型说明
dialog_typeint1: 语音机器人  2:客户
contentstring消息文本内容
create_timestring消息产生时间
示例
{"data":{"msg":[{"dialog_type":1,"content":"您好,我是汽车专属购车顾问,看到您之前有了解过我们品牌,目前我们有很不错的政策,请问现在还在关注吗?","create_time":"2026-09-16 20:03:56"},{"dialog_type":2,"content":"转人工","create_time":"2026-09-16 20:04:01"}],"callUniqueId":"1112619258619568128"},"subType":"robotEvent"}

三、通话能力方法

1、外呼

ue.call.callout(Object object)
参数:
属性类型可选值默认值必填说明
customerNumberstring——是外呼号码
agentTimeoutstring——否呼叫座席侧超时时间,默认60秒
customerTimeoutstring——否呼叫客户侧超时时间,默认120秒
customerDisNumberstring——否指定呼叫客户外显号码
agentDisNumberstring——否指定呼叫座席外显号码
loginTypestringPSTN / SIP / WEBRTCPSTN否登陆类型 1.手机、2.SIP话机、3.WEBRTC
numberGroupNamestring——否号码组名称,传该值,会查找对应名称的号码组,并根据策略选择外显号。未找到号码组按照没传处理
numberGroupIdstring——否号码组编号,传该值,会查找对应Id的号码组,并根据策略选择外显号。未找到号码组按照没传处理,号码组名称和id同时存在时,优先根据编号查找号码组
extrasstring——否自定义参数,通话中通过事件推送,通话后通话记录中可以查询搜索和定位 限制字节数为255个 超出则报错。
successfunction——否外呼成功回调
failfunction——否外呼失败回调
encryptstring0/10否encrypt为1的时候customerNumber需要传加密后的数据,可参考AES加密示例, 该功能自4.0.35版本后开始支持

2、挂断

ue.call.hangup(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否挂机成功回调
failfunction——否挂机失败回调

3、保持或取消保持

该方法仅在通话进行中时可以用
ue.call.holdOrUnHold(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否调用成功回调
failfunction——否调用失败回调
typestring——是操作类型
object.type 的合法值
值说明
1保持
2取消保持

4、静音或取消静音

该方法仅在通话进行中时可以用
ue.call.muteOrUnMute(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否调用成功回调
failfunction——否调用失败回调
typestring——是操作类型
object.type 的合法值
值说明
1静音
2取消静音

5、转接

该方法仅在通话进行中时可以用
ue.call.transfer(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否调用成功回调
failfunction——否调用失败回调
agentNumberstring——否当前座席工号
numberstring——是转接号码、或转接的座席工号
typestring——是转接类型
object.type 的合法值
值说明
agent座席
outline外线电话
ivr语音导航

6、咨询

该方法仅在通话进行中时可以用
ue.call.consult(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否调用成功回调
failfunction——否调用失败回调
agentNumberstring——是当前需要发起咨询的座席工号
numberstring——是可传入,外线号码, 座席工号, 技能组编号例如:15010xxxx, 8000, 10014640
modestring——是咨询类型
object.mode 的合法值
值说明
agent座席
outline外线电话
ivr语音导航

7、取消咨询

该方法仅在通话且处于咨询状态时可用。可保持咨询状态继续咨询其他人
ue.call.cancelconsult(Object object)
参数:
属性类型可选值默认值必传说明
successfunction——是调用成功回调
failfunction——是调用失败回调

8、结束咨询

该方法仅在通话进行且已经在咨询状态时可用。调用后将挂掉被咨询方,用户听到保持音乐,可再咨询其他人或者调用咨询接回回到和客户的通话
ue.call.endConsult(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——是调用成功回调
failfunction——是调用失败回调

9、咨询接回

该方法仅在通话进行且已经在咨询状态时可用。 结束当前咨询,回到跟客户的通话
ue.call.callbackConsult(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——是调用成功回调
failfunction——是调用失败回调

10、咨询转接

该方法仅在通话进行且已经在咨询状态时可用。调用后将把当前通话转接给咨询方
ue.call.consultTransfer(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——是调用成功回调
failfunction——是调用失败回调

11、三方通话

该方法仅在通话进行且已经在咨询状态时可用。调用后将把咨询方拉入通话,形成三方通话。
ue.call.threeWayCall(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——是调用成功回调
failfunction——是调用失败回调

12、满意度评价

该方法仅在通话进行时可用
ue.call.evaluate(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否调用成功回调
failfunction——否调用失败回调
typestring——是要转接的IVRl类型 如SATISFACTION

13、会议

ue.call.meeting(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否调用成功回调
failfunction——否调用失败回调
numberstring——是转接号

14、关闭振铃音

用于呼入场景关闭振铃音响铃
ue.muteRing(Object object)
window.ue.muteRing({ success(res) { console.log(res,'关闭铃声成功') }, error(error) { console.log(error,'关闭铃声失败') } }) })

15、开启或关闭麦克风

该方法仅支持 `WEBRTC` 登录方式,并且需要在通话已建立、本地麦克风音轨存在时调用。其他登录方式调用时会返回失败提示。
ue.webrtc.setMicrophoneEnabled(Object object)
参数:
属性类型可选值默认值必填说明
successfunction--否调用成功回调
failfunction--否调用失败回调
enabledboolean--是是否开启麦克风
object.enabled 的合法值
值说明
true开启麦克风
false关闭麦克风
调用成功返回:
```js { success: true, message: "setMicrophoneEnabled success", enabled: true } ```
 非 WEBRTC 登录方式调用失败返回:
```js { success: false, message: "当前登录方式不支持麦克风控制,请切换为 WEBRTC 登录方式!" } ```
调用示例:
// 开启麦克风 ue.webrtc.setMicrophoneEnabled({ enabled: true, success: function (res) { console.log(res, "开启麦克风成功"); }, fail: function (error) { console.log(error, "开启麦克风失败"); } }); // 关闭麦克风 ue.webrtc.setMicrophoneEnabled({ enabled: false, success: function (res) { console.log(res, "关闭麦克风成功"); }, fail: function (error) { console.log(error, "关闭麦克风失败"); } });

16、查询麦克风状态

该方法用于查询当前 WEBRTC 本地麦克风音轨是否开启。需要在 `WEBRTC` 登录方式下,并且本地麦克风音轨已存在时调用。
ue.webrtc.isMicrophoneEnabled()
参数:
无
返回值:
类型说明
booleantrue 表示麦克风已开启,false 表示麦克风已关闭或当前没有可用的本地麦克风音轨
示例:
const enabled = ue.webrtc.isMicrophoneEnabled(); if (enabled) { console.log("麦克风已开启"); } else { console.log("麦克风已关闭或暂无可用麦克风音轨"); }

17、监控方法

调用监控方法前,需要初始化软电话条,且monitor需要是true

1、监控条件查询(开启监控)

window.ue.sdkMonitorMsg({ type: ['agent','summary','queue'], //监控类型 summary: 监控总览, agent: 座席监控, queue: 服务组监控 requestMsg: { pageNumber: pageNum, // 页码 必传参数 pageSize: 10, //一页能展示多少数据 必传参数 agentNumber:'22, //座席工号 非必传参数 queueNumber:'', //服务组号码 非必传参数 stateName:["未连接","忙碌","空闲","开会","就餐","下午茶","整理"], //服务组号码 非必传参数 sortList:[ //排序状态 非必传参数 asc升序 desc降序 {"field":"agentNumber","orderBy":"asc"}, {"field":"stateDuration","orderBy":"desc"}, {"field":"stateName", "orderBy":["忙碌","未连接","空闲","开会","就餐","整理","呼叫中","振铃","通话中","保持","静音","失效","咨询","三方","签出","离线接听"]} ] }, success(res) { console.log(res, '设置监控请求参数成功'); }, error(error) { console.log(error, '设置监控请求参数失败'); } });

2、监听

window.ue.call.listen({ agentNumber: phoneNumber, //必传 被监听的座席工号 success(res) { console.log('监听成功', res); }, fail(error) { console.log('监听失败', error); } });
3、 抢接
window.ue.call.loot({ agentNumber: phoneNumber, //必传 被抢接的座席工号 success(res) { console.log('抢接成功', res); }, fail(error) { console.log('抢接失败', error); } });
4、 强拆
window.ue.call.forcedHangup({ agentNumber: phoneNumber, //必传 被强拆的座席工号 success(res) { console.log('强拆成功', res); }, fail(error) { console.log('强拆失败', error); } });
5、强插
window.ue.call.breakIn({ agentNumber: phoneNumber, //必传 被强插的座席工号 success(res) { console.log('强插成功', res); }, fail(error) { console.log('强插失败', error); } });
6、耳语
window.ue.call.whisper({ agentNumber: phoneNumber, //必传 被耳语的座席工号 success(res) { console.log('耳语成功', res); }, fail(error) { console.log('耳语失败', error); } });
7、监控监听关闭
window.ue.closeSdkMonitor({ type: ['agent','summary','queue'], //监控类型 success(res) { console.log(res, '关闭成功'); }, error(error) { console.log(error, '关闭失败'); } });

四、坐席相关方法

1、切换接听方式

ue.agent.switchLoginType(Object object)
参数:
属性类型可选值默认值必填说明
loginTypestringPSTN / SIP / WEBRTCPSTN是登陆类型 1.手机、2.SIP话机、3.WEBRTC
loginNumberstring—系统绑定的手机号 或者 SIP号否手机模式:需要更换坐席绑定的手机号时,该字段传新的绑定手机号。不需要更改时不传
successfunction——否更新成功回调函数
failfunction——否更新失败回调函数

2、获取电话条状态列表

ue.agent.findPhoneBarList(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否获取成功回调函数
failfunction——否获取失败回调函数
object.success
回调函数参数Object res
属性类型说明
successboolean执行是否成功
dataarray电话条状态列表
data object
数组里的对象值Object
属性类型说明
namestring状态名称
numberstring切换状态值

3、切换电话条状态

ue.agent.switchPhoneBar(Object object)
参数:
属性类型可选值默认值必填说明
stateNumberstring——是切换状态值
successfunction——否获取成功回调函数
failfunction——否获取失败回调函数
object.success
回调函数参数Object res
属性类型说明
successboolean执行是否成功
object.fail
回调函数参数Object res
属性类型说明
messagestring错误描述

4、退出登录

ue.agent.logout(Object object)
参数:
属性类型可选值默认值必填说明
toAnswerofflinestring'0'/'1''0'否'0': 不离线接听 '1': 离线接听
successfunction——否获取成功回调函数
failfunction——否获取失败回调函数
object.success
回调函数参数Object res
属性类型说明
successboolean执行是否成功
object.fail
回调函数参数Object res
属性类型说明
messagestring错误描述

5、获取服务组空闲座席(用于转接)

ue.agent.findIdleAgentsForQueue(Object object)
参数:
属性类型可选值默认值必填说明
successfunction——否获取成功回调函数
failfunction——否获取失败回调函数
object.success
回调函数参数Object res
属性类型说明
successboolean执行是否成功
object.fail
回调函数参数Object res
属性类型说明
messagestring错误描述

6、销毁实例

ue.destroy({ success(res) { console.log('销毁成功', res); }, fail(error) { console.log('销毁失败', error); } });

五、webrtc模式设备操作方法

1、接听

ue.webrtc.accept()

2、注册设备

ue.webrtc.connect()

3、注销设备

ue.webrtc.disconnect()

4、检查设备是否注册

ue.webrtc.isConnected()

5、发送DTMF

ue.webrtc.sendDTMF(String)
String 的合法值
值说明
11号键
22号键
33号键
44号键
55号键
66号键
77号键
88号键
99号键
00号键
**号键
##号键

六、座席视频通话接入

本文面向使用 Demo 的客户,介绍如何启用座席间视频通话及调用 SDK 提供的 API。视频通话连接由 SDK 管理,使用时无需自行调用视频通话后端接口或管理 SIP 连接。

1. 接入说明

视频通话为可选能力,初始化参数 `enableVideoCall` 默认为 `false`。只有显式设置为 `true`,SDK 才会在电话条登录成功后自动准备视频通话连接。
- 视频通话使用 `ue.videoCall` API。登录成功前不要发起呼叫;可以提前注册事件监听。
- 呼出目标填写被叫座席工号,不是 SIP 用户名。
- 浏览器需要处于 HTTPS 或 localhost 等安全上下文,并取得摄像头、麦克风权限。仅语音呼叫可以使用 `mediaType: "audio"`。

2. 初始化

```js const ue = new ueSoftPhone({ accountName: "8005@uecs1", password: "登录密码", server: "https://app.useasy.cn/api", enableVideoCall: true, }); // 登录成功后视频 SIP 注册由 SDK 自动完成。 // 建议在发起呼叫前监听状态,并在收到来电时展示接听界面。 ue.videoCall.on("stateChange", ({ state, detail }) => { console.log("视频通话状态", state, detail); }); ue.videoCall.on("incomingCall", ({ caller, callerName, callerSip }) => { console.log("视频来电", callerName || caller, callerSip); }); ``` `enableVideoCall` 不设置或设为 `false` 时,不启用视频通话。登录成功后连接由 SDK 自动准备,业务侧只需通过 `ue.videoCall` 使用功能。

3. 前端 API

发起呼叫
```ts ue.videoCall.call({ targetExtension: "8006", // 被叫座席工号 mediaType: "video", // "video"(默认)或 "audio" success: (result) => console.log("呼叫已发起", result), fail: (error) => console.error("呼叫失败", error), }); ```
`call()` 返回 `Promise<void>`。`targetExtension` 必填;视频连接尚未就绪、已有进行中的通话或呼叫失败时会 reject。`success` / `fail` 是可选回调;`fail` 会在部分失败路径触发,所有错误处理请以 Promise 的 `try/catch` 为准。成功表示呼叫邀请已提交,不代表对方已经接听;接通状态以 `accepted` 事件为准。
发起视频呼叫时,浏览器会先请求摄像头和麦克风权限;授权成功后 SDK 才继续呼叫。拒绝授权或设备不可用时不会发起呼叫。如果之前选择了拒绝,浏览器通常不会再次弹授权框;请在浏览器地址栏的站点权限设置中重新允许摄像头和麦克风,再点击呼叫重试,无需重新初始化 SDK。权限提示期间可调用 `hangup()` 取消本次呼叫准备。
业务侧传入的 `targetExtension` 始终是被叫座席工号。
接听、拒绝和挂断
```js await ue.videoCall.answer({ mediaType: "video" }); // 来电接听;默认视频 await ue.videoCall.reject(); // 拒绝当前来电 await ue.videoCall.hangup(); // 挂断当前来电或通话 ```
没有待处理来电时调用 `answer()` 或 `reject()` 会失败。`hangup()` 在当前没有会话时不做任何操作。
媒体流与设备控制
```js ue.videoCall.on("media", ({ localStream, remoteStream }) => { if (localStream) { localVideo.srcObject = localStream; void localVideo.play().catch(() => {}); // 浏览器可能要求用户手势后播放 } if (remoteStream) { remoteVideo.srcObject = remoteStream; void remoteVideo.play().catch(() => {}); } }); ue.videoCall.setCameraEnabled(false); // 关闭本地视频轨道 ue.videoCall.setMicrophoneEnabled(false); // 静音本地音频轨道 const cameraOn = ue.videoCall.isCameraEnabled(); const microphoneOn = ue.videoCall.isMicrophoneEnabled(); ```
`getLocalStream()` 和 `getRemoteStream()` 分别返回当前本地、远端 `MediaStream`,尚无流时返回 `null`。摄像头/麦克风开关方法在对应轨道尚不存在时返回 `false`,成功修改轨道时返回 `true`。它们控制当前通话的轨道,不会重新申请设备权限。

4. 事件

所有事件通过 `ue.videoCall.on(event, callback)` 监听。`on` 返回取消监听函数;也可以调用 `ue.videoCall.off(event, callback)` 取消指定监听。
| 事件 | 负载 | 说明 |
| --- | --- | --- |
| `stateChange` | `{ state, detail }` | 状态变化。状态值:`idle`、`connecting`、`registered`、`calling`、`ringing`、`inCall`、`ended`、`failed`、`disconnected`。`detail` 随状态变化,可能包含阶段、方向、目标或错误信息。 |
| `incomingCall` | `{ caller, callerSip, callerName, invitation }` | 收到来电时触发。`caller` 是主叫座席工号,`callerName` 可能为空;`callerSip` 是连接标识。`invitation` 为 SDK 内部对象,业务侧无需使用。 |
| `progress` | `{ direction, target }` | SIP 会话进入呼叫协商阶段。`direction` 为 `incoming` 或 `outgoing`。 |
| `accepted` | `{ direction, target }` | 通话接通。 |
| `ended` | `{ direction, target }` | 会话结束,包括本端或对端挂断。 |
| `failed` | `{ error, ... }` | 初始化、网络或呼叫过程发生错误;附加字段依失败阶段而异。 |
| `media` | `{ localStream, remoteStream }` | 通话建立或媒体轨道更新时触发。流可能暂时为 `null`,应按需更新视频元素。 |
呼入铃声在收到来电时播放,接听或拒绝时停止;已接通会话结束时播放项目内挂断提示音。

 5. 释放与注意事项

- 收到对端挂断或本端结束通话后,SDK 会停止本地音视频轨道,释放摄像头和麦克风占用。
- 调用电话条实例的 `destroy()` 时,SDK 会结束视频会话、注销 SIP 并关闭独立连接。无需业务侧单独管理视频 SIP 连接。
- `enableVideoCall` 开启后,当前账户需要具备视频通话权限,并确保浏览器网络可访问视频通话服务。
- 如果状态停留在 `connecting` 或进入 `failed` / `disconnected`,请联系系统管理员检查视频通话服务配置和网络连通性,并查看浏览器控制台错误。
- 自动播放策略可能阻止视频元素播放声音或画面;可在用户点击接听等交互后调用 `video.play()`。

七、常见问题及处理方案

1、通话会出现无声

通话无声都是由于未处理互踢逻辑,座席多处注册导致语音流未流向正常座席导致的。可在listenCallEvent里监听互踢,如另一处登录,则销毁上一处实例,禁止多处登录。注意:使用时需把电话条升级到3.0.5以上版本
window.ueSoftphone.listenCallEvent({ event: res => { console.log('互踢触发'); }})
gaojiDemo.html
4.0 KB
demo.html
56.9 KB

2、uniapp前端APP接入电话条功能的麦克风权限获取方案

一、问题背景
在 uniapp 前端开发的 APP 中直接接入电话条功能时,出现 “没麦克风权限” 的报错,原因是电话条 JS 依赖浏览器环境获取权限,而 uniapp 打包的 APP 本身的权限配置无法直接传递给电话条 JS。
二、解决方案
采用 “中间 H5 页面转接权限” 的方式,步骤如下:
  1. 单独部署一个H5 页面,在该 H5 中集成电话条功能(即对接ue-softphone-sdk);
  2. 在 uniapp 的 APP 中,通过webview组件引入这个 H5 页面;
  3. 让 uniapp 的 APP 将麦克风权限授予webview(webview会模拟浏览器环境,使电话条 JS 能正常获取权限)。
三、核心逻辑
电话条功能的 JS SDK 是基于浏览器环境获取麦克风权限的,因此需要借助webview充当 “浏览器载体”,让权限能被电话条 JS 识别到。

七、其他

1、 软电话条密码加密方法

1. 咨询云客服管理员,获取加密密钥secret_pk
2. 使用密钥对密码做加密,得到passwordPk
前端加密示例:
#加密示例# password为原密码 secret_pk为密钥 const PUBLIC_KEY = decodeURIComponent(Base64.decode(secret_pk)); const encryptor = new JSEncrypt(); encryptor.setPublicKey(PUBLIC_KEY); const md5Password = md5(password); const passwordPk = encryptor.encrypt(md5Password);
java加密示例:
import org.apache.commons.codec.digest.DigestUtils; import javax.crypto.Cipher; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.interfaces.RSAPublicKey; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; public class Main { public static String encrypt(String str, String publicKey) throws Exception { byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8"))); return outStr; } public static void main(String[] args) throws Exception { String publicKey = ${secret_pk}; String message = ${password}; String md5 = DigestUtils.md5Hex(message); String messageEn = encrypt(md5, base64ToString(publicKey)); System.out.println(messageEn); } public static String base64ToString(String base64String) { return new String(Base64.getDecoder().decode(base64String), StandardCharsets.UTF_8); } }
2026-10-09