# 实现视频通话
本文档为您展示通过 插件 实现视频客服(含排队机)以及多方视频会话 的相关步骤。视频客服(含排队机): 帮助您在远程银行和视频客服的场景下实现智能排队、座席转接、全景录像、座席管理的相关能力。
# 1. 前提条件
请确认您已完成以下操作:
- 已获取 App Key。
AppKey 作为同个环境的分域依据,同一个域的终端才能实现互通,AppKey 由 Juphoon 视频平台提供。
- 集成插件。
# 2. 初始化
插件的唤起,根据所需要的 座席/访客/多方 模块初始化插件,后续调用 webPlugin 接口进行业务操作
# 调起插件
创建 WebPlugin 实例,初始化 AgentPlugin 插件。一台设备上只能同时运行一个插件,一个插件只能同时连接要给 Web 。当”第二个“网页试图连接插件时,将会收到 OnEventNotify 警告通知。
<script type="text/javascript">
var webPlugin = new WebPlugin()
webPlugin.init('JRTC.AgentPlugin:'
function () {
// 初始化成功
}, function (err){
// 初始化失败
});
</script>
# 插件初始化
因初始化是一个耗时操作所以 webPlugin.init 接口返回了一个 Promise 对象。用户可以在 Promise 中设置对应的处理方法。
插件 所有可用的接口以及回调事件由全局变量 webPlugin 导出。Web 页面应当只关心页面的交互,音视频渲染交由插件负责。
插件有默认使用的 AppKey ,如果出现分域的情况,座席需在 webPlugin.Init时设置 Appkey以初始化插件。
初始化内置参数:
this.initPluginParam = {
LogConsole: true, // 是否需要控制台日志打印。 true需要;false不需要
LogLocalFile: true, // 是否需要本地文件日志打印。 true需要;false不需要
RpcLoss: false, // RPC抗信令丢包。 true开启;false不开启
IPCameras: [] //如果使用网络摄像头,需要传入网络摄像头的厂商名称列表,目前列表支持为:["Hik", "Dahua"]
}
使用:
var webPlugin = new WebPlugin();
/**
* @desc 初始化
* @param {string} appkey - (可选)不填则使用内部appkey
* @param {string} channel - 渠道标识,控制插件内特殊的渠道标识,如双录插件(JuphoonDualRecord)
*/
webPlugin.initPluginParam.LogConsole = _getCheckboxValue('checkbox-local-log');
webPlugin.initPluginParam.LogLocalFile = _getCheckboxValue('checkbox-local-file-log');
webPlugin.initPluginParam.RpcLoss = _getCheckboxValue('checkbox-rpc-loss');
webPlugin.initPluginParam.IPCameras = ["Hik", "Dahua"];
var appkey = _getValue('checkin-appkey');
webPlugin.Init(appkey, "");
*常用的方法解释:_getValue,_getCheckboxValue,_getSelectedIndex,_getValueNum,notUAN,这些方法可以便捷实现常用代码逻辑,在以下文档中可能会涉及到。
// 通过控件id获取控件值
function _getValue(id) {
return document.getElementById(id).value;
}
// 通过控件id获取控件是否被选择
function _getCheckboxValue(id) {
return document.getElementById(id).checked;
}
// 通过控件id获取控件选择序号
function _getSelectedIndex(id) {
return document.getElementById(id).selectedIndex;
}
// 通过控件id获取控件值并转成数字
function _getValueNum(id) {
return Number(document.getElementById(id).value);
}
// 传入一个值,判断是不是没被定义或者没赋值为null
function notUAN(variable) {
return variable !== null && variable !== undefined;
}
初始化结果通知
var webPlugin = new WebPlugin();
/**
* @desc 初始化结果通知
* @param {boolean} result - 是否成功
* @param {Number} httpServerPort - http服务端口
* @param {Number} videoChannelPort - 视频通道websocket端口
* @param {Number} processId - 当前进程号
*/
webPlugin.OnInitResult = function(result, httpServerPort, videoChannelPort, processId) {
console.log('OnInitResult', result, httpServerPort, videoChannelPort, processId);
};
# 获取插件版本号
获取插件本版号可以不需要插件初始化,只需要连接 websocket 即可。
var webPlugin = new WebPlugin();
webPlugin.GetVersion();
获取插件版本号结果通知:
var webPlugin = new WebPlugin();
webPlugin.OnGetVersionResult = function (version) {
//version
console.log('OnGetVersionResult',version);
};
# 获取插件属性及回调
获取插件属性
var webPlugin = new WebPlugin();
/**
* @desc 获取插件属性
*/
webPlugin.GetProperties();
获取插件属性回调
var webPlugin = new WebPlugin();
/**
* @desc 获取插件属性
* @param {String} content - 属性
*/
webPlugin.OnGetPropertiesResult = function (content) {
console.log('OnGetPropertiesResult', content);
};
# 插件属性改变通知
var webPlugin = new WebPlugin();
/**
* @desc 获取插件属性改变通知
* @param {String} content - 属性
*/
webPlugin.OnPropertiesChangeNotify = function () {
console.log('OnPropertiesChangeNotify');
};
# 设置 AppKey
插件有默认使用的 AppKey ,如果出现分域的情况,需要在登录操作前通过调用 webPlugin.setAppkey 方法设置 Appkey 。
var webPlugin = new WebPlugin();
/**
* @desc 设置AppKey
* @param {string} appkey - appkey
*/
webPlugin.SetAppKey(appKey);
注意:在运行前,请联系 Juphoon 市场售前工程师获取 Appkey。
# 3. 签入
方法内包含登录和签入。座席登录成功后,签入到排队机由排队机进行路由分配。
对于需要 Token 校验的场景,提供携带 Token 信息的签入接口。
var webPlugin = new WebPlugin();
/**
* @desc 签入
* @param {string} account - 用户账号
* @param {string} server - 服务器
* @param {object} extraParam - 其他参数
* 其他参数包含如下:
* token: {string} token - 可选,默认为空
* tokenType: {string} token 校验类型 - 可选,默认为空
* certificate: {string} S3 国密证书 Base64 编码内容 - 可选,默认为空
* displayName: {string} 用户昵称 - 可选,默认为空
* password: {string} 用户密码 - 可选,默认为空
* busy: {boolean} 签入后是否示忙 - 可选,默认 false
* termBusy: {boolean} 通话结束后是否示忙 - 可选,默认 false
* workShift: {string} 座席工作班次,报表数据统计需要 - 可选,默认为空
* workTeam: {string} 座席工作班组,报表数据统计需要 - 可选,默认为空
* businessNumberList: {string} 业务号列表,JSON数组格式,例如:"['10086', '10087']" 如果使用菊风业务管理平台配置的业务号,则不需要设置该参数 - 可选,默认为空
*/
webPlugin.CheckIn(account, server, extraParam);
# 4. 签出
当所有业务处理完毕,座席可以使用 CheckOut 接口来从排队机注销,签出后排队机将不会分发访客到这个座席终端,业务管理平台上该座席的状态将变为离线。
var webPlugin = new WebPlugin();
webPlugin.CheckOut();
# 5. 签出/签入通知
var webPlugin = new WebPlugin();
/**
* @desc 签入状态通知
* @param {string} State - 状态
* - Idle: 初始状态
* - logining: 登录中
* - logined: 登录成功
* - CheckFail: 签入失败
* - Checking: 签入中
* - Checked: 已签入
* - CheckOuting: 签出中
* @param {string} reason - 失败原因
*/
webPlugin.OnCheckStateChangeNotify(state, reason) {
console.log('OnCheckStateChangeNotify', state, reason);
switch (state) {
case 'Idle': // checkout
break;
case 'Logining': // Logining
toolbarChangeState(TOOLBAR_STATE.LOGINING);
break;
case 'Checking': // checking
toolbarChangeState(TOOLBAR_STATE.CHECKING);
break;
case 'CheckFail': // checkfail
SDK_STATE.isCheckin = false;
toolbarChangeState(TOOLBAR_STATE.CHECKFAIL);
break;
case 'Checked': // checked
SDK_STATE.isCheckin = true;
toolbarChangeState(TOOLBAR_STATE.CHECKED);
break;
case 'CheckOuting': // checkout
toolbarChangeState(TOOLBAR_STATE.CHECKOUT);
break;
}
};
# 6. 获取签入状态
用户获取签入状态
var webPlugin = new WebPlugin();
/**
* @desc 获取签入状态
*/
webPlugin.GetCheckState();
获取签入状态结果通知
var webPlugin = new WebPlugin();
/**
* @desc 获取签入状态
* @param {string} state - 当前签入状态
* - Idle 未签入
* - Checking 签入中
* - Checked 已签入
* - CheckOut 签出
*/
webPlugin.OnGetCheckStateResult = function (state) {
console.log('OnGetCheckStateResult', state);
};
# 7. 销毁
var webPlugin = new WebPlugin();
/**
* @desc 销毁
*/
webPlugin.Destroy();
# 8. 实现视频通话
# 跑通 demo
- 在JuphoonSDK RTC 文档中心,选择视频客服座席选择项,在 Demo 体验页面下载体验的示例项目。
- 如果是windows端插件下载完成后,安装 \JCCAgent\ 目录下的 JCCAgentPluginSetup.exe 。
如果是 UOS&Kylin 端插件下载完成后,安装相应的deb。
- 插件安装/运行完成后,打开 \JCCAgent\ 目录下的 JCCAgent.html 网页,就可以拉起插件,运行。
- 打开网页调起插件,检测插件是否成功运行。
- 插件成功运行后,填写正确的账号和服务器地址,点击登录,左侧的座席状态可以实时反馈座席当前的状态。示闲按钮可以控制当前登录的座席能否被呼叫。
- 座席成功登录,点击示闲按钮,座席状态转变为空闲时,即可接受访客呼叫,体验座席插件的功能。
# 示忙示闲
座席的忙闲状态表示当前座席号是否可以被呼叫,在座席签入排队机后设置生效。
- 示忙:座席暂停服务,访客无法呼到该座席
- 示闲:座席保持服务,访客可以呼到该座席
var webPlugin = new WebPlugin();
/**
* @desc 示忙/示闲
*
* @param {boolean} pause - true 示忙,false 示闲
* @param {number} subState - 子状态,报表数据统计需要,取值[0, 9]
* - 0: 默认子状态
* - 1~9: 自定义子状态
*/
// 示忙
webPlugin.ApplyPause(true, 9);
// 示闲
webPlugin.ApplyPause(false, 0);
示忙示闲结果通过 webPlugin.OnApplyPauseResult 回调进行上报。
var webPlugin = new WebPlugin();
/**
* @desc 示忙示闲
* @param {boolean} result - 是否成功
* @param {boolean} pause - 示忙\示闲
* @param {number} subState - 当前子状态
* - 0: 默认
* - -1:无效
*/
webPlugin.OnApplyPauseResult = function (result, pause, subState) {
console.log('OnApplyPauseResult', result, pause);
if (succ) {//操作成功
if(pause){
//TODO 示忙成功后处理
}else{
//TODO 示闲成功后处理
}
} else {
//TODO 操作失败处理
}
};
# 应答
座席接听
var webPlugin = new WebPlugin();
webAgent.Answer();
座席处理收到的来电
var webPlugin = new WebPlugin();
/**
* @desc 通话状态回调
*
* @param {string} type - 类型
* - Incoming 来电中
* - Answering 等待接听
* - Joining 正在加入
* - Calling 呼叫中
* - Waiting 等待中
* - Talking 通话中
* - Term: 挂断
* @param {number} incomingType - 来电类型
* @note 当通话类型为来电时有效
* - -1 无效
* - 0 普通来电
* - 1 三方邀请来电
* - 2 转接来电
* - 3 直呼来电
* @param {string} reason - 原因
* @param {string} fromUserId - 对方用户ID
* @param {string} callId - 通话唯一标识,type=='Talking' 时有效,对应于业务管理平台上的callId,可用于查询录像数据、查询录像上传结果等等
* @param {string} extraParam - 随路参数
*/
webPlugin.OnCallStateChangeNotify = function(type, incomingType, reason, fromUserId, callId, extraParam) {
console.log('OnCallStateChangeNotify', type, incomingType, reason, fromUserId, callId, extraParam);
if(type == 'InComing') {
webAgent.Answer();
}
};
座席接听引起通话状态改变,也是通过OnCallStateChangeNotify上报。
# 通话状态通知
- 座席签入成功后即为一个等待通话接入的状态,如果收到来电,触发通话状态改变为 Incoming 通知;
- 座席在空闲状态下回呼访客成功后,触发通话状态改变为 Waiting 通知;
- 座席接听来电,成功建立通话后,触发通话状态改变为 Talking 通知;
- 座席结束通话或者访客结束通话,触发通话状态改变为 Termed 通知;
通知均由 OnCallStateChangeNotify回调进行上报
var webPlugin = new WebPlugin();
/**
* @desc 通话状态回调
*
* @param {string} type - 类型
* - Incoming 来电中
* - Answering 等待接听
* - Joining 正在加入
* - Calling 呼叫中
* - Waiting 等待中
* - Talking 通话中
* - Term: 挂断
* @param {number} incomingType - 来电类型
* @note 当通话类型为来电时有效
* - -1 无效
* - 0 普通来电
* - 1 三方邀请来电
* - 2 转接来电
* - 3 直呼来电
* @param {string} reason - 原因
* @param {string} fromUserId - 对方用户ID
* @param {string} callId - 通话唯一标识,type=='Talking' 时有效,对应于业务管理平台上的callId,可用于查询录像数据、查询录像上传结果等等
* @param {string} extraParam - 随路参数
*/
webPlugin.OnCallStateChangeNotify = function(type, incomingType, reason, fromUserId, callId, extraParam) {
console.log('OnCallStateChangeNotify', type, reason, fromUserId, callId, extraParam);
switch (type) {
case 'Incoming':
toolbarChangeState(TOOLBAR_STATE.INCOMING);
break;
case 'Waiting':
toolbarChangeState(TOOLBAR_STATE.WAITING);
break;
case 'Talking':
toolbarChangeState(TOOLBAR_STATE.TALKING);
break;
case 'Term':
toolbarChangeState(TOOLBAR_STATE.TERM);
break;
}
};
# 排队人数通知
Juphoon 提供的智能排队服务是纯软件解决方案,相较于传统的排队机,智能排队服务轻量化的纯软件灵活部署模式、完美兼容行方现有的集中作业平台、呼叫中心等系统。
智能排队服务是在座席管理后台里通过对业务组、技能组和座席进行灵活配置,将座席资源按照实际的业务所需进行分组,再通过智能调度中心按照不同调度策略结合当前座席资源使用情况,合理的将来自访客终端的呼叫请求分配至相应的座席。实现大流量访客的合理分流,降低排队流失,优化顾客体验
等待排队人数的通知:
var webPlugin = new WebPlugin();
/**
* @desc 排队人数
* @param {string} count - 人数
*/
webPlugin.OnWaitCountNotify = function (count) {
if (typeof count === 'number') count = count.toString(10);
info.waitCount.textContent = count;
};
# 电子签名
通过 SignRequest 向访客发起电子签名,访客签名结果通过OnSignResult上报:
var webPlugin = new WebPlugin();
/**
* @desc 发起电子签名
* @param userId 选择签名者ID
* @param extraInfo 随路数据
*/
webPlugin.SignRequest(userId, extraInfo)
/**
* @desc 访客签名结果
* @param {boolean} result - 是否成功
* @param {string} content - result 为 true 时为 base64 签名数据
*/
webPlugin.OnSignResult = function(result, content, filePath) {
console.log('OnSignResult', result);
};
# 邀请座席
在通话过程中邀请其他座席进入通话
var webPlugin = new WebPlugin();
/**
* 邀请座席
* @param userId 第三方座席用户ID
* @constructor
*/
webPlugin.InviteThirdAgent(userId);
/**
* @desc 邀请座席结果
* @param {boolean} result - 邀请结果true/false
*/
webPlugin.OnInviteAgentResult = function (result) {
console.log('OnInviteAgentResult', result);
};
# 转接
转接到指定座席
var webPlugin = new WebPlugin();
/**
* 转接到指定座席
* @param userId 座席用户ID
* @constructor
*/
webPlugin.TransferCallToAgent(userId);
转接到指定技能组,将会随机选择业务组中一个空闲座席进行转接。
var webPlugin = new WebPlugin();
/**
* 转接到指定技能组
* @param businessNumber 业务号
* @constructor
*/
webPlugin.TransferCallToGroup(businessNumber);
转接结果:
var webPlugin = new WebPlugin();
/**
* @desc 转接结果
* @param {boolean} result - 邀请结果true/false
*/
webPlugin.OnTransferResult = function (result) {
alertDialog('提示', '转接' + (result ? '成功' : '失败'));
};
# 应答加急
座席处理收到的加急请求
var webPlugin = new WebPlugin();
/**
* @desc 收到加急
* @param {string} serialNumber 业务唯一标识
* @param {string} userId 访客用户ID
*/
webPlugin.OnUrgentRequestRecvNotify = function (serialNumber, userId) {
console.log('NotifyOnUrgentRequestRecv', serialNumber, userId);
};
座席处理加急请求
var webPlugin = new WebPlugin();
/**
* @desc 应答加急
* @param {string} serialNumber 业务唯一标识
* @param {string} userId 访客id
* @param {boolean} Agree 加急是否通过
*/
webPlugin.ResponseUrgent(serialNumber, userId, agree);
座席处理加急的结果
var webPlugin = new WebPlugin();
/**
* @desc 座席处理加急结果
* @param {string} result - true/false
*/
webPlugin.OnUrgentResponseResult = function (result) {
console.log('OnUrgentResponseResult', result);
};
综合应用示例:
var webPlugin = new WebPlugin();
webPlugin.OnUrgentRequestRecvNotify = function (serialNumber, userId) {
console.log('NotifyOnUrgentRequestRecv', serialNumber, userId);
webPlugin.ResponseUrgent(serialNumber, userId, true);
};
webPlugin.OnUrgentResponseResult = function (result) {
console.log('OnUrgentResponseResult', result);
};
# 结束通话
当业务办理结束,访客可以主动结束通话,座席也可以主动结束通话,其中座席挂断的方式如下:
var webPlugin = new WebPlugin();
/**
* @desc 挂断
*/
webPlugin.End();
主动和被动的挂断事件与来电、接通一样,都通过 OnCallStateChangeNotify 回调上报。
# 回呼
呼叫参数
this.joinParam = {
// 公共参数
HeartbeatTime: 20, // 心跳间隔,单位s,初始值-1,默认值20s
HeartbeatTimeOut: 60, // 心跳超时,单位s,初始值-1,默认值60s,最长10min。
EnableRemoteRecord: true, // 是否开启远程录制,true开启,false关闭。默认开启
SecurityType: 0, // 加密方式,0=>不加密;1=>SRTP;2=>SM4。默认不加密
ExtraInfo: '', // 随路信息
VideoDefinition: 0, // 清晰度:0自定义、1流畅、2标清、3高清。默认自定义
SaveFlow: true, // 是否省流 true省流,false不省流
SvcResolution: '1 180 250 360 600 720 1400', // svc分辨率,默认为 "1 180 250 360 600 720 1400"
MaxFrameRate: 24, // 最大帧率 1-30, 默认值为 24
VideoEncodeType: 0, // 视频编码 H264=>0、H265=>1、AV1=>2。默认0
AudioEncodeType: 0, // 音频编码 OPUS=>0、PCMA=>1、PCMU=>2。默认0
BusinessId: '', //业务流水号
// 坐席回呼访客特有参数
Sip: false, // 是否是sip通话,默认语音
SipVideo: false, // 是否是sip视频通话,sip = true时生效
}
座席回呼访客,座席可通过访客的UserId对访客进行呼叫。座席回呼访客的结果通知OnCallGuestResult
var webPlugin = new WebPlugin();
function callGuest() {
var value = _getValue('guest-user-id');
if (value.length <= 0) return;
triggerCallGuest(false);
webPlugin.joinParam.Sip = _getCheckboxValue('checkbox-recall-sip');
webPlugin.joinParam.SipVideo = _getCheckboxValue('checkbox-recall-sip-video');
console.log(webPlugin.joinParam)
webPlugin.CallGuest(value);
webPlugin.OnCallGuestResult = function(result, detail) {
if (!result) {
alert(detail);
}
};
}
# SIP呼入呼出升降级
视频客服座席支持在SIP环境下进行呼入、呼出以及音视频升降级。
- 视频客服签入SIP环境后,在示闲状态下可接听SIP的呼叫。
- 视频客服签入SIP环境后,通过CallGuest回呼功能,设置呼叫参数sip、sipVideo可发起SIP呼叫,参数sip代表着是否使用sip呼叫(默认音频)true是sip呼叫,fasle不是sip呼叫,参数sipVideo表示是否使用sip视频呼叫(需要同时设置参数sip)true是sip视频呼叫,fasle不是sip视频呼叫。被呼叫的访客用户名填写手机号(可带+86)即可。
- SIP通话过程中,可通过TurnCallTypeForSIP接口实现通话音视频升降级,要注意与TurnCallType做好区分。切换类型callType:Audio音频、Video视频。
var webPlugin = new WebPlugin();
function turnCallTypeForSIP(type) {
console.log("turnCallTypeForSIP:" + type)
webPlugin.TurnCallTypeForSIP(type)
}
- SIP切换音视频的事件通过OnSIPCallTypeTurnedNotify,将会上报sip通话时,sip音视频切换的结果。当本端调用TurnCallTypeForSIP时,收到协商结果为同意切换时会上报,当收到sip音视频切换的请求,本端处理结果会上报。上报的类型callType:Audio音频、Video视频。
var webPlugin = new WebPlugin();
webPlugin.OnSIPCallTypeTurnedNotify = function(callType) {
console.log('OnSIPCallTypeTurnedNotify', callType);
};
# 切换指定SIP成员为视频
可以通过该接口设置sip端为视频通话,需要在音频通话通话中使用。没有回调不需要协商。
示例代码:
var webPlugin = new WebPlugin();
/**
* @desc 切换指定SIP成员为视频,没有协商通知直接切换
*
* @param {string} userId - 用户id
* @param {string} extraInfo 扩展参数
*/
webPlugin.TurnVideForSIP(userId, extraInfo);
# 加入通话
主要用于观察者加入,通过观察者座席角色加入后,通话中其他成员无感知,加入成功后会收到OnCallStateChangeNotify 通知
/**
* @desc 加入通话
*
* @param {string} serialNumber 业务唯一标识
* @param {number} role 加入通话成员角色
* 1:次座席角色
* 2:观察者角色
*/
webPlugin.JoinCall(serialNumber, role)
# 切换自己在通话中角色
当进入通话后,可以通过该接口将自己切换成主座席角色,此时原先的主座席会被降为次座席
/**
* @desc 切换自己在通话中角色
*
* @param {string} serialNumber 业务唯一标识
* @param {number} role 通话成员角色
* 0:主座席角色
* 1:次座席角色
*/
webPlugin.SwitchPartRole(role)
/**
* @desc 切换自己在通话中角色结果回调
*
* @param {boolean} result - 是否成功
* @param {string} error - 失败原因
*/
webPlugin.OnSwitchPartRoleResult = function (result, error) {
console.log('OnSwitchPartRoleResult', result, error);
}
# 踢出通话成员
主座席可以踢出通话中其他成员,注意:如果踢出的是主访客,通话将自动结束。
/**
* @desc 踢出通话成员
*
* @param {string} userId 用户ID
*/
webPlugin.KickParticipan(userId)
/**
* @desc 踢出通话成员结果回调
*
* @param {boolean} result - 是否成功
* @param {string} error - 失败原因
*/
this.OnKickParticipantResult = function (result, error) {
console.log('OnKickParticipantResult', result, error);
}
# 成员增加、变化、离开上报
该通知会在加入通话成功后生效,到离开通话后停止生效。上报内容如下:
{Number} state
- 1 成员加入
- 2 成员更新
- 3 成员离开
{String} participant 成员信息json
{String} changeParam 成员属性变化,当state=2时有效
注意:成员的加入和离开不会上报自己,自己的离开和加入通过OnCallStateChangeNotify上报,可查看4.7.4。
var webPlugin = new WebPlugin();
webPlugin.OnMemberUpdate = function(state, participant, changeParam) {
console.log('OnMemberUpdate', state, participant, changeParam);
};
# 座席服务时长
座席签入后,获取座席服务时长。签出后重置。
示例代码:
var webPlugin = new WebPlugin();
webPlugin.GetAgentServiceTime();
# 邀请第三方访客加入(包括sip)
示例代码:
var webPlugin = new WebPlugin();
/**
* 邀请第三方访客加入
*
* @param {string} userId 第三方访客用户ID
* @param {string} extraInfo 扩展参数
* @param {object} param - 其他参数
* 其他参数包含如下:
* IsSip: {boolean} 是否是sip邀请,true是,false不是。默认false。
* IsSipVideo: {boolean} 是否是sip视频,true是视频,false是音频。当sip = true时有效。默认true。
*/
webPlugin.InviteThirdGues(userId, extraInfo, param);
上报通知:
/**
* @desc 获取座席在线时服务时长,签入前和签出后都将重置
* @param {number} time 服务时长,毫秒
*/
webPlugin.OnAgentServiceTimeResult = function(time) {}