ysyt-agent-sdk 1.0.84 → 1.0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ declare class YSYTAgentSdk {
7
7
  private constructor();
8
8
  static get instance(): YSYTAgentSdk;
9
9
  static destroyInstance(): Promise<void>;
10
- static getInstance({ url, appKey, appSecret, agentNo, }: {
10
+ static getInstance(config?: {
11
11
  url?: string;
12
12
  appKey: string;
13
13
  appSecret: string;
@@ -19,9 +19,6 @@ declare class YSYTAgentSdk {
19
19
  * 初始化SDK
20
20
  * @param actionNodeParams
21
21
  * @param url
22
- * @param appKey
23
- * @param appSecret
24
- * @param agentNo 坐席工号
25
22
  * @param enableBrowserAlert 是否开启浏览器通知
26
23
  * @param logBuiltinEnabled 是否开启日志
27
24
  */
@@ -6,9 +6,6 @@ export declare class ReactiveStore<T extends Record<string, any>> {
6
6
  private proxy;
7
7
  constructor(initialState: T);
8
8
  getState(): T;
9
- /**
10
- * 推荐使用的统一更新方法,支持批量更新、保证只触发一次 notify
11
- */
12
9
  setState(partial: Partial<T>, forceNotify?: boolean): void;
13
10
  /**
14
11
  * 订阅整个 state 的变化
@@ -9,7 +9,7 @@
9
9
  * @copyright Chen, Yi-Cyuan 2014-2023
10
10
  * @license MIT
11
11
  */
12
- ve=Oe,function(){var t="input is invalid type",s="object"==typeof window,i=s?window:{};i.JS_MD5_NO_WINDOW&&(s=!1);var r=!s&&"object"==typeof self,o=!i.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;o?i=Ke:r&&(i=self);var n,a=!i.JS_MD5_NO_COMMON_JS&&ve.exports,V=!i.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,c="0123456789abcdef".split(""),h=[128,32768,8388608,-2147483648],l=[0,8,16,24],g=["hex","array","digest","buffer","arrayBuffer","base64"],q="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),d=[];if(V){var p=new ArrayBuffer(68);n=new Uint8Array(p),d=new Uint32Array(p)}var u=Array.isArray;!i.JS_MD5_NO_NODE_JS&&u||(u=function(A){return"[object Array]"===Object.prototype.toString.call(A)});var m=ArrayBuffer.isView;!V||!i.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&m||(m=function(A){return"object"==typeof A&&A.buffer&&A.buffer.constructor===ArrayBuffer});var C=function(A){var e=typeof A;if("string"===e)return[A,!0];if("object"!==e||null===A)throw new Error(t);if(V&&A.constructor===ArrayBuffer)return[new Uint8Array(A),!1];if(!u(A)&&!m(A))throw new Error(t);return[A,!1]},E=function(A){return function(e){return new w(!0).update(e)[A]()}},I=function(s){var r,o=A,n=e.Buffer;return r=n.from&&!i.JS_MD5_NO_BUFFER_FROM?n.from:function(A){return new n(A)},function(A){if("string"==typeof A)return o.createHash("md5").update(A,"utf8").digest("hex");if(null==A)throw new Error(t);return A.constructor===ArrayBuffer&&(A=new Uint8Array(A)),u(A)||m(A)||A.constructor===n?o.createHash("md5").update(r(A)).digest("hex"):s(A)}},M=function(A){return function(e,t){return new f(e,!0).update(t)[A]()}};function w(A){if(A)d[0]=d[16]=d[1]=d[2]=d[3]=d[4]=d[5]=d[6]=d[7]=d[8]=d[9]=d[10]=d[11]=d[12]=d[13]=d[14]=d[15]=0,this.blocks=d,this.buffer8=n;else if(V){var e=new ArrayBuffer(68);this.buffer8=new Uint8Array(e),this.blocks=new Uint32Array(e)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}function f(A,e){var t,s=C(A);if(A=s[0],s[1]){var i,r=[],o=A.length,n=0;for(t=0;t<o;++t)(i=A.charCodeAt(t))<128?r[n++]=i:i<2048?(r[n++]=192|i>>>6,r[n++]=128|63&i):i<55296||i>=57344?(r[n++]=224|i>>>12,r[n++]=128|i>>>6&63,r[n++]=128|63&i):(i=65536+((1023&i)<<10|1023&A.charCodeAt(++t)),r[n++]=240|i>>>18,r[n++]=128|i>>>12&63,r[n++]=128|i>>>6&63,r[n++]=128|63&i);A=r}A.length>64&&(A=new w(!0).update(A).array());var a=[],V=[];for(t=0;t<64;++t){var c=A[t]||0;a[t]=92^c,V[t]=54^c}w.call(this,e),this.update(V),this.oKeyPad=a,this.inner=!0,this.sharedMemory=e}w.prototype.update=function(A){if(this.finalized)throw new Error("finalize already called");var e=C(A);A=e[0];for(var t,s,i=e[1],r=0,o=A.length,n=this.blocks,a=this.buffer8;r<o;){if(this.hashed&&(this.hashed=!1,n[0]=n[16],n[16]=n[1]=n[2]=n[3]=n[4]=n[5]=n[6]=n[7]=n[8]=n[9]=n[10]=n[11]=n[12]=n[13]=n[14]=n[15]=0),i)if(V)for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?a[s++]=t:t<2048?(a[s++]=192|t>>>6,a[s++]=128|63&t):t<55296||t>=57344?(a[s++]=224|t>>>12,a[s++]=128|t>>>6&63,a[s++]=128|63&t):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),a[s++]=240|t>>>18,a[s++]=128|t>>>12&63,a[s++]=128|t>>>6&63,a[s++]=128|63&t);else for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?n[s>>>2]|=t<<l[3&s++]:t<2048?(n[s>>>2]|=(192|t>>>6)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):t<55296||t>=57344?(n[s>>>2]|=(224|t>>>12)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),n[s>>>2]|=(240|t>>>18)<<l[3&s++],n[s>>>2]|=(128|t>>>12&63)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]);else if(V)for(s=this.start;r<o&&s<64;++r)a[s++]=A[r];else for(s=this.start;r<o&&s<64;++r)n[s>>>2]|=A[r]<<l[3&s++];this.lastByteIndex=s,this.bytes+=s-this.start,s>=64?(this.start=s-64,this.hash(),this.hashed=!0):this.start=s}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296|0,this.bytes=this.bytes%4294967296),this},w.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var A=this.blocks,e=this.lastByteIndex;A[e>>>2]|=h[3&e],e>=56&&(this.hashed||this.hash(),A[0]=A[16],A[16]=A[1]=A[2]=A[3]=A[4]=A[5]=A[6]=A[7]=A[8]=A[9]=A[10]=A[11]=A[12]=A[13]=A[14]=A[15]=0),A[14]=this.bytes<<3,A[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},w.prototype.hash=function(){var A,e,t,s,i,r,o=this.blocks;this.first?e=((e=((A=((A=o[0]-680876937)<<7|A>>>25)-271733879|0)^(t=((t=(-271733879^(s=((s=(-1732584194^2004318071&A)+o[1]-117830708)<<12|s>>>20)+A|0)&(-271733879^A))+o[2]-1126478375)<<17|t>>>15)+s|0)&(s^A))+o[3]-1316259209)<<22|e>>>10)+t|0:(A=this.h0,e=this.h1,t=this.h2,e=((e+=((A=((A+=((s=this.h3)^e&(t^s))+o[0]-680876936)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[1]-389564586)<<12|s>>>20)+A|0)&(A^e))+o[2]+606105819)<<17|t>>>15)+s|0)&(s^A))+o[3]-1044525330)<<22|e>>>10)+t|0),e=((e+=((A=((A+=(s^e&(t^s))+o[4]-176418897)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[5]+1200080426)<<12|s>>>20)+A|0)&(A^e))+o[6]-1473231341)<<17|t>>>15)+s|0)&(s^A))+o[7]-45705983)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[8]+1770035416)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[9]-1958414417)<<12|s>>>20)+A|0)&(A^e))+o[10]-42063)<<17|t>>>15)+s|0)&(s^A))+o[11]-1990404162)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[12]+1804603682)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[13]-40341101)<<12|s>>>20)+A|0)&(A^e))+o[14]-1502002290)<<17|t>>>15)+s|0)&(s^A))+o[15]+1236535329)<<22|e>>>10)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[1]-165796510)<<5|A>>>27)+e|0)^e))+o[6]-1069501632)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[11]+643717713)<<14|t>>>18)+s|0)^s))+o[0]-373897302)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[5]-701558691)<<5|A>>>27)+e|0)^e))+o[10]+38016083)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[15]-660478335)<<14|t>>>18)+s|0)^s))+o[4]-405537848)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[9]+568446438)<<5|A>>>27)+e|0)^e))+o[14]-1019803690)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[3]-187363961)<<14|t>>>18)+s|0)^s))+o[8]+1163531501)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[13]-1444681467)<<5|A>>>27)+e|0)^e))+o[2]-51403784)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[7]+1735328473)<<14|t>>>18)+s|0)^s))+o[12]-1926607734)<<20|e>>>12)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[5]-378558)<<4|A>>>28)+e|0))+o[8]-2022574463)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[11]+1839030562)<<16|t>>>16)+s|0))+o[14]-35309556)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[1]-1530992060)<<4|A>>>28)+e|0))+o[4]+1272893353)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[7]-155497632)<<16|t>>>16)+s|0))+o[10]-1094730640)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[13]+681279174)<<4|A>>>28)+e|0))+o[0]-358537222)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[3]-722521979)<<16|t>>>16)+s|0))+o[6]+76029189)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[9]-640364487)<<4|A>>>28)+e|0))+o[12]-421815835)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[15]+530742520)<<16|t>>>16)+s|0))+o[2]-995338651)<<23|e>>>9)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[0]-198630844)<<6|A>>>26)+e|0)|~t))+o[7]+1126891415)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[14]-1416354905)<<15|t>>>17)+s|0)|~A))+o[5]-57434055)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[12]+1700485571)<<6|A>>>26)+e|0)|~t))+o[3]-1894986606)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[10]-1051523)<<15|t>>>17)+s|0)|~A))+o[1]-2054922799)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[8]+1873313359)<<6|A>>>26)+e|0)|~t))+o[15]-30611744)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[6]-1560198380)<<15|t>>>17)+s|0)|~A))+o[13]+1309151649)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[4]-145523070)<<6|A>>>26)+e|0)|~t))+o[11]-1120210379)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[2]+718787259)<<15|t>>>17)+s|0)|~A))+o[9]-343485551)<<21|e>>>11)+t|0,this.first?(this.h0=A+1732584193|0,this.h1=e-271733879|0,this.h2=t-1732584194|0,this.h3=s+271733878|0,this.first=!1):(this.h0=this.h0+A|0,this.h1=this.h1+e|0,this.h2=this.h2+t|0,this.h3=this.h3+s|0)},w.prototype.hex=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return c[A>>>4&15]+c[15&A]+c[A>>>12&15]+c[A>>>8&15]+c[A>>>20&15]+c[A>>>16&15]+c[A>>>28&15]+c[A>>>24&15]+c[e>>>4&15]+c[15&e]+c[e>>>12&15]+c[e>>>8&15]+c[e>>>20&15]+c[e>>>16&15]+c[e>>>28&15]+c[e>>>24&15]+c[t>>>4&15]+c[15&t]+c[t>>>12&15]+c[t>>>8&15]+c[t>>>20&15]+c[t>>>16&15]+c[t>>>28&15]+c[t>>>24&15]+c[s>>>4&15]+c[15&s]+c[s>>>12&15]+c[s>>>8&15]+c[s>>>20&15]+c[s>>>16&15]+c[s>>>28&15]+c[s>>>24&15]},w.prototype.toString=w.prototype.hex,w.prototype.digest=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return[255&A,A>>>8&255,A>>>16&255,A>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255,255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&s,s>>>8&255,s>>>16&255,s>>>24&255]},w.prototype.array=w.prototype.digest,w.prototype.arrayBuffer=function(){this.finalize();var A=new ArrayBuffer(16),e=new Uint32Array(A);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,A},w.prototype.buffer=w.prototype.arrayBuffer,w.prototype.base64=function(){for(var A,e,t,s="",i=this.array(),r=0;r<15;)A=i[r++],e=i[r++],t=i[r++],s+=q[A>>>2]+q[63&(A<<4|e>>>4)]+q[63&(e<<2|t>>>6)]+q[63&t];return A=i[r],s+=q[A>>>2]+q[A<<4&63]+"=="},f.prototype=new w,f.prototype.finalize=function(){if(w.prototype.finalize.call(this),this.inner){this.inner=!1;var A=this.array();w.call(this,this.sharedMemory),this.update(this.oKeyPad),this.update(A),w.prototype.finalize.call(this)}};var B=function(){var A=E("hex");o&&(A=I(A)),A.create=function(){return new w},A.update=function(e){return A.create().update(e)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=E(t)}return A}();B.md5=B,B.md5.hmac=function(){var A=M("hex");A.create=function(A){return new f(A)},A.update=function(e,t){return A.create(e).update(t)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=M(t)}return A}(),a?ve.exports=B:i.md5=B}();var Ne=Oe.exports;const be=(A,e)=>{const t=Date.now(),s=`${A}:${t}:${Ne.md5(`${e}${t}`)}`,i=(new TextEncoder).encode(s);return btoa(String.fromCharCode(...i))},Je="/v1/aicc/bmserver",He="/v1/aicc/ccs";let je="",Le="",We="",Pe="";async function ze(A,e){const t=function(){const A=be(Le,We);return Ze.create({prefixUrl:`${je}/api`,timeout:!1,headers:{Authorization:A},hooks:{afterResponse:[async(A,e,t)=>{const s=await t.clone().json();if(0!==s.code)throw new Error(JSON.stringify(s)||"请求失败");return t.json=async()=>s,t}]}})}(),s=A.replace(/^\/+/,"");return t.post(s,{json:e}).json()}const Xe=A=>ze(`${He}/state/change`,A);const _e=new class extends $A{updateRttObject(A){this.setState({rttObject:A}),ae.emit(exports.EventName.WEBSITE_DELAY,A)}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class $e{constructor(A,e){this.config=A,this.eventCallback=e,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.isManuallyStopped=!1,this.handleNetworkInfoChange=A=>{if(A.rttObject?.rtt){0===(A.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())}},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString()),this.destroy()},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString()),this.reconnect()},_e.subscribe(this.handleNetworkInfoChange)}async start(){const A=_A.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!A)throw new Error("无效的SIP配置");const e={uri:A,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:30},contactName:this.config.user,contactParams:{transport:"wss"},userAgentString:"SwiftSIP/1.0.74",sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:400},logBuiltinEnabled:Ve.logBuiltinEnabled};this.userAgent=new _A(e),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(A=>{let e;switch(A){case AA.Connecting:e=exports.WebRtcCallSipEventEnum.WEB_RTC_CONNECTING;break;case AA.Connected:e=exports.WebRtcCallSipEventEnum.WEB_RTC_CONNECTED,this.reconnectAttempts=0,Ve.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case AA.Disconnecting:e=exports.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTING;break;case AA.Disconnected:{if(this.isManuallyStopped)return void console.warn("[SIP] 手动断开,不触发重连");e=exports.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTED;const A=he.get("answerDevice");if(!Ve.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===A){this.reconnectAttempts++;const A=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${A}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},A)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:e="unknown"}this.eventCallback?.({type:e})}),this.userAgent.delegate={onInvite:A=>{this.handleIncomingCall(A)}})}async register(){if(this.userAgent){this.registerer=new rA(this.userAgent),this.registerer?.stateChange.addListener(A=>{let e;switch(A){case _.Initial:e="initial";break;case _.Registered:e=exports.WebRtcCallSipEventEnum.WEB_RTC_REGISTERED;break;case _.Unregistered:e=exports.WebRtcCallSipEventEnum.WEB_RTC_UNREGISTERED;break;case _.Terminated:e=exports.WebRtcCallSipEventEnum.WEB_RTC_TERMINATED;break;default:e="unknown"}this.eventCallback?.({type:e})});try{await this.registerer.register()}catch(A){this.eventCallback?.({type:exports.WebRtcCallSipEventEnum.WEB_RTC_REGISTER_FAILED,data:A})}}}attachRemoteAudio(A){const e=A.sessionDescriptionHandler;if(e){const A=e.peerConnection;if(!A)return;const t=new MediaStream;A.getReceivers().forEach(A=>{A.track&&"audio"===A.track.kind&&t.addTrack(A.track)});let s=document.getElementById("sip-remote-audio");s||(s=document.createElement("audio"),s.id="sip-remote-audio",s.autoplay=!0,s.style.display="none",document.body.appendChild(s)),s.srcObject=t,s.play().catch(A=>{console.error("音频播放失败,需要用户交互触发",A)})}}handleSessionState(A,e,t){A.stateChange.addListener(e=>{switch(e){case j.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=A,this.attachRemoteAudio(A);break;case j.Terminating:break;case j.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case j.Establishing:}})}handleIncomingCall(A){this.incomingInvitation=A,this.handleSessionState(A,!1);const{soft_device_auto_answer:e,auto_answer_time:t}=Ve.agentInfo,s=he.get("direction"),i=1===e;if(s===exports.DirectionEnum.OUTGOING)this.answerCall();else if(i&&s===exports.DirectionEnum.INCOMING){const A=Number(t)||0;A>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},A):this.answerCall()}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{this.activeSession=this.incomingInvitation,await this.incomingInvitation.accept(),this.incomingInvitation=null}catch(A){this.eventCallback?.({type:exports.WebRtcCallSipEventEnum.WEB_RTC_ANSWER_FAILED,data:{detail:A}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,he.updateDirection(null),he.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(A){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:A}})}}sendDTMF(A){if(!this.activeSession)throw new Error("当前没有活跃的通话");const e=this.activeSession.sessionDescriptionHandler;e&&"function"==typeof e.sendDtmf?(e.sendDtmf(A),this.eventCallback?.({type:exports.WebRtcCallSipEventEnum.WEB_RTC_SEND_DTMF,data:{tone:A}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession,this.activeSession){clearTimeout(this.callTimeoutTimer);const A=this.activeSession;if(!A)return;const e=A.state;try{e===j.Established?await A.bye():e===j.Establishing&&(A instanceof X?await A.cancel():A instanceof z&&await A.reject()),clearTimeout(this.callTimeoutTimer)}catch(A){console.error("挂断失败",A)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof z&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(this.isManuallyStopped=!0,clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(A){console.warn("注销失败",A)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!Ve.isRtcReconnecting){Ve.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),this.isOffline=!1}catch(A){console.error("重连失败",A)}finally{Ve.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const A=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!A)return null;const e=await A.getStats(),t={};return e.forEach(A=>{"candidate-pair"===A.type&&"succeeded"===A.state&&null!=A.currentRoundTripTime&&(t.rtt=+(1e3*A.currentRoundTripTime).toFixed(2)),"inbound-rtp"===A.type&&"audio"===A.kind&&(t.jitter=+(1e3*A.jitter).toFixed(2),t.packetsLost=A.packetsLost,t.packetsReceived=A.packetsReceived,A.bytesReceived&&A.timestamp&&(t.recvBitrate=+(A.bytesReceived/1024).toFixed(2))),"outbound-rtp"===A.type&&"audio"===A.kind&&(t.packetsSent=A.packetsSent,A.bytesSent&&A.timestamp&&(t.sendBitrate=+(A.bytesSent/1024).toFixed(2))),"codec"===A.type&&A.mimeType&&(t.codec=A.mimeType)}),{...t,rtt:t?.rtt||40}}try{const A=Date.now();await ze(`${Je}/config/ping`,{});const e=Date.now();return{rtt:e-A||1}}catch(A){}}}
12
+ ve=Oe,function(){var t="input is invalid type",s="object"==typeof window,i=s?window:{};i.JS_MD5_NO_WINDOW&&(s=!1);var r=!s&&"object"==typeof self,o=!i.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;o?i=Ke:r&&(i=self);var n,a=!i.JS_MD5_NO_COMMON_JS&&ve.exports,V=!i.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,c="0123456789abcdef".split(""),h=[128,32768,8388608,-2147483648],l=[0,8,16,24],g=["hex","array","digest","buffer","arrayBuffer","base64"],q="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),d=[];if(V){var p=new ArrayBuffer(68);n=new Uint8Array(p),d=new Uint32Array(p)}var u=Array.isArray;!i.JS_MD5_NO_NODE_JS&&u||(u=function(A){return"[object Array]"===Object.prototype.toString.call(A)});var m=ArrayBuffer.isView;!V||!i.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&m||(m=function(A){return"object"==typeof A&&A.buffer&&A.buffer.constructor===ArrayBuffer});var C=function(A){var e=typeof A;if("string"===e)return[A,!0];if("object"!==e||null===A)throw new Error(t);if(V&&A.constructor===ArrayBuffer)return[new Uint8Array(A),!1];if(!u(A)&&!m(A))throw new Error(t);return[A,!1]},E=function(A){return function(e){return new w(!0).update(e)[A]()}},I=function(s){var r,o=A,n=e.Buffer;return r=n.from&&!i.JS_MD5_NO_BUFFER_FROM?n.from:function(A){return new n(A)},function(A){if("string"==typeof A)return o.createHash("md5").update(A,"utf8").digest("hex");if(null==A)throw new Error(t);return A.constructor===ArrayBuffer&&(A=new Uint8Array(A)),u(A)||m(A)||A.constructor===n?o.createHash("md5").update(r(A)).digest("hex"):s(A)}},M=function(A){return function(e,t){return new f(e,!0).update(t)[A]()}};function w(A){if(A)d[0]=d[16]=d[1]=d[2]=d[3]=d[4]=d[5]=d[6]=d[7]=d[8]=d[9]=d[10]=d[11]=d[12]=d[13]=d[14]=d[15]=0,this.blocks=d,this.buffer8=n;else if(V){var e=new ArrayBuffer(68);this.buffer8=new Uint8Array(e),this.blocks=new Uint32Array(e)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}function f(A,e){var t,s=C(A);if(A=s[0],s[1]){var i,r=[],o=A.length,n=0;for(t=0;t<o;++t)(i=A.charCodeAt(t))<128?r[n++]=i:i<2048?(r[n++]=192|i>>>6,r[n++]=128|63&i):i<55296||i>=57344?(r[n++]=224|i>>>12,r[n++]=128|i>>>6&63,r[n++]=128|63&i):(i=65536+((1023&i)<<10|1023&A.charCodeAt(++t)),r[n++]=240|i>>>18,r[n++]=128|i>>>12&63,r[n++]=128|i>>>6&63,r[n++]=128|63&i);A=r}A.length>64&&(A=new w(!0).update(A).array());var a=[],V=[];for(t=0;t<64;++t){var c=A[t]||0;a[t]=92^c,V[t]=54^c}w.call(this,e),this.update(V),this.oKeyPad=a,this.inner=!0,this.sharedMemory=e}w.prototype.update=function(A){if(this.finalized)throw new Error("finalize already called");var e=C(A);A=e[0];for(var t,s,i=e[1],r=0,o=A.length,n=this.blocks,a=this.buffer8;r<o;){if(this.hashed&&(this.hashed=!1,n[0]=n[16],n[16]=n[1]=n[2]=n[3]=n[4]=n[5]=n[6]=n[7]=n[8]=n[9]=n[10]=n[11]=n[12]=n[13]=n[14]=n[15]=0),i)if(V)for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?a[s++]=t:t<2048?(a[s++]=192|t>>>6,a[s++]=128|63&t):t<55296||t>=57344?(a[s++]=224|t>>>12,a[s++]=128|t>>>6&63,a[s++]=128|63&t):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),a[s++]=240|t>>>18,a[s++]=128|t>>>12&63,a[s++]=128|t>>>6&63,a[s++]=128|63&t);else for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?n[s>>>2]|=t<<l[3&s++]:t<2048?(n[s>>>2]|=(192|t>>>6)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):t<55296||t>=57344?(n[s>>>2]|=(224|t>>>12)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),n[s>>>2]|=(240|t>>>18)<<l[3&s++],n[s>>>2]|=(128|t>>>12&63)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]);else if(V)for(s=this.start;r<o&&s<64;++r)a[s++]=A[r];else for(s=this.start;r<o&&s<64;++r)n[s>>>2]|=A[r]<<l[3&s++];this.lastByteIndex=s,this.bytes+=s-this.start,s>=64?(this.start=s-64,this.hash(),this.hashed=!0):this.start=s}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296|0,this.bytes=this.bytes%4294967296),this},w.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var A=this.blocks,e=this.lastByteIndex;A[e>>>2]|=h[3&e],e>=56&&(this.hashed||this.hash(),A[0]=A[16],A[16]=A[1]=A[2]=A[3]=A[4]=A[5]=A[6]=A[7]=A[8]=A[9]=A[10]=A[11]=A[12]=A[13]=A[14]=A[15]=0),A[14]=this.bytes<<3,A[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},w.prototype.hash=function(){var A,e,t,s,i,r,o=this.blocks;this.first?e=((e=((A=((A=o[0]-680876937)<<7|A>>>25)-271733879|0)^(t=((t=(-271733879^(s=((s=(-1732584194^2004318071&A)+o[1]-117830708)<<12|s>>>20)+A|0)&(-271733879^A))+o[2]-1126478375)<<17|t>>>15)+s|0)&(s^A))+o[3]-1316259209)<<22|e>>>10)+t|0:(A=this.h0,e=this.h1,t=this.h2,e=((e+=((A=((A+=((s=this.h3)^e&(t^s))+o[0]-680876936)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[1]-389564586)<<12|s>>>20)+A|0)&(A^e))+o[2]+606105819)<<17|t>>>15)+s|0)&(s^A))+o[3]-1044525330)<<22|e>>>10)+t|0),e=((e+=((A=((A+=(s^e&(t^s))+o[4]-176418897)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[5]+1200080426)<<12|s>>>20)+A|0)&(A^e))+o[6]-1473231341)<<17|t>>>15)+s|0)&(s^A))+o[7]-45705983)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[8]+1770035416)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[9]-1958414417)<<12|s>>>20)+A|0)&(A^e))+o[10]-42063)<<17|t>>>15)+s|0)&(s^A))+o[11]-1990404162)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[12]+1804603682)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[13]-40341101)<<12|s>>>20)+A|0)&(A^e))+o[14]-1502002290)<<17|t>>>15)+s|0)&(s^A))+o[15]+1236535329)<<22|e>>>10)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[1]-165796510)<<5|A>>>27)+e|0)^e))+o[6]-1069501632)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[11]+643717713)<<14|t>>>18)+s|0)^s))+o[0]-373897302)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[5]-701558691)<<5|A>>>27)+e|0)^e))+o[10]+38016083)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[15]-660478335)<<14|t>>>18)+s|0)^s))+o[4]-405537848)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[9]+568446438)<<5|A>>>27)+e|0)^e))+o[14]-1019803690)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[3]-187363961)<<14|t>>>18)+s|0)^s))+o[8]+1163531501)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[13]-1444681467)<<5|A>>>27)+e|0)^e))+o[2]-51403784)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[7]+1735328473)<<14|t>>>18)+s|0)^s))+o[12]-1926607734)<<20|e>>>12)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[5]-378558)<<4|A>>>28)+e|0))+o[8]-2022574463)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[11]+1839030562)<<16|t>>>16)+s|0))+o[14]-35309556)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[1]-1530992060)<<4|A>>>28)+e|0))+o[4]+1272893353)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[7]-155497632)<<16|t>>>16)+s|0))+o[10]-1094730640)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[13]+681279174)<<4|A>>>28)+e|0))+o[0]-358537222)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[3]-722521979)<<16|t>>>16)+s|0))+o[6]+76029189)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[9]-640364487)<<4|A>>>28)+e|0))+o[12]-421815835)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[15]+530742520)<<16|t>>>16)+s|0))+o[2]-995338651)<<23|e>>>9)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[0]-198630844)<<6|A>>>26)+e|0)|~t))+o[7]+1126891415)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[14]-1416354905)<<15|t>>>17)+s|0)|~A))+o[5]-57434055)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[12]+1700485571)<<6|A>>>26)+e|0)|~t))+o[3]-1894986606)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[10]-1051523)<<15|t>>>17)+s|0)|~A))+o[1]-2054922799)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[8]+1873313359)<<6|A>>>26)+e|0)|~t))+o[15]-30611744)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[6]-1560198380)<<15|t>>>17)+s|0)|~A))+o[13]+1309151649)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[4]-145523070)<<6|A>>>26)+e|0)|~t))+o[11]-1120210379)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[2]+718787259)<<15|t>>>17)+s|0)|~A))+o[9]-343485551)<<21|e>>>11)+t|0,this.first?(this.h0=A+1732584193|0,this.h1=e-271733879|0,this.h2=t-1732584194|0,this.h3=s+271733878|0,this.first=!1):(this.h0=this.h0+A|0,this.h1=this.h1+e|0,this.h2=this.h2+t|0,this.h3=this.h3+s|0)},w.prototype.hex=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return c[A>>>4&15]+c[15&A]+c[A>>>12&15]+c[A>>>8&15]+c[A>>>20&15]+c[A>>>16&15]+c[A>>>28&15]+c[A>>>24&15]+c[e>>>4&15]+c[15&e]+c[e>>>12&15]+c[e>>>8&15]+c[e>>>20&15]+c[e>>>16&15]+c[e>>>28&15]+c[e>>>24&15]+c[t>>>4&15]+c[15&t]+c[t>>>12&15]+c[t>>>8&15]+c[t>>>20&15]+c[t>>>16&15]+c[t>>>28&15]+c[t>>>24&15]+c[s>>>4&15]+c[15&s]+c[s>>>12&15]+c[s>>>8&15]+c[s>>>20&15]+c[s>>>16&15]+c[s>>>28&15]+c[s>>>24&15]},w.prototype.toString=w.prototype.hex,w.prototype.digest=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return[255&A,A>>>8&255,A>>>16&255,A>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255,255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&s,s>>>8&255,s>>>16&255,s>>>24&255]},w.prototype.array=w.prototype.digest,w.prototype.arrayBuffer=function(){this.finalize();var A=new ArrayBuffer(16),e=new Uint32Array(A);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,A},w.prototype.buffer=w.prototype.arrayBuffer,w.prototype.base64=function(){for(var A,e,t,s="",i=this.array(),r=0;r<15;)A=i[r++],e=i[r++],t=i[r++],s+=q[A>>>2]+q[63&(A<<4|e>>>4)]+q[63&(e<<2|t>>>6)]+q[63&t];return A=i[r],s+=q[A>>>2]+q[A<<4&63]+"=="},f.prototype=new w,f.prototype.finalize=function(){if(w.prototype.finalize.call(this),this.inner){this.inner=!1;var A=this.array();w.call(this,this.sharedMemory),this.update(this.oKeyPad),this.update(A),w.prototype.finalize.call(this)}};var B=function(){var A=E("hex");o&&(A=I(A)),A.create=function(){return new w},A.update=function(e){return A.create().update(e)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=E(t)}return A}();B.md5=B,B.md5.hmac=function(){var A=M("hex");A.create=function(A){return new f(A)},A.update=function(e,t){return A.create(e).update(t)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=M(t)}return A}(),a?ve.exports=B:i.md5=B}();var Ne=Oe.exports;const be=(A,e)=>{const t=Date.now(),s=`${A}:${t}:${Ne.md5(`${e}${t}`)}`,i=(new TextEncoder).encode(s);return btoa(String.fromCharCode(...i))},Je="/v1/aicc/bmserver",He="/v1/aicc/ccs";let je="",Le="",We="",Pe="";async function ze(A,e){const t=function(){const A=be(Le,We);return Ze.create({prefixUrl:`${je}/api`,timeout:!1,headers:{Authorization:A},hooks:{afterResponse:[async(A,e,t)=>{const s=await t.clone().json();if(0!==s.code)throw new Error(JSON.stringify(s)||"请求失败");return t.json=async()=>s,t}]}})}(),s=A.replace(/^\/+/,"");return t.post(s,{json:e}).json()}const Xe=A=>ze(`${He}/state/change`,A);const _e=new class extends $A{updateRttObject(A){this.setState({rttObject:A}),ae.emit(exports.EventName.WEBSITE_DELAY,A)}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class $e{constructor(A,e){this.config=A,this.eventCallback=e,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.isManuallyStopped=!1,this.handleNetworkInfoChange=A=>{if(A.rttObject?.rtt){0===(A.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())}},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString()),this.destroy()},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString()),this.reconnect()},_e.subscribe(this.handleNetworkInfoChange)}async start(){const A=_A.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!A)throw new Error("无效的SIP配置");const e={uri:A,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:30},contactName:this.config.user,contactParams:{transport:"wss"},userAgentString:"SwiftSIP/1.0.74",sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:3},logBuiltinEnabled:Ve.logBuiltinEnabled};this.userAgent=new _A(e),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(A=>{let e;switch(A){case AA.Connecting:e=exports.WebRtcCallSipEventEnum.WEB_RTC_CONNECTING;break;case AA.Connected:e=exports.WebRtcCallSipEventEnum.WEB_RTC_CONNECTED,this.reconnectAttempts=0,Ve.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case AA.Disconnecting:e=exports.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTING;break;case AA.Disconnected:{if(this.isManuallyStopped)return void console.warn("[SIP] 手动断开,不触发重连");e=exports.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTED;const A=he.get("answerDevice");if(!Ve.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===A){this.reconnectAttempts++;const A=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${A}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},A)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:e="unknown"}this.eventCallback?.({type:e})}),this.userAgent.delegate={onInvite:A=>{this.handleIncomingCall(A)}})}async register(){if(this.userAgent){this.registerer=new rA(this.userAgent),this.registerer?.stateChange.addListener(A=>{let e;switch(A){case _.Initial:e="initial";break;case _.Registered:e=exports.WebRtcCallSipEventEnum.WEB_RTC_REGISTERED;break;case _.Unregistered:e=exports.WebRtcCallSipEventEnum.WEB_RTC_UNREGISTERED;break;case _.Terminated:e=exports.WebRtcCallSipEventEnum.WEB_RTC_TERMINATED;break;default:e="unknown"}this.eventCallback?.({type:e})});try{await this.registerer.register()}catch(A){this.eventCallback?.({type:exports.WebRtcCallSipEventEnum.WEB_RTC_REGISTER_FAILED,data:A})}}}attachRemoteAudio(A){const e=A.sessionDescriptionHandler;if(e){const A=e.peerConnection;if(!A)return;const t=new MediaStream;A.getReceivers().forEach(A=>{A.track&&"audio"===A.track.kind&&t.addTrack(A.track)});let s=document.getElementById("sip-remote-audio");s||(s=document.createElement("audio"),s.id="sip-remote-audio",s.autoplay=!0,s.style.display="none",document.body.appendChild(s)),s.srcObject=t,s.play().catch(A=>{console.error("音频播放失败,需要用户交互触发",A)})}}handleSessionState(A,e,t){A.stateChange.addListener(e=>{switch(e){case j.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=A,this.attachRemoteAudio(A);break;case j.Terminating:break;case j.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case j.Establishing:}})}handleIncomingCall(A){this.incomingInvitation=A,this.handleSessionState(A,!1);const{soft_device_auto_answer:e,auto_answer_time:t}=Ve.agentInfo,s=he.get("direction"),i=1===e;if(s===exports.DirectionEnum.OUTGOING)this.answerCall();else if(i&&s===exports.DirectionEnum.INCOMING){const A=Number(t)||0;A>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},A):this.answerCall()}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{await this.incomingInvitation.accept(),this.activeSession=this.incomingInvitation,this.incomingInvitation=null}catch(A){this.eventCallback?.({type:exports.WebRtcCallSipEventEnum.WEB_RTC_ANSWER_FAILED,data:{detail:A}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,he.updateDirection(null),he.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(A){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:A}})}}sendDTMF(A){if(!this.activeSession)throw new Error("当前没有活跃的通话");const e=this.activeSession.sessionDescriptionHandler;e&&"function"==typeof e.sendDtmf?(e.sendDtmf(A),this.eventCallback?.({type:exports.WebRtcCallSipEventEnum.WEB_RTC_SEND_DTMF,data:{tone:A}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession,this.activeSession){clearTimeout(this.callTimeoutTimer);const A=this.activeSession;if(!A)return;const e=A.state;try{e===j.Established?await A.bye():e===j.Establishing&&(A instanceof X?await A.cancel():A instanceof z&&await A.reject()),clearTimeout(this.callTimeoutTimer)}catch(A){console.error("挂断失败",A)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof z&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(this.isManuallyStopped=!0,clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(A){console.warn("注销失败",A)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!Ve.isRtcReconnecting){Ve.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),this.isOffline=!1}catch(A){console.error("重连失败",A)}finally{Ve.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const A=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!A)return null;const e=await A.getStats(),t={};return e.forEach(A=>{"candidate-pair"===A.type&&"succeeded"===A.state&&null!=A.currentRoundTripTime&&(t.rtt=+(1e3*A.currentRoundTripTime).toFixed(2)),"inbound-rtp"===A.type&&"audio"===A.kind&&(t.jitter=+(1e3*A.jitter).toFixed(2),t.packetsLost=A.packetsLost,t.packetsReceived=A.packetsReceived,A.bytesReceived&&A.timestamp&&(t.recvBitrate=+(A.bytesReceived/1024).toFixed(2))),"outbound-rtp"===A.type&&"audio"===A.kind&&(t.packetsSent=A.packetsSent,A.bytesSent&&A.timestamp&&(t.sendBitrate=+(A.bytesSent/1024).toFixed(2))),"codec"===A.type&&A.mimeType&&(t.codec=A.mimeType)}),{...t,rtt:t?.rtt||40}}try{const A=Date.now();await ze(`${Je}/config/ping`,{});const e=Date.now();return{rtt:e-A||1}}catch(A){}}}
13
13
  /**
14
14
  * @license
15
15
  * Copyright 2019 Google LLC
@@ -911,4 +911,4 @@ const Cs=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
911
911
  `:""}
912
912
  </div>
913
913
  </my-popover>
914
- `;is(s,this.rttHTML)}}class Ks{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Os=console.log,Ns=(...A)=>{Ve.logBuiltinEnabled&&Os(...A)};let bs=null;class Js{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new ks,this.initWebSocket()}static getInstance(A){if(!bs){if(!A)throw new Error("WebSocket 尚未初始化");bs=new Js(A)}return bs}stateIdleChange(){const{state:A}=Ve.stateObject;A!==exports.AgentStatus.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Ns("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===exports.WebsocketTypeEnum.OUT_CALL&&(0!==i?(he.reset(),ae.emit(exports.CallSipCallEvent.OUT_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(exports.CallSipCallEvent.OUT_SUCCESS)),t===exports.WebsocketTypeEnum.AGENT_STATE){Ve.stateObject.state!==exports.AgentStatus.IDLE&&Ve.stateObject.state!==exports.AgentStatus.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),ae.emit(exports.CallSipCallEvent.AGENT_STATE,{state:A,state_name:e})}if(t===exports.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(ae.emit(exports.CallSipCallEvent.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.OUT_HANGUP,s),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(Vs))),t===exports.WebsocketTypeEnum.OUT_CALL_RINGING&&1===s.type&&(ae.emit(exports.CallSipCallEvent.OUT_RINGING,s),he.updateDisplayText(exports.DisplayTextEnum.RINGING)),t===exports.WebsocketTypeEnum.OUT_CALL_ANSWER&&(ae.emit(exports.CallSipCallEvent.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.CONSULT_RINGING&&(ae.emit(exports.CallSipCallEvent.CONSULT_RINGING),he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),he.updateActionConfigs([])),t===exports.WebsocketTypeEnum.CONSULT_ANSWER&&(ae.emit(exports.CallSipCallEvent.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CONSULTING),he.updateActionConfigs(gs)),t===exports.WebsocketTypeEnum.CONSULT_FAIL&&(ae.emit(exports.CallSipCallEvent.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN&&(ae.emit(exports.CallSipCallEvent.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.CONSULT),he.updateDisplayText(exports.DisplayTextEnum.CONSULT_CALL_IN),he.updateActionConfigs(ps),Ve.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(qs)),t===exports.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(exports.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(exports.CallSipCallEvent.MUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.MUTING)):(ae.emit(exports.CallSipCallEvent.MUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(exports.CallSipCallEvent.UNMUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING)):(ae.emit(exports.CallSipCallEvent.UNMUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(exports.DisplayTextEnum.HOLDING),ae.emit(exports.CallSipCallEvent.HOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.HOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_UNHOLD&&(0===i?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateIsHold(!1),ae.emit(exports.CallSipCallEvent.UNHOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.UNHOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===i?ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,s.status),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(us),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===exports.WebsocketTypeEnum.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.INCOMING_CALL),ae.emit(exports.CallSipCallEvent.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(ps),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===exports.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(us),he.updateDisplayText(exports.DisplayTextEnum.CALLING)),t===exports.WebsocketTypeEnum.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_END),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(Vs))),t===exports.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===i?ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==i?(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(exports.DirectionEnum.MEETING),he.updateDisplayText(exports.DisplayTextEnum.MEETING),he.updateActionConfigs(ds),ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===exports.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.TRANSFERRING),ae.emit(exports.CallSipCallEvent.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(exports.CallSipCallEvent.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.TRANSFER),he.updateDisplayText(exports.DisplayTextEnum.TRANSFER_INCOMING_CALL),he.updateActionConfigs(ps),Ve.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===exports.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(us)),t===exports.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===s.status){ae.emit(exports.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===exports.DirectionEnum.OUTGOING?he.updateActionConfigs(ls):A===exports.DirectionEnum.INCOMING&&he.updateActionConfigs(us)}t===exports.WebsocketTypeEnum.KICK_OFFLINE&&ae.emit(exports.EventName.KICK_OFF)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Ns("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){bs&&(bs.close(),bs=null)}static __internalSend(A){if(!bs)throw new Error("WebSocket 尚未初始化");bs.sendMessage(A)}}class Hs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:A}})}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.OUTGOING),Js.__internalSend({type:exports.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:A,caller:t}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:exports.WebsocketTypeEnum.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:exports.WebsocketTypeEnum.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Js.__internalSend({type:exports.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class js{static{this._instance=null}#A=null;#e=new ks;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!js._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();_e.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null}),this.on(exports.EventName.KICK_OFF,()=>{this.destroy()})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance({url:A,appKey:e,appSecret:t,agentNo:s}){if(!this._instance){js._creatingInstance=!0,this._instance=new js;je=A||"https://aicc.yescloudy.com",Le=e,We=t,Pe=s,delete js._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})}return this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new $e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,enableBrowserAlert:e,logBuiltinEnabled:t}){try{const{viewHtmlElement:s,rttHTML:i}=A||{};Ve.logBuiltinEnabled=t||!1,await this.#e._agentLogin(Pe);const{agent_no:r,current_answer_device:o,current_state:n,out_display_number:a,out_display_select_switch:V}=Ve.agentInfo;n===exports.AgentStatus.IDLE?(he.updateActionConfigs(Vs),Ve.stateObject={state:n,state_name:"空闲"}):n===exports.AgentStatus.BUSY&&(he.updateActionConfigs(cs),Ve.stateObject={state:n,state_name:"忙碌"}),1===V?he.updateSelectOutNumber(a):he.updateSelectOutNumber("");let c="";const h=new URL(je).host;c=je.includes("https")?`wss://${h}`:`ws://${h}`,Js.getInstance(`${c}/ccs-ws/api/v1/ws/call/${r}?Authorization=`),he.updateAnswerDevice(o),1===o&&await this.initWebRtc(),this.#t=new Hs(this.#A),A&&s&&(this.#i=!0,new Zs({container:s,rttHTML:i,statusParams:{state:exports.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=e,e&&Ks.requestPermission(),ae.emit(exports.EventName.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&xs("初始化失败"),ae.emit(exports.EventName.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){js._instance&&(await this.destroyRtc(),clearInterval(this.#s),Js.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,js._instance=null,he.reset(),he.updateSelectOutNumber(""))}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A)),checkAgentLogin:A=>this.#e.checkAgentLogin(A)}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}exports.default=js;
914
+ `;is(s,this.rttHTML)}}class Ks{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Os=console.log,Ns=(...A)=>{Ve.logBuiltinEnabled&&Os(...A)};let bs=null;class Js{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new ks,this.initWebSocket()}static getInstance(A){if(!bs){if(!A)throw new Error("WebSocket 尚未初始化");bs=new Js(A)}return bs}stateIdleChange(){const{state:A}=Ve.stateObject;A!==exports.AgentStatus.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Ns("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===exports.WebsocketTypeEnum.OUT_CALL&&(0!==i?(he.reset(),ae.emit(exports.CallSipCallEvent.OUT_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(exports.CallSipCallEvent.OUT_SUCCESS)),t===exports.WebsocketTypeEnum.AGENT_STATE){Ve.stateObject.state!==exports.AgentStatus.IDLE&&Ve.stateObject.state!==exports.AgentStatus.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),ae.emit(exports.CallSipCallEvent.AGENT_STATE,{state:A,state_name:e})}if(t===exports.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(ae.emit(exports.CallSipCallEvent.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.OUT_HANGUP,s),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(Vs))),t===exports.WebsocketTypeEnum.OUT_CALL_RINGING&&1===s.type&&(ae.emit(exports.CallSipCallEvent.OUT_RINGING,s),he.updateDisplayText(exports.DisplayTextEnum.RINGING)),t===exports.WebsocketTypeEnum.OUT_CALL_ANSWER&&(ae.emit(exports.CallSipCallEvent.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.CONSULT_RINGING&&(ae.emit(exports.CallSipCallEvent.CONSULT_RINGING),he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),he.updateActionConfigs([])),t===exports.WebsocketTypeEnum.CONSULT_ANSWER&&(ae.emit(exports.CallSipCallEvent.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CONSULTING),he.updateActionConfigs(gs)),t===exports.WebsocketTypeEnum.CONSULT_FAIL&&(ae.emit(exports.CallSipCallEvent.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN&&(ae.emit(exports.CallSipCallEvent.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.CONSULT),he.updateDisplayText(exports.DisplayTextEnum.CONSULT_CALL_IN),he.updateActionConfigs(ps),Ve.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(qs)),t===exports.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(exports.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(exports.CallSipCallEvent.MUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.MUTING)):(ae.emit(exports.CallSipCallEvent.MUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(exports.CallSipCallEvent.UNMUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING)):(ae.emit(exports.CallSipCallEvent.UNMUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(exports.DisplayTextEnum.HOLDING),ae.emit(exports.CallSipCallEvent.HOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.HOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_UNHOLD&&(0===i?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateIsHold(!1),ae.emit(exports.CallSipCallEvent.UNHOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.UNHOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===i?ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,s.status),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(us),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===exports.WebsocketTypeEnum.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.INCOMING_CALL),ae.emit(exports.CallSipCallEvent.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(ps),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===exports.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(us),he.updateDisplayText(exports.DisplayTextEnum.CALLING)),t===exports.WebsocketTypeEnum.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_END),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(Vs))),t===exports.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===i?ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==i?(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(exports.DirectionEnum.MEETING),he.updateDisplayText(exports.DisplayTextEnum.MEETING),he.updateActionConfigs(ds),ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===exports.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.TRANSFERRING),ae.emit(exports.CallSipCallEvent.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(exports.CallSipCallEvent.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.TRANSFER),he.updateDisplayText(exports.DisplayTextEnum.TRANSFER_INCOMING_CALL),he.updateActionConfigs(ps),Ve.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===exports.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(us)),t===exports.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===s.status){ae.emit(exports.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===exports.DirectionEnum.OUTGOING?he.updateActionConfigs(ls):A===exports.DirectionEnum.INCOMING&&he.updateActionConfigs(us)}t===exports.WebsocketTypeEnum.KICK_OFFLINE&&ae.emit(exports.EventName.KICK_OFF)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Ns("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){bs&&(bs.close(),bs=null)}static __internalSend(A){if(!bs)throw new Error("WebSocket 尚未初始化");bs.sendMessage(A)}}class Hs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:A}})}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.OUTGOING),Js.__internalSend({type:exports.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:A,caller:t}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:exports.WebsocketTypeEnum.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:exports.WebsocketTypeEnum.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Js.__internalSend({type:exports.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class js{static{this._instance=null}#A=null;#e=new ks;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!js._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();_e.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null}),this.on(exports.EventName.KICK_OFF,()=>{this.destroy()})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(A){if(!this._instance){if(!A)throw new Error("首次调用必须传入配置参数");const{url:e,appKey:t,appSecret:s,agentNo:i}=A;je=e||"https://aicc.yescloudy.com",Le=t,We=s,Pe=i,js._creatingInstance=!0,this._instance=new js,delete js._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})}return this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new $e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,enableBrowserAlert:e,logBuiltinEnabled:t}){try{const{viewHtmlElement:s,rttHTML:i}=A||{};Ve.logBuiltinEnabled=t||!1,await this.#e._agentLogin(Pe);const{agent_no:r,current_answer_device:o,current_state:n,out_display_number:a,out_display_select_switch:V}=Ve.agentInfo;n===exports.AgentStatus.IDLE?(he.updateActionConfigs(Vs),Ve.stateObject={state:n,state_name:"空闲"}):n===exports.AgentStatus.BUSY&&(he.updateActionConfigs(cs),Ve.stateObject={state:n,state_name:"忙碌"}),1===V?he.updateSelectOutNumber(a):he.updateSelectOutNumber("");let c="";const h=new URL(je).host;c=je.includes("https")?`wss://${h}`:`ws://${h}`,Js.getInstance(`${c}/ccs-ws/api/v1/ws/call/${r}?Authorization=`),he.updateAnswerDevice(o),1===o&&await this.initWebRtc(),this.#t=new Hs(this.#A),A&&s&&(this.#i=!0,new Zs({container:s,rttHTML:i,statusParams:{state:exports.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=e,e&&Ks.requestPermission(),ae.emit(exports.EventName.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&xs("初始化失败"),ae.emit(exports.EventName.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){js._instance&&(await this.destroyRtc(),clearInterval(this.#s),Js.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,js._instance=null,he.reset(),he.updateSelectOutNumber(""))}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A)),checkAgentLogin:A=>this.#e.checkAgentLogin(A)}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}exports.default=js;
@@ -9,7 +9,7 @@ import A from"crypto";import e from"buffer";class t extends Error{constructor(A)
9
9
  * @copyright Chen, Yi-Cyuan 2014-2023
10
10
  * @license MIT
11
11
  */
12
- ve=Oe,function(){var t="input is invalid type",s="object"==typeof window,i=s?window:{};i.JS_MD5_NO_WINDOW&&(s=!1);var r=!s&&"object"==typeof self,o=!i.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;o?i=Ke:r&&(i=self);var n,a=!i.JS_MD5_NO_COMMON_JS&&ve.exports,V=!i.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,c="0123456789abcdef".split(""),h=[128,32768,8388608,-2147483648],l=[0,8,16,24],g=["hex","array","digest","buffer","arrayBuffer","base64"],q="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),d=[];if(V){var u=new ArrayBuffer(68);n=new Uint8Array(u),d=new Uint32Array(u)}var p=Array.isArray;!i.JS_MD5_NO_NODE_JS&&p||(p=function(A){return"[object Array]"===Object.prototype.toString.call(A)});var m=ArrayBuffer.isView;!V||!i.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&m||(m=function(A){return"object"==typeof A&&A.buffer&&A.buffer.constructor===ArrayBuffer});var C=function(A){var e=typeof A;if("string"===e)return[A,!0];if("object"!==e||null===A)throw new Error(t);if(V&&A.constructor===ArrayBuffer)return[new Uint8Array(A),!1];if(!p(A)&&!m(A))throw new Error(t);return[A,!1]},E=function(A){return function(e){return new w(!0).update(e)[A]()}},I=function(s){var r,o=A,n=e.Buffer;return r=n.from&&!i.JS_MD5_NO_BUFFER_FROM?n.from:function(A){return new n(A)},function(A){if("string"==typeof A)return o.createHash("md5").update(A,"utf8").digest("hex");if(null==A)throw new Error(t);return A.constructor===ArrayBuffer&&(A=new Uint8Array(A)),p(A)||m(A)||A.constructor===n?o.createHash("md5").update(r(A)).digest("hex"):s(A)}},M=function(A){return function(e,t){return new f(e,!0).update(t)[A]()}};function w(A){if(A)d[0]=d[16]=d[1]=d[2]=d[3]=d[4]=d[5]=d[6]=d[7]=d[8]=d[9]=d[10]=d[11]=d[12]=d[13]=d[14]=d[15]=0,this.blocks=d,this.buffer8=n;else if(V){var e=new ArrayBuffer(68);this.buffer8=new Uint8Array(e),this.blocks=new Uint32Array(e)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}function f(A,e){var t,s=C(A);if(A=s[0],s[1]){var i,r=[],o=A.length,n=0;for(t=0;t<o;++t)(i=A.charCodeAt(t))<128?r[n++]=i:i<2048?(r[n++]=192|i>>>6,r[n++]=128|63&i):i<55296||i>=57344?(r[n++]=224|i>>>12,r[n++]=128|i>>>6&63,r[n++]=128|63&i):(i=65536+((1023&i)<<10|1023&A.charCodeAt(++t)),r[n++]=240|i>>>18,r[n++]=128|i>>>12&63,r[n++]=128|i>>>6&63,r[n++]=128|63&i);A=r}A.length>64&&(A=new w(!0).update(A).array());var a=[],V=[];for(t=0;t<64;++t){var c=A[t]||0;a[t]=92^c,V[t]=54^c}w.call(this,e),this.update(V),this.oKeyPad=a,this.inner=!0,this.sharedMemory=e}w.prototype.update=function(A){if(this.finalized)throw new Error("finalize already called");var e=C(A);A=e[0];for(var t,s,i=e[1],r=0,o=A.length,n=this.blocks,a=this.buffer8;r<o;){if(this.hashed&&(this.hashed=!1,n[0]=n[16],n[16]=n[1]=n[2]=n[3]=n[4]=n[5]=n[6]=n[7]=n[8]=n[9]=n[10]=n[11]=n[12]=n[13]=n[14]=n[15]=0),i)if(V)for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?a[s++]=t:t<2048?(a[s++]=192|t>>>6,a[s++]=128|63&t):t<55296||t>=57344?(a[s++]=224|t>>>12,a[s++]=128|t>>>6&63,a[s++]=128|63&t):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),a[s++]=240|t>>>18,a[s++]=128|t>>>12&63,a[s++]=128|t>>>6&63,a[s++]=128|63&t);else for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?n[s>>>2]|=t<<l[3&s++]:t<2048?(n[s>>>2]|=(192|t>>>6)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):t<55296||t>=57344?(n[s>>>2]|=(224|t>>>12)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),n[s>>>2]|=(240|t>>>18)<<l[3&s++],n[s>>>2]|=(128|t>>>12&63)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]);else if(V)for(s=this.start;r<o&&s<64;++r)a[s++]=A[r];else for(s=this.start;r<o&&s<64;++r)n[s>>>2]|=A[r]<<l[3&s++];this.lastByteIndex=s,this.bytes+=s-this.start,s>=64?(this.start=s-64,this.hash(),this.hashed=!0):this.start=s}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296|0,this.bytes=this.bytes%4294967296),this},w.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var A=this.blocks,e=this.lastByteIndex;A[e>>>2]|=h[3&e],e>=56&&(this.hashed||this.hash(),A[0]=A[16],A[16]=A[1]=A[2]=A[3]=A[4]=A[5]=A[6]=A[7]=A[8]=A[9]=A[10]=A[11]=A[12]=A[13]=A[14]=A[15]=0),A[14]=this.bytes<<3,A[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},w.prototype.hash=function(){var A,e,t,s,i,r,o=this.blocks;this.first?e=((e=((A=((A=o[0]-680876937)<<7|A>>>25)-271733879|0)^(t=((t=(-271733879^(s=((s=(-1732584194^2004318071&A)+o[1]-117830708)<<12|s>>>20)+A|0)&(-271733879^A))+o[2]-1126478375)<<17|t>>>15)+s|0)&(s^A))+o[3]-1316259209)<<22|e>>>10)+t|0:(A=this.h0,e=this.h1,t=this.h2,e=((e+=((A=((A+=((s=this.h3)^e&(t^s))+o[0]-680876936)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[1]-389564586)<<12|s>>>20)+A|0)&(A^e))+o[2]+606105819)<<17|t>>>15)+s|0)&(s^A))+o[3]-1044525330)<<22|e>>>10)+t|0),e=((e+=((A=((A+=(s^e&(t^s))+o[4]-176418897)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[5]+1200080426)<<12|s>>>20)+A|0)&(A^e))+o[6]-1473231341)<<17|t>>>15)+s|0)&(s^A))+o[7]-45705983)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[8]+1770035416)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[9]-1958414417)<<12|s>>>20)+A|0)&(A^e))+o[10]-42063)<<17|t>>>15)+s|0)&(s^A))+o[11]-1990404162)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[12]+1804603682)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[13]-40341101)<<12|s>>>20)+A|0)&(A^e))+o[14]-1502002290)<<17|t>>>15)+s|0)&(s^A))+o[15]+1236535329)<<22|e>>>10)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[1]-165796510)<<5|A>>>27)+e|0)^e))+o[6]-1069501632)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[11]+643717713)<<14|t>>>18)+s|0)^s))+o[0]-373897302)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[5]-701558691)<<5|A>>>27)+e|0)^e))+o[10]+38016083)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[15]-660478335)<<14|t>>>18)+s|0)^s))+o[4]-405537848)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[9]+568446438)<<5|A>>>27)+e|0)^e))+o[14]-1019803690)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[3]-187363961)<<14|t>>>18)+s|0)^s))+o[8]+1163531501)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[13]-1444681467)<<5|A>>>27)+e|0)^e))+o[2]-51403784)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[7]+1735328473)<<14|t>>>18)+s|0)^s))+o[12]-1926607734)<<20|e>>>12)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[5]-378558)<<4|A>>>28)+e|0))+o[8]-2022574463)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[11]+1839030562)<<16|t>>>16)+s|0))+o[14]-35309556)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[1]-1530992060)<<4|A>>>28)+e|0))+o[4]+1272893353)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[7]-155497632)<<16|t>>>16)+s|0))+o[10]-1094730640)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[13]+681279174)<<4|A>>>28)+e|0))+o[0]-358537222)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[3]-722521979)<<16|t>>>16)+s|0))+o[6]+76029189)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[9]-640364487)<<4|A>>>28)+e|0))+o[12]-421815835)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[15]+530742520)<<16|t>>>16)+s|0))+o[2]-995338651)<<23|e>>>9)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[0]-198630844)<<6|A>>>26)+e|0)|~t))+o[7]+1126891415)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[14]-1416354905)<<15|t>>>17)+s|0)|~A))+o[5]-57434055)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[12]+1700485571)<<6|A>>>26)+e|0)|~t))+o[3]-1894986606)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[10]-1051523)<<15|t>>>17)+s|0)|~A))+o[1]-2054922799)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[8]+1873313359)<<6|A>>>26)+e|0)|~t))+o[15]-30611744)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[6]-1560198380)<<15|t>>>17)+s|0)|~A))+o[13]+1309151649)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[4]-145523070)<<6|A>>>26)+e|0)|~t))+o[11]-1120210379)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[2]+718787259)<<15|t>>>17)+s|0)|~A))+o[9]-343485551)<<21|e>>>11)+t|0,this.first?(this.h0=A+1732584193|0,this.h1=e-271733879|0,this.h2=t-1732584194|0,this.h3=s+271733878|0,this.first=!1):(this.h0=this.h0+A|0,this.h1=this.h1+e|0,this.h2=this.h2+t|0,this.h3=this.h3+s|0)},w.prototype.hex=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return c[A>>>4&15]+c[15&A]+c[A>>>12&15]+c[A>>>8&15]+c[A>>>20&15]+c[A>>>16&15]+c[A>>>28&15]+c[A>>>24&15]+c[e>>>4&15]+c[15&e]+c[e>>>12&15]+c[e>>>8&15]+c[e>>>20&15]+c[e>>>16&15]+c[e>>>28&15]+c[e>>>24&15]+c[t>>>4&15]+c[15&t]+c[t>>>12&15]+c[t>>>8&15]+c[t>>>20&15]+c[t>>>16&15]+c[t>>>28&15]+c[t>>>24&15]+c[s>>>4&15]+c[15&s]+c[s>>>12&15]+c[s>>>8&15]+c[s>>>20&15]+c[s>>>16&15]+c[s>>>28&15]+c[s>>>24&15]},w.prototype.toString=w.prototype.hex,w.prototype.digest=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return[255&A,A>>>8&255,A>>>16&255,A>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255,255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&s,s>>>8&255,s>>>16&255,s>>>24&255]},w.prototype.array=w.prototype.digest,w.prototype.arrayBuffer=function(){this.finalize();var A=new ArrayBuffer(16),e=new Uint32Array(A);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,A},w.prototype.buffer=w.prototype.arrayBuffer,w.prototype.base64=function(){for(var A,e,t,s="",i=this.array(),r=0;r<15;)A=i[r++],e=i[r++],t=i[r++],s+=q[A>>>2]+q[63&(A<<4|e>>>4)]+q[63&(e<<2|t>>>6)]+q[63&t];return A=i[r],s+=q[A>>>2]+q[A<<4&63]+"=="},f.prototype=new w,f.prototype.finalize=function(){if(w.prototype.finalize.call(this),this.inner){this.inner=!1;var A=this.array();w.call(this,this.sharedMemory),this.update(this.oKeyPad),this.update(A),w.prototype.finalize.call(this)}};var B=function(){var A=E("hex");o&&(A=I(A)),A.create=function(){return new w},A.update=function(e){return A.create().update(e)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=E(t)}return A}();B.md5=B,B.md5.hmac=function(){var A=M("hex");A.create=function(A){return new f(A)},A.update=function(e,t){return A.create(e).update(t)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=M(t)}return A}(),a?ve.exports=B:i.md5=B}();var Ne=Oe.exports;const be=(A,e)=>{const t=Date.now(),s=`${A}:${t}:${Ne.md5(`${e}${t}`)}`,i=(new TextEncoder).encode(s);return btoa(String.fromCharCode(...i))},Je="/v1/aicc/bmserver",He="/v1/aicc/ccs";let je="",Le="",We="",Pe="";async function ze(A,e){const t=function(){const A=be(Le,We);return xe.create({prefixUrl:`${je}/api`,timeout:!1,headers:{Authorization:A},hooks:{afterResponse:[async(A,e,t)=>{const s=await t.clone().json();if(0!==s.code)throw new Error(JSON.stringify(s)||"请求失败");return t.json=async()=>s,t}]}})}(),s=A.replace(/^\/+/,"");return t.post(s,{json:e}).json()}const Xe=A=>ze(`${He}/state/change`,A);const _e=new class extends $A{updateRttObject(A){this.setState({rttObject:A}),ae.emit(re.WEBSITE_DELAY,A)}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class $e{constructor(A,e){this.config=A,this.eventCallback=e,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.isManuallyStopped=!1,this.handleNetworkInfoChange=A=>{if(A.rttObject?.rtt){0===(A.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())}},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString()),this.destroy()},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString()),this.reconnect()},_e.subscribe(this.handleNetworkInfoChange)}async start(){const A=_A.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!A)throw new Error("无效的SIP配置");const e={uri:A,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:30},contactName:this.config.user,contactParams:{transport:"wss"},userAgentString:"SwiftSIP/1.0.74",sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:400},logBuiltinEnabled:Ve.logBuiltinEnabled};this.userAgent=new _A(e),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(A=>{let e;switch(A){case AA.Connecting:e=te.WEB_RTC_CONNECTING;break;case AA.Connected:e=te.WEB_RTC_CONNECTED,this.reconnectAttempts=0,Ve.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case AA.Disconnecting:e=te.WEB_RTC_DISCONNECTING;break;case AA.Disconnected:{if(this.isManuallyStopped)return void console.warn("[SIP] 手动断开,不触发重连");e=te.WEB_RTC_DISCONNECTED;const A=he.get("answerDevice");if(!Ve.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===A){this.reconnectAttempts++;const A=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${A}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},A)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:e="unknown"}this.eventCallback?.({type:e})}),this.userAgent.delegate={onInvite:A=>{this.handleIncomingCall(A)}})}async register(){if(this.userAgent){this.registerer=new rA(this.userAgent),this.registerer?.stateChange.addListener(A=>{let e;switch(A){case _.Initial:e="initial";break;case _.Registered:e=te.WEB_RTC_REGISTERED;break;case _.Unregistered:e=te.WEB_RTC_UNREGISTERED;break;case _.Terminated:e=te.WEB_RTC_TERMINATED;break;default:e="unknown"}this.eventCallback?.({type:e})});try{await this.registerer.register()}catch(A){this.eventCallback?.({type:te.WEB_RTC_REGISTER_FAILED,data:A})}}}attachRemoteAudio(A){const e=A.sessionDescriptionHandler;if(e){const A=e.peerConnection;if(!A)return;const t=new MediaStream;A.getReceivers().forEach(A=>{A.track&&"audio"===A.track.kind&&t.addTrack(A.track)});let s=document.getElementById("sip-remote-audio");s||(s=document.createElement("audio"),s.id="sip-remote-audio",s.autoplay=!0,s.style.display="none",document.body.appendChild(s)),s.srcObject=t,s.play().catch(A=>{console.error("音频播放失败,需要用户交互触发",A)})}}handleSessionState(A,e,t){A.stateChange.addListener(e=>{switch(e){case j.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=A,this.attachRemoteAudio(A);break;case j.Terminating:break;case j.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case j.Establishing:}})}handleIncomingCall(A){this.incomingInvitation=A,this.handleSessionState(A,!1);const{soft_device_auto_answer:e,auto_answer_time:t}=Ve.agentInfo,s=he.get("direction"),i=1===e;if(s===ee.OUTGOING)this.answerCall();else if(i&&s===ee.INCOMING){const A=Number(t)||0;A>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},A):this.answerCall()}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{this.activeSession=this.incomingInvitation,await this.incomingInvitation.accept(),this.incomingInvitation=null}catch(A){this.eventCallback?.({type:te.WEB_RTC_ANSWER_FAILED,data:{detail:A}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,he.updateDirection(null),he.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(A){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:A}})}}sendDTMF(A){if(!this.activeSession)throw new Error("当前没有活跃的通话");const e=this.activeSession.sessionDescriptionHandler;e&&"function"==typeof e.sendDtmf?(e.sendDtmf(A),this.eventCallback?.({type:te.WEB_RTC_SEND_DTMF,data:{tone:A}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession,this.activeSession){clearTimeout(this.callTimeoutTimer);const A=this.activeSession;if(!A)return;const e=A.state;try{e===j.Established?await A.bye():e===j.Establishing&&(A instanceof X?await A.cancel():A instanceof z&&await A.reject()),clearTimeout(this.callTimeoutTimer)}catch(A){console.error("挂断失败",A)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof z&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(this.isManuallyStopped=!0,clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(A){console.warn("注销失败",A)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!Ve.isRtcReconnecting){Ve.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),this.isOffline=!1}catch(A){console.error("重连失败",A)}finally{Ve.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const A=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!A)return null;const e=await A.getStats(),t={};return e.forEach(A=>{"candidate-pair"===A.type&&"succeeded"===A.state&&null!=A.currentRoundTripTime&&(t.rtt=+(1e3*A.currentRoundTripTime).toFixed(2)),"inbound-rtp"===A.type&&"audio"===A.kind&&(t.jitter=+(1e3*A.jitter).toFixed(2),t.packetsLost=A.packetsLost,t.packetsReceived=A.packetsReceived,A.bytesReceived&&A.timestamp&&(t.recvBitrate=+(A.bytesReceived/1024).toFixed(2))),"outbound-rtp"===A.type&&"audio"===A.kind&&(t.packetsSent=A.packetsSent,A.bytesSent&&A.timestamp&&(t.sendBitrate=+(A.bytesSent/1024).toFixed(2))),"codec"===A.type&&A.mimeType&&(t.codec=A.mimeType)}),{...t,rtt:t?.rtt||40}}try{const A=Date.now();await ze(`${Je}/config/ping`,{});const e=Date.now();return{rtt:e-A||1}}catch(A){}}}
12
+ ve=Oe,function(){var t="input is invalid type",s="object"==typeof window,i=s?window:{};i.JS_MD5_NO_WINDOW&&(s=!1);var r=!s&&"object"==typeof self,o=!i.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;o?i=Ke:r&&(i=self);var n,a=!i.JS_MD5_NO_COMMON_JS&&ve.exports,V=!i.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,c="0123456789abcdef".split(""),h=[128,32768,8388608,-2147483648],l=[0,8,16,24],g=["hex","array","digest","buffer","arrayBuffer","base64"],q="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),d=[];if(V){var u=new ArrayBuffer(68);n=new Uint8Array(u),d=new Uint32Array(u)}var p=Array.isArray;!i.JS_MD5_NO_NODE_JS&&p||(p=function(A){return"[object Array]"===Object.prototype.toString.call(A)});var m=ArrayBuffer.isView;!V||!i.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&m||(m=function(A){return"object"==typeof A&&A.buffer&&A.buffer.constructor===ArrayBuffer});var C=function(A){var e=typeof A;if("string"===e)return[A,!0];if("object"!==e||null===A)throw new Error(t);if(V&&A.constructor===ArrayBuffer)return[new Uint8Array(A),!1];if(!p(A)&&!m(A))throw new Error(t);return[A,!1]},E=function(A){return function(e){return new w(!0).update(e)[A]()}},I=function(s){var r,o=A,n=e.Buffer;return r=n.from&&!i.JS_MD5_NO_BUFFER_FROM?n.from:function(A){return new n(A)},function(A){if("string"==typeof A)return o.createHash("md5").update(A,"utf8").digest("hex");if(null==A)throw new Error(t);return A.constructor===ArrayBuffer&&(A=new Uint8Array(A)),p(A)||m(A)||A.constructor===n?o.createHash("md5").update(r(A)).digest("hex"):s(A)}},M=function(A){return function(e,t){return new f(e,!0).update(t)[A]()}};function w(A){if(A)d[0]=d[16]=d[1]=d[2]=d[3]=d[4]=d[5]=d[6]=d[7]=d[8]=d[9]=d[10]=d[11]=d[12]=d[13]=d[14]=d[15]=0,this.blocks=d,this.buffer8=n;else if(V){var e=new ArrayBuffer(68);this.buffer8=new Uint8Array(e),this.blocks=new Uint32Array(e)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}function f(A,e){var t,s=C(A);if(A=s[0],s[1]){var i,r=[],o=A.length,n=0;for(t=0;t<o;++t)(i=A.charCodeAt(t))<128?r[n++]=i:i<2048?(r[n++]=192|i>>>6,r[n++]=128|63&i):i<55296||i>=57344?(r[n++]=224|i>>>12,r[n++]=128|i>>>6&63,r[n++]=128|63&i):(i=65536+((1023&i)<<10|1023&A.charCodeAt(++t)),r[n++]=240|i>>>18,r[n++]=128|i>>>12&63,r[n++]=128|i>>>6&63,r[n++]=128|63&i);A=r}A.length>64&&(A=new w(!0).update(A).array());var a=[],V=[];for(t=0;t<64;++t){var c=A[t]||0;a[t]=92^c,V[t]=54^c}w.call(this,e),this.update(V),this.oKeyPad=a,this.inner=!0,this.sharedMemory=e}w.prototype.update=function(A){if(this.finalized)throw new Error("finalize already called");var e=C(A);A=e[0];for(var t,s,i=e[1],r=0,o=A.length,n=this.blocks,a=this.buffer8;r<o;){if(this.hashed&&(this.hashed=!1,n[0]=n[16],n[16]=n[1]=n[2]=n[3]=n[4]=n[5]=n[6]=n[7]=n[8]=n[9]=n[10]=n[11]=n[12]=n[13]=n[14]=n[15]=0),i)if(V)for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?a[s++]=t:t<2048?(a[s++]=192|t>>>6,a[s++]=128|63&t):t<55296||t>=57344?(a[s++]=224|t>>>12,a[s++]=128|t>>>6&63,a[s++]=128|63&t):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),a[s++]=240|t>>>18,a[s++]=128|t>>>12&63,a[s++]=128|t>>>6&63,a[s++]=128|63&t);else for(s=this.start;r<o&&s<64;++r)(t=A.charCodeAt(r))<128?n[s>>>2]|=t<<l[3&s++]:t<2048?(n[s>>>2]|=(192|t>>>6)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):t<55296||t>=57344?(n[s>>>2]|=(224|t>>>12)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),n[s>>>2]|=(240|t>>>18)<<l[3&s++],n[s>>>2]|=(128|t>>>12&63)<<l[3&s++],n[s>>>2]|=(128|t>>>6&63)<<l[3&s++],n[s>>>2]|=(128|63&t)<<l[3&s++]);else if(V)for(s=this.start;r<o&&s<64;++r)a[s++]=A[r];else for(s=this.start;r<o&&s<64;++r)n[s>>>2]|=A[r]<<l[3&s++];this.lastByteIndex=s,this.bytes+=s-this.start,s>=64?(this.start=s-64,this.hash(),this.hashed=!0):this.start=s}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296|0,this.bytes=this.bytes%4294967296),this},w.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var A=this.blocks,e=this.lastByteIndex;A[e>>>2]|=h[3&e],e>=56&&(this.hashed||this.hash(),A[0]=A[16],A[16]=A[1]=A[2]=A[3]=A[4]=A[5]=A[6]=A[7]=A[8]=A[9]=A[10]=A[11]=A[12]=A[13]=A[14]=A[15]=0),A[14]=this.bytes<<3,A[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},w.prototype.hash=function(){var A,e,t,s,i,r,o=this.blocks;this.first?e=((e=((A=((A=o[0]-680876937)<<7|A>>>25)-271733879|0)^(t=((t=(-271733879^(s=((s=(-1732584194^2004318071&A)+o[1]-117830708)<<12|s>>>20)+A|0)&(-271733879^A))+o[2]-1126478375)<<17|t>>>15)+s|0)&(s^A))+o[3]-1316259209)<<22|e>>>10)+t|0:(A=this.h0,e=this.h1,t=this.h2,e=((e+=((A=((A+=((s=this.h3)^e&(t^s))+o[0]-680876936)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[1]-389564586)<<12|s>>>20)+A|0)&(A^e))+o[2]+606105819)<<17|t>>>15)+s|0)&(s^A))+o[3]-1044525330)<<22|e>>>10)+t|0),e=((e+=((A=((A+=(s^e&(t^s))+o[4]-176418897)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[5]+1200080426)<<12|s>>>20)+A|0)&(A^e))+o[6]-1473231341)<<17|t>>>15)+s|0)&(s^A))+o[7]-45705983)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[8]+1770035416)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[9]-1958414417)<<12|s>>>20)+A|0)&(A^e))+o[10]-42063)<<17|t>>>15)+s|0)&(s^A))+o[11]-1990404162)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+o[12]+1804603682)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+o[13]-40341101)<<12|s>>>20)+A|0)&(A^e))+o[14]-1502002290)<<17|t>>>15)+s|0)&(s^A))+o[15]+1236535329)<<22|e>>>10)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[1]-165796510)<<5|A>>>27)+e|0)^e))+o[6]-1069501632)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[11]+643717713)<<14|t>>>18)+s|0)^s))+o[0]-373897302)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[5]-701558691)<<5|A>>>27)+e|0)^e))+o[10]+38016083)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[15]-660478335)<<14|t>>>18)+s|0)^s))+o[4]-405537848)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[9]+568446438)<<5|A>>>27)+e|0)^e))+o[14]-1019803690)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[3]-187363961)<<14|t>>>18)+s|0)^s))+o[8]+1163531501)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+o[13]-1444681467)<<5|A>>>27)+e|0)^e))+o[2]-51403784)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+o[7]+1735328473)<<14|t>>>18)+s|0)^s))+o[12]-1926607734)<<20|e>>>12)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[5]-378558)<<4|A>>>28)+e|0))+o[8]-2022574463)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[11]+1839030562)<<16|t>>>16)+s|0))+o[14]-35309556)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[1]-1530992060)<<4|A>>>28)+e|0))+o[4]+1272893353)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[7]-155497632)<<16|t>>>16)+s|0))+o[10]-1094730640)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[13]+681279174)<<4|A>>>28)+e|0))+o[0]-358537222)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[3]-722521979)<<16|t>>>16)+s|0))+o[6]+76029189)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+o[9]-640364487)<<4|A>>>28)+e|0))+o[12]-421815835)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+o[15]+530742520)<<16|t>>>16)+s|0))+o[2]-995338651)<<23|e>>>9)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[0]-198630844)<<6|A>>>26)+e|0)|~t))+o[7]+1126891415)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[14]-1416354905)<<15|t>>>17)+s|0)|~A))+o[5]-57434055)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[12]+1700485571)<<6|A>>>26)+e|0)|~t))+o[3]-1894986606)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[10]-1051523)<<15|t>>>17)+s|0)|~A))+o[1]-2054922799)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[8]+1873313359)<<6|A>>>26)+e|0)|~t))+o[15]-30611744)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[6]-1560198380)<<15|t>>>17)+s|0)|~A))+o[13]+1309151649)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+o[4]-145523070)<<6|A>>>26)+e|0)|~t))+o[11]-1120210379)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+o[2]+718787259)<<15|t>>>17)+s|0)|~A))+o[9]-343485551)<<21|e>>>11)+t|0,this.first?(this.h0=A+1732584193|0,this.h1=e-271733879|0,this.h2=t-1732584194|0,this.h3=s+271733878|0,this.first=!1):(this.h0=this.h0+A|0,this.h1=this.h1+e|0,this.h2=this.h2+t|0,this.h3=this.h3+s|0)},w.prototype.hex=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return c[A>>>4&15]+c[15&A]+c[A>>>12&15]+c[A>>>8&15]+c[A>>>20&15]+c[A>>>16&15]+c[A>>>28&15]+c[A>>>24&15]+c[e>>>4&15]+c[15&e]+c[e>>>12&15]+c[e>>>8&15]+c[e>>>20&15]+c[e>>>16&15]+c[e>>>28&15]+c[e>>>24&15]+c[t>>>4&15]+c[15&t]+c[t>>>12&15]+c[t>>>8&15]+c[t>>>20&15]+c[t>>>16&15]+c[t>>>28&15]+c[t>>>24&15]+c[s>>>4&15]+c[15&s]+c[s>>>12&15]+c[s>>>8&15]+c[s>>>20&15]+c[s>>>16&15]+c[s>>>28&15]+c[s>>>24&15]},w.prototype.toString=w.prototype.hex,w.prototype.digest=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return[255&A,A>>>8&255,A>>>16&255,A>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255,255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&s,s>>>8&255,s>>>16&255,s>>>24&255]},w.prototype.array=w.prototype.digest,w.prototype.arrayBuffer=function(){this.finalize();var A=new ArrayBuffer(16),e=new Uint32Array(A);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,A},w.prototype.buffer=w.prototype.arrayBuffer,w.prototype.base64=function(){for(var A,e,t,s="",i=this.array(),r=0;r<15;)A=i[r++],e=i[r++],t=i[r++],s+=q[A>>>2]+q[63&(A<<4|e>>>4)]+q[63&(e<<2|t>>>6)]+q[63&t];return A=i[r],s+=q[A>>>2]+q[A<<4&63]+"=="},f.prototype=new w,f.prototype.finalize=function(){if(w.prototype.finalize.call(this),this.inner){this.inner=!1;var A=this.array();w.call(this,this.sharedMemory),this.update(this.oKeyPad),this.update(A),w.prototype.finalize.call(this)}};var B=function(){var A=E("hex");o&&(A=I(A)),A.create=function(){return new w},A.update=function(e){return A.create().update(e)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=E(t)}return A}();B.md5=B,B.md5.hmac=function(){var A=M("hex");A.create=function(A){return new f(A)},A.update=function(e,t){return A.create(e).update(t)};for(var e=0;e<g.length;++e){var t=g[e];A[t]=M(t)}return A}(),a?ve.exports=B:i.md5=B}();var Ne=Oe.exports;const be=(A,e)=>{const t=Date.now(),s=`${A}:${t}:${Ne.md5(`${e}${t}`)}`,i=(new TextEncoder).encode(s);return btoa(String.fromCharCode(...i))},Je="/v1/aicc/bmserver",He="/v1/aicc/ccs";let je="",Le="",We="",Pe="";async function ze(A,e){const t=function(){const A=be(Le,We);return xe.create({prefixUrl:`${je}/api`,timeout:!1,headers:{Authorization:A},hooks:{afterResponse:[async(A,e,t)=>{const s=await t.clone().json();if(0!==s.code)throw new Error(JSON.stringify(s)||"请求失败");return t.json=async()=>s,t}]}})}(),s=A.replace(/^\/+/,"");return t.post(s,{json:e}).json()}const Xe=A=>ze(`${He}/state/change`,A);const _e=new class extends $A{updateRttObject(A){this.setState({rttObject:A}),ae.emit(re.WEBSITE_DELAY,A)}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class $e{constructor(A,e){this.config=A,this.eventCallback=e,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.isManuallyStopped=!1,this.handleNetworkInfoChange=A=>{if(A.rttObject?.rtt){0===(A.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())}},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString()),this.destroy()},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString()),this.reconnect()},_e.subscribe(this.handleNetworkInfoChange)}async start(){const A=_A.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!A)throw new Error("无效的SIP配置");const e={uri:A,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:30},contactName:this.config.user,contactParams:{transport:"wss"},userAgentString:"SwiftSIP/1.0.74",sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:3},logBuiltinEnabled:Ve.logBuiltinEnabled};this.userAgent=new _A(e),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(A=>{let e;switch(A){case AA.Connecting:e=te.WEB_RTC_CONNECTING;break;case AA.Connected:e=te.WEB_RTC_CONNECTED,this.reconnectAttempts=0,Ve.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case AA.Disconnecting:e=te.WEB_RTC_DISCONNECTING;break;case AA.Disconnected:{if(this.isManuallyStopped)return void console.warn("[SIP] 手动断开,不触发重连");e=te.WEB_RTC_DISCONNECTED;const A=he.get("answerDevice");if(!Ve.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===A){this.reconnectAttempts++;const A=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${A}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},A)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:e="unknown"}this.eventCallback?.({type:e})}),this.userAgent.delegate={onInvite:A=>{this.handleIncomingCall(A)}})}async register(){if(this.userAgent){this.registerer=new rA(this.userAgent),this.registerer?.stateChange.addListener(A=>{let e;switch(A){case _.Initial:e="initial";break;case _.Registered:e=te.WEB_RTC_REGISTERED;break;case _.Unregistered:e=te.WEB_RTC_UNREGISTERED;break;case _.Terminated:e=te.WEB_RTC_TERMINATED;break;default:e="unknown"}this.eventCallback?.({type:e})});try{await this.registerer.register()}catch(A){this.eventCallback?.({type:te.WEB_RTC_REGISTER_FAILED,data:A})}}}attachRemoteAudio(A){const e=A.sessionDescriptionHandler;if(e){const A=e.peerConnection;if(!A)return;const t=new MediaStream;A.getReceivers().forEach(A=>{A.track&&"audio"===A.track.kind&&t.addTrack(A.track)});let s=document.getElementById("sip-remote-audio");s||(s=document.createElement("audio"),s.id="sip-remote-audio",s.autoplay=!0,s.style.display="none",document.body.appendChild(s)),s.srcObject=t,s.play().catch(A=>{console.error("音频播放失败,需要用户交互触发",A)})}}handleSessionState(A,e,t){A.stateChange.addListener(e=>{switch(e){case j.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=A,this.attachRemoteAudio(A);break;case j.Terminating:break;case j.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case j.Establishing:}})}handleIncomingCall(A){this.incomingInvitation=A,this.handleSessionState(A,!1);const{soft_device_auto_answer:e,auto_answer_time:t}=Ve.agentInfo,s=he.get("direction"),i=1===e;if(s===ee.OUTGOING)this.answerCall();else if(i&&s===ee.INCOMING){const A=Number(t)||0;A>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},A):this.answerCall()}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{await this.incomingInvitation.accept(),this.activeSession=this.incomingInvitation,this.incomingInvitation=null}catch(A){this.eventCallback?.({type:te.WEB_RTC_ANSWER_FAILED,data:{detail:A}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,he.updateDirection(null),he.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(A){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:A}})}}sendDTMF(A){if(!this.activeSession)throw new Error("当前没有活跃的通话");const e=this.activeSession.sessionDescriptionHandler;e&&"function"==typeof e.sendDtmf?(e.sendDtmf(A),this.eventCallback?.({type:te.WEB_RTC_SEND_DTMF,data:{tone:A}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession,this.activeSession){clearTimeout(this.callTimeoutTimer);const A=this.activeSession;if(!A)return;const e=A.state;try{e===j.Established?await A.bye():e===j.Establishing&&(A instanceof X?await A.cancel():A instanceof z&&await A.reject()),clearTimeout(this.callTimeoutTimer)}catch(A){console.error("挂断失败",A)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof z&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(this.isManuallyStopped=!0,clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(A){console.warn("注销失败",A)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!Ve.isRtcReconnecting){Ve.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),this.isOffline=!1}catch(A){console.error("重连失败",A)}finally{Ve.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const A=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!A)return null;const e=await A.getStats(),t={};return e.forEach(A=>{"candidate-pair"===A.type&&"succeeded"===A.state&&null!=A.currentRoundTripTime&&(t.rtt=+(1e3*A.currentRoundTripTime).toFixed(2)),"inbound-rtp"===A.type&&"audio"===A.kind&&(t.jitter=+(1e3*A.jitter).toFixed(2),t.packetsLost=A.packetsLost,t.packetsReceived=A.packetsReceived,A.bytesReceived&&A.timestamp&&(t.recvBitrate=+(A.bytesReceived/1024).toFixed(2))),"outbound-rtp"===A.type&&"audio"===A.kind&&(t.packetsSent=A.packetsSent,A.bytesSent&&A.timestamp&&(t.sendBitrate=+(A.bytesSent/1024).toFixed(2))),"codec"===A.type&&A.mimeType&&(t.codec=A.mimeType)}),{...t,rtt:t?.rtt||40}}try{const A=Date.now();await ze(`${Je}/config/ping`,{});const e=Date.now();return{rtt:e-A||1}}catch(A){}}}
13
13
  /**
14
14
  * @license
15
15
  * Copyright 2019 Google LLC
@@ -911,4 +911,4 @@ const Cs=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
911
911
  `:""}
912
912
  </div>
913
913
  </my-popover>
914
- `;is(s,this.rttHTML)}}class Ks{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Os=console.log,Ns=(...A)=>{Ve.logBuiltinEnabled&&Os(...A)};let bs=null;class Js{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new ks,this.initWebSocket()}static getInstance(A){if(!bs){if(!A)throw new Error("WebSocket 尚未初始化");bs=new Js(A)}return bs}stateIdleChange(){const{state:A}=Ve.stateObject;A!==Ae.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(se.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(se.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Ns("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===ie.OUT_CALL&&(0!==i?(he.reset(),ae.emit(se.OUT_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(se.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(se.OUT_SUCCESS)),t===ie.AGENT_STATE){Ve.stateObject.state!==Ae.IDLE&&Ve.stateObject.state!==Ae.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(oe.AGENT_RINGING),ae.emit(se.AGENT_STATE,{state:A,state_name:e})}if(t===ie.OUT_CALL_INCOMING_CALL&&(ae.emit(se.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(hs)),t===ie.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.OUT_HANGUP,s),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(Vs))),t===ie.OUT_CALL_RINGING&&1===s.type&&(ae.emit(se.OUT_RINGING,s),he.updateDisplayText(oe.RINGING)),t===ie.OUT_CALL_ANSWER&&(ae.emit(se.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(ls)),t===ie.CONSULT_RINGING&&(ae.emit(se.CONSULT_RINGING),he.updateDisplayText(oe.AGENT_RINGING),he.updateActionConfigs([])),t===ie.CONSULT_ANSWER&&(ae.emit(se.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CONSULTING),he.updateActionConfigs(gs)),t===ie.CONSULT_FAIL&&(ae.emit(se.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(ls)),t===ie.CONSULT_CALL_IN&&(ae.emit(se.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(ee.CONSULT),he.updateDisplayText(oe.CONSULT_CALL_IN),he.updateActionConfigs(us),Ve.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===ie.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(se.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(qs)),t===ie.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(se.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)),t===ie.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(se.MUTE_SUCCESS),he.updateDisplayText(oe.MUTING)):(ae.emit(se.MUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(se.UNMUTE_SUCCESS),he.updateDisplayText(oe.CALLING)):(ae.emit(se.UNMUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(oe.HOLDING),ae.emit(se.HOLD_SUCCESS)):(ae.emit(se.HOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_UNHOLD&&(0===i?(he.updateDisplayText(oe.CALLING),he.updateIsHold(!1),ae.emit(se.UNHOLD_SUCCESS)):(ae.emit(se.UNHOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER&&(0===i?ae.emit(se.CONSULT_TRANSFER_SUCCESS):(ae.emit(se.CONSULT_TRANSFER_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER_FAILED&&ae.emit(se.CONSULT_TRANSFER_FAILED,s.status),t===ie.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.CALLING),ae.emit(se.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(ps),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===ie.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.INCOMING_CALL),ae.emit(se.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(us),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===ie.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(se.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(ps),he.updateDisplayText(oe.CALLING)),t===ie.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.INCOMING_CALL_END),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(Vs))),t===ie.SATISFACTION_EVALUATION&&(0===i?ae.emit(se.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(se.SATISFACTION_EVALUATION_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_THREE_WAY&&(0!==i?(ae.emit(se.CONSULT_THREE_WAY_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===ie.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(ee.MEETING),he.updateDisplayText(oe.MEETING),he.updateActionConfigs(ds),ae.emit(se.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(se.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===ie.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(oe.TRANSFERRING),ae.emit(se.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(se.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(ee.TRANSFER),he.updateDisplayText(oe.TRANSFER_INCOMING_CALL),he.updateActionConfigs(us),Ve.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===ie.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(se.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(ps)),t===ie.TRANSFER_FAILED&&"failed"===s.status){ae.emit(se.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===ee.OUTGOING?he.updateActionConfigs(ls):A===ee.INCOMING&&he.updateActionConfigs(ps)}t===ie.KICK_OFFLINE&&ae.emit(re.KICK_OFF)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Ns("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){bs&&(bs.close(),bs=null)}static __internalSend(A){if(!bs)throw new Error("WebSocket 尚未初始化");bs.sendMessage(A)}}class Hs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Js.__internalSend({type:ie.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Js.__internalSend({type:ie.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:A}})}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Js.__internalSend({type:ie.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(ee.OUTGOING),Js.__internalSend({type:ie.OUT_CALL,data:{customer_phone:A,caller:t}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:ie.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:ie.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:ie.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Js.__internalSend({type:ie.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:ie.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:ie.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class js{static{this._instance=null}#A=null;#e=new ks;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!js._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();_e.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null}),this.on(re.KICK_OFF,()=>{this.destroy()})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance({url:A,appKey:e,appSecret:t,agentNo:s}){if(!this._instance){js._creatingInstance=!0,this._instance=new js;je=A||"https://aicc.yescloudy.com",Le=e,We=t,Pe=s,delete js._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})}return this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new $e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,enableBrowserAlert:e,logBuiltinEnabled:t}){try{const{viewHtmlElement:s,rttHTML:i}=A||{};Ve.logBuiltinEnabled=t||!1,await this.#e._agentLogin(Pe);const{agent_no:r,current_answer_device:o,current_state:n,out_display_number:a,out_display_select_switch:V}=Ve.agentInfo;n===Ae.IDLE?(he.updateActionConfigs(Vs),Ve.stateObject={state:n,state_name:"空闲"}):n===Ae.BUSY&&(he.updateActionConfigs(cs),Ve.stateObject={state:n,state_name:"忙碌"}),1===V?he.updateSelectOutNumber(a):he.updateSelectOutNumber("");let c="";const h=new URL(je).host;c=je.includes("https")?`wss://${h}`:`ws://${h}`,Js.getInstance(`${c}/ccs-ws/api/v1/ws/call/${r}?Authorization=`),he.updateAnswerDevice(o),1===o&&await this.initWebRtc(),this.#t=new Hs(this.#A),A&&s&&(this.#i=!0,new xs({container:s,rttHTML:i,statusParams:{state:Ae.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=e,e&&Ks.requestPermission(),ae.emit(re.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&Zs("初始化失败"),ae.emit(re.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){js._instance&&(await this.destroyRtc(),clearInterval(this.#s),Js.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,js._instance=null,he.reset(),he.updateSelectOutNumber(""))}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A)),checkAgentLogin:A=>this.#e.checkAgentLogin(A)}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}import.meta.hot&&import.meta.hot.dispose(()=>{js.instance&&js.destroyInstance()});export{Ae as AgentStatus,se as CallSipCallEvent,ee as DirectionEnum,oe as DisplayTextEnum,re as EventName,te as WebRtcCallSipEventEnum,ie as WebsocketTypeEnum,js as default};
914
+ `;is(s,this.rttHTML)}}class Ks{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Os=console.log,Ns=(...A)=>{Ve.logBuiltinEnabled&&Os(...A)};let bs=null;class Js{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new ks,this.initWebSocket()}static getInstance(A){if(!bs){if(!A)throw new Error("WebSocket 尚未初始化");bs=new Js(A)}return bs}stateIdleChange(){const{state:A}=Ve.stateObject;A!==Ae.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(se.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(se.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Ns("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===ie.OUT_CALL&&(0!==i?(he.reset(),ae.emit(se.OUT_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(se.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(se.OUT_SUCCESS)),t===ie.AGENT_STATE){Ve.stateObject.state!==Ae.IDLE&&Ve.stateObject.state!==Ae.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(oe.AGENT_RINGING),ae.emit(se.AGENT_STATE,{state:A,state_name:e})}if(t===ie.OUT_CALL_INCOMING_CALL&&(ae.emit(se.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(hs)),t===ie.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.OUT_HANGUP,s),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(Vs))),t===ie.OUT_CALL_RINGING&&1===s.type&&(ae.emit(se.OUT_RINGING,s),he.updateDisplayText(oe.RINGING)),t===ie.OUT_CALL_ANSWER&&(ae.emit(se.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(ls)),t===ie.CONSULT_RINGING&&(ae.emit(se.CONSULT_RINGING),he.updateDisplayText(oe.AGENT_RINGING),he.updateActionConfigs([])),t===ie.CONSULT_ANSWER&&(ae.emit(se.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CONSULTING),he.updateActionConfigs(gs)),t===ie.CONSULT_FAIL&&(ae.emit(se.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(ls)),t===ie.CONSULT_CALL_IN&&(ae.emit(se.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(ee.CONSULT),he.updateDisplayText(oe.CONSULT_CALL_IN),he.updateActionConfigs(us),Ve.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===ie.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(se.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(qs)),t===ie.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(se.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)),t===ie.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(se.MUTE_SUCCESS),he.updateDisplayText(oe.MUTING)):(ae.emit(se.MUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(se.UNMUTE_SUCCESS),he.updateDisplayText(oe.CALLING)):(ae.emit(se.UNMUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(oe.HOLDING),ae.emit(se.HOLD_SUCCESS)):(ae.emit(se.HOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_UNHOLD&&(0===i?(he.updateDisplayText(oe.CALLING),he.updateIsHold(!1),ae.emit(se.UNHOLD_SUCCESS)):(ae.emit(se.UNHOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER&&(0===i?ae.emit(se.CONSULT_TRANSFER_SUCCESS):(ae.emit(se.CONSULT_TRANSFER_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER_FAILED&&ae.emit(se.CONSULT_TRANSFER_FAILED,s.status),t===ie.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.CALLING),ae.emit(se.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(ps),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===ie.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.INCOMING_CALL),ae.emit(se.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(us),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===ie.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(se.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(ps),he.updateDisplayText(oe.CALLING)),t===ie.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.INCOMING_CALL_END),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(Vs)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(ls)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(Vs)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(Vs))),t===ie.SATISFACTION_EVALUATION&&(0===i?ae.emit(se.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(se.SATISFACTION_EVALUATION_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_THREE_WAY&&(0!==i?(ae.emit(se.CONSULT_THREE_WAY_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===ie.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(ee.MEETING),he.updateDisplayText(oe.MEETING),he.updateActionConfigs(ds),ae.emit(se.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(se.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===ie.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(oe.TRANSFERRING),ae.emit(se.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(se.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(ee.TRANSFER),he.updateDisplayText(oe.TRANSFER_INCOMING_CALL),he.updateActionConfigs(us),Ve.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===ie.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(se.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(ps)),t===ie.TRANSFER_FAILED&&"failed"===s.status){ae.emit(se.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===ee.OUTGOING?he.updateActionConfigs(ls):A===ee.INCOMING&&he.updateActionConfigs(ps)}t===ie.KICK_OFFLINE&&ae.emit(re.KICK_OFF)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Ns("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){bs&&(bs.close(),bs=null)}static __internalSend(A){if(!bs)throw new Error("WebSocket 尚未初始化");bs.sendMessage(A)}}class Hs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Js.__internalSend({type:ie.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Js.__internalSend({type:ie.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:A}})}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Js.__internalSend({type:ie.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(ee.OUTGOING),Js.__internalSend({type:ie.OUT_CALL,data:{customer_phone:A,caller:t}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;Js.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:ie.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:ie.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:ie.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Js.__internalSend({type:ie.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:ie.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:ie.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class js{static{this._instance=null}#A=null;#e=new ks;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!js._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();_e.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null}),this.on(re.KICK_OFF,()=>{this.destroy()})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(A){if(!this._instance){if(!A)throw new Error("首次调用必须传入配置参数");const{url:e,appKey:t,appSecret:s,agentNo:i}=A;je=e||"https://aicc.yescloudy.com",Le=t,We=s,Pe=i,js._creatingInstance=!0,this._instance=new js,delete js._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})}return this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new $e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,enableBrowserAlert:e,logBuiltinEnabled:t}){try{const{viewHtmlElement:s,rttHTML:i}=A||{};Ve.logBuiltinEnabled=t||!1,await this.#e._agentLogin(Pe);const{agent_no:r,current_answer_device:o,current_state:n,out_display_number:a,out_display_select_switch:V}=Ve.agentInfo;n===Ae.IDLE?(he.updateActionConfigs(Vs),Ve.stateObject={state:n,state_name:"空闲"}):n===Ae.BUSY&&(he.updateActionConfigs(cs),Ve.stateObject={state:n,state_name:"忙碌"}),1===V?he.updateSelectOutNumber(a):he.updateSelectOutNumber("");let c="";const h=new URL(je).host;c=je.includes("https")?`wss://${h}`:`ws://${h}`,Js.getInstance(`${c}/ccs-ws/api/v1/ws/call/${r}?Authorization=`),he.updateAnswerDevice(o),1===o&&await this.initWebRtc(),this.#t=new Hs(this.#A),A&&s&&(this.#i=!0,new xs({container:s,rttHTML:i,statusParams:{state:Ae.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=e,e&&Ks.requestPermission(),ae.emit(re.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&Zs("初始化失败"),ae.emit(re.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){js._instance&&(await this.destroyRtc(),clearInterval(this.#s),Js.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,js._instance=null,he.reset(),he.updateSelectOutNumber(""))}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A)),checkAgentLogin:A=>this.#e.checkAgentLogin(A)}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}import.meta.hot&&import.meta.hot.dispose(()=>{window.location.reload()});export{Ae as AgentStatus,se as CallSipCallEvent,ee as DirectionEnum,oe as DisplayTextEnum,re as EventName,te as WebRtcCallSipEventEnum,ie as WebsocketTypeEnum,js as default};
@@ -9,7 +9,7 @@
9
9
  * @copyright Chen, Yi-Cyuan 2014-2023
10
10
  * @license MIT
11
11
  */
12
- !function(A){!function(){var s="input is invalid type",i="object"==typeof window,r=i?window:{};r.JS_MD5_NO_WINDOW&&(i=!1);var n=!i&&"object"==typeof self,o=!r.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;o?r=Ke:n&&(r=self);var a,V=!r.JS_MD5_NO_COMMON_JS&&A.exports,c=!r.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,h="0123456789abcdef".split(""),l=[128,32768,8388608,-2147483648],g=[0,8,16,24],q=["hex","array","digest","buffer","arrayBuffer","base64"],d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),u=[];if(c){var p=new ArrayBuffer(68);a=new Uint8Array(p),u=new Uint32Array(p)}var m=Array.isArray;!r.JS_MD5_NO_NODE_JS&&m||(m=function(A){return"[object Array]"===Object.prototype.toString.call(A)});var C=ArrayBuffer.isView;!c||!r.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&C||(C=function(A){return"object"==typeof A&&A.buffer&&A.buffer.constructor===ArrayBuffer});var E=function(A){var e=typeof A;if("string"===e)return[A,!0];if("object"!==e||null===A)throw new Error(s);if(c&&A.constructor===ArrayBuffer)return[new Uint8Array(A),!1];if(!m(A)&&!C(A))throw new Error(s);return[A,!1]},I=function(A){return function(e){return new f(!0).update(e)[A]()}},M=function(A){var i,n=e,o=t.Buffer;i=o.from&&!r.JS_MD5_NO_BUFFER_FROM?o.from:function(A){return new o(A)};return function(e){if("string"==typeof e)return n.createHash("md5").update(e,"utf8").digest("hex");if(null==e)throw new Error(s);return e.constructor===ArrayBuffer&&(e=new Uint8Array(e)),m(e)||C(e)||e.constructor===o?n.createHash("md5").update(i(e)).digest("hex"):A(e)}},w=function(A){return function(e,t){return new B(e,!0).update(t)[A]()}};function f(A){if(A)u[0]=u[16]=u[1]=u[2]=u[3]=u[4]=u[5]=u[6]=u[7]=u[8]=u[9]=u[10]=u[11]=u[12]=u[13]=u[14]=u[15]=0,this.blocks=u,this.buffer8=a;else if(c){var e=new ArrayBuffer(68);this.buffer8=new Uint8Array(e),this.blocks=new Uint32Array(e)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}function B(A,e){var t,s=E(A);if(A=s[0],s[1]){var i,r=[],n=A.length,o=0;for(t=0;t<n;++t)(i=A.charCodeAt(t))<128?r[o++]=i:i<2048?(r[o++]=192|i>>>6,r[o++]=128|63&i):i<55296||i>=57344?(r[o++]=224|i>>>12,r[o++]=128|i>>>6&63,r[o++]=128|63&i):(i=65536+((1023&i)<<10|1023&A.charCodeAt(++t)),r[o++]=240|i>>>18,r[o++]=128|i>>>12&63,r[o++]=128|i>>>6&63,r[o++]=128|63&i);A=r}A.length>64&&(A=new f(!0).update(A).array());var a=[],V=[];for(t=0;t<64;++t){var c=A[t]||0;a[t]=92^c,V[t]=54^c}f.call(this,e),this.update(V),this.oKeyPad=a,this.inner=!0,this.sharedMemory=e}f.prototype.update=function(A){if(this.finalized)throw new Error("finalize already called");var e=E(A);A=e[0];for(var t,s,i=e[1],r=0,n=A.length,o=this.blocks,a=this.buffer8;r<n;){if(this.hashed&&(this.hashed=!1,o[0]=o[16],o[16]=o[1]=o[2]=o[3]=o[4]=o[5]=o[6]=o[7]=o[8]=o[9]=o[10]=o[11]=o[12]=o[13]=o[14]=o[15]=0),i)if(c)for(s=this.start;r<n&&s<64;++r)(t=A.charCodeAt(r))<128?a[s++]=t:t<2048?(a[s++]=192|t>>>6,a[s++]=128|63&t):t<55296||t>=57344?(a[s++]=224|t>>>12,a[s++]=128|t>>>6&63,a[s++]=128|63&t):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),a[s++]=240|t>>>18,a[s++]=128|t>>>12&63,a[s++]=128|t>>>6&63,a[s++]=128|63&t);else for(s=this.start;r<n&&s<64;++r)(t=A.charCodeAt(r))<128?o[s>>>2]|=t<<g[3&s++]:t<2048?(o[s>>>2]|=(192|t>>>6)<<g[3&s++],o[s>>>2]|=(128|63&t)<<g[3&s++]):t<55296||t>=57344?(o[s>>>2]|=(224|t>>>12)<<g[3&s++],o[s>>>2]|=(128|t>>>6&63)<<g[3&s++],o[s>>>2]|=(128|63&t)<<g[3&s++]):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),o[s>>>2]|=(240|t>>>18)<<g[3&s++],o[s>>>2]|=(128|t>>>12&63)<<g[3&s++],o[s>>>2]|=(128|t>>>6&63)<<g[3&s++],o[s>>>2]|=(128|63&t)<<g[3&s++]);else if(c)for(s=this.start;r<n&&s<64;++r)a[s++]=A[r];else for(s=this.start;r<n&&s<64;++r)o[s>>>2]|=A[r]<<g[3&s++];this.lastByteIndex=s,this.bytes+=s-this.start,s>=64?(this.start=s-64,this.hash(),this.hashed=!0):this.start=s}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296|0,this.bytes=this.bytes%4294967296),this},f.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var A=this.blocks,e=this.lastByteIndex;A[e>>>2]|=l[3&e],e>=56&&(this.hashed||this.hash(),A[0]=A[16],A[16]=A[1]=A[2]=A[3]=A[4]=A[5]=A[6]=A[7]=A[8]=A[9]=A[10]=A[11]=A[12]=A[13]=A[14]=A[15]=0),A[14]=this.bytes<<3,A[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},f.prototype.hash=function(){var A,e,t,s,i,r,n=this.blocks;this.first?e=((e=((A=((A=n[0]-680876937)<<7|A>>>25)-271733879|0)^(t=((t=(-271733879^(s=((s=(-1732584194^2004318071&A)+n[1]-117830708)<<12|s>>>20)+A|0)&(-271733879^A))+n[2]-1126478375)<<17|t>>>15)+s|0)&(s^A))+n[3]-1316259209)<<22|e>>>10)+t|0:(A=this.h0,e=this.h1,t=this.h2,e=((e+=((A=((A+=((s=this.h3)^e&(t^s))+n[0]-680876936)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[1]-389564586)<<12|s>>>20)+A|0)&(A^e))+n[2]+606105819)<<17|t>>>15)+s|0)&(s^A))+n[3]-1044525330)<<22|e>>>10)+t|0),e=((e+=((A=((A+=(s^e&(t^s))+n[4]-176418897)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[5]+1200080426)<<12|s>>>20)+A|0)&(A^e))+n[6]-1473231341)<<17|t>>>15)+s|0)&(s^A))+n[7]-45705983)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+n[8]+1770035416)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[9]-1958414417)<<12|s>>>20)+A|0)&(A^e))+n[10]-42063)<<17|t>>>15)+s|0)&(s^A))+n[11]-1990404162)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+n[12]+1804603682)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[13]-40341101)<<12|s>>>20)+A|0)&(A^e))+n[14]-1502002290)<<17|t>>>15)+s|0)&(s^A))+n[15]+1236535329)<<22|e>>>10)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[1]-165796510)<<5|A>>>27)+e|0)^e))+n[6]-1069501632)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[11]+643717713)<<14|t>>>18)+s|0)^s))+n[0]-373897302)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[5]-701558691)<<5|A>>>27)+e|0)^e))+n[10]+38016083)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[15]-660478335)<<14|t>>>18)+s|0)^s))+n[4]-405537848)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[9]+568446438)<<5|A>>>27)+e|0)^e))+n[14]-1019803690)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[3]-187363961)<<14|t>>>18)+s|0)^s))+n[8]+1163531501)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[13]-1444681467)<<5|A>>>27)+e|0)^e))+n[2]-51403784)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[7]+1735328473)<<14|t>>>18)+s|0)^s))+n[12]-1926607734)<<20|e>>>12)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[5]-378558)<<4|A>>>28)+e|0))+n[8]-2022574463)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[11]+1839030562)<<16|t>>>16)+s|0))+n[14]-35309556)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[1]-1530992060)<<4|A>>>28)+e|0))+n[4]+1272893353)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[7]-155497632)<<16|t>>>16)+s|0))+n[10]-1094730640)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[13]+681279174)<<4|A>>>28)+e|0))+n[0]-358537222)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[3]-722521979)<<16|t>>>16)+s|0))+n[6]+76029189)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[9]-640364487)<<4|A>>>28)+e|0))+n[12]-421815835)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[15]+530742520)<<16|t>>>16)+s|0))+n[2]-995338651)<<23|e>>>9)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[0]-198630844)<<6|A>>>26)+e|0)|~t))+n[7]+1126891415)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[14]-1416354905)<<15|t>>>17)+s|0)|~A))+n[5]-57434055)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[12]+1700485571)<<6|A>>>26)+e|0)|~t))+n[3]-1894986606)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[10]-1051523)<<15|t>>>17)+s|0)|~A))+n[1]-2054922799)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[8]+1873313359)<<6|A>>>26)+e|0)|~t))+n[15]-30611744)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[6]-1560198380)<<15|t>>>17)+s|0)|~A))+n[13]+1309151649)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[4]-145523070)<<6|A>>>26)+e|0)|~t))+n[11]-1120210379)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[2]+718787259)<<15|t>>>17)+s|0)|~A))+n[9]-343485551)<<21|e>>>11)+t|0,this.first?(this.h0=A+1732584193|0,this.h1=e-271733879|0,this.h2=t-1732584194|0,this.h3=s+271733878|0,this.first=!1):(this.h0=this.h0+A|0,this.h1=this.h1+e|0,this.h2=this.h2+t|0,this.h3=this.h3+s|0)},f.prototype.hex=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return h[A>>>4&15]+h[15&A]+h[A>>>12&15]+h[A>>>8&15]+h[A>>>20&15]+h[A>>>16&15]+h[A>>>28&15]+h[A>>>24&15]+h[e>>>4&15]+h[15&e]+h[e>>>12&15]+h[e>>>8&15]+h[e>>>20&15]+h[e>>>16&15]+h[e>>>28&15]+h[e>>>24&15]+h[t>>>4&15]+h[15&t]+h[t>>>12&15]+h[t>>>8&15]+h[t>>>20&15]+h[t>>>16&15]+h[t>>>28&15]+h[t>>>24&15]+h[s>>>4&15]+h[15&s]+h[s>>>12&15]+h[s>>>8&15]+h[s>>>20&15]+h[s>>>16&15]+h[s>>>28&15]+h[s>>>24&15]},f.prototype.toString=f.prototype.hex,f.prototype.digest=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return[255&A,A>>>8&255,A>>>16&255,A>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255,255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&s,s>>>8&255,s>>>16&255,s>>>24&255]},f.prototype.array=f.prototype.digest,f.prototype.arrayBuffer=function(){this.finalize();var A=new ArrayBuffer(16),e=new Uint32Array(A);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,A},f.prototype.buffer=f.prototype.arrayBuffer,f.prototype.base64=function(){for(var A,e,t,s="",i=this.array(),r=0;r<15;)A=i[r++],e=i[r++],t=i[r++],s+=d[A>>>2]+d[63&(A<<4|e>>>4)]+d[63&(e<<2|t>>>6)]+d[63&t];return A=i[r],s+=d[A>>>2]+d[A<<4&63]+"=="},B.prototype=new f,B.prototype.finalize=function(){if(f.prototype.finalize.call(this),this.inner){this.inner=!1;var A=this.array();f.call(this,this.sharedMemory),this.update(this.oKeyPad),this.update(A),f.prototype.finalize.call(this)}};var Q=function(){var A=I("hex");o&&(A=M(A)),A.create=function(){return new f},A.update=function(e){return A.create().update(e)};for(var e=0;e<q.length;++e){var t=q[e];A[t]=I(t)}return A}();Q.md5=Q,Q.md5.hmac=function(){var A=w("hex");A.create=function(A){return new B(A)},A.update=function(e,t){return A.create(e).update(t)};for(var e=0;e<q.length;++e){var t=q[e];A[t]=w(t)}return A}(),V?A.exports=Q:r.md5=Q}()}(Oe);var Ne=Oe.exports;const be=(A,e)=>{const t=Date.now(),s=`${A}:${t}:${Ne.md5(`${e}${t}`)}`,i=(new TextEncoder).encode(s);return btoa(String.fromCharCode(...i))},Je="/v1/aicc/bmserver",He="/v1/aicc/ccs";let je="",Le="",We="",Pe="";async function ze(A,e){const t=function(){const A=be(Le,We);return xe.create({prefixUrl:`${je}/api`,timeout:!1,headers:{Authorization:A},hooks:{afterResponse:[async(A,e,t)=>{const s=await t.clone().json();if(0!==s.code)throw new Error(JSON.stringify(s)||"请求失败");return t.json=async()=>s,t}]}})}(),s=A.replace(/^\/+/,"");return t.post(s,{json:e}).json()}const Xe=A=>ze(`${He}/state/change`,A);const _e=new class extends Ae{updateRttObject(e){this.setState({rttObject:e}),Ve.emit(A.EventName.WEBSITE_DELAY,e)}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class $e{constructor(A,e){this.config=A,this.eventCallback=e,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.isManuallyStopped=!1,this.handleNetworkInfoChange=A=>{if(A.rttObject?.rtt){0===(A.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())}},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString()),this.destroy()},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString()),this.reconnect()},_e.subscribe(this.handleNetworkInfoChange)}async start(){const A=$A.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!A)throw new Error("无效的SIP配置");const e={uri:A,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:30},contactName:this.config.user,contactParams:{transport:"wss"},userAgentString:"SwiftSIP/1.0.74",sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:400},logBuiltinEnabled:ce.logBuiltinEnabled};this.userAgent=new $A(e),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(e=>{let t;switch(e){case eA.Connecting:t=A.WebRtcCallSipEventEnum.WEB_RTC_CONNECTING;break;case eA.Connected:t=A.WebRtcCallSipEventEnum.WEB_RTC_CONNECTED,this.reconnectAttempts=0,ce.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case eA.Disconnecting:t=A.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTING;break;case eA.Disconnected:{if(this.isManuallyStopped)return void console.warn("[SIP] 手动断开,不触发重连");t=A.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTED;const e=le.get("answerDevice");if(!ce.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===e){this.reconnectAttempts++;const A=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${A}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},A)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:t="unknown"}this.eventCallback?.({type:t})}),this.userAgent.delegate={onInvite:A=>{this.handleIncomingCall(A)}})}async register(){if(this.userAgent){this.registerer=new nA(this.userAgent),this.registerer?.stateChange.addListener(e=>{let t;switch(e){case $.Initial:t="initial";break;case $.Registered:t=A.WebRtcCallSipEventEnum.WEB_RTC_REGISTERED;break;case $.Unregistered:t=A.WebRtcCallSipEventEnum.WEB_RTC_UNREGISTERED;break;case $.Terminated:t=A.WebRtcCallSipEventEnum.WEB_RTC_TERMINATED;break;default:t="unknown"}this.eventCallback?.({type:t})});try{await this.registerer.register()}catch(e){this.eventCallback?.({type:A.WebRtcCallSipEventEnum.WEB_RTC_REGISTER_FAILED,data:e})}}}attachRemoteAudio(A){const e=A.sessionDescriptionHandler;if(e){const A=e.peerConnection;if(!A)return;const t=new MediaStream;A.getReceivers().forEach(A=>{A.track&&"audio"===A.track.kind&&t.addTrack(A.track)});let s=document.getElementById("sip-remote-audio");s||(s=document.createElement("audio"),s.id="sip-remote-audio",s.autoplay=!0,s.style.display="none",document.body.appendChild(s)),s.srcObject=t,s.play().catch(A=>{console.error("音频播放失败,需要用户交互触发",A)})}}handleSessionState(A,e,t){A.stateChange.addListener(e=>{switch(e){case L.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=A,this.attachRemoteAudio(A);break;case L.Terminating:break;case L.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case L.Establishing:}})}handleIncomingCall(e){this.incomingInvitation=e,this.handleSessionState(e,!1);const{soft_device_auto_answer:t,auto_answer_time:s}=ce.agentInfo,i=le.get("direction"),r=1===t;if(i===A.DirectionEnum.OUTGOING)this.answerCall();else if(r&&i===A.DirectionEnum.INCOMING){const A=Number(s)||0;A>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},A):this.answerCall()}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{this.activeSession=this.incomingInvitation,await this.incomingInvitation.accept(),this.incomingInvitation=null}catch(e){this.eventCallback?.({type:A.WebRtcCallSipEventEnum.WEB_RTC_ANSWER_FAILED,data:{detail:e}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,le.updateDirection(null),le.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(A){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:A}})}}sendDTMF(e){if(!this.activeSession)throw new Error("当前没有活跃的通话");const t=this.activeSession.sessionDescriptionHandler;t&&"function"==typeof t.sendDtmf?(t.sendDtmf(e),this.eventCallback?.({type:A.WebRtcCallSipEventEnum.WEB_RTC_SEND_DTMF,data:{tone:e}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession,this.activeSession){clearTimeout(this.callTimeoutTimer);const A=this.activeSession;if(!A)return;const e=A.state;try{e===L.Established?await A.bye():e===L.Establishing&&(A instanceof _?await A.cancel():A instanceof X&&await A.reject()),clearTimeout(this.callTimeoutTimer)}catch(A){console.error("挂断失败",A)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof X&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(this.isManuallyStopped=!0,clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(A){console.warn("注销失败",A)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!ce.isRtcReconnecting){ce.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),this.isOffline=!1}catch(A){console.error("重连失败",A)}finally{ce.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const A=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!A)return null;const e=await A.getStats(),t={};return e.forEach(A=>{"candidate-pair"===A.type&&"succeeded"===A.state&&null!=A.currentRoundTripTime&&(t.rtt=+(1e3*A.currentRoundTripTime).toFixed(2)),"inbound-rtp"===A.type&&"audio"===A.kind&&(t.jitter=+(1e3*A.jitter).toFixed(2),t.packetsLost=A.packetsLost,t.packetsReceived=A.packetsReceived,A.bytesReceived&&A.timestamp&&(t.recvBitrate=+(A.bytesReceived/1024).toFixed(2))),"outbound-rtp"===A.type&&"audio"===A.kind&&(t.packetsSent=A.packetsSent,A.bytesSent&&A.timestamp&&(t.sendBitrate=+(A.bytesSent/1024).toFixed(2))),"codec"===A.type&&A.mimeType&&(t.codec=A.mimeType)}),{...t,rtt:t?.rtt||40}}try{const A=Date.now();await ze(`${Je}/config/ping`,{});const e=Date.now();return{rtt:e-A||1}}catch(A){}}}
12
+ !function(A){!function(){var s="input is invalid type",i="object"==typeof window,r=i?window:{};r.JS_MD5_NO_WINDOW&&(i=!1);var n=!i&&"object"==typeof self,o=!r.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;o?r=Ke:n&&(r=self);var a,V=!r.JS_MD5_NO_COMMON_JS&&A.exports,c=!r.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,h="0123456789abcdef".split(""),l=[128,32768,8388608,-2147483648],g=[0,8,16,24],q=["hex","array","digest","buffer","arrayBuffer","base64"],d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),u=[];if(c){var p=new ArrayBuffer(68);a=new Uint8Array(p),u=new Uint32Array(p)}var m=Array.isArray;!r.JS_MD5_NO_NODE_JS&&m||(m=function(A){return"[object Array]"===Object.prototype.toString.call(A)});var C=ArrayBuffer.isView;!c||!r.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&C||(C=function(A){return"object"==typeof A&&A.buffer&&A.buffer.constructor===ArrayBuffer});var E=function(A){var e=typeof A;if("string"===e)return[A,!0];if("object"!==e||null===A)throw new Error(s);if(c&&A.constructor===ArrayBuffer)return[new Uint8Array(A),!1];if(!m(A)&&!C(A))throw new Error(s);return[A,!1]},I=function(A){return function(e){return new f(!0).update(e)[A]()}},M=function(A){var i,n=e,o=t.Buffer;i=o.from&&!r.JS_MD5_NO_BUFFER_FROM?o.from:function(A){return new o(A)};return function(e){if("string"==typeof e)return n.createHash("md5").update(e,"utf8").digest("hex");if(null==e)throw new Error(s);return e.constructor===ArrayBuffer&&(e=new Uint8Array(e)),m(e)||C(e)||e.constructor===o?n.createHash("md5").update(i(e)).digest("hex"):A(e)}},w=function(A){return function(e,t){return new B(e,!0).update(t)[A]()}};function f(A){if(A)u[0]=u[16]=u[1]=u[2]=u[3]=u[4]=u[5]=u[6]=u[7]=u[8]=u[9]=u[10]=u[11]=u[12]=u[13]=u[14]=u[15]=0,this.blocks=u,this.buffer8=a;else if(c){var e=new ArrayBuffer(68);this.buffer8=new Uint8Array(e),this.blocks=new Uint32Array(e)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}function B(A,e){var t,s=E(A);if(A=s[0],s[1]){var i,r=[],n=A.length,o=0;for(t=0;t<n;++t)(i=A.charCodeAt(t))<128?r[o++]=i:i<2048?(r[o++]=192|i>>>6,r[o++]=128|63&i):i<55296||i>=57344?(r[o++]=224|i>>>12,r[o++]=128|i>>>6&63,r[o++]=128|63&i):(i=65536+((1023&i)<<10|1023&A.charCodeAt(++t)),r[o++]=240|i>>>18,r[o++]=128|i>>>12&63,r[o++]=128|i>>>6&63,r[o++]=128|63&i);A=r}A.length>64&&(A=new f(!0).update(A).array());var a=[],V=[];for(t=0;t<64;++t){var c=A[t]||0;a[t]=92^c,V[t]=54^c}f.call(this,e),this.update(V),this.oKeyPad=a,this.inner=!0,this.sharedMemory=e}f.prototype.update=function(A){if(this.finalized)throw new Error("finalize already called");var e=E(A);A=e[0];for(var t,s,i=e[1],r=0,n=A.length,o=this.blocks,a=this.buffer8;r<n;){if(this.hashed&&(this.hashed=!1,o[0]=o[16],o[16]=o[1]=o[2]=o[3]=o[4]=o[5]=o[6]=o[7]=o[8]=o[9]=o[10]=o[11]=o[12]=o[13]=o[14]=o[15]=0),i)if(c)for(s=this.start;r<n&&s<64;++r)(t=A.charCodeAt(r))<128?a[s++]=t:t<2048?(a[s++]=192|t>>>6,a[s++]=128|63&t):t<55296||t>=57344?(a[s++]=224|t>>>12,a[s++]=128|t>>>6&63,a[s++]=128|63&t):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),a[s++]=240|t>>>18,a[s++]=128|t>>>12&63,a[s++]=128|t>>>6&63,a[s++]=128|63&t);else for(s=this.start;r<n&&s<64;++r)(t=A.charCodeAt(r))<128?o[s>>>2]|=t<<g[3&s++]:t<2048?(o[s>>>2]|=(192|t>>>6)<<g[3&s++],o[s>>>2]|=(128|63&t)<<g[3&s++]):t<55296||t>=57344?(o[s>>>2]|=(224|t>>>12)<<g[3&s++],o[s>>>2]|=(128|t>>>6&63)<<g[3&s++],o[s>>>2]|=(128|63&t)<<g[3&s++]):(t=65536+((1023&t)<<10|1023&A.charCodeAt(++r)),o[s>>>2]|=(240|t>>>18)<<g[3&s++],o[s>>>2]|=(128|t>>>12&63)<<g[3&s++],o[s>>>2]|=(128|t>>>6&63)<<g[3&s++],o[s>>>2]|=(128|63&t)<<g[3&s++]);else if(c)for(s=this.start;r<n&&s<64;++r)a[s++]=A[r];else for(s=this.start;r<n&&s<64;++r)o[s>>>2]|=A[r]<<g[3&s++];this.lastByteIndex=s,this.bytes+=s-this.start,s>=64?(this.start=s-64,this.hash(),this.hashed=!0):this.start=s}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296|0,this.bytes=this.bytes%4294967296),this},f.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var A=this.blocks,e=this.lastByteIndex;A[e>>>2]|=l[3&e],e>=56&&(this.hashed||this.hash(),A[0]=A[16],A[16]=A[1]=A[2]=A[3]=A[4]=A[5]=A[6]=A[7]=A[8]=A[9]=A[10]=A[11]=A[12]=A[13]=A[14]=A[15]=0),A[14]=this.bytes<<3,A[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},f.prototype.hash=function(){var A,e,t,s,i,r,n=this.blocks;this.first?e=((e=((A=((A=n[0]-680876937)<<7|A>>>25)-271733879|0)^(t=((t=(-271733879^(s=((s=(-1732584194^2004318071&A)+n[1]-117830708)<<12|s>>>20)+A|0)&(-271733879^A))+n[2]-1126478375)<<17|t>>>15)+s|0)&(s^A))+n[3]-1316259209)<<22|e>>>10)+t|0:(A=this.h0,e=this.h1,t=this.h2,e=((e+=((A=((A+=((s=this.h3)^e&(t^s))+n[0]-680876936)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[1]-389564586)<<12|s>>>20)+A|0)&(A^e))+n[2]+606105819)<<17|t>>>15)+s|0)&(s^A))+n[3]-1044525330)<<22|e>>>10)+t|0),e=((e+=((A=((A+=(s^e&(t^s))+n[4]-176418897)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[5]+1200080426)<<12|s>>>20)+A|0)&(A^e))+n[6]-1473231341)<<17|t>>>15)+s|0)&(s^A))+n[7]-45705983)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+n[8]+1770035416)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[9]-1958414417)<<12|s>>>20)+A|0)&(A^e))+n[10]-42063)<<17|t>>>15)+s|0)&(s^A))+n[11]-1990404162)<<22|e>>>10)+t|0,e=((e+=((A=((A+=(s^e&(t^s))+n[12]+1804603682)<<7|A>>>25)+e|0)^(t=((t+=(e^(s=((s+=(t^A&(e^t))+n[13]-40341101)<<12|s>>>20)+A|0)&(A^e))+n[14]-1502002290)<<17|t>>>15)+s|0)&(s^A))+n[15]+1236535329)<<22|e>>>10)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[1]-165796510)<<5|A>>>27)+e|0)^e))+n[6]-1069501632)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[11]+643717713)<<14|t>>>18)+s|0)^s))+n[0]-373897302)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[5]-701558691)<<5|A>>>27)+e|0)^e))+n[10]+38016083)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[15]-660478335)<<14|t>>>18)+s|0)^s))+n[4]-405537848)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[9]+568446438)<<5|A>>>27)+e|0)^e))+n[14]-1019803690)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[3]-187363961)<<14|t>>>18)+s|0)^s))+n[8]+1163531501)<<20|e>>>12)+t|0,e=((e+=((s=((s+=(e^t&((A=((A+=(t^s&(e^t))+n[13]-1444681467)<<5|A>>>27)+e|0)^e))+n[2]-51403784)<<9|s>>>23)+A|0)^A&((t=((t+=(A^e&(s^A))+n[7]+1735328473)<<14|t>>>18)+s|0)^s))+n[12]-1926607734)<<20|e>>>12)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[5]-378558)<<4|A>>>28)+e|0))+n[8]-2022574463)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[11]+1839030562)<<16|t>>>16)+s|0))+n[14]-35309556)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[1]-1530992060)<<4|A>>>28)+e|0))+n[4]+1272893353)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[7]-155497632)<<16|t>>>16)+s|0))+n[10]-1094730640)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[13]+681279174)<<4|A>>>28)+e|0))+n[0]-358537222)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[3]-722521979)<<16|t>>>16)+s|0))+n[6]+76029189)<<23|e>>>9)+t|0,e=((e+=((r=(s=((s+=((i=e^t)^(A=((A+=(i^s)+n[9]-640364487)<<4|A>>>28)+e|0))+n[12]-421815835)<<11|s>>>21)+A|0)^A)^(t=((t+=(r^e)+n[15]+530742520)<<16|t>>>16)+s|0))+n[2]-995338651)<<23|e>>>9)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[0]-198630844)<<6|A>>>26)+e|0)|~t))+n[7]+1126891415)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[14]-1416354905)<<15|t>>>17)+s|0)|~A))+n[5]-57434055)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[12]+1700485571)<<6|A>>>26)+e|0)|~t))+n[3]-1894986606)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[10]-1051523)<<15|t>>>17)+s|0)|~A))+n[1]-2054922799)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[8]+1873313359)<<6|A>>>26)+e|0)|~t))+n[15]-30611744)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[6]-1560198380)<<15|t>>>17)+s|0)|~A))+n[13]+1309151649)<<21|e>>>11)+t|0,e=((e+=((s=((s+=(e^((A=((A+=(t^(e|~s))+n[4]-145523070)<<6|A>>>26)+e|0)|~t))+n[11]-1120210379)<<10|s>>>22)+A|0)^((t=((t+=(A^(s|~e))+n[2]+718787259)<<15|t>>>17)+s|0)|~A))+n[9]-343485551)<<21|e>>>11)+t|0,this.first?(this.h0=A+1732584193|0,this.h1=e-271733879|0,this.h2=t-1732584194|0,this.h3=s+271733878|0,this.first=!1):(this.h0=this.h0+A|0,this.h1=this.h1+e|0,this.h2=this.h2+t|0,this.h3=this.h3+s|0)},f.prototype.hex=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return h[A>>>4&15]+h[15&A]+h[A>>>12&15]+h[A>>>8&15]+h[A>>>20&15]+h[A>>>16&15]+h[A>>>28&15]+h[A>>>24&15]+h[e>>>4&15]+h[15&e]+h[e>>>12&15]+h[e>>>8&15]+h[e>>>20&15]+h[e>>>16&15]+h[e>>>28&15]+h[e>>>24&15]+h[t>>>4&15]+h[15&t]+h[t>>>12&15]+h[t>>>8&15]+h[t>>>20&15]+h[t>>>16&15]+h[t>>>28&15]+h[t>>>24&15]+h[s>>>4&15]+h[15&s]+h[s>>>12&15]+h[s>>>8&15]+h[s>>>20&15]+h[s>>>16&15]+h[s>>>28&15]+h[s>>>24&15]},f.prototype.toString=f.prototype.hex,f.prototype.digest=function(){this.finalize();var A=this.h0,e=this.h1,t=this.h2,s=this.h3;return[255&A,A>>>8&255,A>>>16&255,A>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255,255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&s,s>>>8&255,s>>>16&255,s>>>24&255]},f.prototype.array=f.prototype.digest,f.prototype.arrayBuffer=function(){this.finalize();var A=new ArrayBuffer(16),e=new Uint32Array(A);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,A},f.prototype.buffer=f.prototype.arrayBuffer,f.prototype.base64=function(){for(var A,e,t,s="",i=this.array(),r=0;r<15;)A=i[r++],e=i[r++],t=i[r++],s+=d[A>>>2]+d[63&(A<<4|e>>>4)]+d[63&(e<<2|t>>>6)]+d[63&t];return A=i[r],s+=d[A>>>2]+d[A<<4&63]+"=="},B.prototype=new f,B.prototype.finalize=function(){if(f.prototype.finalize.call(this),this.inner){this.inner=!1;var A=this.array();f.call(this,this.sharedMemory),this.update(this.oKeyPad),this.update(A),f.prototype.finalize.call(this)}};var Q=function(){var A=I("hex");o&&(A=M(A)),A.create=function(){return new f},A.update=function(e){return A.create().update(e)};for(var e=0;e<q.length;++e){var t=q[e];A[t]=I(t)}return A}();Q.md5=Q,Q.md5.hmac=function(){var A=w("hex");A.create=function(A){return new B(A)},A.update=function(e,t){return A.create(e).update(t)};for(var e=0;e<q.length;++e){var t=q[e];A[t]=w(t)}return A}(),V?A.exports=Q:r.md5=Q}()}(Oe);var Ne=Oe.exports;const be=(A,e)=>{const t=Date.now(),s=`${A}:${t}:${Ne.md5(`${e}${t}`)}`,i=(new TextEncoder).encode(s);return btoa(String.fromCharCode(...i))},Je="/v1/aicc/bmserver",He="/v1/aicc/ccs";let je="",Le="",We="",Pe="";async function ze(A,e){const t=function(){const A=be(Le,We);return xe.create({prefixUrl:`${je}/api`,timeout:!1,headers:{Authorization:A},hooks:{afterResponse:[async(A,e,t)=>{const s=await t.clone().json();if(0!==s.code)throw new Error(JSON.stringify(s)||"请求失败");return t.json=async()=>s,t}]}})}(),s=A.replace(/^\/+/,"");return t.post(s,{json:e}).json()}const Xe=A=>ze(`${He}/state/change`,A);const _e=new class extends Ae{updateRttObject(e){this.setState({rttObject:e}),Ve.emit(A.EventName.WEBSITE_DELAY,e)}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class $e{constructor(A,e){this.config=A,this.eventCallback=e,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.isManuallyStopped=!1,this.handleNetworkInfoChange=A=>{if(A.rttObject?.rtt){0===(A.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())}},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString()),this.destroy()},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString()),this.reconnect()},_e.subscribe(this.handleNetworkInfoChange)}async start(){const A=$A.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!A)throw new Error("无效的SIP配置");const e={uri:A,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:30},contactName:this.config.user,contactParams:{transport:"wss"},userAgentString:"SwiftSIP/1.0.74",sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:3},logBuiltinEnabled:ce.logBuiltinEnabled};this.userAgent=new $A(e),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(e=>{let t;switch(e){case eA.Connecting:t=A.WebRtcCallSipEventEnum.WEB_RTC_CONNECTING;break;case eA.Connected:t=A.WebRtcCallSipEventEnum.WEB_RTC_CONNECTED,this.reconnectAttempts=0,ce.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case eA.Disconnecting:t=A.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTING;break;case eA.Disconnected:{if(this.isManuallyStopped)return void console.warn("[SIP] 手动断开,不触发重连");t=A.WebRtcCallSipEventEnum.WEB_RTC_DISCONNECTED;const e=le.get("answerDevice");if(!ce.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===e){this.reconnectAttempts++;const A=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${A}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},A)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:t="unknown"}this.eventCallback?.({type:t})}),this.userAgent.delegate={onInvite:A=>{this.handleIncomingCall(A)}})}async register(){if(this.userAgent){this.registerer=new nA(this.userAgent),this.registerer?.stateChange.addListener(e=>{let t;switch(e){case $.Initial:t="initial";break;case $.Registered:t=A.WebRtcCallSipEventEnum.WEB_RTC_REGISTERED;break;case $.Unregistered:t=A.WebRtcCallSipEventEnum.WEB_RTC_UNREGISTERED;break;case $.Terminated:t=A.WebRtcCallSipEventEnum.WEB_RTC_TERMINATED;break;default:t="unknown"}this.eventCallback?.({type:t})});try{await this.registerer.register()}catch(e){this.eventCallback?.({type:A.WebRtcCallSipEventEnum.WEB_RTC_REGISTER_FAILED,data:e})}}}attachRemoteAudio(A){const e=A.sessionDescriptionHandler;if(e){const A=e.peerConnection;if(!A)return;const t=new MediaStream;A.getReceivers().forEach(A=>{A.track&&"audio"===A.track.kind&&t.addTrack(A.track)});let s=document.getElementById("sip-remote-audio");s||(s=document.createElement("audio"),s.id="sip-remote-audio",s.autoplay=!0,s.style.display="none",document.body.appendChild(s)),s.srcObject=t,s.play().catch(A=>{console.error("音频播放失败,需要用户交互触发",A)})}}handleSessionState(A,e,t){A.stateChange.addListener(e=>{switch(e){case L.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=A,this.attachRemoteAudio(A);break;case L.Terminating:break;case L.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case L.Establishing:}})}handleIncomingCall(e){this.incomingInvitation=e,this.handleSessionState(e,!1);const{soft_device_auto_answer:t,auto_answer_time:s}=ce.agentInfo,i=le.get("direction"),r=1===t;if(i===A.DirectionEnum.OUTGOING)this.answerCall();else if(r&&i===A.DirectionEnum.INCOMING){const A=Number(s)||0;A>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},A):this.answerCall()}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{await this.incomingInvitation.accept(),this.activeSession=this.incomingInvitation,this.incomingInvitation=null}catch(e){this.eventCallback?.({type:A.WebRtcCallSipEventEnum.WEB_RTC_ANSWER_FAILED,data:{detail:e}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,le.updateDirection(null),le.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(A){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:A}})}}sendDTMF(e){if(!this.activeSession)throw new Error("当前没有活跃的通话");const t=this.activeSession.sessionDescriptionHandler;t&&"function"==typeof t.sendDtmf?(t.sendDtmf(e),this.eventCallback?.({type:A.WebRtcCallSipEventEnum.WEB_RTC_SEND_DTMF,data:{tone:e}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession,this.activeSession){clearTimeout(this.callTimeoutTimer);const A=this.activeSession;if(!A)return;const e=A.state;try{e===L.Established?await A.bye():e===L.Establishing&&(A instanceof _?await A.cancel():A instanceof X&&await A.reject()),clearTimeout(this.callTimeoutTimer)}catch(A){console.error("挂断失败",A)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof X&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(this.isManuallyStopped=!0,clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(A){console.warn("注销失败",A)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!ce.isRtcReconnecting){ce.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),this.isOffline=!1}catch(A){console.error("重连失败",A)}finally{ce.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const A=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!A)return null;const e=await A.getStats(),t={};return e.forEach(A=>{"candidate-pair"===A.type&&"succeeded"===A.state&&null!=A.currentRoundTripTime&&(t.rtt=+(1e3*A.currentRoundTripTime).toFixed(2)),"inbound-rtp"===A.type&&"audio"===A.kind&&(t.jitter=+(1e3*A.jitter).toFixed(2),t.packetsLost=A.packetsLost,t.packetsReceived=A.packetsReceived,A.bytesReceived&&A.timestamp&&(t.recvBitrate=+(A.bytesReceived/1024).toFixed(2))),"outbound-rtp"===A.type&&"audio"===A.kind&&(t.packetsSent=A.packetsSent,A.bytesSent&&A.timestamp&&(t.sendBitrate=+(A.bytesSent/1024).toFixed(2))),"codec"===A.type&&A.mimeType&&(t.codec=A.mimeType)}),{...t,rtt:t?.rtt||40}}try{const A=Date.now();await ze(`${Je}/config/ping`,{});const e=Date.now();return{rtt:e-A||1}}catch(A){}}}
13
13
  /**
14
14
  * @license
15
15
  * Copyright 2019 Google LLC
@@ -911,4 +911,4 @@ const Cs=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
911
911
  `:""}
912
912
  </div>
913
913
  </my-popover>
914
- `;is(s,this.rttHTML)}}class Ks{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Os=console.log,Ns=(...A)=>{ce.logBuiltinEnabled&&Os(...A)};let bs=null;class Js{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new ks,this.initWebSocket()}static getInstance(A){if(!bs){if(!A)throw new Error("WebSocket 尚未初始化");bs=new Js(A)}return bs}stateIdleChange(){const{state:e}=ce.stateObject;e!==A.AgentStatus.IDLE&&this.apiClient._changeState({data:{...ce.stateBeforeChange}})}async getCustomerInfo(e){try{await this.apiClient._getInCallCrmDetail({data:{phone:e},success:e=>{const{contact_count:t,customer_name:s,phone:i,city:r,province:n}=e.data;Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,{customer_name:s||"未知客户",phone:i,city:r||"未知",province:n||"未知",contact_count:t||0})}})}catch(A){}}putAgentState(){ce.sessionId="";const{post_call_process_time:e}=ce.agentInfo,t=e||0;ce.autoStateTimer&&(clearTimeout(ce.autoStateTimer),ce.autoStateTimer=null),Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0),t>0?ce.autoStateTimer=setTimeout(()=>{ce.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){const e=be(Le,We);this.ws=new WebSocket(this.url+e),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=e=>{const t=JSON.parse(e.data),{type:s,data:i,code:r,msg:n}=t;if(0!==s&&Ns("%cWebSocket 收到消息:","color: blue; font-weight: bold;",t),s===A.WebsocketTypeEnum.OUT_CALL&&(0!==r?(le.reset(),Ve.emit(A.CallSipCallEvent.OUT_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n),setTimeout(()=>{Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===r&&Ve.emit(A.CallSipCallEvent.OUT_SUCCESS)),s===A.WebsocketTypeEnum.AGENT_STATE){ce.stateObject.state!==A.AgentStatus.IDLE&&ce.stateObject.state!==A.AgentStatus.BUSY||(ce.stateBeforeChange=ce.stateObject);const{state:e,state_name:t}=i;ce.stateObject={state:e,state_name:t},"振铃中"===t&&le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),Ve.emit(A.CallSipCallEvent.AGENT_STATE,{state:e,state_name:t})}if(s===A.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(Ve.emit(A.CallSipCallEvent.OUT_INCOMING_CALL),ce.sessionId=i.session_id,le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.OUT_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.OUT_HANGUP,i),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(ls)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(Vs)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(Vs))),s===A.WebsocketTypeEnum.OUT_CALL_RINGING&&1===i.type&&(Ve.emit(A.CallSipCallEvent.OUT_RINGING,i),le.updateDisplayText(A.DisplayTextEnum.RINGING)),s===A.WebsocketTypeEnum.OUT_CALL_ANSWER&&(Ve.emit(A.CallSipCallEvent.OUT_OFF_ANSWER,i),le.updateOutCallIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.CONSULT_RINGING&&(Ve.emit(A.CallSipCallEvent.CONSULT_RINGING),le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),le.updateActionConfigs([])),s===A.WebsocketTypeEnum.CONSULT_ANSWER&&(Ve.emit(A.CallSipCallEvent.CONSULT_OFF_HOOK,i),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CONSULTING),le.updateActionConfigs(gs)),s===A.WebsocketTypeEnum.CONSULT_FAIL&&(Ve.emit(A.CallSipCallEvent.CONSULT_FAILED,{custom_reason:i.custom_reason}),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.CONSULT_CALL_IN&&(Ve.emit(A.CallSipCallEvent.CONSULT_INCOMING,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.CONSULT),le.updateDisplayText(A.DisplayTextEnum.CONSULT_CALL_IN),le.updateActionConfigs(us),ce.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===A.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(qs)),s===A.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(le.updateConsultIsAnswer(!1),Ve.emit(A.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.MUTE&&(0===r?(le.updateIsMuted(!0),Ve.emit(A.CallSipCallEvent.MUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.MUTING)):(Ve.emit(A.CallSipCallEvent.MUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.UNMUTE&&(0===r?(le.updateIsMuted(!1),Ve.emit(A.CallSipCallEvent.UNMUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING)):(Ve.emit(A.CallSipCallEvent.UNMUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_HOLD&&(0===r?(le.updateIsHold(!0),le.updateDisplayText(A.DisplayTextEnum.HOLDING),Ve.emit(A.CallSipCallEvent.HOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.HOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_UNHOLD&&(0===r?(le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateIsHold(!1),Ve.emit(A.CallSipCallEvent.UNHOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.UNHOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===r?Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,i.status),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),le.updateActionConfigs(ps),le.updateIncomingIsAnswer(!0),le.updateConsultIsAnswer(!1)),s===A.WebsocketTypeEnum.INCOMING_CALL&&(ce.sessionId=i.session_id,le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.INCOMING_CALL),Ve.emit(A.CallSipCallEvent.INCOMING_CALL,{customer_phone:i.customer_phone}),le.updateActionConfigs(us),this.getCustomerInfo(i.customer_phone),ce.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===A.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(le.updateIncomingIsAnswer(!0),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),le.updateActionConfigs(ps),le.updateDisplayText(A.DisplayTextEnum.CALLING)),s===A.WebsocketTypeEnum.INCOMING_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_END),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(ls)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(Vs)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(Vs))),s===A.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===r?Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==r?(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n)):0===r&&le.updateIsMeeting(!0)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===i.status?(le.updateDirection(A.DirectionEnum.MEETING),le.updateDisplayText(A.DisplayTextEnum.MEETING),le.updateActionConfigs(ds),Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:i.conf_name}),le.updateIsMeeting(!1))),s===A.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(i.agent_no===ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.TRANSFERRING),Ve.emit(A.CallSipCallEvent.TRANSFER_PROGRESS),le.updateActionConfigs([]),le.updateTransferIsAnswer(!0)):(Ve.emit(A.CallSipCallEvent.TRANSFER_INCOMING_CALL,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.TRANSFER),le.updateDisplayText(A.DisplayTextEnum.TRANSFER_INCOMING_CALL),le.updateActionConfigs(us),ce.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${i.agent_no}] 正在转接...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_no})}))),s===A.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.TRANSFER_OFF_HOOK),le.updateTransferIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(ps)),s===A.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===i.status){Ve.emit(A.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const e=le.get("direction");e===A.DirectionEnum.OUTGOING?le.updateActionConfigs(ls):e===A.DirectionEnum.INCOMING&&le.updateActionConfigs(ps)}s===A.WebsocketTypeEnum.KICK_OFFLINE&&Ve.emit(A.EventName.KICK_OFF)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Ns("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){bs&&(bs.close(),bs=null)}static __internalSend(A){if(!bs)throw new Error("WebSocket 尚未初始化");bs.sendMessage(A)}}class Hs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=le.get("isCalling"),e=ce.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const e=le.get("isHold"),{sessionId:t}=ce;if(!t)return;if(!le.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Js.__internalSend({type:A.WebsocketTypeEnum.CALL_HOLD,data:{session_id:t}})}unholdCall(){this.roleMute();const{isHold:e}=le.getState(),{sessionId:t}=ce;if(!le.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(t){if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Js.__internalSend({type:A.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:t}})}}sendDTMF(A){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!le.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=le.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!le.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=ce.sessionId;Js.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}async consultCall(e){this.roleMute();const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=le.getState(),n=ce.sessionId;if(!le.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(i)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(t||s||r))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!n)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async answerCall(){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(e){const t=le.get("isCalling"),s=le.get("selectOutNumber")||"";if(t)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.OUTGOING),Js.__internalSend({type:A.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:e,caller:s}})}async hangup(){if(!le.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=ce.sessionId;Js.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}mute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!e.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:A.WebsocketTypeEnum.MUTE,data:{session_id:s}})}unmute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(!t)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!e.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:A.WebsocketTypeEnum.UNMUTE,data:{session_id:s}})}consultTransfer(){this.roleMute();const e=le.get("consultIsAnswer"),t=ce.sessionId;if(!le.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:t}})}satisfactionEvaluation(){this.roleMute();const e=ce.sessionId;if(!le.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Js.__internalSend({type:A.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:e}})}startConference(){this.roleMute();if(!le.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:e}})}consultRetrieve(){this.roleMute();if(!le.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:e}})}async transferAgent(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:0,transfer_dest:e}})}async transferOutline(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(e))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:2,transfer_dest:e}})}}class js{static{this._instance=null}#A=null;#e=new ks;#t;#s=null;#i=!1;#r;#n=!1;constructor(){if(!js._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();_e.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),this.#r=le.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null}),this.on(A.EventName.KICK_OFF,()=>{this.destroy()})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance({url:A,appKey:e,appSecret:t,agentNo:s}){if(!this._instance){js._creatingInstance=!0,this._instance=new js;je=A||"https://aicc.yescloudy.com",Le=e,We=t,Pe=s,delete js._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})}return this._instance}getInit(){return this.#n}async initWebRtc(){if(this.#A)return;const A=ce.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new $e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:e,enableBrowserAlert:t,logBuiltinEnabled:s}){try{const{viewHtmlElement:i,rttHTML:r}=e||{};ce.logBuiltinEnabled=s||!1,await this.#e._agentLogin(Pe);const{agent_no:n,current_answer_device:o,current_state:a,out_display_number:V,out_display_select_switch:c}=ce.agentInfo;a===A.AgentStatus.IDLE?(le.updateActionConfigs(Vs),ce.stateObject={state:a,state_name:"空闲"}):a===A.AgentStatus.BUSY&&(le.updateActionConfigs(cs),ce.stateObject={state:a,state_name:"忙碌"}),1===c?le.updateSelectOutNumber(V):le.updateSelectOutNumber("");let h="";const l=new URL(je).host;h=je.includes("https")?`wss://${l}`:`ws://${l}`,Js.getInstance(`${h}/ccs-ws/api/v1/ws/call/${n}?Authorization=`),le.updateAnswerDevice(o),1===o&&await this.initWebRtc(),this.#t=new Hs(this.#A),e&&i&&(this.#i=!0,new xs({container:i,rttHTML:r,statusParams:{state:A.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),ce.enableBrowserAlert=t,t&&Ks.requestPermission(),Ve.emit(A.EventName.AGENT_INIT_STATUS,!0),this.#n=!0}catch(e){this.#i&&vs("初始化失败"),Ve.emit(A.EventName.AGENT_INIT_STATUS,!1),this.#n=!1}}#a=A=>{const{type:e,data:t}=A;Ve.emit(e,t)};on(A,e){return Ve.on(A,e),this}off(A,e){Ve.off(A,e)}offAll(){Ve.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){js._instance&&(await this.destroyRtc(),clearInterval(this.#s),Js.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,js._instance=null,le.reset(),le.updateSelectOutNumber(""))}async#o(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A)),checkAgentLogin:A=>this.#e.checkAgentLogin(A)}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:n}=ce.agentInfo,{stateObject:o}=ce,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:n,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:o}}}A.default=js,Object.defineProperty(A,"__esModule",{value:!0})});
914
+ `;is(s,this.rttHTML)}}class Ks{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Os=console.log,Ns=(...A)=>{ce.logBuiltinEnabled&&Os(...A)};let bs=null;class Js{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new ks,this.initWebSocket()}static getInstance(A){if(!bs){if(!A)throw new Error("WebSocket 尚未初始化");bs=new Js(A)}return bs}stateIdleChange(){const{state:e}=ce.stateObject;e!==A.AgentStatus.IDLE&&this.apiClient._changeState({data:{...ce.stateBeforeChange}})}async getCustomerInfo(e){try{await this.apiClient._getInCallCrmDetail({data:{phone:e},success:e=>{const{contact_count:t,customer_name:s,phone:i,city:r,province:n}=e.data;Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,{customer_name:s||"未知客户",phone:i,city:r||"未知",province:n||"未知",contact_count:t||0})}})}catch(A){}}putAgentState(){ce.sessionId="";const{post_call_process_time:e}=ce.agentInfo,t=e||0;ce.autoStateTimer&&(clearTimeout(ce.autoStateTimer),ce.autoStateTimer=null),Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0),t>0?ce.autoStateTimer=setTimeout(()=>{ce.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){const e=be(Le,We);this.ws=new WebSocket(this.url+e),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=e=>{const t=JSON.parse(e.data),{type:s,data:i,code:r,msg:n}=t;if(0!==s&&Ns("%cWebSocket 收到消息:","color: blue; font-weight: bold;",t),s===A.WebsocketTypeEnum.OUT_CALL&&(0!==r?(le.reset(),Ve.emit(A.CallSipCallEvent.OUT_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n),setTimeout(()=>{Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===r&&Ve.emit(A.CallSipCallEvent.OUT_SUCCESS)),s===A.WebsocketTypeEnum.AGENT_STATE){ce.stateObject.state!==A.AgentStatus.IDLE&&ce.stateObject.state!==A.AgentStatus.BUSY||(ce.stateBeforeChange=ce.stateObject);const{state:e,state_name:t}=i;ce.stateObject={state:e,state_name:t},"振铃中"===t&&le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),Ve.emit(A.CallSipCallEvent.AGENT_STATE,{state:e,state_name:t})}if(s===A.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(Ve.emit(A.CallSipCallEvent.OUT_INCOMING_CALL),ce.sessionId=i.session_id,le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.OUT_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.OUT_HANGUP,i),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(ls)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(Vs)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(Vs))),s===A.WebsocketTypeEnum.OUT_CALL_RINGING&&1===i.type&&(Ve.emit(A.CallSipCallEvent.OUT_RINGING,i),le.updateDisplayText(A.DisplayTextEnum.RINGING)),s===A.WebsocketTypeEnum.OUT_CALL_ANSWER&&(Ve.emit(A.CallSipCallEvent.OUT_OFF_ANSWER,i),le.updateOutCallIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.CONSULT_RINGING&&(Ve.emit(A.CallSipCallEvent.CONSULT_RINGING),le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),le.updateActionConfigs([])),s===A.WebsocketTypeEnum.CONSULT_ANSWER&&(Ve.emit(A.CallSipCallEvent.CONSULT_OFF_HOOK,i),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CONSULTING),le.updateActionConfigs(gs)),s===A.WebsocketTypeEnum.CONSULT_FAIL&&(Ve.emit(A.CallSipCallEvent.CONSULT_FAILED,{custom_reason:i.custom_reason}),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.CONSULT_CALL_IN&&(Ve.emit(A.CallSipCallEvent.CONSULT_INCOMING,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.CONSULT),le.updateDisplayText(A.DisplayTextEnum.CONSULT_CALL_IN),le.updateActionConfigs(us),ce.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===A.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(qs)),s===A.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(le.updateConsultIsAnswer(!1),Ve.emit(A.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.MUTE&&(0===r?(le.updateIsMuted(!0),Ve.emit(A.CallSipCallEvent.MUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.MUTING)):(Ve.emit(A.CallSipCallEvent.MUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.UNMUTE&&(0===r?(le.updateIsMuted(!1),Ve.emit(A.CallSipCallEvent.UNMUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING)):(Ve.emit(A.CallSipCallEvent.UNMUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_HOLD&&(0===r?(le.updateIsHold(!0),le.updateDisplayText(A.DisplayTextEnum.HOLDING),Ve.emit(A.CallSipCallEvent.HOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.HOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_UNHOLD&&(0===r?(le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateIsHold(!1),Ve.emit(A.CallSipCallEvent.UNHOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.UNHOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===r?Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,i.status),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),le.updateActionConfigs(ps),le.updateIncomingIsAnswer(!0),le.updateConsultIsAnswer(!1)),s===A.WebsocketTypeEnum.INCOMING_CALL&&(ce.sessionId=i.session_id,le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.INCOMING_CALL),Ve.emit(A.CallSipCallEvent.INCOMING_CALL,{customer_phone:i.customer_phone}),le.updateActionConfigs(us),this.getCustomerInfo(i.customer_phone),ce.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===A.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(le.updateIncomingIsAnswer(!0),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),le.updateActionConfigs(ps),le.updateDisplayText(A.DisplayTextEnum.CALLING)),s===A.WebsocketTypeEnum.INCOMING_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_END),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(Vs)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(ls)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(Vs)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(Vs))),s===A.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===r?Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==r?(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n)):0===r&&le.updateIsMeeting(!0)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===i.status?(le.updateDirection(A.DirectionEnum.MEETING),le.updateDisplayText(A.DisplayTextEnum.MEETING),le.updateActionConfigs(ds),Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:i.conf_name}),le.updateIsMeeting(!1))),s===A.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(i.agent_no===ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.TRANSFERRING),Ve.emit(A.CallSipCallEvent.TRANSFER_PROGRESS),le.updateActionConfigs([]),le.updateTransferIsAnswer(!0)):(Ve.emit(A.CallSipCallEvent.TRANSFER_INCOMING_CALL,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.TRANSFER),le.updateDisplayText(A.DisplayTextEnum.TRANSFER_INCOMING_CALL),le.updateActionConfigs(us),ce.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${i.agent_no}] 正在转接...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_no})}))),s===A.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.TRANSFER_OFF_HOOK),le.updateTransferIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(ps)),s===A.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===i.status){Ve.emit(A.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const e=le.get("direction");e===A.DirectionEnum.OUTGOING?le.updateActionConfigs(ls):e===A.DirectionEnum.INCOMING&&le.updateActionConfigs(ps)}s===A.WebsocketTypeEnum.KICK_OFFLINE&&Ve.emit(A.EventName.KICK_OFF)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Ns("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){bs&&(bs.close(),bs=null)}static __internalSend(A){if(!bs)throw new Error("WebSocket 尚未初始化");bs.sendMessage(A)}}class Hs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=le.get("isCalling"),e=ce.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const e=le.get("isHold"),{sessionId:t}=ce;if(!t)return;if(!le.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Js.__internalSend({type:A.WebsocketTypeEnum.CALL_HOLD,data:{session_id:t}})}unholdCall(){this.roleMute();const{isHold:e}=le.getState(),{sessionId:t}=ce;if(!le.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(t){if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Js.__internalSend({type:A.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:t}})}}sendDTMF(A){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!le.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=le.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!le.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=ce.sessionId;Js.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}async consultCall(e){this.roleMute();const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=le.getState(),n=ce.sessionId;if(!le.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(i)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(t||s||r))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!n)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async answerCall(){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(e){const t=le.get("isCalling"),s=le.get("selectOutNumber")||"";if(t)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.OUTGOING),Js.__internalSend({type:A.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:e,caller:s}})}async hangup(){if(!le.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=ce.sessionId;Js.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}mute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!e.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:A.WebsocketTypeEnum.MUTE,data:{session_id:s}})}unmute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(!t)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!e.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Js.__internalSend({type:A.WebsocketTypeEnum.UNMUTE,data:{session_id:s}})}consultTransfer(){this.roleMute();const e=le.get("consultIsAnswer"),t=ce.sessionId;if(!le.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:t}})}satisfactionEvaluation(){this.roleMute();const e=ce.sessionId;if(!le.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Js.__internalSend({type:A.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:e}})}startConference(){this.roleMute();if(!le.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:e}})}consultRetrieve(){this.roleMute();if(!le.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Js.__internalSend({type:A.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:e}})}async transferAgent(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:0,transfer_dest:e}})}async transferOutline(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(e))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Js.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:2,transfer_dest:e}})}}class js{static{this._instance=null}#A=null;#e=new ks;#t;#s=null;#i=!1;#r;#n=!1;constructor(){if(!js._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();_e.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),this.#r=le.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null}),this.on(A.EventName.KICK_OFF,()=>{this.destroy()})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(A){if(!this._instance){if(!A)throw new Error("首次调用必须传入配置参数");const{url:e,appKey:t,appSecret:s,agentNo:i}=A;je=e||"https://aicc.yescloudy.com",Le=t,We=s,Pe=i,js._creatingInstance=!0,this._instance=new js,delete js._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})}return this._instance}getInit(){return this.#n}async initWebRtc(){if(this.#A)return;const A=ce.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new $e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:e,enableBrowserAlert:t,logBuiltinEnabled:s}){try{const{viewHtmlElement:i,rttHTML:r}=e||{};ce.logBuiltinEnabled=s||!1,await this.#e._agentLogin(Pe);const{agent_no:n,current_answer_device:o,current_state:a,out_display_number:V,out_display_select_switch:c}=ce.agentInfo;a===A.AgentStatus.IDLE?(le.updateActionConfigs(Vs),ce.stateObject={state:a,state_name:"空闲"}):a===A.AgentStatus.BUSY&&(le.updateActionConfigs(cs),ce.stateObject={state:a,state_name:"忙碌"}),1===c?le.updateSelectOutNumber(V):le.updateSelectOutNumber("");let h="";const l=new URL(je).host;h=je.includes("https")?`wss://${l}`:`ws://${l}`,Js.getInstance(`${h}/ccs-ws/api/v1/ws/call/${n}?Authorization=`),le.updateAnswerDevice(o),1===o&&await this.initWebRtc(),this.#t=new Hs(this.#A),e&&i&&(this.#i=!0,new xs({container:i,rttHTML:r,statusParams:{state:A.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),ce.enableBrowserAlert=t,t&&Ks.requestPermission(),Ve.emit(A.EventName.AGENT_INIT_STATUS,!0),this.#n=!0}catch(e){this.#i&&vs("初始化失败"),Ve.emit(A.EventName.AGENT_INIT_STATUS,!1),this.#n=!1}}#a=A=>{const{type:e,data:t}=A;Ve.emit(e,t)};on(A,e){return Ve.on(A,e),this}off(A,e){Ve.off(A,e)}offAll(){Ve.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){js._instance&&(await this.destroyRtc(),clearInterval(this.#s),Js.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,js._instance=null,le.reset(),le.updateSelectOutNumber(""))}async#o(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A)),checkAgentLogin:A=>this.#e.checkAgentLogin(A)}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:n}=ce.agentInfo,{stateObject:o}=ce,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:n,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:o}}}A.default=js,Object.defineProperty(A,"__esModule",{value:!0})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ysyt-agent-sdk",
3
- "version": "1.0.84",
3
+ "version": "1.0.86",
4
4
  "main": "dist/ysyt-agent-sdk.cjs.js",
5
5
  "module": "dist/ysyt-agent-sdk.esm.js",
6
6
  "types": "dist/src/index.d.ts",