- 最新动态
- 产品介绍
- 快速入门
-
用户指南
- 云控制台操作指南
-
租户管理员指南
- 认识您的租间
- 配置员工中心
- 启用人工服务
- 配置移动客服
- 配置多媒体渠道
-
机器人管理配置指南
- 快速入门
-
配置智能机器人
- 概述
- 配置一个预约挂号机器人(任务型对话机器人)
- 添加问答型对话机器人
- 其他操作
-
相关参考
- 图元
- 参数
-
TUC接口
- /chatbot/rest/tuc/v1/nlp/detectRegularEntity
- /chatbot/rest/tuc/v1/nlp/identify
- /chatbot/rest/tuc/v1/recommendFaq
- /chatbot/rest/tuc/v1/qualityInspection/qiOnline/recognize
- /chatbot/rest/tuc/v1/nlp/feedback
- /chatbot/rest/tuc/v1/nlp/textClassify
- /chatbot/rest/tuc/v1/nlp/detectEntity
- /chatbot/rest/tuc/v1/qualityInspection
- 内置函数
- 常见问题
- 操作员:配置普通IVR
- 配置预置流程
- IVR Journey分析
- 外呼风险监控
- 管理工单配置
- 质检管理
- 管理通知中心
- 管理客户中心
- 配置智能外呼
- 管理问卷
- 管理智能实训
- 配置知识库
- 配置公共资源
- 业务故障放通管理
- 护航浏览
- 社交媒体运营
- 绩效管理
- 客服座席指南
- 质检员指南
- 价格说明
-
开发指南
- 开发概述
- 用户接入——VOIP音视频接入
- 用户接入——网页版客户端集成 (RESTful)
- 用户接入——网页版轻量级客户端集成 (JS)
- 座席集成——座席轻量级接续块集成(JS)
- 座席集成——座席呼叫处理 (RESTful)
-
座席集成——Openeye H5 软电话接口集成
- 修订记录
- OpenEye H5软电话接口概述
- OpenEye软电话安装指导
- 座席侧集成H5软电话开发指导
- 音频呼叫接口
-
音视频呼叫接口扩展
- 音视频呼叫
-
设备管理
- getMediaDevices(获取设备列表)
- setMicIndex(设置麦克风)
- mediaGetMicIndex(查询当前使用的麦克风)
- setSpeakIndex (设置扬声器)
- mediaGetSpeakIndex (查询当前使用的扬声器)
- setMicVol(设置麦克风音量)
- getMicVol(查询麦克风当前音量)
- setSpkVol(设置扬声器音量)
- getSpkVol(查询扬声器当前音量)
- setVideoWindowParam(设置视频窗口位置和宽高)
- setVideoLayoutMode(设置视频窗口画面排列模式)
- setVideoDisplayMode(设置视频窗口画面裁剪模式)
- openCamera(打开摄像头)
- closeCamera(关闭摄像头)
- 屏幕共享
- 截屏
- 录屏
- 错误码列表
- 运营管理——座席工作台集成第三方Web页面
-
API参考
- 接口概述
- 相关术语
- 修改记录
- 接口鉴权方式
-
呼叫中心配置类
-
座席管理
- 单个创建座席业务账号(agentAccount/create)
- 单个删除指定座席业务账号(agentAccount/delete)
- 单个修改座席业务账号信息(agentAccount/update)
- 查询座席业务账号信息(agentAccount/query)
- 绑定座席和技能队列(addSkillsToAgent)
- 解绑座席某技能队列(releaseAgentBySkillId)
- 通过技能队列ID查询座席信息(queryAgentInfoBySkillId)
- 修改座席软电话号码登录密码(updateSipPhonePassword)
- 查询所有座席的软电话信息 (不包含业务账号) (querySysInfo)
- 查询所有座席的软电话信息 (包含业务账号) (queryAgentInfo)
- 查询账号登录结果 (queryAgentLoginParams)
- 根据登录账号查询座席信息 (queryAgentInfoByAccount)
- 按客户号码清理数据 (cleancustpersonaldata)
- 技能队列管理
- 号码管理
- IVR流程管理
-
座席管理
-
座席工作台
- 座席控制
-
座席双呼
- 创建双呼呼叫 (V1.0.0) (createCall)
- 创建双呼呼叫 (V3.0.0) (createCall)
- 查询呼叫历史记录 (queryCallDetailRecord)
- 查询呼叫状态 (queryCallState)
- 获取录音文件地址 (getRecordingAddress)
- 查询分配的软电话号码 (V1.0.0) (queryPhone)
- 查询分配的软电话号码 (V2.0.0) (queryPhone)
- 获取呼叫目的设备信息 (getCalledInfo)
- 创建语音外呼(V1.0.0)(createVoiceNotification)
- 创建语音外呼(V2.0.0)(createVoiceNotification)
- 查询当前会话客户的最近历史接触记录(queryUserContactLimit)
- 查询通话信息(queryCallInfoByCallId)
- ITA双呼结果通知(statusnotify)
- 回调接口
- 订阅语音识别结果接口
- App个人设置
- 附录
- 电销外呼
- 调查问卷
- 知识库管理
- 机器人管理
-
网页客户端接入
- 接口调用流程
- 第三方请求鉴权 (applyToken)
- 查询排队信息 (queryQueueInfo)
- 主动轮询座席侧发送的信息 (poll)
- 保存客户提交的满意度评价结果 (saveSatisfaction)
- 发送消息 (send)
- 客户发送文件 (uploadFileStream)
- 客户接收文件 (downloadFileStream)
- 根据客户输入联想常用语 (queryPhraseByKeyword)
- 检查当前租间是否支持点击通话 (checkClickToCallSupport)
- 创建点击通话 (createClickToCall)
- 获取点击通话事件 (getClickToCallEvents)
- 释放点击通话 (dropClickToCall)
- 创建匿名通话 (createcall)
- 客户提交留言 (doLeaveMessage)
- 提交客户对机器人满意度评价结果 (feedbacksatisfaction)
- 查询历史消息 (queryHistoryChatMessage)
- 丢弃邮件(chat_dropMail)
- 提供whatsapp发送下行消息(sendWhatsappMessage)
- 查询在线交谈工作台当前交谈的消息(getUserInfoBycallId)
- 查询满意度调查配置(getSatisfactionSurveyMode)
-
质检/监控/统计类
- 实时质检:qualitycontrol
-
智能质检
- 质检评分接口 (scoresetting)
- 句子管理接口 (sentencemanagement)
- 敏感词管理接口 (sensitiveWordManage)
- 话术接口 (conversationspecific)
- 句子、敏感词训练接口 (SemanticKeywordTraining)
- 对话逻辑接口 (conversationflow)
- 对话规则接口 (conversationrules)
- 抢插话规则接口 (interposalrules)
- 静默规则接口 (silencerule)
- 语速规则接口 (speedrule)
- 质检场景管理接口 (scenariomanage)
- 通话质检接口 (qualitycheckmanage)
- 人工抽检任务接口 (regularQualityTask)
- 质检任务接口 (qualitytask)
- 质检任务详情接口 (qualitytaskdetail)
- 质检申诉接口 (qualityitem)
- 第三方录音质检接口 (asrtrans)
-
监控/统计
-
实时数据查询类接口
-
VDN维度实时接口
- 查询指定VDN下的系统接入码信息
- 查询指定VDN下的座席休息情况
- 查询指定VDN下的座席电话号码
- 查询指定VDN下的所有座席信息
- 查询指定VDN下的所有座席的当前状态信息
- 查询指定VDN下的所有座席的静态配置信息
- 查询指定VDN下的IVR详细状态信息
- 查询指定VDN下的IVR流程接入码信息
- 查询指定VDN下的各技能队列相关信息
- 查询指定VDN所有休息原因码
- 查询指定接入码编号的呼叫信息
- 查询指定VDN下的呼叫信息
- 查询指定VDN下的呼叫信息(v2)
- 查询指定VDN下的通话轨迹数据
- 查询指定VDN下的所有座席的静态配置信息(CTI3.6版本不支持)
- 查询指定VDN下的所有座席信息(CTI3.6版本不支持)
- 获取VDN实时监控指标
- 技能队列维度实时接口
- 座席维度实时接口
- 呼叫明细维度实时接口
-
VDN维度实时接口
- 历史数据查询类接口
- 配置数据查询类接口
- 质检关系维护接口
- 外呼任务列表查询接口
- 系统指标查询接口
- 健康检查接口
- 附录
-
实时数据查询类接口
- 录音/话单类
- 语音通知
- OMA接口参考
- Case2.0接口参考
- DataProcess接口参考
- 其他类接口参考
- 常见问题
- 文档下载
- 通用参考
展开导读
链接复制成功!
代码使用示例-用户发起点击通话
发起点击通话的前提,是在接收用户消息时,通过了webRTC环境的校验。
当demo中出现了以下按钮,代表可以发起点击通话。
发起的方法,可以参考Footer.vue中的createCall方法。
/音视频通话 createCall(callType) { this.mode = callType === '0' ? 'audio' : 'video'; let callbacks = function () { EventBus.$emit("startCallPoll"); } this.$Chat.createClickToCall(callType, callbacks); this.isTalking = true; this.callType = callType; }
该方法会调用createClickToCall接口,当方法得到成功返回后,会调用callbacks回调函数,回调函数中的方法EventBus.$emit("startCallPoll")意为发送一个startCallPoll事件。
事件的监听方法如下:
//轮询座席消息 EventBus.$on("startCallPoll", () => { this.getCallEvent(); });
会开始调用getClickToCallEvents接口,开始轮询点击通话事件。
//轮询获取通话事件 getCallEvent() { setTimeout(() => { this.$Chat.getClickToCallEvents(this.callbacks); }, 100); }
这里面的callbacks方法如下,其中new AudioCodesUA()来自奥科的SDK
//音视频相关回调函数 callbacks(data) { if (data && data['resultCode'] === '0') { let eventId = data['eventId']; if (eventId) { if (eventId === 168101) { //已接入到座席 const msgContent = data['content']; // eslint-disable-next-line no-undef this.webRtcConfig.phone = new AudioCodesUA(); this.webRtcConfig.callTo = msgContent['accessCode'] this.webRtcConfig.serverConfig.domain = msgContent['domain'] this.webRtcConfig.serverConfig.addresses = msgContent['gwAddresses'] this.webRtcConfig.account.user = msgContent['clickToCallCaller'] this.webRtcConfig.account.displayName = msgContent['clickToCallCaller'] this.initSipStack(); } else if (eventId === 168102) { //that.$Chat.guiInfo('排队中....') } else if (eventId === 168106) { // 呼叫转移 //that.$Chat.guiInfo('呼叫转移中') } else if (eventId === 168110) { // 呼叫释放 this.isTalking = false } else if (eventId === 168103) { // 呼叫排队超时 this.isTalking = false } else if (eventId === 168105) { // 呼叫失败 this.isTalking = false this.$message({ message: '建立通话失败!', type: 'warning' }); }else { this.$message({ message: '建立通话失败!失败原因码为:' + eventId, type: 'warning' }); if (this.callType === '1'){ EventBus.$emit("videoDrop"); }else { EventBus.$emit("audioDrop"); } } } } else { this.isTalking = false; } if (this.isTalking) { EventBus.$emit("startCallPoll"); } }
在收到168101事件代表已成功接入到座席,这时候会调用initSipStack方法参考如下。
initSipStack() { let phone = this.webRtcConfig.phone phone.setServerConfig(this.webRtcConfig.serverConfig.addresses, this.webRtcConfig.serverConfig.domain, this.webRtcConfig.serverConfig.iceServers) phone.setAccount(this.webRtcConfig.account.user, this.webRtcConfig.account.displayName, this.webRtcConfig.account.password) // Set phone API listeners let that = this phone.setListeners({ loginStateChanged: function (isLogin, cause) { switch (cause) { case 'connected': that.ac_log('phone>>> loginStateChanged: connected') if (that.webRtcConfig.activeCall !== null) { that.ac_log('Already exists active call') } else { if (that.mode === 'video') { that.webRtcConfig.activeCall = phone.call(phone.VIDEO, that.webRtcConfig.callTo) } else { that.webRtcConfig.activeCall = phone.call(phone.AUDIO, that.webRtcConfig.callTo) } EventBus.$emit("showAudio"); } break case 'disconnected': that.ac_log('phone>>> loginStateChanged: disconnected') if (phone.isInitialized()) { that.ac_log('Cannot connect to SBC server') } if (that.callType === '1'){ EventBus.$emit("videoDrop"); }else { EventBus.$emit("audioDrop"); } that.ac_log('service disconnected') break case 'login failed': that.ac_log('phone>>> loginStateChanged: login failed') break case 'login': that.ac_log('phone>>> loginStateChanged: login') break case 'logout': that.ac_log('phone>>> loginStateChanged: logout') break } }, // eslint-disable-next-line no-unused-vars outgoingCallProgress: function (call, response) { that.ac_log('phone>>> outgoing call progress') EventBus.$emit("callMessage", "呼叫中"); }, // eslint-disable-next-line no-unused-vars callTerminated: function (call, message, cause, redirectTo) { that.ac_log('phone>>> call terminated callback, cause=%o', cause) if (call !== that.webRtcConfig.activeCall) { that.ac_log('terminated no active call') return } that.webRtcConfig.activeCall = null that.ac_log('Call terminated: ', cause) phone.deinit() // Disconnect from SBC server. that.isTalking = false // 轮询结束 console.log('Stop polling, drop existing ClickToCall, reset CallDurationTimer and enable ClickToCall') that.guiClearVideoView() }, // eslint-disable-next-line no-unused-vars callConfirmed: function (call, message, cause) { that.ac_log('phone>>> callConfirmed') // Show or hide video controls, according call property 'video' let hasVideo = call.hasVideo() that.guiToggleLocalVideo() // set local video according current check box setting. if (hasVideo) { EventBus.$emit("showVideo"); EventBus.$emit("hideAudioImmediately"); } else { EventBus.$emit("callMessage", "time"); } }, callShowStreams: function (call, localStream, remoteStream) { console.log('phone>>> callShowStreams') let remoteVideo = document.getElementById('remote_video') remoteVideo.srcObject = remoteStream // to play audio and optional video }, // eslint-disable-next-line no-unused-vars incomingCall: function (call, invite) { console.log('phone>>> incomingCall') call.reject() }, // eslint-disable-next-line no-unused-vars callHoldStateChanged: function (call, isHold, isRemote) { console.log('phone>>> callHoldStateChanged ' + isHold ? 'hold' : 'unhold') } }) phone.init(false) }
上述的方法来自奥科文档,具体使用方式可以参考奥科官网,搜索webrtc-web-browser-client-sdk-api-reference-guide了解。本处提示几个地方:
本方和对方的音视频展示,需要有一个video标签,可以参考VideoWindow.vue中的:
callConfirmed: function (call, message, cause) { that.ac_log('phone>>> callConfirmed') // Show or hide video controls, according call property 'video' let hasVideo = call.hasVideo() that.guiToggleLocalVideo() // set local video according current check box setting. if (hasVideo) { EventBus.$emit("showVideo"); EventBus.$emit("hideAudioImmediately"); } else { EventBus.$emit("callMessage", "time"); } }
会展示本方的音视频媒体。
存在对方媒体时会调用callShowStreams展示对方媒体。
callShowStreams: function (call, localStream, remoteStream) { console.log('phone>>> callShowStreams') let remoteVideo = document.getElementById('remote_video') remoteVideo.srcObject = remoteStream // to play audio and optional video }
callTerminated: function (call, message, cause, redirectTo) { that.ac_log('phone>>> call terminated callback, cause=%o', cause) if (call !== that.webRtcConfig.activeCall) { that.ac_log('terminated no active call') return } that.webRtcConfig.activeCall = null that.ac_log('Call terminated: ', cause) phone.deinit() // Disconnect from SBC server. that.isTalking = false // 轮询结束 console.log('Stop polling, drop existing ClickToCall, reset CallDurationTimer and enable ClickToCall') that.guiClearVideoView() }
因其他情况结束了通话流程会触发disconnected事件。
case 'disconnected': that.ac_log('phone>>> loginStateChanged: disconnected') if (phone.isInitialized()) { that.ac_log('Cannot connect to SBC server') } if (that.callType === '1'){ EventBus.$emit("videoDrop"); }else { EventBus.$emit("audioDrop"); } that.ac_log('service disconnected') break
语音通话的结束按键方法可以参考MainContent.vue中的HangUp方法。
/** * 挂断点击通话 */ hangUp() { if (this.hangUpButton) { EventBus.$emit("hangUp"); clearInterval(this.talkTimeTask); this.hangUpButton = false; this.audioIn = "0"; this.sec = 0; this.min = 0; let msg = { avatar: "zph", text: `<img src="` + audioPng + `" class="footer-image" alt="" style="height: 16px;margin-right: 5px;vertical-align: middle;margin-bottom: 2px">` + "通话时长" + this.infos, type: 0, time: this.$Utils.getDateString(), float: "right", }; if (this.infos!=='呼叫中'){ EventBus.$emit("pushInRecords", JSON.stringify(msg)); } this.infos = "00:00"; } }
该方法会发送hangUp事件:EventBus.$emit("hangUp");在Footer.vue中有该事件的监听,会调用cancel方法。
//音视频挂断 EventBus.$on("hangUp", () => { this.cancel(); });
其中dropClickToCall会调用dropClickToCall接口。
cancel() { if (this.webRtcConfig.activeCall != null) { this.webRtcConfig.activeCall.terminate() this.webRtcConfig.activeCall = null } this.$Chat.dropClickToCall(); }
在视频通话中
- 挂断方法在VideoWindow.vue中的hangUpVideoCall。
2. hangUpVideoCall(){ if (this.videoView){ EventBus.$emit("hangUp"); this.videoView = false; let msg = { avatar: "zph", text: `<img src="`+videoPng+`" class="footer-image" alt="" style="height: 16px;margin-right: 5px;vertical-align: middle;margin-bottom: 2px">`+"通话时长"+this.infos, type: 0, time: this.$Utils.getDateString(), float: "right", }; if (this.infos!=='呼叫中'){ EventBus.$emit("pushInRecords", JSON.stringify(msg)); } this.infos = "00:00"; this.sec = 0; this.min = 0; clearInterval(this.talkTimeTask); this.talkTimeTask = ""; } }
该方法同样会发送hangUp事件,同音频挂断。
2. 停止发送本地视频VideoWindow.vue中的hangUpVideoCall
/** * 视频画面停止 */ videoMuteEvent(){ this.videoIsOff = !this.videoIsOff; EventBus.$emit("videoMute"); }
该方法会发送videoMute事件,在Footer.vue中监听。
EventBus.$on("videoMute", () => { this.videoMute() });
videoMute() { let muted = this.webRtcConfig.activeCall.isVideoMuted() this.webRtcConfig.activeCall.muteVideo(!muted) }
3. 视频静音方法VideoWindow.vue中的audioMuteEvent。
/** * 视频语音静音 */ audioMuteEvent(){ this.voiceIsOff = !this.voiceIsOff; EventBus.$emit("audioMute"); }
该方法会发送audioMute事件,在Footer.vue中监听。
EventBus.$on("audioMute", () => { this.audioMute() })
audioMute() { let muted = this.webRtcConfig.activeCall.isAudioMuted() this.webRtcConfig.activeCall.muteAudio(!muted) }