ysyt-agent-sdk 1.0.58 → 1.0.60
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.
|
@@ -14,7 +14,7 @@ const Re=globalThis,Ue=Re.trustedTypes,ke=Ue?Ue.createPolicy("lit-html",{createH
|
|
|
14
14
|
* @license
|
|
15
15
|
* Copyright 2017 Google LLC
|
|
16
16
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
17
|
-
*/},qt=globalThis;class dt extends De{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const A=super.createRenderRoot();return this.renderOptions.renderBefore??=A.firstChild,A}update(A){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(A),this._$Do=gt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return Xe}}dt._$litElement$=!0,dt.finalized=!0,qt.litElementHydrateSupport?.({LitElement:dt});const pt=qt.litElementPolyfillSupport;pt?.({LitElement:dt}),(qt.litElementVersions??=[]).push("4.2.1");const ut={statusColor:{[exports.AgentStatus.IDLE]:"#1D92E9",[exports.AgentStatus.BUSY]:"#F5212D",[exports.AgentStatus.OFFLINE]:"#8c8c8c",[exports.AgentStatus.RINGING]:"#e9b91d"}},mt=["call_number"],Ct=[],Et=["hangup"],It=["hold","hangup","unhold","mute","unmute","transfer","consult","satisfaction","dtmf"],Mt=["consult_transfer","conference","consult_retrieve"],wt=["hangup"],ft=["hangup"],Bt=["answer","reject"],Qt=["hangup","consult","transfer","hold","unhold","mute","unmute","satisfaction","dtmf"],St={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null},yt={isCalling:!1,direction:null,outCallIsAnswer:!1,incomingIsAnswer:!1,transferIsAnswer:!1,isMeeting:!1,isHold:!1,displayText:"",isMuted:!1,consultIsAnswer:!1,actionConfigs:[],answerDevice:1};const Tt=new class extends $A{updateIsCalling(A){this.setState({isCalling:A})}updateDirection(A){this.setState({direction:A})}updateOutCallIsAnswer(A){this.setState({outCallIsAnswer:A})}updateIsHold(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"hold"!==A)];A.push("unhold"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unhold"!==A)];A.push("hold"),this.updateActionConfigs(A)}this.getState().isHold=A}updateDisplayText(A){this.setState({displayText:A}),console.log("displayText:",A),ae.emit(exports.CallSipCallEvent.CALL_PROGRESS,A)}updateActionConfigs(A){const{show_satisfaction:e}=St.agentInfo||{},t=this.get("answerDevice");this.setState({actionConfigs:A.filter(A=>(0!==e||"satisfaction"!==A)&&(2!==t&&3!==t||"hangup"!==A&&"dtmf"!==A))}),ae.emit(exports.EventName.PHONE_BAR_OPERATION,A)}updateConsultIsAnswer(A){this.setState({consultIsAnswer:A})}updateIsMuted(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"mute"!==A)];A.push("unmute"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unmute"!==A)];A.push("mute"),this.updateActionConfigs(A)}this.setState({isMuted:A})}updateIncomingIsAnswer(A){this.setState({incomingIsAnswer:A})}updateAnswerDevice(A){this.setState({answerDevice:A}),St.stateObject.state===exports.AgentStatus.IDLE?this.updateActionConfigs(mt):St.stateObject.state===exports.AgentStatus.BUSY&&this.updateActionConfigs(Ct),ae.emit(exports.EventName.UPDATE_ANSWER_DEVICE,A)}updateIsMeeting(A){this.setState({isMeeting:A})}updateTransferIsAnswer(A){this.setState({transferIsAnswer:A})}reset(){this.setState({...yt},!0)}getCallInfo(){return this.getState()}get(A){return this.getState()[A]}}(yt);class Dt extends Error{response;request;options;constructor(A,e,t){const s=`${A.status||0===A.status?A.status:""} ${A.statusText||""}`.trim();super(`Request failed with ${s?`status code ${s}`:"an unknown error"}: ${e.method} ${e.url}`),this.name="HTTPError",this.response=A,this.request=e,this.options=t}}class Rt extends Error{request;constructor(A){super(`Request timed out: ${A.method} ${A.url}`),this.name="TimeoutError",this.request=A}}const Ut=(()=>{let A=!1,e=!1;const t="function"==typeof globalThis.ReadableStream,s="function"==typeof globalThis.Request;if(t&&s)try{e=new globalThis.Request("https://empty.invalid",{body:new globalThis.ReadableStream,method:"POST",get duplex(){return A=!0,"half"}}).headers.has("Content-Type")}catch(A){if(A instanceof Error&&"unsupported BodyInit type"===A.message)return!1;throw A}return A&&!e})(),kt="function"==typeof globalThis.AbortController,Gt="function"==typeof globalThis.AbortSignal&&"function"==typeof globalThis.AbortSignal.any,Yt="function"==typeof globalThis.ReadableStream,Ft="function"==typeof globalThis.FormData,xt=["get","post","put","patch","head","delete"],Zt={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},vt=2147483647,Kt=(new TextEncoder).encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length,Ot=Symbol("stop"),Nt={json:!0,parseJson:!0,stringifyJson:!0,searchParams:!0,prefixUrl:!0,retry:!0,timeout:!0,hooks:!0,throwHttpErrors:!0,onDownloadProgress:!0,onUploadProgress:!0,fetch:!0},bt={method:!0,headers:!0,body:!0,mode:!0,credentials:!0,cache:!0,redirect:!0,referrer:!0,referrerPolicy:!0,integrity:!0,keepalive:!0,signal:!0,window:!0,dispatcher:!0,duplex:!0,priority:!0},Jt=(A,e)=>{const t=(A=>{if(!A)return 0;if(A instanceof FormData){let e=0;for(const[t,s]of A)e+=Kt,e+=(new TextEncoder).encode(`Content-Disposition: form-data; name="${t}"`).length,e+="string"==typeof s?(new TextEncoder).encode(s).length:s.size;return e}if(A instanceof Blob)return A.size;if(A instanceof ArrayBuffer)return A.byteLength;if("string"==typeof A)return(new TextEncoder).encode(A).length;if(A instanceof URLSearchParams)return(new TextEncoder).encode(A.toString()).length;if("byteLength"in A)return A.byteLength;if("object"==typeof A&&null!==A)try{const e=JSON.stringify(A);return(new TextEncoder).encode(e).length}catch{return 0}return 0})(A.body);let s=0;return new Request(A,{duplex:"half",body:new ReadableStream({async start(i){const r=A.body instanceof ReadableStream?A.body.getReader():new Response("").body.getReader();await async function A(){const{done:o,value:n}=await r.read();if(o)return e&&e({percent:1,transferredBytes:s,totalBytes:Math.max(t,s)},new Uint8Array),void i.close();s+=n.byteLength;let a=0===t?0:s/t;(t<s||1===a)&&(a=.99),e&&e({percent:Number(a.toFixed(2)),transferredBytes:s,totalBytes:t},n),i.enqueue(n),await A()}()}})})},Ht=A=>null!==A&&"object"==typeof A,jt=(...A)=>{for(const e of A)if((!Ht(e)||Array.isArray(e))&&void 0!==e)throw new TypeError("The `options` argument must be an object");return zt({},...A)},Lt=(A={},e={})=>{const t=new globalThis.Headers(A),s=e instanceof globalThis.Headers,i=new globalThis.Headers(e);for(const[A,e]of i.entries())s&&"undefined"===e||void 0===e?t.delete(A):t.set(A,e);return t};function Wt(A,e,t){return Object.hasOwn(e,t)&&void 0===e[t]?[]:zt(A[t]??[],e[t]??[])}const Pt=(A={},e={})=>({beforeRequest:Wt(A,e,"beforeRequest"),beforeRetry:Wt(A,e,"beforeRetry"),afterResponse:Wt(A,e,"afterResponse"),beforeError:Wt(A,e,"beforeError")}),zt=(...A)=>{let e={},t={},s={};for(const i of A)if(Array.isArray(i))Array.isArray(e)||(e=[]),e=[...e,...i];else if(Ht(i)){for(let[A,t]of Object.entries(i))Ht(t)&&A in e&&(t=zt(e[A],t)),e={...e,[A]:t};Ht(i.hooks)&&(s=Pt(s,i.hooks),e.hooks=s),Ht(i.headers)&&(t=Lt(t,i.headers),e.headers=t)}return e},Xt=A=>xt.includes(A)?A.toUpperCase():A,_t={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:Number.POSITIVE_INFINITY,backoffLimit:Number.POSITIVE_INFINITY,delay:A=>.3*2**(A-1)*1e3},$t=(A={})=>{if("number"==typeof A)return{..._t,limit:A};if(A.methods&&!Array.isArray(A.methods))throw new Error("retry.methods must be an array");if(A.statusCodes&&!Array.isArray(A.statusCodes))throw new Error("retry.statusCodes must be an array");return{..._t,...A}};class As{static create(A,e){const t=new As(A,e),s=async()=>{if("number"==typeof t._options.timeout&&t._options.timeout>vt)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await Promise.resolve();let A=await t._fetch();for(const e of t._options.hooks.afterResponse){const s=await e(t.request,t._options,t._decorateResponse(A.clone()));s instanceof globalThis.Response&&(A=s)}if(t._decorateResponse(A),!A.ok&&t._options.throwHttpErrors){let e=new Dt(A,t.request,t._options);for(const A of t._options.hooks.beforeError)e=await A(e);throw e}if(t._options.onDownloadProgress){if("function"!=typeof t._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!Yt)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return((A,e)=>{const t=Number(A.headers.get("content-length"))||0;let s=0;return 204===A.status?(e&&e({percent:1,totalBytes:t,transferredBytes:s},new Uint8Array),new Response(null,{status:A.status,statusText:A.statusText,headers:A.headers})):new Response(new ReadableStream({async start(i){const r=A.body.getReader();e&&e({percent:0,transferredBytes:0,totalBytes:t},new Uint8Array),await async function A(){const{done:o,value:n}=await r.read();o?i.close():(e&&(s+=n.byteLength,e({percent:0===t?0:s/t,transferredBytes:s,totalBytes:t},n)),i.enqueue(n),await A())}()}}),{status:A.status,statusText:A.statusText,headers:A.headers})})(A.clone(),t._options.onDownloadProgress)}return A},i=(t._options.retry.methods.includes(t.request.method.toLowerCase())?t._retry(s):s()).finally(async()=>{t.request.bodyUsed||await(t.request.body?.cancel())});for(const[A,s]of Object.entries(Zt))i[A]=async()=>{t.request.headers.set("accept",t.request.headers.get("accept")||s);const r=await i;if("json"===A){if(204===r.status)return"";if(0===(await r.clone().arrayBuffer()).byteLength)return"";if(e.parseJson)return e.parseJson(await r.text())}return r[A]()};return i}request;abortController;_retryCount=0;_input;_options;constructor(A,e={}){if(this._input=A,this._options={...e,headers:Lt(this._input.headers,e.headers),hooks:Pt({beforeRequest:[],beforeRetry:[],beforeError:[],afterResponse:[]},e.hooks),method:Xt(e.method??this._input.method??"GET"),prefixUrl:String(e.prefixUrl||""),retry:$t(e.retry),throwHttpErrors:!1!==e.throwHttpErrors,timeout:e.timeout??1e4,fetch:e.fetch??globalThis.fetch.bind(globalThis)},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof globalThis.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(kt&&Gt){const A=this._options.signal??this._input.signal;this.abortController=new globalThis.AbortController,this._options.signal=A?AbortSignal.any([A,this.abortController.signal]):this.abortController.signal}if(Ut&&(this._options.duplex="half"),void 0!==this._options.json&&(this._options.body=this._options.stringifyJson?.(this._options.json)??JSON.stringify(this._options.json),this._options.headers.set("content-type",this._options.headers.get("content-type")??"application/json")),this.request=new globalThis.Request(this._input,this._options),this._options.searchParams){const A="?"+("string"==typeof this._options.searchParams?this._options.searchParams.replace(/^\?/,""):new URLSearchParams(this._options.searchParams).toString()),e=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,A);!(Ft&&this._options.body instanceof globalThis.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new globalThis.Request(new globalThis.Request(e,{...this.request}),this._options)}if(this._options.onUploadProgress){if("function"!=typeof this._options.onUploadProgress)throw new TypeError("The `onUploadProgress` option must be a function");if(!Ut)throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");this.request.body&&(this.request=Jt(this.request,this._options.onUploadProgress))}}_calculateRetryDelay(A){if(this._retryCount++,this._retryCount>this._options.retry.limit||A instanceof Rt)throw A;if(A instanceof Dt){if(!this._options.retry.statusCodes.includes(A.response.status))throw A;const e=A.response.headers.get("Retry-After")??A.response.headers.get("RateLimit-Reset")??A.response.headers.get("X-RateLimit-Reset")??A.response.headers.get("X-Rate-Limit-Reset");if(e&&this._options.retry.afterStatusCodes.includes(A.response.status)){let A=1e3*Number(e);Number.isNaN(A)?A=Date.parse(e)-Date.now():A>=Date.parse("2024-01-01")&&(A-=Date.now());const t=this._options.retry.maxRetryAfter??A;return A<t?A:t}if(413===A.response.status)throw A}const e=this._options.retry.delay(this._retryCount);return Math.min(this._options.retry.backoffLimit,e)}_decorateResponse(A){return this._options.parseJson&&(A.json=async()=>this._options.parseJson(await A.text())),A}async _retry(A){try{return await A()}catch(e){const t=Math.min(this._calculateRetryDelay(e),vt);if(this._retryCount<1)throw e;await async function(A,{signal:e}){return new Promise((t,s)=>{function i(){clearTimeout(r),s(e.reason)}e&&(e.throwIfAborted(),e.addEventListener("abort",i,{once:!0}));const r=setTimeout(()=>{e?.removeEventListener("abort",i),t()},A)})}(t,{signal:this._options.signal});for(const A of this._options.hooks.beforeRetry){if(await A({request:this.request,options:this._options,error:e,retryCount:this._retryCount})===Ot)return}return this._retry(A)}}async _fetch(){for(const A of this._options.hooks.beforeRequest){const e=await A(this.request,this._options);if(e instanceof Request){this.request=e;break}if(e instanceof Response)return e}const A=((A,e)=>{const t={};for(const s in e)s in bt||s in Nt||s in A||(t[s]=e[s]);return t})(this.request,this._options),e=this.request;return this.request=e.clone(),!1===this._options.timeout?this._options.fetch(e,A):async function(A,e,t,s){return new Promise((i,r)=>{const o=setTimeout(()=>{t&&t.abort(),r(new Rt(A))},s.timeout);s.fetch(A,e).then(i).catch(r).then(()=>{clearTimeout(o)})})}(e,A,this.abortController,this._options)}}
|
|
17
|
+
*/},qt=globalThis;class dt extends De{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const A=super.createRenderRoot();return this.renderOptions.renderBefore??=A.firstChild,A}update(A){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(A),this._$Do=gt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return Xe}}dt._$litElement$=!0,dt.finalized=!0,qt.litElementHydrateSupport?.({LitElement:dt});const pt=qt.litElementPolyfillSupport;pt?.({LitElement:dt}),(qt.litElementVersions??=[]).push("4.2.1");const ut={statusColor:{[exports.AgentStatus.IDLE]:"#1D92E9",[exports.AgentStatus.BUSY]:"#F5212D",[exports.AgentStatus.OFFLINE]:"#8c8c8c",[exports.AgentStatus.RINGING]:"#e9b91d"}},mt=["call_number"],Ct=[],Et=["hangup"],It=["hold","hangup","mute","transfer","consult","satisfaction","dtmf"],Mt=["consult_transfer","conference","consult_retrieve"],wt=["hangup"],ft=["hangup"],Bt=["answer","reject"],Qt=["hangup","consult","transfer","hold","mute","satisfaction","dtmf"],St={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null},yt={isCalling:!1,direction:null,outCallIsAnswer:!1,incomingIsAnswer:!1,transferIsAnswer:!1,isMeeting:!1,isHold:!1,displayText:"",isMuted:!1,consultIsAnswer:!1,actionConfigs:[],answerDevice:1};const Tt=new class extends $A{updateIsCalling(A){this.setState({isCalling:A})}updateDirection(A){this.setState({direction:A})}updateOutCallIsAnswer(A){this.setState({outCallIsAnswer:A})}updateIsHold(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"hold"!==A)];A.push("unhold"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unhold"!==A)];A.push("hold"),this.updateActionConfigs(A)}this.getState().isHold=A}updateDisplayText(A){this.setState({displayText:A}),console.log("displayText:",A),ae.emit(exports.CallSipCallEvent.CALL_PROGRESS,A)}updateActionConfigs(A){const{show_satisfaction:e}=St.agentInfo||{},t=this.get("answerDevice"),s=A.filter(A=>(0!==e||"satisfaction"!==A)&&(2!==t&&3!==t||"hangup"!==A&&"dtmf"!==A));console.log(s),this.setState({actionConfigs:s}),console.log(s),ae.emit(exports.EventName.PHONE_BAR_OPERATION,s)}updateConsultIsAnswer(A){this.setState({consultIsAnswer:A})}updateIsMuted(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"mute"!==A)];A.push("unmute"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unmute"!==A)];A.push("mute"),this.updateActionConfigs(A)}this.setState({isMuted:A})}updateIncomingIsAnswer(A){this.setState({incomingIsAnswer:A})}updateAnswerDevice(A){this.setState({answerDevice:A}),St.stateObject.state===exports.AgentStatus.IDLE?this.updateActionConfigs(mt):St.stateObject.state===exports.AgentStatus.BUSY&&this.updateActionConfigs(Ct),ae.emit(exports.EventName.UPDATE_ANSWER_DEVICE,A)}updateIsMeeting(A){this.setState({isMeeting:A})}updateTransferIsAnswer(A){this.setState({transferIsAnswer:A})}reset(){this.setState({...yt},!0)}getCallInfo(){return this.getState()}get(A){return this.getState()[A]}}(yt);class Dt extends Error{response;request;options;constructor(A,e,t){const s=`${A.status||0===A.status?A.status:""} ${A.statusText||""}`.trim();super(`Request failed with ${s?`status code ${s}`:"an unknown error"}: ${e.method} ${e.url}`),this.name="HTTPError",this.response=A,this.request=e,this.options=t}}class Rt extends Error{request;constructor(A){super(`Request timed out: ${A.method} ${A.url}`),this.name="TimeoutError",this.request=A}}const Ut=(()=>{let A=!1,e=!1;const t="function"==typeof globalThis.ReadableStream,s="function"==typeof globalThis.Request;if(t&&s)try{e=new globalThis.Request("https://empty.invalid",{body:new globalThis.ReadableStream,method:"POST",get duplex(){return A=!0,"half"}}).headers.has("Content-Type")}catch(A){if(A instanceof Error&&"unsupported BodyInit type"===A.message)return!1;throw A}return A&&!e})(),kt="function"==typeof globalThis.AbortController,Gt="function"==typeof globalThis.AbortSignal&&"function"==typeof globalThis.AbortSignal.any,Yt="function"==typeof globalThis.ReadableStream,Ft="function"==typeof globalThis.FormData,xt=["get","post","put","patch","head","delete"],Zt={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},vt=2147483647,Kt=(new TextEncoder).encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length,Ot=Symbol("stop"),Nt={json:!0,parseJson:!0,stringifyJson:!0,searchParams:!0,prefixUrl:!0,retry:!0,timeout:!0,hooks:!0,throwHttpErrors:!0,onDownloadProgress:!0,onUploadProgress:!0,fetch:!0},bt={method:!0,headers:!0,body:!0,mode:!0,credentials:!0,cache:!0,redirect:!0,referrer:!0,referrerPolicy:!0,integrity:!0,keepalive:!0,signal:!0,window:!0,dispatcher:!0,duplex:!0,priority:!0},Jt=(A,e)=>{const t=(A=>{if(!A)return 0;if(A instanceof FormData){let e=0;for(const[t,s]of A)e+=Kt,e+=(new TextEncoder).encode(`Content-Disposition: form-data; name="${t}"`).length,e+="string"==typeof s?(new TextEncoder).encode(s).length:s.size;return e}if(A instanceof Blob)return A.size;if(A instanceof ArrayBuffer)return A.byteLength;if("string"==typeof A)return(new TextEncoder).encode(A).length;if(A instanceof URLSearchParams)return(new TextEncoder).encode(A.toString()).length;if("byteLength"in A)return A.byteLength;if("object"==typeof A&&null!==A)try{const e=JSON.stringify(A);return(new TextEncoder).encode(e).length}catch{return 0}return 0})(A.body);let s=0;return new Request(A,{duplex:"half",body:new ReadableStream({async start(i){const r=A.body instanceof ReadableStream?A.body.getReader():new Response("").body.getReader();await async function A(){const{done:o,value:n}=await r.read();if(o)return e&&e({percent:1,transferredBytes:s,totalBytes:Math.max(t,s)},new Uint8Array),void i.close();s+=n.byteLength;let a=0===t?0:s/t;(t<s||1===a)&&(a=.99),e&&e({percent:Number(a.toFixed(2)),transferredBytes:s,totalBytes:t},n),i.enqueue(n),await A()}()}})})},Ht=A=>null!==A&&"object"==typeof A,jt=(...A)=>{for(const e of A)if((!Ht(e)||Array.isArray(e))&&void 0!==e)throw new TypeError("The `options` argument must be an object");return zt({},...A)},Lt=(A={},e={})=>{const t=new globalThis.Headers(A),s=e instanceof globalThis.Headers,i=new globalThis.Headers(e);for(const[A,e]of i.entries())s&&"undefined"===e||void 0===e?t.delete(A):t.set(A,e);return t};function Wt(A,e,t){return Object.hasOwn(e,t)&&void 0===e[t]?[]:zt(A[t]??[],e[t]??[])}const Pt=(A={},e={})=>({beforeRequest:Wt(A,e,"beforeRequest"),beforeRetry:Wt(A,e,"beforeRetry"),afterResponse:Wt(A,e,"afterResponse"),beforeError:Wt(A,e,"beforeError")}),zt=(...A)=>{let e={},t={},s={};for(const i of A)if(Array.isArray(i))Array.isArray(e)||(e=[]),e=[...e,...i];else if(Ht(i)){for(let[A,t]of Object.entries(i))Ht(t)&&A in e&&(t=zt(e[A],t)),e={...e,[A]:t};Ht(i.hooks)&&(s=Pt(s,i.hooks),e.hooks=s),Ht(i.headers)&&(t=Lt(t,i.headers),e.headers=t)}return e},Xt=A=>xt.includes(A)?A.toUpperCase():A,_t={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:Number.POSITIVE_INFINITY,backoffLimit:Number.POSITIVE_INFINITY,delay:A=>.3*2**(A-1)*1e3},$t=(A={})=>{if("number"==typeof A)return{..._t,limit:A};if(A.methods&&!Array.isArray(A.methods))throw new Error("retry.methods must be an array");if(A.statusCodes&&!Array.isArray(A.statusCodes))throw new Error("retry.statusCodes must be an array");return{..._t,...A}};class As{static create(A,e){const t=new As(A,e),s=async()=>{if("number"==typeof t._options.timeout&&t._options.timeout>vt)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await Promise.resolve();let A=await t._fetch();for(const e of t._options.hooks.afterResponse){const s=await e(t.request,t._options,t._decorateResponse(A.clone()));s instanceof globalThis.Response&&(A=s)}if(t._decorateResponse(A),!A.ok&&t._options.throwHttpErrors){let e=new Dt(A,t.request,t._options);for(const A of t._options.hooks.beforeError)e=await A(e);throw e}if(t._options.onDownloadProgress){if("function"!=typeof t._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!Yt)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return((A,e)=>{const t=Number(A.headers.get("content-length"))||0;let s=0;return 204===A.status?(e&&e({percent:1,totalBytes:t,transferredBytes:s},new Uint8Array),new Response(null,{status:A.status,statusText:A.statusText,headers:A.headers})):new Response(new ReadableStream({async start(i){const r=A.body.getReader();e&&e({percent:0,transferredBytes:0,totalBytes:t},new Uint8Array),await async function A(){const{done:o,value:n}=await r.read();o?i.close():(e&&(s+=n.byteLength,e({percent:0===t?0:s/t,transferredBytes:s,totalBytes:t},n)),i.enqueue(n),await A())}()}}),{status:A.status,statusText:A.statusText,headers:A.headers})})(A.clone(),t._options.onDownloadProgress)}return A},i=(t._options.retry.methods.includes(t.request.method.toLowerCase())?t._retry(s):s()).finally(async()=>{t.request.bodyUsed||await(t.request.body?.cancel())});for(const[A,s]of Object.entries(Zt))i[A]=async()=>{t.request.headers.set("accept",t.request.headers.get("accept")||s);const r=await i;if("json"===A){if(204===r.status)return"";if(0===(await r.clone().arrayBuffer()).byteLength)return"";if(e.parseJson)return e.parseJson(await r.text())}return r[A]()};return i}request;abortController;_retryCount=0;_input;_options;constructor(A,e={}){if(this._input=A,this._options={...e,headers:Lt(this._input.headers,e.headers),hooks:Pt({beforeRequest:[],beforeRetry:[],beforeError:[],afterResponse:[]},e.hooks),method:Xt(e.method??this._input.method??"GET"),prefixUrl:String(e.prefixUrl||""),retry:$t(e.retry),throwHttpErrors:!1!==e.throwHttpErrors,timeout:e.timeout??1e4,fetch:e.fetch??globalThis.fetch.bind(globalThis)},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof globalThis.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(kt&&Gt){const A=this._options.signal??this._input.signal;this.abortController=new globalThis.AbortController,this._options.signal=A?AbortSignal.any([A,this.abortController.signal]):this.abortController.signal}if(Ut&&(this._options.duplex="half"),void 0!==this._options.json&&(this._options.body=this._options.stringifyJson?.(this._options.json)??JSON.stringify(this._options.json),this._options.headers.set("content-type",this._options.headers.get("content-type")??"application/json")),this.request=new globalThis.Request(this._input,this._options),this._options.searchParams){const A="?"+("string"==typeof this._options.searchParams?this._options.searchParams.replace(/^\?/,""):new URLSearchParams(this._options.searchParams).toString()),e=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,A);!(Ft&&this._options.body instanceof globalThis.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new globalThis.Request(new globalThis.Request(e,{...this.request}),this._options)}if(this._options.onUploadProgress){if("function"!=typeof this._options.onUploadProgress)throw new TypeError("The `onUploadProgress` option must be a function");if(!Ut)throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");this.request.body&&(this.request=Jt(this.request,this._options.onUploadProgress))}}_calculateRetryDelay(A){if(this._retryCount++,this._retryCount>this._options.retry.limit||A instanceof Rt)throw A;if(A instanceof Dt){if(!this._options.retry.statusCodes.includes(A.response.status))throw A;const e=A.response.headers.get("Retry-After")??A.response.headers.get("RateLimit-Reset")??A.response.headers.get("X-RateLimit-Reset")??A.response.headers.get("X-Rate-Limit-Reset");if(e&&this._options.retry.afterStatusCodes.includes(A.response.status)){let A=1e3*Number(e);Number.isNaN(A)?A=Date.parse(e)-Date.now():A>=Date.parse("2024-01-01")&&(A-=Date.now());const t=this._options.retry.maxRetryAfter??A;return A<t?A:t}if(413===A.response.status)throw A}const e=this._options.retry.delay(this._retryCount);return Math.min(this._options.retry.backoffLimit,e)}_decorateResponse(A){return this._options.parseJson&&(A.json=async()=>this._options.parseJson(await A.text())),A}async _retry(A){try{return await A()}catch(e){const t=Math.min(this._calculateRetryDelay(e),vt);if(this._retryCount<1)throw e;await async function(A,{signal:e}){return new Promise((t,s)=>{function i(){clearTimeout(r),s(e.reason)}e&&(e.throwIfAborted(),e.addEventListener("abort",i,{once:!0}));const r=setTimeout(()=>{e?.removeEventListener("abort",i),t()},A)})}(t,{signal:this._options.signal});for(const A of this._options.hooks.beforeRetry){if(await A({request:this.request,options:this._options,error:e,retryCount:this._retryCount})===Ot)return}return this._retry(A)}}async _fetch(){for(const A of this._options.hooks.beforeRequest){const e=await A(this.request,this._options);if(e instanceof Request){this.request=e;break}if(e instanceof Response)return e}const A=((A,e)=>{const t={};for(const s in e)s in bt||s in Nt||s in A||(t[s]=e[s]);return t})(this.request,this._options),e=this.request;return this.request=e.clone(),!1===this._options.timeout?this._options.fetch(e,A):async function(A,e,t,s){return new Promise((i,r)=>{const o=setTimeout(()=>{t&&t.abort(),r(new Rt(A))},s.timeout);s.fetch(A,e).then(i).catch(r).then(()=>{clearTimeout(o)})})}(e,A,this.abortController,this._options)}}
|
|
18
18
|
/*! MIT License © Sindre Sorhus */const es=A=>{const e=(e,t)=>As.create(e,jt(A,t));for(const t of xt)e[t]=(e,s)=>As.create(e,jt(A,s,{method:t}));return e.create=A=>es(jt(A)),e.extend=e=>("function"==typeof e&&(e=e(A??{})),es(jt(A,e))),e.stop=Ot,e};var ts,ss=es(),is="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},rs={exports:{}};
|
|
19
19
|
/**
|
|
20
20
|
* [js-md5]{@link https://github.com/emn178/js-md5}
|
|
@@ -757,7 +757,7 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
|
|
|
757
757
|
`}
|
|
758
758
|
</div>
|
|
759
759
|
</my-modal-wrapper>
|
|
760
|
-
`;gt(s,this.modalRoot)}})}catch(A){Fs(A)}}getActionConfigs(){const
|
|
760
|
+
`;gt(s,this.modalRoot)}})}catch(A){Fs(A)}}getActionConfigs(){const A=Tt.get("actionConfigs");return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"},{render:this.renderConsultRetrieve,type:"consult_retrieve"},{render:this.renderConference,type:"conference"}].filter(({type:e})=>A.includes(e))}async render(){const{displayText:A}=Tt.getState(),{answer_devices:e}=St.agentInfo,t=(e||"").split(","),s=this.getActionConfigs(),i={...ut},{statusColor:r}=i,o=document.querySelector("head");if(o){const A=ze`
|
|
761
761
|
<style>
|
|
762
762
|
.ysyt-phone-body {
|
|
763
763
|
background: ${r[this.statusParams.state]};
|
|
@@ -873,4 +873,4 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
|
|
|
873
873
|
`:""}
|
|
874
874
|
</div>
|
|
875
875
|
</my-popover>
|
|
876
|
-
`;gt(s,this.rttHTML)}}const vs=new class{constructor(){this.events={}}on(A,e){this.events[A]=this.events[A]||[],this.events[A].push(e)}off(A,e){this.events[A]=(this.events[A]||[]).filter(A=>A!==e)}emit(A,...e){(this.events[A]||[]).forEach(A=>A(...e))}};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 console.log("已授权麦克风权限"),null;const e=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),e}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}}}let Os=null;class Ns{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Os){if(!A)throw new Error("WebSocket 尚未初始化");Os=new Ns(A)}return Os}stateIdleChange(){const{state:A}=St.stateObject;A!==exports.AgentStatus.IDLE&&this.apiClient._changeState({data:{state:exports.AgentStatus.IDLE,state_name:"空闲"}})}putAgentState(){St.sessionId="";const{post_call_process_time:A}=St.agentInfo,e=A||0;St.autoStateTimer&&(clearTimeout(St.autoStateTimer),St.autoStateTimer=null),e>0?St.autoStateTimer=setTimeout(()=>{St.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(t),t===exports.WebsocketTypeEnum.OUT_CALL&&(0!==i?(Tt.reset(),ae.emit(exports.CallSipCallEvent.OUT_FAILED,r),this.stateIdleChange()):0===i&&ae.emit(exports.CallSipCallEvent.OUT_SUCCESS)),t===exports.WebsocketTypeEnum.AGENT_STATE){const{state:A,state_name:e}=s;St.stateObject={state:A,state_name:e},"振铃中"===e&&Tt.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),St.sessionId=s.session_id,Tt.updateActionConfigs(Et)),t===exports.WebsocketTypeEnum.OUT_CALL_END&&(1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.OUT_HANGUP,s),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),Tt.updateActionConfigs(mt))),t===exports.WebsocketTypeEnum.OUT_CALL_RINGING&&1===s.type&&(ae.emit(exports.CallSipCallEvent.OUT_RINGING,s),Tt.updateDisplayText(exports.DisplayTextEnum.RINGING)),t===exports.WebsocketTypeEnum.OUT_CALL_ANSWER&&(ae.emit(exports.CallSipCallEvent.OUT_OFF_ANSWER,s),Tt.updateOutCallIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(It)),t===exports.WebsocketTypeEnum.CONSULT_RINGING&&(ae.emit(exports.CallSipCallEvent.CONSULT_RINGING),Tt.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),Tt.updateActionConfigs([])),t===exports.WebsocketTypeEnum.CONSULT_ANSWER&&(ae.emit(exports.CallSipCallEvent.CONSULT_OFF_HOOK,s),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CONSULTING),Tt.updateActionConfigs(Mt)),t===exports.WebsocketTypeEnum.CONSULT_FAIL&&(ae.emit(exports.CallSipCallEvent.CONSULT_FAILED,{custom_reason:s.custom_reason}),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(It)),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN&&(ae.emit(exports.CallSipCallEvent.CONSULT_INCOMING,s),Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.CONSULT),Tt.updateDisplayText(exports.DisplayTextEnum.CONSULT_CALL_IN),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(St.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(wt)),t===exports.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(ae.emit(exports.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)),t===exports.WebsocketTypeEnum.MUTE&&(0===i?(Tt.updateIsMuted(!0),ae.emit(exports.CallSipCallEvent.MUTE_SUCCESS),Tt.updateDisplayText(exports.DisplayTextEnum.MUTING)):ae.emit(exports.CallSipCallEvent.MUTE_FAILED,r)),t===exports.WebsocketTypeEnum.UNMUTE&&(0===i?(Tt.updateIsMuted(!1),ae.emit(exports.CallSipCallEvent.UNMUTE_SUCCESS),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING)):ae.emit(exports.CallSipCallEvent.UNMUTE_FAILED,r)),t===exports.WebsocketTypeEnum.CALL_HOLD&&(0===i?(Tt.updateIsHold(!0),Tt.updateDisplayText(exports.DisplayTextEnum.HOLDING),ae.emit(exports.CallSipCallEvent.HOLD_SUCCESS)):ae.emit(exports.CallSipCallEvent.HOLD_FAILED,r)),t===exports.WebsocketTypeEnum.CALL_UNHOLD&&(0===i?(Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateIsHold(!1),ae.emit(exports.CallSipCallEvent.UNHOLD_SUCCESS)):ae.emit(exports.CallSipCallEvent.UNHOLD_FAILED,r)),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===i?ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,r)),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,s.status),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(Tt.updateDirection(exports.DirectionEnum.INCOMING),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateIncomingIsAnswer(!0),Tt.updateConsultIsAnswer(!1)),t===exports.WebsocketTypeEnum.INCOMING_CALL&&(St.sessionId=s.session_id,Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.INCOMING),Tt.updateDisplayText(exports.DisplayTextEnum.INCOMING_CALL),ae.emit(exports.CallSipCallEvent.INCOMING_CALL,{customer_phone:s.customer_phone}),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===exports.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(Tt.updateIncomingIsAnswer(!0),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING)),t===exports.WebsocketTypeEnum.INCOMING_CALL_END&&(1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_END),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),Tt.updateActionConfigs(mt))),t===exports.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===i?ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,r)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==i?ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,r):0===i&&Tt.updateIsMeeting(!0)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(Tt.updateDirection(exports.DirectionEnum.MEETING),Tt.updateDisplayText(exports.DisplayTextEnum.MEETING),Tt.updateActionConfigs(ft),ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),Tt.updateIsMeeting(!1))),t===exports.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(s.agent_no===St.agentInfo.agent_no?(Tt.updateDisplayText(exports.DisplayTextEnum.TRANSFERRING),ae.emit(exports.CallSipCallEvent.TRANSFER_PROGRESS),Tt.updateActionConfigs([]),Tt.updateTransferIsAnswer(!0)):(ae.emit(exports.CallSipCallEvent.TRANSFER_INCOMING_CALL,s),Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.TRANSFER),Tt.updateDisplayText(exports.DisplayTextEnum.TRANSFER_INCOMING_CALL),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===exports.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(St.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.TRANSFER_OFF_HOOK),Tt.updateTransferIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(Qt)),t===exports.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===s.status){ae.emit(exports.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const A=Tt.get("direction");A===exports.DirectionEnum.OUTGOING?Tt.updateActionConfigs(It):A===exports.DirectionEnum.INCOMING&&Tt.updateActionConfigs(Qt)}0!==t&&vs.emit("ws-message",e)},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?this.ws.send(JSON.stringify(A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Os&&(Os.close(),Os=null)}static __internalSend(A){if(!Os)throw new Error("WebSocket 尚未初始化");Os.sendMessage(A)}}class bs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=Tt.get("isCalling"),e=St.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=Tt.get("isHold"),{sessionId:e}=St;if(!e)return;if(!Tt.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=Tt.getState(),{sessionId:e}=St;if(!Tt.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=Tt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("reject"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用拒接"}));const{isCalling:A,direction:e,outCallIsAnswer:t}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));t||(e===exports.DirectionEnum.INCOMING?this.rejectInCall():e===exports.DirectionEnum.OUTGOING&&this.rejectOutCall())}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=Tt.getState(),r=St.sessionId;if(!Tt.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不存在"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(A){if(Tt.getState().isCalling)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.OUTGOING),Ns.__internalSend({type:exports.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:A}})}async rejectOutCall(){const{isCalling:A}=Tt.getState();if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectOutCall()}async hangup(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.hangup()}mute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=Tt.get("consultIsAnswer"),e=St.sessionId;if(!Tt.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=St.sessionId;if(!Tt.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!Tt.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!Tt.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!Tt.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!Tt.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}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}exports.default=class{#A=null;#e=new Us;#t;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();ds.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=Tt.subscribeKey("answerDevice",A=>{1===A&&this.initWebRtc()})}async initWebRtc(){const A=St.agentInfo.sip_account_list.find(A=>1===A.device_type);if(A){const e=A.sip_register_addr;this.#A=new ps({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#n),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r}){try{const{viewHtmlElement:o,rttHTML:n}=A||{},a=e||"https://aicc.yescloudy.com";cs=a,hs=t,ls=s;const V=ns(t,s);await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,init_state:l}=St.agentInfo;l===exports.AgentStatus.IDLE?(Tt.updateActionConfigs(mt),St.stateObject={state:l,state_name:"空闲"}):l===exports.AgentStatus.BUSY&&(Tt.updateActionConfigs(Ct),St.stateObject={state:l,state_name:"忙碌"});let g="";const q=new URL(a).host;g=a.includes("https")?`wss://${q}`:`ws://${q}`,Ns.getInstance(`${g}/ccs-ws/api/v1/ws/call/${c}?Authorization=${V}`),Tt.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new bs(this.#A),A&&o&&(this.#i=!0,new Zs({container:o,rttHTML:n,statusParams:{state:exports.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),St.enableBrowserAlert=r,r&&Ks.requestPermission()}catch(A){this.#i&&Fs("初始化失败"),console.log(A)}}#n=A=>{const{type:e,data:t}=A;ae.emit(e,t)};#a=A=>{};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())}destroy(){this.destroyRtc(),clearInterval(this.#s),vs.off("ws-message",this.#a),Ns.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#e=null,this.#i=!1}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(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))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,init_state:s,default_device:i}=St.agentInfo,{stateObject:r}=St,o={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:s,default_device:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:o[Number(A)]})),stateObject:r}}};
|
|
876
|
+
`;gt(s,this.rttHTML)}}const vs=new class{constructor(){this.events={}}on(A,e){this.events[A]=this.events[A]||[],this.events[A].push(e)}off(A,e){this.events[A]=(this.events[A]||[]).filter(A=>A!==e)}emit(A,...e){(this.events[A]||[]).forEach(A=>A(...e))}};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 console.log("已授权麦克风权限"),null;const e=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),e}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}}}let Os=null;class Ns{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Os){if(!A)throw new Error("WebSocket 尚未初始化");Os=new Ns(A)}return Os}stateIdleChange(){const{state:A}=St.stateObject;A!==exports.AgentStatus.IDLE&&this.apiClient._changeState({data:{state:exports.AgentStatus.IDLE,state_name:"空闲"}})}putAgentState(){St.sessionId="";const{post_call_process_time:A}=St.agentInfo,e=A||0;St.autoStateTimer&&(clearTimeout(St.autoStateTimer),St.autoStateTimer=null),e>0?St.autoStateTimer=setTimeout(()=>{St.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(t),t===exports.WebsocketTypeEnum.OUT_CALL&&(0!==i?(Tt.reset(),ae.emit(exports.CallSipCallEvent.OUT_FAILED,r),this.stateIdleChange()):0===i&&ae.emit(exports.CallSipCallEvent.OUT_SUCCESS)),t===exports.WebsocketTypeEnum.AGENT_STATE){const{state:A,state_name:e}=s;St.stateObject={state:A,state_name:e},"振铃中"===e&&Tt.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),St.sessionId=s.session_id,Tt.updateActionConfigs(Et)),t===exports.WebsocketTypeEnum.OUT_CALL_END&&(Tt.updateDisplayText(""),1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.OUT_HANGUP,s),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),Tt.updateActionConfigs(mt))),t===exports.WebsocketTypeEnum.OUT_CALL_RINGING&&1===s.type&&(ae.emit(exports.CallSipCallEvent.OUT_RINGING,s),Tt.updateDisplayText(exports.DisplayTextEnum.RINGING)),t===exports.WebsocketTypeEnum.OUT_CALL_ANSWER&&(ae.emit(exports.CallSipCallEvent.OUT_OFF_ANSWER,s),Tt.updateOutCallIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(It)),t===exports.WebsocketTypeEnum.CONSULT_RINGING&&(ae.emit(exports.CallSipCallEvent.CONSULT_RINGING),Tt.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),Tt.updateActionConfigs([])),t===exports.WebsocketTypeEnum.CONSULT_ANSWER&&(ae.emit(exports.CallSipCallEvent.CONSULT_OFF_HOOK,s),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CONSULTING),Tt.updateActionConfigs(Mt)),t===exports.WebsocketTypeEnum.CONSULT_FAIL&&(ae.emit(exports.CallSipCallEvent.CONSULT_FAILED,{custom_reason:s.custom_reason}),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(It)),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN&&(ae.emit(exports.CallSipCallEvent.CONSULT_INCOMING,s),Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.CONSULT),Tt.updateDisplayText(exports.DisplayTextEnum.CONSULT_CALL_IN),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(St.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(wt)),t===exports.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(ae.emit(exports.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)),t===exports.WebsocketTypeEnum.MUTE&&(0===i?(Tt.updateIsMuted(!0),ae.emit(exports.CallSipCallEvent.MUTE_SUCCESS),Tt.updateDisplayText(exports.DisplayTextEnum.MUTING)):ae.emit(exports.CallSipCallEvent.MUTE_FAILED,r)),t===exports.WebsocketTypeEnum.UNMUTE&&(0===i?(Tt.updateIsMuted(!1),ae.emit(exports.CallSipCallEvent.UNMUTE_SUCCESS),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING)):ae.emit(exports.CallSipCallEvent.UNMUTE_FAILED,r)),t===exports.WebsocketTypeEnum.CALL_HOLD&&(0===i?(Tt.updateIsHold(!0),Tt.updateDisplayText(exports.DisplayTextEnum.HOLDING),ae.emit(exports.CallSipCallEvent.HOLD_SUCCESS)):ae.emit(exports.CallSipCallEvent.HOLD_FAILED,r)),t===exports.WebsocketTypeEnum.CALL_UNHOLD&&(0===i?(Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateIsHold(!1),ae.emit(exports.CallSipCallEvent.UNHOLD_SUCCESS)):ae.emit(exports.CallSipCallEvent.UNHOLD_FAILED,r)),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===i?ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,r)),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,s.status),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(Tt.updateDirection(exports.DirectionEnum.INCOMING),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateIncomingIsAnswer(!0),Tt.updateConsultIsAnswer(!1)),t===exports.WebsocketTypeEnum.INCOMING_CALL&&(St.sessionId=s.session_id,Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.INCOMING),Tt.updateDisplayText(exports.DisplayTextEnum.INCOMING_CALL),ae.emit(exports.CallSipCallEvent.INCOMING_CALL,{customer_phone:s.customer_phone}),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===exports.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(Tt.updateIncomingIsAnswer(!0),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING)),t===exports.WebsocketTypeEnum.INCOMING_CALL_END&&(Tt.updateDisplayText(""),1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_END),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),Tt.updateActionConfigs(mt))),t===exports.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===i?ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,r)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==i?ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,r):0===i&&Tt.updateIsMeeting(!0)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(Tt.updateDirection(exports.DirectionEnum.MEETING),Tt.updateDisplayText(exports.DisplayTextEnum.MEETING),Tt.updateActionConfigs(ft),ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),Tt.updateIsMeeting(!1))),t===exports.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(s.agent_no===St.agentInfo.agent_no?(Tt.updateDisplayText(exports.DisplayTextEnum.TRANSFERRING),ae.emit(exports.CallSipCallEvent.TRANSFER_PROGRESS),Tt.updateActionConfigs([]),Tt.updateTransferIsAnswer(!0)):(ae.emit(exports.CallSipCallEvent.TRANSFER_INCOMING_CALL,s),Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.TRANSFER),Tt.updateDisplayText(exports.DisplayTextEnum.TRANSFER_INCOMING_CALL),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===exports.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(St.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.TRANSFER_OFF_HOOK),Tt.updateTransferIsAnswer(!0),Tt.updateDisplayText(exports.DisplayTextEnum.CALLING),Tt.updateActionConfigs(Qt)),t===exports.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===s.status){ae.emit(exports.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const A=Tt.get("direction");A===exports.DirectionEnum.OUTGOING?Tt.updateActionConfigs(It):A===exports.DirectionEnum.INCOMING&&Tt.updateActionConfigs(Qt)}0!==t&&vs.emit("ws-message",e)},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?this.ws.send(JSON.stringify(A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Os&&(Os.close(),Os=null)}static __internalSend(A){if(!Os)throw new Error("WebSocket 尚未初始化");Os.sendMessage(A)}}class bs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=Tt.get("isCalling"),e=St.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=Tt.get("isHold"),{sessionId:e}=St;if(!e)return;if(!Tt.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=Tt.getState(),{sessionId:e}=St;if(!Tt.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=Tt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("reject"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用拒接"}));const{isCalling:A,direction:e,outCallIsAnswer:t}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));t||(e===exports.DirectionEnum.INCOMING?this.rejectInCall():e===exports.DirectionEnum.OUTGOING&&this.rejectOutCall())}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=Tt.getState(),r=St.sessionId;if(!Tt.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不存在"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(A){if(Tt.getState().isCalling)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));Tt.updateIsCalling(!0),Tt.updateDirection(exports.DirectionEnum.OUTGOING),Ns.__internalSend({type:exports.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:A}})}async rejectOutCall(){const{isCalling:A}=Tt.getState();if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectOutCall()}async hangup(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.hangup()}mute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=Tt.get("consultIsAnswer"),e=St.sessionId;if(!Tt.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=St.sessionId;if(!Tt.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!Tt.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!Tt.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!Tt.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!Tt.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}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}exports.default=class{#A=null;#e=new Us;#t;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();ds.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=Tt.subscribeKey("answerDevice",A=>{1===A&&this.initWebRtc()})}async initWebRtc(){const A=St.agentInfo.sip_account_list.find(A=>1===A.device_type);if(A){const e=A.sip_register_addr;this.#A=new ps({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#n),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r}){try{const{viewHtmlElement:o,rttHTML:n}=A||{},a=e||"https://aicc.yescloudy.com";cs=a,hs=t,ls=s;const V=ns(t,s);await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,init_state:l}=St.agentInfo;l===exports.AgentStatus.IDLE?(Tt.updateActionConfigs(mt),St.stateObject={state:l,state_name:"空闲"}):l===exports.AgentStatus.BUSY&&(Tt.updateActionConfigs(Ct),St.stateObject={state:l,state_name:"忙碌"});let g="";const q=new URL(a).host;g=a.includes("https")?`wss://${q}`:`ws://${q}`,Ns.getInstance(`${g}/ccs-ws/api/v1/ws/call/${c}?Authorization=${V}`),Tt.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new bs(this.#A),A&&o&&(this.#i=!0,new Zs({container:o,rttHTML:n,statusParams:{state:exports.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),St.enableBrowserAlert=r,r&&Ks.requestPermission()}catch(A){this.#i&&Fs("初始化失败"),console.log(A)}}#n=A=>{const{type:e,data:t}=A;ae.emit(e,t)};#a=A=>{};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())}destroy(){this.destroyRtc(),clearInterval(this.#s),vs.off("ws-message",this.#a),Ns.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#e=null,this.#i=!1}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(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))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,init_state:s,default_device:i}=St.agentInfo,{stateObject:r}=St,o={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:s,default_device:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:o[Number(A)]})),stateObject:r}}};
|
|
@@ -14,7 +14,7 @@ const Re=globalThis,Ue=Re.trustedTypes,ke=Ue?Ue.createPolicy("lit-html",{createH
|
|
|
14
14
|
* @license
|
|
15
15
|
* Copyright 2017 Google LLC
|
|
16
16
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
17
|
-
*/},qt=globalThis;class dt extends De{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const A=super.createRenderRoot();return this.renderOptions.renderBefore??=A.firstChild,A}update(A){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(A),this._$Do=gt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return Xe}}dt._$litElement$=!0,dt.finalized=!0,qt.litElementHydrateSupport?.({LitElement:dt});const ut=qt.litElementPolyfillSupport;ut?.({LitElement:dt}),(qt.litElementVersions??=[]).push("4.2.1");const pt={statusColor:{[Ae.IDLE]:"#1D92E9",[Ae.BUSY]:"#F5212D",[Ae.OFFLINE]:"#8c8c8c",[Ae.RINGING]:"#e9b91d"}},mt=["call_number"],Ct=[],Et=["hangup"],It=["hold","hangup","unhold","mute","unmute","transfer","consult","satisfaction","dtmf"],Mt=["consult_transfer","conference","consult_retrieve"],wt=["hangup"],ft=["hangup"],Bt=["answer","reject"],Qt=["hangup","consult","transfer","hold","unhold","mute","unmute","satisfaction","dtmf"],St={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null},yt={isCalling:!1,direction:null,outCallIsAnswer:!1,incomingIsAnswer:!1,transferIsAnswer:!1,isMeeting:!1,isHold:!1,displayText:"",isMuted:!1,consultIsAnswer:!1,actionConfigs:[],answerDevice:1};const Tt=new class extends $A{updateIsCalling(A){this.setState({isCalling:A})}updateDirection(A){this.setState({direction:A})}updateOutCallIsAnswer(A){this.setState({outCallIsAnswer:A})}updateIsHold(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"hold"!==A)];A.push("unhold"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unhold"!==A)];A.push("hold"),this.updateActionConfigs(A)}this.getState().isHold=A}updateDisplayText(A){this.setState({displayText:A}),console.log("displayText:",A),ae.emit(se.CALL_PROGRESS,A)}updateActionConfigs(A){const{show_satisfaction:e}=St.agentInfo||{},t=this.get("answerDevice");this.setState({actionConfigs:A.filter(A=>(0!==e||"satisfaction"!==A)&&(2!==t&&3!==t||"hangup"!==A&&"dtmf"!==A))}),ae.emit(re.PHONE_BAR_OPERATION,A)}updateConsultIsAnswer(A){this.setState({consultIsAnswer:A})}updateIsMuted(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"mute"!==A)];A.push("unmute"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unmute"!==A)];A.push("mute"),this.updateActionConfigs(A)}this.setState({isMuted:A})}updateIncomingIsAnswer(A){this.setState({incomingIsAnswer:A})}updateAnswerDevice(A){this.setState({answerDevice:A}),St.stateObject.state===Ae.IDLE?this.updateActionConfigs(mt):St.stateObject.state===Ae.BUSY&&this.updateActionConfigs(Ct),ae.emit(re.UPDATE_ANSWER_DEVICE,A)}updateIsMeeting(A){this.setState({isMeeting:A})}updateTransferIsAnswer(A){this.setState({transferIsAnswer:A})}reset(){this.setState({...yt},!0)}getCallInfo(){return this.getState()}get(A){return this.getState()[A]}}(yt);class Dt extends Error{response;request;options;constructor(A,e,t){const s=`${A.status||0===A.status?A.status:""} ${A.statusText||""}`.trim();super(`Request failed with ${s?`status code ${s}`:"an unknown error"}: ${e.method} ${e.url}`),this.name="HTTPError",this.response=A,this.request=e,this.options=t}}class Rt extends Error{request;constructor(A){super(`Request timed out: ${A.method} ${A.url}`),this.name="TimeoutError",this.request=A}}const Ut=(()=>{let A=!1,e=!1;const t="function"==typeof globalThis.ReadableStream,s="function"==typeof globalThis.Request;if(t&&s)try{e=new globalThis.Request("https://empty.invalid",{body:new globalThis.ReadableStream,method:"POST",get duplex(){return A=!0,"half"}}).headers.has("Content-Type")}catch(A){if(A instanceof Error&&"unsupported BodyInit type"===A.message)return!1;throw A}return A&&!e})(),kt="function"==typeof globalThis.AbortController,Gt="function"==typeof globalThis.AbortSignal&&"function"==typeof globalThis.AbortSignal.any,Yt="function"==typeof globalThis.ReadableStream,Ft="function"==typeof globalThis.FormData,Zt=["get","post","put","patch","head","delete"],vt={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},xt=2147483647,Kt=(new TextEncoder).encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length,Ot=Symbol("stop"),Nt={json:!0,parseJson:!0,stringifyJson:!0,searchParams:!0,prefixUrl:!0,retry:!0,timeout:!0,hooks:!0,throwHttpErrors:!0,onDownloadProgress:!0,onUploadProgress:!0,fetch:!0},Jt={method:!0,headers:!0,body:!0,mode:!0,credentials:!0,cache:!0,redirect:!0,referrer:!0,referrerPolicy:!0,integrity:!0,keepalive:!0,signal:!0,window:!0,dispatcher:!0,duplex:!0,priority:!0},bt=(A,e)=>{const t=(A=>{if(!A)return 0;if(A instanceof FormData){let e=0;for(const[t,s]of A)e+=Kt,e+=(new TextEncoder).encode(`Content-Disposition: form-data; name="${t}"`).length,e+="string"==typeof s?(new TextEncoder).encode(s).length:s.size;return e}if(A instanceof Blob)return A.size;if(A instanceof ArrayBuffer)return A.byteLength;if("string"==typeof A)return(new TextEncoder).encode(A).length;if(A instanceof URLSearchParams)return(new TextEncoder).encode(A.toString()).length;if("byteLength"in A)return A.byteLength;if("object"==typeof A&&null!==A)try{const e=JSON.stringify(A);return(new TextEncoder).encode(e).length}catch{return 0}return 0})(A.body);let s=0;return new Request(A,{duplex:"half",body:new ReadableStream({async start(i){const r=A.body instanceof ReadableStream?A.body.getReader():new Response("").body.getReader();await async function A(){const{done:o,value:n}=await r.read();if(o)return e&&e({percent:1,transferredBytes:s,totalBytes:Math.max(t,s)},new Uint8Array),void i.close();s+=n.byteLength;let a=0===t?0:s/t;(t<s||1===a)&&(a=.99),e&&e({percent:Number(a.toFixed(2)),transferredBytes:s,totalBytes:t},n),i.enqueue(n),await A()}()}})})},Ht=A=>null!==A&&"object"==typeof A,jt=(...A)=>{for(const e of A)if((!Ht(e)||Array.isArray(e))&&void 0!==e)throw new TypeError("The `options` argument must be an object");return zt({},...A)},Lt=(A={},e={})=>{const t=new globalThis.Headers(A),s=e instanceof globalThis.Headers,i=new globalThis.Headers(e);for(const[A,e]of i.entries())s&&"undefined"===e||void 0===e?t.delete(A):t.set(A,e);return t};function Wt(A,e,t){return Object.hasOwn(e,t)&&void 0===e[t]?[]:zt(A[t]??[],e[t]??[])}const Pt=(A={},e={})=>({beforeRequest:Wt(A,e,"beforeRequest"),beforeRetry:Wt(A,e,"beforeRetry"),afterResponse:Wt(A,e,"afterResponse"),beforeError:Wt(A,e,"beforeError")}),zt=(...A)=>{let e={},t={},s={};for(const i of A)if(Array.isArray(i))Array.isArray(e)||(e=[]),e=[...e,...i];else if(Ht(i)){for(let[A,t]of Object.entries(i))Ht(t)&&A in e&&(t=zt(e[A],t)),e={...e,[A]:t};Ht(i.hooks)&&(s=Pt(s,i.hooks),e.hooks=s),Ht(i.headers)&&(t=Lt(t,i.headers),e.headers=t)}return e},Xt=A=>Zt.includes(A)?A.toUpperCase():A,_t={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:Number.POSITIVE_INFINITY,backoffLimit:Number.POSITIVE_INFINITY,delay:A=>.3*2**(A-1)*1e3},$t=(A={})=>{if("number"==typeof A)return{..._t,limit:A};if(A.methods&&!Array.isArray(A.methods))throw new Error("retry.methods must be an array");if(A.statusCodes&&!Array.isArray(A.statusCodes))throw new Error("retry.statusCodes must be an array");return{..._t,...A}};class As{static create(A,e){const t=new As(A,e),s=async()=>{if("number"==typeof t._options.timeout&&t._options.timeout>xt)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await Promise.resolve();let A=await t._fetch();for(const e of t._options.hooks.afterResponse){const s=await e(t.request,t._options,t._decorateResponse(A.clone()));s instanceof globalThis.Response&&(A=s)}if(t._decorateResponse(A),!A.ok&&t._options.throwHttpErrors){let e=new Dt(A,t.request,t._options);for(const A of t._options.hooks.beforeError)e=await A(e);throw e}if(t._options.onDownloadProgress){if("function"!=typeof t._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!Yt)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return((A,e)=>{const t=Number(A.headers.get("content-length"))||0;let s=0;return 204===A.status?(e&&e({percent:1,totalBytes:t,transferredBytes:s},new Uint8Array),new Response(null,{status:A.status,statusText:A.statusText,headers:A.headers})):new Response(new ReadableStream({async start(i){const r=A.body.getReader();e&&e({percent:0,transferredBytes:0,totalBytes:t},new Uint8Array),await async function A(){const{done:o,value:n}=await r.read();o?i.close():(e&&(s+=n.byteLength,e({percent:0===t?0:s/t,transferredBytes:s,totalBytes:t},n)),i.enqueue(n),await A())}()}}),{status:A.status,statusText:A.statusText,headers:A.headers})})(A.clone(),t._options.onDownloadProgress)}return A},i=(t._options.retry.methods.includes(t.request.method.toLowerCase())?t._retry(s):s()).finally(async()=>{t.request.bodyUsed||await(t.request.body?.cancel())});for(const[A,s]of Object.entries(vt))i[A]=async()=>{t.request.headers.set("accept",t.request.headers.get("accept")||s);const r=await i;if("json"===A){if(204===r.status)return"";if(0===(await r.clone().arrayBuffer()).byteLength)return"";if(e.parseJson)return e.parseJson(await r.text())}return r[A]()};return i}request;abortController;_retryCount=0;_input;_options;constructor(A,e={}){if(this._input=A,this._options={...e,headers:Lt(this._input.headers,e.headers),hooks:Pt({beforeRequest:[],beforeRetry:[],beforeError:[],afterResponse:[]},e.hooks),method:Xt(e.method??this._input.method??"GET"),prefixUrl:String(e.prefixUrl||""),retry:$t(e.retry),throwHttpErrors:!1!==e.throwHttpErrors,timeout:e.timeout??1e4,fetch:e.fetch??globalThis.fetch.bind(globalThis)},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof globalThis.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(kt&&Gt){const A=this._options.signal??this._input.signal;this.abortController=new globalThis.AbortController,this._options.signal=A?AbortSignal.any([A,this.abortController.signal]):this.abortController.signal}if(Ut&&(this._options.duplex="half"),void 0!==this._options.json&&(this._options.body=this._options.stringifyJson?.(this._options.json)??JSON.stringify(this._options.json),this._options.headers.set("content-type",this._options.headers.get("content-type")??"application/json")),this.request=new globalThis.Request(this._input,this._options),this._options.searchParams){const A="?"+("string"==typeof this._options.searchParams?this._options.searchParams.replace(/^\?/,""):new URLSearchParams(this._options.searchParams).toString()),e=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,A);!(Ft&&this._options.body instanceof globalThis.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new globalThis.Request(new globalThis.Request(e,{...this.request}),this._options)}if(this._options.onUploadProgress){if("function"!=typeof this._options.onUploadProgress)throw new TypeError("The `onUploadProgress` option must be a function");if(!Ut)throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");this.request.body&&(this.request=bt(this.request,this._options.onUploadProgress))}}_calculateRetryDelay(A){if(this._retryCount++,this._retryCount>this._options.retry.limit||A instanceof Rt)throw A;if(A instanceof Dt){if(!this._options.retry.statusCodes.includes(A.response.status))throw A;const e=A.response.headers.get("Retry-After")??A.response.headers.get("RateLimit-Reset")??A.response.headers.get("X-RateLimit-Reset")??A.response.headers.get("X-Rate-Limit-Reset");if(e&&this._options.retry.afterStatusCodes.includes(A.response.status)){let A=1e3*Number(e);Number.isNaN(A)?A=Date.parse(e)-Date.now():A>=Date.parse("2024-01-01")&&(A-=Date.now());const t=this._options.retry.maxRetryAfter??A;return A<t?A:t}if(413===A.response.status)throw A}const e=this._options.retry.delay(this._retryCount);return Math.min(this._options.retry.backoffLimit,e)}_decorateResponse(A){return this._options.parseJson&&(A.json=async()=>this._options.parseJson(await A.text())),A}async _retry(A){try{return await A()}catch(e){const t=Math.min(this._calculateRetryDelay(e),xt);if(this._retryCount<1)throw e;await async function(A,{signal:e}){return new Promise((t,s)=>{function i(){clearTimeout(r),s(e.reason)}e&&(e.throwIfAborted(),e.addEventListener("abort",i,{once:!0}));const r=setTimeout(()=>{e?.removeEventListener("abort",i),t()},A)})}(t,{signal:this._options.signal});for(const A of this._options.hooks.beforeRetry){if(await A({request:this.request,options:this._options,error:e,retryCount:this._retryCount})===Ot)return}return this._retry(A)}}async _fetch(){for(const A of this._options.hooks.beforeRequest){const e=await A(this.request,this._options);if(e instanceof Request){this.request=e;break}if(e instanceof Response)return e}const A=((A,e)=>{const t={};for(const s in e)s in Jt||s in Nt||s in A||(t[s]=e[s]);return t})(this.request,this._options),e=this.request;return this.request=e.clone(),!1===this._options.timeout?this._options.fetch(e,A):async function(A,e,t,s){return new Promise((i,r)=>{const o=setTimeout(()=>{t&&t.abort(),r(new Rt(A))},s.timeout);s.fetch(A,e).then(i).catch(r).then(()=>{clearTimeout(o)})})}(e,A,this.abortController,this._options)}}
|
|
17
|
+
*/},qt=globalThis;class dt extends De{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const A=super.createRenderRoot();return this.renderOptions.renderBefore??=A.firstChild,A}update(A){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(A),this._$Do=gt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return Xe}}dt._$litElement$=!0,dt.finalized=!0,qt.litElementHydrateSupport?.({LitElement:dt});const ut=qt.litElementPolyfillSupport;ut?.({LitElement:dt}),(qt.litElementVersions??=[]).push("4.2.1");const pt={statusColor:{[Ae.IDLE]:"#1D92E9",[Ae.BUSY]:"#F5212D",[Ae.OFFLINE]:"#8c8c8c",[Ae.RINGING]:"#e9b91d"}},mt=["call_number"],Ct=[],Et=["hangup"],It=["hold","hangup","mute","transfer","consult","satisfaction","dtmf"],Mt=["consult_transfer","conference","consult_retrieve"],wt=["hangup"],ft=["hangup"],Bt=["answer","reject"],Qt=["hangup","consult","transfer","hold","mute","satisfaction","dtmf"],St={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null},yt={isCalling:!1,direction:null,outCallIsAnswer:!1,incomingIsAnswer:!1,transferIsAnswer:!1,isMeeting:!1,isHold:!1,displayText:"",isMuted:!1,consultIsAnswer:!1,actionConfigs:[],answerDevice:1};const Tt=new class extends $A{updateIsCalling(A){this.setState({isCalling:A})}updateDirection(A){this.setState({direction:A})}updateOutCallIsAnswer(A){this.setState({outCallIsAnswer:A})}updateIsHold(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"hold"!==A)];A.push("unhold"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unhold"!==A)];A.push("hold"),this.updateActionConfigs(A)}this.getState().isHold=A}updateDisplayText(A){this.setState({displayText:A}),console.log("displayText:",A),ae.emit(se.CALL_PROGRESS,A)}updateActionConfigs(A){const{show_satisfaction:e}=St.agentInfo||{},t=this.get("answerDevice"),s=A.filter(A=>(0!==e||"satisfaction"!==A)&&(2!==t&&3!==t||"hangup"!==A&&"dtmf"!==A));console.log(s),this.setState({actionConfigs:s}),console.log(s),ae.emit(re.PHONE_BAR_OPERATION,s)}updateConsultIsAnswer(A){this.setState({consultIsAnswer:A})}updateIsMuted(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"mute"!==A)];A.push("unmute"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unmute"!==A)];A.push("mute"),this.updateActionConfigs(A)}this.setState({isMuted:A})}updateIncomingIsAnswer(A){this.setState({incomingIsAnswer:A})}updateAnswerDevice(A){this.setState({answerDevice:A}),St.stateObject.state===Ae.IDLE?this.updateActionConfigs(mt):St.stateObject.state===Ae.BUSY&&this.updateActionConfigs(Ct),ae.emit(re.UPDATE_ANSWER_DEVICE,A)}updateIsMeeting(A){this.setState({isMeeting:A})}updateTransferIsAnswer(A){this.setState({transferIsAnswer:A})}reset(){this.setState({...yt},!0)}getCallInfo(){return this.getState()}get(A){return this.getState()[A]}}(yt);class Dt extends Error{response;request;options;constructor(A,e,t){const s=`${A.status||0===A.status?A.status:""} ${A.statusText||""}`.trim();super(`Request failed with ${s?`status code ${s}`:"an unknown error"}: ${e.method} ${e.url}`),this.name="HTTPError",this.response=A,this.request=e,this.options=t}}class Rt extends Error{request;constructor(A){super(`Request timed out: ${A.method} ${A.url}`),this.name="TimeoutError",this.request=A}}const Ut=(()=>{let A=!1,e=!1;const t="function"==typeof globalThis.ReadableStream,s="function"==typeof globalThis.Request;if(t&&s)try{e=new globalThis.Request("https://empty.invalid",{body:new globalThis.ReadableStream,method:"POST",get duplex(){return A=!0,"half"}}).headers.has("Content-Type")}catch(A){if(A instanceof Error&&"unsupported BodyInit type"===A.message)return!1;throw A}return A&&!e})(),kt="function"==typeof globalThis.AbortController,Gt="function"==typeof globalThis.AbortSignal&&"function"==typeof globalThis.AbortSignal.any,Yt="function"==typeof globalThis.ReadableStream,Ft="function"==typeof globalThis.FormData,Zt=["get","post","put","patch","head","delete"],vt={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},xt=2147483647,Kt=(new TextEncoder).encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length,Ot=Symbol("stop"),Nt={json:!0,parseJson:!0,stringifyJson:!0,searchParams:!0,prefixUrl:!0,retry:!0,timeout:!0,hooks:!0,throwHttpErrors:!0,onDownloadProgress:!0,onUploadProgress:!0,fetch:!0},Jt={method:!0,headers:!0,body:!0,mode:!0,credentials:!0,cache:!0,redirect:!0,referrer:!0,referrerPolicy:!0,integrity:!0,keepalive:!0,signal:!0,window:!0,dispatcher:!0,duplex:!0,priority:!0},bt=(A,e)=>{const t=(A=>{if(!A)return 0;if(A instanceof FormData){let e=0;for(const[t,s]of A)e+=Kt,e+=(new TextEncoder).encode(`Content-Disposition: form-data; name="${t}"`).length,e+="string"==typeof s?(new TextEncoder).encode(s).length:s.size;return e}if(A instanceof Blob)return A.size;if(A instanceof ArrayBuffer)return A.byteLength;if("string"==typeof A)return(new TextEncoder).encode(A).length;if(A instanceof URLSearchParams)return(new TextEncoder).encode(A.toString()).length;if("byteLength"in A)return A.byteLength;if("object"==typeof A&&null!==A)try{const e=JSON.stringify(A);return(new TextEncoder).encode(e).length}catch{return 0}return 0})(A.body);let s=0;return new Request(A,{duplex:"half",body:new ReadableStream({async start(i){const r=A.body instanceof ReadableStream?A.body.getReader():new Response("").body.getReader();await async function A(){const{done:o,value:n}=await r.read();if(o)return e&&e({percent:1,transferredBytes:s,totalBytes:Math.max(t,s)},new Uint8Array),void i.close();s+=n.byteLength;let a=0===t?0:s/t;(t<s||1===a)&&(a=.99),e&&e({percent:Number(a.toFixed(2)),transferredBytes:s,totalBytes:t},n),i.enqueue(n),await A()}()}})})},Ht=A=>null!==A&&"object"==typeof A,jt=(...A)=>{for(const e of A)if((!Ht(e)||Array.isArray(e))&&void 0!==e)throw new TypeError("The `options` argument must be an object");return zt({},...A)},Lt=(A={},e={})=>{const t=new globalThis.Headers(A),s=e instanceof globalThis.Headers,i=new globalThis.Headers(e);for(const[A,e]of i.entries())s&&"undefined"===e||void 0===e?t.delete(A):t.set(A,e);return t};function Wt(A,e,t){return Object.hasOwn(e,t)&&void 0===e[t]?[]:zt(A[t]??[],e[t]??[])}const Pt=(A={},e={})=>({beforeRequest:Wt(A,e,"beforeRequest"),beforeRetry:Wt(A,e,"beforeRetry"),afterResponse:Wt(A,e,"afterResponse"),beforeError:Wt(A,e,"beforeError")}),zt=(...A)=>{let e={},t={},s={};for(const i of A)if(Array.isArray(i))Array.isArray(e)||(e=[]),e=[...e,...i];else if(Ht(i)){for(let[A,t]of Object.entries(i))Ht(t)&&A in e&&(t=zt(e[A],t)),e={...e,[A]:t};Ht(i.hooks)&&(s=Pt(s,i.hooks),e.hooks=s),Ht(i.headers)&&(t=Lt(t,i.headers),e.headers=t)}return e},Xt=A=>Zt.includes(A)?A.toUpperCase():A,_t={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:Number.POSITIVE_INFINITY,backoffLimit:Number.POSITIVE_INFINITY,delay:A=>.3*2**(A-1)*1e3},$t=(A={})=>{if("number"==typeof A)return{..._t,limit:A};if(A.methods&&!Array.isArray(A.methods))throw new Error("retry.methods must be an array");if(A.statusCodes&&!Array.isArray(A.statusCodes))throw new Error("retry.statusCodes must be an array");return{..._t,...A}};class As{static create(A,e){const t=new As(A,e),s=async()=>{if("number"==typeof t._options.timeout&&t._options.timeout>xt)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await Promise.resolve();let A=await t._fetch();for(const e of t._options.hooks.afterResponse){const s=await e(t.request,t._options,t._decorateResponse(A.clone()));s instanceof globalThis.Response&&(A=s)}if(t._decorateResponse(A),!A.ok&&t._options.throwHttpErrors){let e=new Dt(A,t.request,t._options);for(const A of t._options.hooks.beforeError)e=await A(e);throw e}if(t._options.onDownloadProgress){if("function"!=typeof t._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!Yt)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return((A,e)=>{const t=Number(A.headers.get("content-length"))||0;let s=0;return 204===A.status?(e&&e({percent:1,totalBytes:t,transferredBytes:s},new Uint8Array),new Response(null,{status:A.status,statusText:A.statusText,headers:A.headers})):new Response(new ReadableStream({async start(i){const r=A.body.getReader();e&&e({percent:0,transferredBytes:0,totalBytes:t},new Uint8Array),await async function A(){const{done:o,value:n}=await r.read();o?i.close():(e&&(s+=n.byteLength,e({percent:0===t?0:s/t,transferredBytes:s,totalBytes:t},n)),i.enqueue(n),await A())}()}}),{status:A.status,statusText:A.statusText,headers:A.headers})})(A.clone(),t._options.onDownloadProgress)}return A},i=(t._options.retry.methods.includes(t.request.method.toLowerCase())?t._retry(s):s()).finally(async()=>{t.request.bodyUsed||await(t.request.body?.cancel())});for(const[A,s]of Object.entries(vt))i[A]=async()=>{t.request.headers.set("accept",t.request.headers.get("accept")||s);const r=await i;if("json"===A){if(204===r.status)return"";if(0===(await r.clone().arrayBuffer()).byteLength)return"";if(e.parseJson)return e.parseJson(await r.text())}return r[A]()};return i}request;abortController;_retryCount=0;_input;_options;constructor(A,e={}){if(this._input=A,this._options={...e,headers:Lt(this._input.headers,e.headers),hooks:Pt({beforeRequest:[],beforeRetry:[],beforeError:[],afterResponse:[]},e.hooks),method:Xt(e.method??this._input.method??"GET"),prefixUrl:String(e.prefixUrl||""),retry:$t(e.retry),throwHttpErrors:!1!==e.throwHttpErrors,timeout:e.timeout??1e4,fetch:e.fetch??globalThis.fetch.bind(globalThis)},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof globalThis.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(kt&&Gt){const A=this._options.signal??this._input.signal;this.abortController=new globalThis.AbortController,this._options.signal=A?AbortSignal.any([A,this.abortController.signal]):this.abortController.signal}if(Ut&&(this._options.duplex="half"),void 0!==this._options.json&&(this._options.body=this._options.stringifyJson?.(this._options.json)??JSON.stringify(this._options.json),this._options.headers.set("content-type",this._options.headers.get("content-type")??"application/json")),this.request=new globalThis.Request(this._input,this._options),this._options.searchParams){const A="?"+("string"==typeof this._options.searchParams?this._options.searchParams.replace(/^\?/,""):new URLSearchParams(this._options.searchParams).toString()),e=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,A);!(Ft&&this._options.body instanceof globalThis.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new globalThis.Request(new globalThis.Request(e,{...this.request}),this._options)}if(this._options.onUploadProgress){if("function"!=typeof this._options.onUploadProgress)throw new TypeError("The `onUploadProgress` option must be a function");if(!Ut)throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");this.request.body&&(this.request=bt(this.request,this._options.onUploadProgress))}}_calculateRetryDelay(A){if(this._retryCount++,this._retryCount>this._options.retry.limit||A instanceof Rt)throw A;if(A instanceof Dt){if(!this._options.retry.statusCodes.includes(A.response.status))throw A;const e=A.response.headers.get("Retry-After")??A.response.headers.get("RateLimit-Reset")??A.response.headers.get("X-RateLimit-Reset")??A.response.headers.get("X-Rate-Limit-Reset");if(e&&this._options.retry.afterStatusCodes.includes(A.response.status)){let A=1e3*Number(e);Number.isNaN(A)?A=Date.parse(e)-Date.now():A>=Date.parse("2024-01-01")&&(A-=Date.now());const t=this._options.retry.maxRetryAfter??A;return A<t?A:t}if(413===A.response.status)throw A}const e=this._options.retry.delay(this._retryCount);return Math.min(this._options.retry.backoffLimit,e)}_decorateResponse(A){return this._options.parseJson&&(A.json=async()=>this._options.parseJson(await A.text())),A}async _retry(A){try{return await A()}catch(e){const t=Math.min(this._calculateRetryDelay(e),xt);if(this._retryCount<1)throw e;await async function(A,{signal:e}){return new Promise((t,s)=>{function i(){clearTimeout(r),s(e.reason)}e&&(e.throwIfAborted(),e.addEventListener("abort",i,{once:!0}));const r=setTimeout(()=>{e?.removeEventListener("abort",i),t()},A)})}(t,{signal:this._options.signal});for(const A of this._options.hooks.beforeRetry){if(await A({request:this.request,options:this._options,error:e,retryCount:this._retryCount})===Ot)return}return this._retry(A)}}async _fetch(){for(const A of this._options.hooks.beforeRequest){const e=await A(this.request,this._options);if(e instanceof Request){this.request=e;break}if(e instanceof Response)return e}const A=((A,e)=>{const t={};for(const s in e)s in Jt||s in Nt||s in A||(t[s]=e[s]);return t})(this.request,this._options),e=this.request;return this.request=e.clone(),!1===this._options.timeout?this._options.fetch(e,A):async function(A,e,t,s){return new Promise((i,r)=>{const o=setTimeout(()=>{t&&t.abort(),r(new Rt(A))},s.timeout);s.fetch(A,e).then(i).catch(r).then(()=>{clearTimeout(o)})})}(e,A,this.abortController,this._options)}}
|
|
18
18
|
/*! MIT License © Sindre Sorhus */const es=A=>{const e=(e,t)=>As.create(e,jt(A,t));for(const t of Zt)e[t]=(e,s)=>As.create(e,jt(A,s,{method:t}));return e.create=A=>es(jt(A)),e.extend=e=>("function"==typeof e&&(e=e(A??{})),es(jt(A,e))),e.stop=Ot,e};var ts,ss=es(),is="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},rs={exports:{}};
|
|
19
19
|
/**
|
|
20
20
|
* [js-md5]{@link https://github.com/emn178/js-md5}
|
|
@@ -757,7 +757,7 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
|
|
|
757
757
|
`}
|
|
758
758
|
</div>
|
|
759
759
|
</my-modal-wrapper>
|
|
760
|
-
`;gt(s,this.modalRoot)}})}catch(A){Fs(A)}}getActionConfigs(){const
|
|
760
|
+
`;gt(s,this.modalRoot)}})}catch(A){Fs(A)}}getActionConfigs(){const A=Tt.get("actionConfigs");return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"},{render:this.renderConsultRetrieve,type:"consult_retrieve"},{render:this.renderConference,type:"conference"}].filter(({type:e})=>A.includes(e))}async render(){const{displayText:A}=Tt.getState(),{answer_devices:e}=St.agentInfo,t=(e||"").split(","),s=this.getActionConfigs(),i={...pt},{statusColor:r}=i,o=document.querySelector("head");if(o){const A=ze`
|
|
761
761
|
<style>
|
|
762
762
|
.ysyt-phone-body {
|
|
763
763
|
background: ${r[this.statusParams.state]};
|
|
@@ -873,4 +873,4 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
|
|
|
873
873
|
`:""}
|
|
874
874
|
</div>
|
|
875
875
|
</my-popover>
|
|
876
|
-
`;gt(s,this.rttHTML)}}const xs=new class{constructor(){this.events={}}on(A,e){this.events[A]=this.events[A]||[],this.events[A].push(e)}off(A,e){this.events[A]=(this.events[A]||[]).filter(A=>A!==e)}emit(A,...e){(this.events[A]||[]).forEach(A=>A(...e))}};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 console.log("已授权麦克风权限"),null;const e=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),e}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}}}let Os=null;class Ns{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Os){if(!A)throw new Error("WebSocket 尚未初始化");Os=new Ns(A)}return Os}stateIdleChange(){const{state:A}=St.stateObject;A!==Ae.IDLE&&this.apiClient._changeState({data:{state:Ae.IDLE,state_name:"空闲"}})}putAgentState(){St.sessionId="";const{post_call_process_time:A}=St.agentInfo,e=A||0;St.autoStateTimer&&(clearTimeout(St.autoStateTimer),St.autoStateTimer=null),e>0?St.autoStateTimer=setTimeout(()=>{St.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(t),t===ie.OUT_CALL&&(0!==i?(Tt.reset(),ae.emit(se.OUT_FAILED,r),this.stateIdleChange()):0===i&&ae.emit(se.OUT_SUCCESS)),t===ie.AGENT_STATE){const{state:A,state_name:e}=s;St.stateObject={state:A,state_name:e},"振铃中"===e&&Tt.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),St.sessionId=s.session_id,Tt.updateActionConfigs(Et)),t===ie.OUT_CALL_END&&(1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.OUT_HANGUP,s),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(se.TRANSFER_END),Tt.updateActionConfigs(mt))),t===ie.OUT_CALL_RINGING&&1===s.type&&(ae.emit(se.OUT_RINGING,s),Tt.updateDisplayText(oe.RINGING)),t===ie.OUT_CALL_ANSWER&&(ae.emit(se.OUT_OFF_ANSWER,s),Tt.updateOutCallIsAnswer(!0),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(It)),t===ie.CONSULT_RINGING&&(ae.emit(se.CONSULT_RINGING),Tt.updateDisplayText(oe.AGENT_RINGING),Tt.updateActionConfigs([])),t===ie.CONSULT_ANSWER&&(ae.emit(se.CONSULT_OFF_HOOK,s),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(oe.CONSULTING),Tt.updateActionConfigs(Mt)),t===ie.CONSULT_FAIL&&(ae.emit(se.CONSULT_FAILED,{custom_reason:s.custom_reason}),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(It)),t===ie.CONSULT_CALL_IN&&(ae.emit(se.CONSULT_INCOMING,s),Tt.updateIsCalling(!0),Tt.updateDirection(ee.CONSULT),Tt.updateDisplayText(oe.CONSULT_CALL_IN),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===ie.CONSULT_CALL_IN_SUCCESS&&(St.sessionId=s.session_id,ae.emit(se.CONSULT_CALL_IN_SUCCESS),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(wt)),t===ie.CONSULT_RETURN_CALL_SUCCESS&&(ae.emit(se.CONSULT_RETURN_CALL_SUCCESS),Tt.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)),t===ie.MUTE&&(0===i?(Tt.updateIsMuted(!0),ae.emit(se.MUTE_SUCCESS),Tt.updateDisplayText(oe.MUTING)):ae.emit(se.MUTE_FAILED,r)),t===ie.UNMUTE&&(0===i?(Tt.updateIsMuted(!1),ae.emit(se.UNMUTE_SUCCESS),Tt.updateDisplayText(oe.CALLING)):ae.emit(se.UNMUTE_FAILED,r)),t===ie.CALL_HOLD&&(0===i?(Tt.updateIsHold(!0),Tt.updateDisplayText(oe.HOLDING),ae.emit(se.HOLD_SUCCESS)):ae.emit(se.HOLD_FAILED,r)),t===ie.CALL_UNHOLD&&(0===i?(Tt.updateDisplayText(oe.CALLING),Tt.updateIsHold(!1),ae.emit(se.UNHOLD_SUCCESS)):ae.emit(se.UNHOLD_FAILED,r)),t===ie.CONSULT_TRANSFER&&(0===i?ae.emit(se.CONSULT_TRANSFER_SUCCESS):ae.emit(se.CONSULT_TRANSFER_FAILED,r)),t===ie.CONSULT_TRANSFER_FAILED&&ae.emit(se.CONSULT_TRANSFER_FAILED,s.status),t===ie.CONSULT_TRANSFER_OFF_HOOK&&(Tt.updateDirection(ee.INCOMING),Tt.updateDisplayText(oe.CALLING),ae.emit(se.CONSULT_TRANSFER_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateIncomingIsAnswer(!0),Tt.updateConsultIsAnswer(!1)),t===ie.INCOMING_CALL&&(St.sessionId=s.session_id,Tt.updateIsCalling(!0),Tt.updateDirection(ee.INCOMING),Tt.updateDisplayText(oe.INCOMING_CALL),ae.emit(se.INCOMING_CALL,{customer_phone:s.customer_phone}),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===ie.INCOMING_CALL_OFF_HOOK&&(Tt.updateIncomingIsAnswer(!0),ae.emit(se.INCOMING_CALL_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateDisplayText(oe.CALLING)),t===ie.INCOMING_CALL_END&&(1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.INCOMING_CALL_END),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(se.TRANSFER_END),Tt.updateActionConfigs(mt))),t===ie.SATISFACTION_EVALUATION&&(0===i?ae.emit(se.SATISFACTION_EVALUATION_SUCCESS):ae.emit(se.SATISFACTION_EVALUATION_FAILED,r)),t===ie.CONSULT_THREE_WAY&&(0!==i?ae.emit(se.CONSULT_THREE_WAY_FAILED,r):0===i&&Tt.updateIsMeeting(!0)),t===ie.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(Tt.updateDirection(ee.MEETING),Tt.updateDisplayText(oe.MEETING),Tt.updateActionConfigs(ft),ae.emit(se.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(se.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),Tt.updateIsMeeting(!1))),t===ie.TRANSFER_INCOMING_CALL&&(s.agent_no===St.agentInfo.agent_no?(Tt.updateDisplayText(oe.TRANSFERRING),ae.emit(se.TRANSFER_PROGRESS),Tt.updateActionConfigs([]),Tt.updateTransferIsAnswer(!0)):(ae.emit(se.TRANSFER_INCOMING_CALL,s),Tt.updateIsCalling(!0),Tt.updateDirection(ee.TRANSFER),Tt.updateDisplayText(oe.TRANSFER_INCOMING_CALL),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===ie.TRANSFER_OFF_HOOK&&(St.sessionId=s.session_id,ae.emit(se.TRANSFER_OFF_HOOK),Tt.updateTransferIsAnswer(!0),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(Qt)),t===ie.TRANSFER_FAILED&&"failed"===s.status){ae.emit(se.TRANSFER_FAILED,"未知原因");const A=Tt.get("direction");A===ee.OUTGOING?Tt.updateActionConfigs(It):A===ee.INCOMING&&Tt.updateActionConfigs(Qt)}0!==t&&xs.emit("ws-message",e)},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?this.ws.send(JSON.stringify(A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Os&&(Os.close(),Os=null)}static __internalSend(A){if(!Os)throw new Error("WebSocket 尚未初始化");Os.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=Tt.get("isCalling"),e=St.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=Tt.get("isHold"),{sessionId:e}=St;if(!e)return;if(!Tt.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Ns.__internalSend({type:ie.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=Tt.getState(),{sessionId:e}=St;if(!Tt.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Ns.__internalSend({type:ie.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=Tt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("reject"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用拒接"}));const{isCalling:A,direction:e,outCallIsAnswer:t}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));t||(e===ee.INCOMING?this.rejectInCall():e===ee.OUTGOING&&this.rejectOutCall())}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=Tt.getState(),r=St.sessionId;if(!Tt.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不存在"}));Ns.__internalSend({type:ie.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(A){if(Tt.getState().isCalling)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));Tt.updateIsCalling(!0),Tt.updateDirection(ee.OUTGOING),Ns.__internalSend({type:ie.OUT_CALL,data:{customer_phone:A}})}async rejectOutCall(){const{isCalling:A}=Tt.getState();if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectOutCall()}async hangup(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.hangup()}mute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:ie.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:ie.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=Tt.get("consultIsAnswer"),e=St.sessionId;if(!Tt.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:ie.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=St.sessionId;if(!Tt.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Ns.__internalSend({type:ie.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!Tt.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:ie.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!Tt.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:ie.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!Tt.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!Tt.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}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class bs{#A=null;#e=new Us;#t;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();ds.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=Tt.subscribeKey("answerDevice",A=>{1===A&&this.initWebRtc()})}async initWebRtc(){const A=St.agentInfo.sip_account_list.find(A=>1===A.device_type);if(A){const e=A.sip_register_addr;this.#A=new us({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#n),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r}){try{const{viewHtmlElement:o,rttHTML:n}=A||{},a=e||"https://aicc.yescloudy.com";cs=a,hs=t,ls=s;const V=ns(t,s);await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,init_state:l}=St.agentInfo;l===Ae.IDLE?(Tt.updateActionConfigs(mt),St.stateObject={state:l,state_name:"空闲"}):l===Ae.BUSY&&(Tt.updateActionConfigs(Ct),St.stateObject={state:l,state_name:"忙碌"});let g="";const q=new URL(a).host;g=a.includes("https")?`wss://${q}`:`ws://${q}`,Ns.getInstance(`${g}/ccs-ws/api/v1/ws/call/${c}?Authorization=${V}`),Tt.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new Js(this.#A),A&&o&&(this.#i=!0,new vs({container:o,rttHTML:n,statusParams:{state:Ae.IDLE,statusName:"空闲"}},this,this.#t)),St.enableBrowserAlert=r,r&&Ks.requestPermission()}catch(A){this.#i&&Fs("初始化失败"),console.log(A)}}#n=A=>{const{type:e,data:t}=A;ae.emit(e,t)};#a=A=>{};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())}destroy(){this.destroyRtc(),clearInterval(this.#s),xs.off("ws-message",this.#a),Ns.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#e=null,this.#i=!1}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(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))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,init_state:s,default_device:i}=St.agentInfo,{stateObject:r}=St,o={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:s,default_device:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:o[Number(A)]})),stateObject:r}}}export{Ae as AgentStatus,se as CallSipCallEvent,ee as DirectionEnum,oe as DisplayTextEnum,re as EventName,te as WebRtcCallSipEventEnum,ie as WebsocketTypeEnum,bs as default};
|
|
876
|
+
`;gt(s,this.rttHTML)}}const xs=new class{constructor(){this.events={}}on(A,e){this.events[A]=this.events[A]||[],this.events[A].push(e)}off(A,e){this.events[A]=(this.events[A]||[]).filter(A=>A!==e)}emit(A,...e){(this.events[A]||[]).forEach(A=>A(...e))}};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 console.log("已授权麦克风权限"),null;const e=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),e}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}}}let Os=null;class Ns{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Os){if(!A)throw new Error("WebSocket 尚未初始化");Os=new Ns(A)}return Os}stateIdleChange(){const{state:A}=St.stateObject;A!==Ae.IDLE&&this.apiClient._changeState({data:{state:Ae.IDLE,state_name:"空闲"}})}putAgentState(){St.sessionId="";const{post_call_process_time:A}=St.agentInfo,e=A||0;St.autoStateTimer&&(clearTimeout(St.autoStateTimer),St.autoStateTimer=null),e>0?St.autoStateTimer=setTimeout(()=>{St.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(t),t===ie.OUT_CALL&&(0!==i?(Tt.reset(),ae.emit(se.OUT_FAILED,r),this.stateIdleChange()):0===i&&ae.emit(se.OUT_SUCCESS)),t===ie.AGENT_STATE){const{state:A,state_name:e}=s;St.stateObject={state:A,state_name:e},"振铃中"===e&&Tt.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),St.sessionId=s.session_id,Tt.updateActionConfigs(Et)),t===ie.OUT_CALL_END&&(Tt.updateDisplayText(""),1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.OUT_HANGUP,s),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(se.TRANSFER_END),Tt.updateActionConfigs(mt))),t===ie.OUT_CALL_RINGING&&1===s.type&&(ae.emit(se.OUT_RINGING,s),Tt.updateDisplayText(oe.RINGING)),t===ie.OUT_CALL_ANSWER&&(ae.emit(se.OUT_OFF_ANSWER,s),Tt.updateOutCallIsAnswer(!0),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(It)),t===ie.CONSULT_RINGING&&(ae.emit(se.CONSULT_RINGING),Tt.updateDisplayText(oe.AGENT_RINGING),Tt.updateActionConfigs([])),t===ie.CONSULT_ANSWER&&(ae.emit(se.CONSULT_OFF_HOOK,s),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(oe.CONSULTING),Tt.updateActionConfigs(Mt)),t===ie.CONSULT_FAIL&&(ae.emit(se.CONSULT_FAILED,{custom_reason:s.custom_reason}),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(It)),t===ie.CONSULT_CALL_IN&&(ae.emit(se.CONSULT_INCOMING,s),Tt.updateIsCalling(!0),Tt.updateDirection(ee.CONSULT),Tt.updateDisplayText(oe.CONSULT_CALL_IN),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===ie.CONSULT_CALL_IN_SUCCESS&&(St.sessionId=s.session_id,ae.emit(se.CONSULT_CALL_IN_SUCCESS),Tt.updateConsultIsAnswer(!0),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(wt)),t===ie.CONSULT_RETURN_CALL_SUCCESS&&(ae.emit(se.CONSULT_RETURN_CALL_SUCCESS),Tt.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)),t===ie.MUTE&&(0===i?(Tt.updateIsMuted(!0),ae.emit(se.MUTE_SUCCESS),Tt.updateDisplayText(oe.MUTING)):ae.emit(se.MUTE_FAILED,r)),t===ie.UNMUTE&&(0===i?(Tt.updateIsMuted(!1),ae.emit(se.UNMUTE_SUCCESS),Tt.updateDisplayText(oe.CALLING)):ae.emit(se.UNMUTE_FAILED,r)),t===ie.CALL_HOLD&&(0===i?(Tt.updateIsHold(!0),Tt.updateDisplayText(oe.HOLDING),ae.emit(se.HOLD_SUCCESS)):ae.emit(se.HOLD_FAILED,r)),t===ie.CALL_UNHOLD&&(0===i?(Tt.updateDisplayText(oe.CALLING),Tt.updateIsHold(!1),ae.emit(se.UNHOLD_SUCCESS)):ae.emit(se.UNHOLD_FAILED,r)),t===ie.CONSULT_TRANSFER&&(0===i?ae.emit(se.CONSULT_TRANSFER_SUCCESS):ae.emit(se.CONSULT_TRANSFER_FAILED,r)),t===ie.CONSULT_TRANSFER_FAILED&&ae.emit(se.CONSULT_TRANSFER_FAILED,s.status),t===ie.CONSULT_TRANSFER_OFF_HOOK&&(Tt.updateDirection(ee.INCOMING),Tt.updateDisplayText(oe.CALLING),ae.emit(se.CONSULT_TRANSFER_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateIncomingIsAnswer(!0),Tt.updateConsultIsAnswer(!1)),t===ie.INCOMING_CALL&&(St.sessionId=s.session_id,Tt.updateIsCalling(!0),Tt.updateDirection(ee.INCOMING),Tt.updateDisplayText(oe.INCOMING_CALL),ae.emit(se.INCOMING_CALL,{customer_phone:s.customer_phone}),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===ie.INCOMING_CALL_OFF_HOOK&&(Tt.updateIncomingIsAnswer(!0),ae.emit(se.INCOMING_CALL_OFF_HOOK),Tt.updateActionConfigs(Qt),Tt.updateDisplayText(oe.CALLING)),t===ie.INCOMING_CALL_END&&(Tt.updateDisplayText(""),1===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.INCOMING_CALL_END),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no===St.agentInfo.agent_no?(Tt.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),Tt.updateActionConfigs(mt)):2===s.device_type&&s.agent_no!==St.agentInfo.agent_no?(Tt.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),Tt.updateActionConfigs(It)):3===s.device_type&&s.agent_no===St.agentInfo.agent_no?(this.putAgentState(),Tt.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),Tt.updateActionConfigs(mt)):4===s.device_type&&s.agent_no===St.agentInfo.agent_no&&(this.putAgentState(),Tt.reset(),ae.emit(se.TRANSFER_END),Tt.updateActionConfigs(mt))),t===ie.SATISFACTION_EVALUATION&&(0===i?ae.emit(se.SATISFACTION_EVALUATION_SUCCESS):ae.emit(se.SATISFACTION_EVALUATION_FAILED,r)),t===ie.CONSULT_THREE_WAY&&(0!==i?ae.emit(se.CONSULT_THREE_WAY_FAILED,r):0===i&&Tt.updateIsMeeting(!0)),t===ie.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(Tt.updateDirection(ee.MEETING),Tt.updateDisplayText(oe.MEETING),Tt.updateActionConfigs(ft),ae.emit(se.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(se.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),Tt.updateIsMeeting(!1))),t===ie.TRANSFER_INCOMING_CALL&&(s.agent_no===St.agentInfo.agent_no?(Tt.updateDisplayText(oe.TRANSFERRING),ae.emit(se.TRANSFER_PROGRESS),Tt.updateActionConfigs([]),Tt.updateTransferIsAnswer(!0)):(ae.emit(se.TRANSFER_INCOMING_CALL,s),Tt.updateIsCalling(!0),Tt.updateDirection(ee.TRANSFER),Tt.updateDisplayText(oe.TRANSFER_INCOMING_CALL),Tt.updateActionConfigs(Bt),St.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===ie.TRANSFER_OFF_HOOK&&(St.sessionId=s.session_id,ae.emit(se.TRANSFER_OFF_HOOK),Tt.updateTransferIsAnswer(!0),Tt.updateDisplayText(oe.CALLING),Tt.updateActionConfigs(Qt)),t===ie.TRANSFER_FAILED&&"failed"===s.status){ae.emit(se.TRANSFER_FAILED,"未知原因");const A=Tt.get("direction");A===ee.OUTGOING?Tt.updateActionConfigs(It):A===ee.INCOMING&&Tt.updateActionConfigs(Qt)}0!==t&&xs.emit("ws-message",e)},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?this.ws.send(JSON.stringify(A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Os&&(Os.close(),Os=null)}static __internalSend(A){if(!Os)throw new Error("WebSocket 尚未初始化");Os.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=Tt.get("isCalling"),e=St.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=Tt.get("isHold"),{sessionId:e}=St;if(!e)return;if(!Tt.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Ns.__internalSend({type:ie.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=Tt.getState(),{sessionId:e}=St;if(!Tt.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Ns.__internalSend({type:ie.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=Tt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("actionConfigs").includes("reject"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用拒接"}));const{isCalling:A,direction:e,outCallIsAnswer:t}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));t||(e===ee.INCOMING?this.rejectInCall():e===ee.OUTGOING&&this.rejectOutCall())}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=Tt.getState(),r=St.sessionId;if(!Tt.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不存在"}));Ns.__internalSend({type:ie.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=Tt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(A){if(Tt.getState().isCalling)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));Tt.updateIsCalling(!0),Tt.updateDirection(ee.OUTGOING),Ns.__internalSend({type:ie.OUT_CALL,data:{customer_phone:A}})}async rejectOutCall(){const{isCalling:A}=Tt.getState();if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectOutCall()}async hangup(){if(1!==Tt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Tt.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.hangup()}mute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:ie.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=Tt.get("actionConfigs"),e=Tt.get("isMuted"),t=St.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:ie.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=Tt.get("consultIsAnswer"),e=St.sessionId;if(!Tt.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:ie.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=St.sessionId;if(!Tt.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Ns.__internalSend({type:ie.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!Tt.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:ie.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!Tt.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=St.sessionId;if(!Tt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:ie.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!Tt.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!Tt.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}=Tt.getState(),t=St.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class bs{#A=null;#e=new Us;#t;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();ds.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=Tt.subscribeKey("answerDevice",A=>{1===A&&this.initWebRtc()})}async initWebRtc(){const A=St.agentInfo.sip_account_list.find(A=>1===A.device_type);if(A){const e=A.sip_register_addr;this.#A=new us({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#n),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r}){try{const{viewHtmlElement:o,rttHTML:n}=A||{},a=e||"https://aicc.yescloudy.com";cs=a,hs=t,ls=s;const V=ns(t,s);await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,init_state:l}=St.agentInfo;l===Ae.IDLE?(Tt.updateActionConfigs(mt),St.stateObject={state:l,state_name:"空闲"}):l===Ae.BUSY&&(Tt.updateActionConfigs(Ct),St.stateObject={state:l,state_name:"忙碌"});let g="";const q=new URL(a).host;g=a.includes("https")?`wss://${q}`:`ws://${q}`,Ns.getInstance(`${g}/ccs-ws/api/v1/ws/call/${c}?Authorization=${V}`),Tt.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new Js(this.#A),A&&o&&(this.#i=!0,new vs({container:o,rttHTML:n,statusParams:{state:Ae.IDLE,statusName:"空闲"}},this,this.#t)),St.enableBrowserAlert=r,r&&Ks.requestPermission()}catch(A){this.#i&&Fs("初始化失败"),console.log(A)}}#n=A=>{const{type:e,data:t}=A;ae.emit(e,t)};#a=A=>{};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())}destroy(){this.destroyRtc(),clearInterval(this.#s),xs.off("ws-message",this.#a),Ns.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#e=null,this.#i=!1}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(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))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,init_state:s,default_device:i}=St.agentInfo,{stateObject:r}=St,o={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:s,default_device:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:o[Number(A)]})),stateObject:r}}}export{Ae as AgentStatus,se as CallSipCallEvent,ee as DirectionEnum,oe as DisplayTextEnum,re as EventName,te as WebRtcCallSipEventEnum,ie as WebsocketTypeEnum,bs as default};
|
|
@@ -14,7 +14,7 @@ const Ue=globalThis,ke=Ue.trustedTypes,Ge=ke?ke.createPolicy("lit-html",{createH
|
|
|
14
14
|
* @license
|
|
15
15
|
* Copyright 2017 Google LLC
|
|
16
16
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
17
|
-
*/},dt=globalThis;class ut extends Re{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const A=super.createRenderRoot();return this.renderOptions.renderBefore??=A.firstChild,A}update(A){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(A),this._$Do=qt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return _e}}ut._$litElement$=!0,ut.finalized=!0,dt.litElementHydrateSupport?.({LitElement:ut});const pt=dt.litElementPolyfillSupport;pt?.({LitElement:ut}),(dt.litElementVersions??=[]).push("4.2.1");const mt={statusColor:{[A.AgentStatus.IDLE]:"#1D92E9",[A.AgentStatus.BUSY]:"#F5212D",[A.AgentStatus.OFFLINE]:"#8c8c8c",[A.AgentStatus.RINGING]:"#e9b91d"}},Ct=["call_number"],Et=[],It=["hangup"],Mt=["hold","hangup","unhold","mute","unmute","transfer","consult","satisfaction","dtmf"],wt=["consult_transfer","conference","consult_retrieve"],ft=["hangup"],Bt=["hangup"],Qt=["answer","reject"],St=["hangup","consult","transfer","hold","unhold","mute","unmute","satisfaction","dtmf"],yt={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null},Tt={isCalling:!1,direction:null,outCallIsAnswer:!1,incomingIsAnswer:!1,transferIsAnswer:!1,isMeeting:!1,isHold:!1,displayText:"",isMuted:!1,consultIsAnswer:!1,actionConfigs:[],answerDevice:1};const Dt=new class extends Ae{updateIsCalling(A){this.setState({isCalling:A})}updateDirection(A){this.setState({direction:A})}updateOutCallIsAnswer(A){this.setState({outCallIsAnswer:A})}updateIsHold(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"hold"!==A)];A.push("unhold"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unhold"!==A)];A.push("hold"),this.updateActionConfigs(A)}this.getState().isHold=A}updateDisplayText(e){this.setState({displayText:e}),console.log("displayText:",e),Ve.emit(A.CallSipCallEvent.CALL_PROGRESS,e)}updateActionConfigs(e){const{show_satisfaction:t}=yt.agentInfo||{},s=this.get("answerDevice");this.setState({actionConfigs:e.filter(A=>(0!==t||"satisfaction"!==A)&&(2!==s&&3!==s||"hangup"!==A&&"dtmf"!==A))}),Ve.emit(A.EventName.PHONE_BAR_OPERATION,e)}updateConsultIsAnswer(A){this.setState({consultIsAnswer:A})}updateIsMuted(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"mute"!==A)];A.push("unmute"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unmute"!==A)];A.push("mute"),this.updateActionConfigs(A)}this.setState({isMuted:A})}updateIncomingIsAnswer(A){this.setState({incomingIsAnswer:A})}updateAnswerDevice(e){this.setState({answerDevice:e}),yt.stateObject.state===A.AgentStatus.IDLE?this.updateActionConfigs(Ct):yt.stateObject.state===A.AgentStatus.BUSY&&this.updateActionConfigs(Et),Ve.emit(A.EventName.UPDATE_ANSWER_DEVICE,e)}updateIsMeeting(A){this.setState({isMeeting:A})}updateTransferIsAnswer(A){this.setState({transferIsAnswer:A})}reset(){this.setState({...Tt},!0)}getCallInfo(){return this.getState()}get(A){return this.getState()[A]}}(Tt);class Rt extends Error{response;request;options;constructor(A,e,t){const s=`${A.status||0===A.status?A.status:""} ${A.statusText||""}`.trim();super(`Request failed with ${s?`status code ${s}`:"an unknown error"}: ${e.method} ${e.url}`),this.name="HTTPError",this.response=A,this.request=e,this.options=t}}class Ut extends Error{request;constructor(A){super(`Request timed out: ${A.method} ${A.url}`),this.name="TimeoutError",this.request=A}}const kt=(()=>{let A=!1,e=!1;const t="function"==typeof globalThis.ReadableStream,s="function"==typeof globalThis.Request;if(t&&s)try{e=new globalThis.Request("https://empty.invalid",{body:new globalThis.ReadableStream,method:"POST",get duplex(){return A=!0,"half"}}).headers.has("Content-Type")}catch(A){if(A instanceof Error&&"unsupported BodyInit type"===A.message)return!1;throw A}return A&&!e})(),Gt="function"==typeof globalThis.AbortController,Yt="function"==typeof globalThis.AbortSignal&&"function"==typeof globalThis.AbortSignal.any,Ft="function"==typeof globalThis.ReadableStream,Zt="function"==typeof globalThis.FormData,vt=["get","post","put","patch","head","delete"],xt={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},Kt=2147483647,Ot=(new TextEncoder).encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length,Nt=Symbol("stop"),bt={json:!0,parseJson:!0,stringifyJson:!0,searchParams:!0,prefixUrl:!0,retry:!0,timeout:!0,hooks:!0,throwHttpErrors:!0,onDownloadProgress:!0,onUploadProgress:!0,fetch:!0},Jt={method:!0,headers:!0,body:!0,mode:!0,credentials:!0,cache:!0,redirect:!0,referrer:!0,referrerPolicy:!0,integrity:!0,keepalive:!0,signal:!0,window:!0,dispatcher:!0,duplex:!0,priority:!0},Ht=(A,e)=>{const t=(A=>{if(!A)return 0;if(A instanceof FormData){let e=0;for(const[t,s]of A)e+=Ot,e+=(new TextEncoder).encode(`Content-Disposition: form-data; name="${t}"`).length,e+="string"==typeof s?(new TextEncoder).encode(s).length:s.size;return e}if(A instanceof Blob)return A.size;if(A instanceof ArrayBuffer)return A.byteLength;if("string"==typeof A)return(new TextEncoder).encode(A).length;if(A instanceof URLSearchParams)return(new TextEncoder).encode(A.toString()).length;if("byteLength"in A)return A.byteLength;if("object"==typeof A&&null!==A)try{const e=JSON.stringify(A);return(new TextEncoder).encode(e).length}catch{return 0}return 0})(A.body);let s=0;return new Request(A,{duplex:"half",body:new ReadableStream({async start(i){const r=A.body instanceof ReadableStream?A.body.getReader():new Response("").body.getReader();await async function A(){const{done:o,value:n}=await r.read();if(o)return e&&e({percent:1,transferredBytes:s,totalBytes:Math.max(t,s)},new Uint8Array),void i.close();s+=n.byteLength;let a=0===t?0:s/t;(t<s||1===a)&&(a=.99),e&&e({percent:Number(a.toFixed(2)),transferredBytes:s,totalBytes:t},n),i.enqueue(n),await A()}()}})})},jt=A=>null!==A&&"object"==typeof A,Lt=(...A)=>{for(const e of A)if((!jt(e)||Array.isArray(e))&&void 0!==e)throw new TypeError("The `options` argument must be an object");return Xt({},...A)},Wt=(A={},e={})=>{const t=new globalThis.Headers(A),s=e instanceof globalThis.Headers,i=new globalThis.Headers(e);for(const[A,e]of i.entries())s&&"undefined"===e||void 0===e?t.delete(A):t.set(A,e);return t};function Pt(A,e,t){return Object.hasOwn(e,t)&&void 0===e[t]?[]:Xt(A[t]??[],e[t]??[])}const zt=(A={},e={})=>({beforeRequest:Pt(A,e,"beforeRequest"),beforeRetry:Pt(A,e,"beforeRetry"),afterResponse:Pt(A,e,"afterResponse"),beforeError:Pt(A,e,"beforeError")}),Xt=(...A)=>{let e={},t={},s={};for(const i of A)if(Array.isArray(i))Array.isArray(e)||(e=[]),e=[...e,...i];else if(jt(i)){for(let[A,t]of Object.entries(i))jt(t)&&A in e&&(t=Xt(e[A],t)),e={...e,[A]:t};jt(i.hooks)&&(s=zt(s,i.hooks),e.hooks=s),jt(i.headers)&&(t=Wt(t,i.headers),e.headers=t)}return e},_t=A=>vt.includes(A)?A.toUpperCase():A,$t={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:Number.POSITIVE_INFINITY,backoffLimit:Number.POSITIVE_INFINITY,delay:A=>.3*2**(A-1)*1e3},As=(A={})=>{if("number"==typeof A)return{...$t,limit:A};if(A.methods&&!Array.isArray(A.methods))throw new Error("retry.methods must be an array");if(A.statusCodes&&!Array.isArray(A.statusCodes))throw new Error("retry.statusCodes must be an array");return{...$t,...A}};class es{static create(A,e){const t=new es(A,e),s=async()=>{if("number"==typeof t._options.timeout&&t._options.timeout>Kt)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await Promise.resolve();let A=await t._fetch();for(const e of t._options.hooks.afterResponse){const s=await e(t.request,t._options,t._decorateResponse(A.clone()));s instanceof globalThis.Response&&(A=s)}if(t._decorateResponse(A),!A.ok&&t._options.throwHttpErrors){let e=new Rt(A,t.request,t._options);for(const A of t._options.hooks.beforeError)e=await A(e);throw e}if(t._options.onDownloadProgress){if("function"!=typeof t._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!Ft)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return((A,e)=>{const t=Number(A.headers.get("content-length"))||0;let s=0;return 204===A.status?(e&&e({percent:1,totalBytes:t,transferredBytes:s},new Uint8Array),new Response(null,{status:A.status,statusText:A.statusText,headers:A.headers})):new Response(new ReadableStream({async start(i){const r=A.body.getReader();e&&e({percent:0,transferredBytes:0,totalBytes:t},new Uint8Array),await async function A(){const{done:o,value:n}=await r.read();o?i.close():(e&&(s+=n.byteLength,e({percent:0===t?0:s/t,transferredBytes:s,totalBytes:t},n)),i.enqueue(n),await A())}()}}),{status:A.status,statusText:A.statusText,headers:A.headers})})(A.clone(),t._options.onDownloadProgress)}return A},i=(t._options.retry.methods.includes(t.request.method.toLowerCase())?t._retry(s):s()).finally(async()=>{t.request.bodyUsed||await(t.request.body?.cancel())});for(const[A,s]of Object.entries(xt))i[A]=async()=>{t.request.headers.set("accept",t.request.headers.get("accept")||s);const r=await i;if("json"===A){if(204===r.status)return"";if(0===(await r.clone().arrayBuffer()).byteLength)return"";if(e.parseJson)return e.parseJson(await r.text())}return r[A]()};return i}request;abortController;_retryCount=0;_input;_options;constructor(A,e={}){if(this._input=A,this._options={...e,headers:Wt(this._input.headers,e.headers),hooks:zt({beforeRequest:[],beforeRetry:[],beforeError:[],afterResponse:[]},e.hooks),method:_t(e.method??this._input.method??"GET"),prefixUrl:String(e.prefixUrl||""),retry:As(e.retry),throwHttpErrors:!1!==e.throwHttpErrors,timeout:e.timeout??1e4,fetch:e.fetch??globalThis.fetch.bind(globalThis)},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof globalThis.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(Gt&&Yt){const A=this._options.signal??this._input.signal;this.abortController=new globalThis.AbortController,this._options.signal=A?AbortSignal.any([A,this.abortController.signal]):this.abortController.signal}if(kt&&(this._options.duplex="half"),void 0!==this._options.json&&(this._options.body=this._options.stringifyJson?.(this._options.json)??JSON.stringify(this._options.json),this._options.headers.set("content-type",this._options.headers.get("content-type")??"application/json")),this.request=new globalThis.Request(this._input,this._options),this._options.searchParams){const A="?"+("string"==typeof this._options.searchParams?this._options.searchParams.replace(/^\?/,""):new URLSearchParams(this._options.searchParams).toString()),e=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,A);!(Zt&&this._options.body instanceof globalThis.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new globalThis.Request(new globalThis.Request(e,{...this.request}),this._options)}if(this._options.onUploadProgress){if("function"!=typeof this._options.onUploadProgress)throw new TypeError("The `onUploadProgress` option must be a function");if(!kt)throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");this.request.body&&(this.request=Ht(this.request,this._options.onUploadProgress))}}_calculateRetryDelay(A){if(this._retryCount++,this._retryCount>this._options.retry.limit||A instanceof Ut)throw A;if(A instanceof Rt){if(!this._options.retry.statusCodes.includes(A.response.status))throw A;const e=A.response.headers.get("Retry-After")??A.response.headers.get("RateLimit-Reset")??A.response.headers.get("X-RateLimit-Reset")??A.response.headers.get("X-Rate-Limit-Reset");if(e&&this._options.retry.afterStatusCodes.includes(A.response.status)){let A=1e3*Number(e);Number.isNaN(A)?A=Date.parse(e)-Date.now():A>=Date.parse("2024-01-01")&&(A-=Date.now());const t=this._options.retry.maxRetryAfter??A;return A<t?A:t}if(413===A.response.status)throw A}const e=this._options.retry.delay(this._retryCount);return Math.min(this._options.retry.backoffLimit,e)}_decorateResponse(A){return this._options.parseJson&&(A.json=async()=>this._options.parseJson(await A.text())),A}async _retry(A){try{return await A()}catch(e){const t=Math.min(this._calculateRetryDelay(e),Kt);if(this._retryCount<1)throw e;await async function(A,{signal:e}){return new Promise((t,s)=>{function i(){clearTimeout(r),s(e.reason)}e&&(e.throwIfAborted(),e.addEventListener("abort",i,{once:!0}));const r=setTimeout(()=>{e?.removeEventListener("abort",i),t()},A)})}(t,{signal:this._options.signal});for(const A of this._options.hooks.beforeRetry){if(await A({request:this.request,options:this._options,error:e,retryCount:this._retryCount})===Nt)return}return this._retry(A)}}async _fetch(){for(const A of this._options.hooks.beforeRequest){const e=await A(this.request,this._options);if(e instanceof Request){this.request=e;break}if(e instanceof Response)return e}const A=((A,e)=>{const t={};for(const s in e)s in Jt||s in bt||s in A||(t[s]=e[s]);return t})(this.request,this._options),e=this.request;return this.request=e.clone(),!1===this._options.timeout?this._options.fetch(e,A):async function(A,e,t,s){return new Promise((i,r)=>{const o=setTimeout(()=>{t&&t.abort(),r(new Ut(A))},s.timeout);s.fetch(A,e).then(i).catch(r).then(()=>{clearTimeout(o)})})}(e,A,this.abortController,this._options)}}
|
|
17
|
+
*/},dt=globalThis;class ut extends Re{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const A=super.createRenderRoot();return this.renderOptions.renderBefore??=A.firstChild,A}update(A){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(A),this._$Do=qt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return _e}}ut._$litElement$=!0,ut.finalized=!0,dt.litElementHydrateSupport?.({LitElement:ut});const pt=dt.litElementPolyfillSupport;pt?.({LitElement:ut}),(dt.litElementVersions??=[]).push("4.2.1");const mt={statusColor:{[A.AgentStatus.IDLE]:"#1D92E9",[A.AgentStatus.BUSY]:"#F5212D",[A.AgentStatus.OFFLINE]:"#8c8c8c",[A.AgentStatus.RINGING]:"#e9b91d"}},Ct=["call_number"],Et=[],It=["hangup"],Mt=["hold","hangup","mute","transfer","consult","satisfaction","dtmf"],wt=["consult_transfer","conference","consult_retrieve"],ft=["hangup"],Bt=["hangup"],Qt=["answer","reject"],St=["hangup","consult","transfer","hold","mute","satisfaction","dtmf"],yt={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null},Tt={isCalling:!1,direction:null,outCallIsAnswer:!1,incomingIsAnswer:!1,transferIsAnswer:!1,isMeeting:!1,isHold:!1,displayText:"",isMuted:!1,consultIsAnswer:!1,actionConfigs:[],answerDevice:1};const Dt=new class extends Ae{updateIsCalling(A){this.setState({isCalling:A})}updateDirection(A){this.setState({direction:A})}updateOutCallIsAnswer(A){this.setState({outCallIsAnswer:A})}updateIsHold(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"hold"!==A)];A.push("unhold"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unhold"!==A)];A.push("hold"),this.updateActionConfigs(A)}this.getState().isHold=A}updateDisplayText(e){this.setState({displayText:e}),console.log("displayText:",e),Ve.emit(A.CallSipCallEvent.CALL_PROGRESS,e)}updateActionConfigs(e){const{show_satisfaction:t}=yt.agentInfo||{},s=this.get("answerDevice"),i=e.filter(A=>(0!==t||"satisfaction"!==A)&&(2!==s&&3!==s||"hangup"!==A&&"dtmf"!==A));console.log(i),this.setState({actionConfigs:i}),console.log(i),Ve.emit(A.EventName.PHONE_BAR_OPERATION,i)}updateConsultIsAnswer(A){this.setState({consultIsAnswer:A})}updateIsMuted(A){const e=this.get("actionConfigs");if(A){const A=[...e.filter(A=>"mute"!==A)];A.push("unmute"),this.updateActionConfigs(A)}else{const A=[...e.filter(A=>"unmute"!==A)];A.push("mute"),this.updateActionConfigs(A)}this.setState({isMuted:A})}updateIncomingIsAnswer(A){this.setState({incomingIsAnswer:A})}updateAnswerDevice(e){this.setState({answerDevice:e}),yt.stateObject.state===A.AgentStatus.IDLE?this.updateActionConfigs(Ct):yt.stateObject.state===A.AgentStatus.BUSY&&this.updateActionConfigs(Et),Ve.emit(A.EventName.UPDATE_ANSWER_DEVICE,e)}updateIsMeeting(A){this.setState({isMeeting:A})}updateTransferIsAnswer(A){this.setState({transferIsAnswer:A})}reset(){this.setState({...Tt},!0)}getCallInfo(){return this.getState()}get(A){return this.getState()[A]}}(Tt);class Rt extends Error{response;request;options;constructor(A,e,t){const s=`${A.status||0===A.status?A.status:""} ${A.statusText||""}`.trim();super(`Request failed with ${s?`status code ${s}`:"an unknown error"}: ${e.method} ${e.url}`),this.name="HTTPError",this.response=A,this.request=e,this.options=t}}class Ut extends Error{request;constructor(A){super(`Request timed out: ${A.method} ${A.url}`),this.name="TimeoutError",this.request=A}}const kt=(()=>{let A=!1,e=!1;const t="function"==typeof globalThis.ReadableStream,s="function"==typeof globalThis.Request;if(t&&s)try{e=new globalThis.Request("https://empty.invalid",{body:new globalThis.ReadableStream,method:"POST",get duplex(){return A=!0,"half"}}).headers.has("Content-Type")}catch(A){if(A instanceof Error&&"unsupported BodyInit type"===A.message)return!1;throw A}return A&&!e})(),Gt="function"==typeof globalThis.AbortController,Yt="function"==typeof globalThis.AbortSignal&&"function"==typeof globalThis.AbortSignal.any,Ft="function"==typeof globalThis.ReadableStream,Zt="function"==typeof globalThis.FormData,vt=["get","post","put","patch","head","delete"],xt={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},Kt=2147483647,Ot=(new TextEncoder).encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length,Nt=Symbol("stop"),bt={json:!0,parseJson:!0,stringifyJson:!0,searchParams:!0,prefixUrl:!0,retry:!0,timeout:!0,hooks:!0,throwHttpErrors:!0,onDownloadProgress:!0,onUploadProgress:!0,fetch:!0},Jt={method:!0,headers:!0,body:!0,mode:!0,credentials:!0,cache:!0,redirect:!0,referrer:!0,referrerPolicy:!0,integrity:!0,keepalive:!0,signal:!0,window:!0,dispatcher:!0,duplex:!0,priority:!0},Ht=(A,e)=>{const t=(A=>{if(!A)return 0;if(A instanceof FormData){let e=0;for(const[t,s]of A)e+=Ot,e+=(new TextEncoder).encode(`Content-Disposition: form-data; name="${t}"`).length,e+="string"==typeof s?(new TextEncoder).encode(s).length:s.size;return e}if(A instanceof Blob)return A.size;if(A instanceof ArrayBuffer)return A.byteLength;if("string"==typeof A)return(new TextEncoder).encode(A).length;if(A instanceof URLSearchParams)return(new TextEncoder).encode(A.toString()).length;if("byteLength"in A)return A.byteLength;if("object"==typeof A&&null!==A)try{const e=JSON.stringify(A);return(new TextEncoder).encode(e).length}catch{return 0}return 0})(A.body);let s=0;return new Request(A,{duplex:"half",body:new ReadableStream({async start(i){const r=A.body instanceof ReadableStream?A.body.getReader():new Response("").body.getReader();await async function A(){const{done:o,value:n}=await r.read();if(o)return e&&e({percent:1,transferredBytes:s,totalBytes:Math.max(t,s)},new Uint8Array),void i.close();s+=n.byteLength;let a=0===t?0:s/t;(t<s||1===a)&&(a=.99),e&&e({percent:Number(a.toFixed(2)),transferredBytes:s,totalBytes:t},n),i.enqueue(n),await A()}()}})})},jt=A=>null!==A&&"object"==typeof A,Lt=(...A)=>{for(const e of A)if((!jt(e)||Array.isArray(e))&&void 0!==e)throw new TypeError("The `options` argument must be an object");return Xt({},...A)},Wt=(A={},e={})=>{const t=new globalThis.Headers(A),s=e instanceof globalThis.Headers,i=new globalThis.Headers(e);for(const[A,e]of i.entries())s&&"undefined"===e||void 0===e?t.delete(A):t.set(A,e);return t};function Pt(A,e,t){return Object.hasOwn(e,t)&&void 0===e[t]?[]:Xt(A[t]??[],e[t]??[])}const zt=(A={},e={})=>({beforeRequest:Pt(A,e,"beforeRequest"),beforeRetry:Pt(A,e,"beforeRetry"),afterResponse:Pt(A,e,"afterResponse"),beforeError:Pt(A,e,"beforeError")}),Xt=(...A)=>{let e={},t={},s={};for(const i of A)if(Array.isArray(i))Array.isArray(e)||(e=[]),e=[...e,...i];else if(jt(i)){for(let[A,t]of Object.entries(i))jt(t)&&A in e&&(t=Xt(e[A],t)),e={...e,[A]:t};jt(i.hooks)&&(s=zt(s,i.hooks),e.hooks=s),jt(i.headers)&&(t=Wt(t,i.headers),e.headers=t)}return e},_t=A=>vt.includes(A)?A.toUpperCase():A,$t={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:Number.POSITIVE_INFINITY,backoffLimit:Number.POSITIVE_INFINITY,delay:A=>.3*2**(A-1)*1e3},As=(A={})=>{if("number"==typeof A)return{...$t,limit:A};if(A.methods&&!Array.isArray(A.methods))throw new Error("retry.methods must be an array");if(A.statusCodes&&!Array.isArray(A.statusCodes))throw new Error("retry.statusCodes must be an array");return{...$t,...A}};class es{static create(A,e){const t=new es(A,e),s=async()=>{if("number"==typeof t._options.timeout&&t._options.timeout>Kt)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await Promise.resolve();let A=await t._fetch();for(const e of t._options.hooks.afterResponse){const s=await e(t.request,t._options,t._decorateResponse(A.clone()));s instanceof globalThis.Response&&(A=s)}if(t._decorateResponse(A),!A.ok&&t._options.throwHttpErrors){let e=new Rt(A,t.request,t._options);for(const A of t._options.hooks.beforeError)e=await A(e);throw e}if(t._options.onDownloadProgress){if("function"!=typeof t._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!Ft)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return((A,e)=>{const t=Number(A.headers.get("content-length"))||0;let s=0;return 204===A.status?(e&&e({percent:1,totalBytes:t,transferredBytes:s},new Uint8Array),new Response(null,{status:A.status,statusText:A.statusText,headers:A.headers})):new Response(new ReadableStream({async start(i){const r=A.body.getReader();e&&e({percent:0,transferredBytes:0,totalBytes:t},new Uint8Array),await async function A(){const{done:o,value:n}=await r.read();o?i.close():(e&&(s+=n.byteLength,e({percent:0===t?0:s/t,transferredBytes:s,totalBytes:t},n)),i.enqueue(n),await A())}()}}),{status:A.status,statusText:A.statusText,headers:A.headers})})(A.clone(),t._options.onDownloadProgress)}return A},i=(t._options.retry.methods.includes(t.request.method.toLowerCase())?t._retry(s):s()).finally(async()=>{t.request.bodyUsed||await(t.request.body?.cancel())});for(const[A,s]of Object.entries(xt))i[A]=async()=>{t.request.headers.set("accept",t.request.headers.get("accept")||s);const r=await i;if("json"===A){if(204===r.status)return"";if(0===(await r.clone().arrayBuffer()).byteLength)return"";if(e.parseJson)return e.parseJson(await r.text())}return r[A]()};return i}request;abortController;_retryCount=0;_input;_options;constructor(A,e={}){if(this._input=A,this._options={...e,headers:Wt(this._input.headers,e.headers),hooks:zt({beforeRequest:[],beforeRetry:[],beforeError:[],afterResponse:[]},e.hooks),method:_t(e.method??this._input.method??"GET"),prefixUrl:String(e.prefixUrl||""),retry:As(e.retry),throwHttpErrors:!1!==e.throwHttpErrors,timeout:e.timeout??1e4,fetch:e.fetch??globalThis.fetch.bind(globalThis)},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof globalThis.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(Gt&&Yt){const A=this._options.signal??this._input.signal;this.abortController=new globalThis.AbortController,this._options.signal=A?AbortSignal.any([A,this.abortController.signal]):this.abortController.signal}if(kt&&(this._options.duplex="half"),void 0!==this._options.json&&(this._options.body=this._options.stringifyJson?.(this._options.json)??JSON.stringify(this._options.json),this._options.headers.set("content-type",this._options.headers.get("content-type")??"application/json")),this.request=new globalThis.Request(this._input,this._options),this._options.searchParams){const A="?"+("string"==typeof this._options.searchParams?this._options.searchParams.replace(/^\?/,""):new URLSearchParams(this._options.searchParams).toString()),e=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,A);!(Zt&&this._options.body instanceof globalThis.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new globalThis.Request(new globalThis.Request(e,{...this.request}),this._options)}if(this._options.onUploadProgress){if("function"!=typeof this._options.onUploadProgress)throw new TypeError("The `onUploadProgress` option must be a function");if(!kt)throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");this.request.body&&(this.request=Ht(this.request,this._options.onUploadProgress))}}_calculateRetryDelay(A){if(this._retryCount++,this._retryCount>this._options.retry.limit||A instanceof Ut)throw A;if(A instanceof Rt){if(!this._options.retry.statusCodes.includes(A.response.status))throw A;const e=A.response.headers.get("Retry-After")??A.response.headers.get("RateLimit-Reset")??A.response.headers.get("X-RateLimit-Reset")??A.response.headers.get("X-Rate-Limit-Reset");if(e&&this._options.retry.afterStatusCodes.includes(A.response.status)){let A=1e3*Number(e);Number.isNaN(A)?A=Date.parse(e)-Date.now():A>=Date.parse("2024-01-01")&&(A-=Date.now());const t=this._options.retry.maxRetryAfter??A;return A<t?A:t}if(413===A.response.status)throw A}const e=this._options.retry.delay(this._retryCount);return Math.min(this._options.retry.backoffLimit,e)}_decorateResponse(A){return this._options.parseJson&&(A.json=async()=>this._options.parseJson(await A.text())),A}async _retry(A){try{return await A()}catch(e){const t=Math.min(this._calculateRetryDelay(e),Kt);if(this._retryCount<1)throw e;await async function(A,{signal:e}){return new Promise((t,s)=>{function i(){clearTimeout(r),s(e.reason)}e&&(e.throwIfAborted(),e.addEventListener("abort",i,{once:!0}));const r=setTimeout(()=>{e?.removeEventListener("abort",i),t()},A)})}(t,{signal:this._options.signal});for(const A of this._options.hooks.beforeRetry){if(await A({request:this.request,options:this._options,error:e,retryCount:this._retryCount})===Nt)return}return this._retry(A)}}async _fetch(){for(const A of this._options.hooks.beforeRequest){const e=await A(this.request,this._options);if(e instanceof Request){this.request=e;break}if(e instanceof Response)return e}const A=((A,e)=>{const t={};for(const s in e)s in Jt||s in bt||s in A||(t[s]=e[s]);return t})(this.request,this._options),e=this.request;return this.request=e.clone(),!1===this._options.timeout?this._options.fetch(e,A):async function(A,e,t,s){return new Promise((i,r)=>{const o=setTimeout(()=>{t&&t.abort(),r(new Ut(A))},s.timeout);s.fetch(A,e).then(i).catch(r).then(()=>{clearTimeout(o)})})}(e,A,this.abortController,this._options)}}
|
|
18
18
|
/*! MIT License © Sindre Sorhus */const ts=A=>{const e=(e,t)=>es.create(e,Lt(A,t));for(const t of vt)e[t]=(e,s)=>es.create(e,Lt(A,s,{method:t}));return e.create=A=>ts(Lt(A)),e.extend=e=>("function"==typeof e&&(e=e(A??{})),ts(Lt(A,e))),e.stop=Nt,e};var ss=ts(),is="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},rs={exports:{}};
|
|
19
19
|
/**
|
|
20
20
|
* [js-md5]{@link https://github.com/emn178/js-md5}
|
|
@@ -757,7 +757,7 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
|
|
|
757
757
|
`}
|
|
758
758
|
</div>
|
|
759
759
|
</my-modal-wrapper>
|
|
760
|
-
`;qt(s,this.modalRoot)}})}catch(A){Fs(A)}}getActionConfigs(){const
|
|
760
|
+
`;qt(s,this.modalRoot)}})}catch(A){Fs(A)}}getActionConfigs(){const A=Dt.get("actionConfigs");return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"},{render:this.renderConsultRetrieve,type:"consult_retrieve"},{render:this.renderConference,type:"conference"}].filter(({type:e})=>A.includes(e))}async render(){const{displayText:e}=Dt.getState(),{answer_devices:t}=yt.agentInfo,s=(t||"").split(","),i=this.getActionConfigs(),r={...mt},{statusColor:o}=r,n=document.querySelector("head");if(n){const A=Xe`
|
|
761
761
|
<style>
|
|
762
762
|
.ysyt-phone-body {
|
|
763
763
|
background: ${o[this.statusParams.state]};
|
|
@@ -873,4 +873,4 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
|
|
|
873
873
|
`:""}
|
|
874
874
|
</div>
|
|
875
875
|
</my-popover>
|
|
876
|
-
`;qt(s,this.rttHTML)}}const xs=new class{constructor(){this.events={}}on(A,e){this.events[A]=this.events[A]||[],this.events[A].push(e)}off(A,e){this.events[A]=(this.events[A]||[]).filter(A=>A!==e)}emit(A,...e){(this.events[A]||[]).forEach(A=>A(...e))}};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 console.log("已授权麦克风权限"),null;const e=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),e}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}}}let Os=null;class Ns{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Os){if(!A)throw new Error("WebSocket 尚未初始化");Os=new Ns(A)}return Os}stateIdleChange(){const{state:e}=yt.stateObject;e!==A.AgentStatus.IDLE&&this.apiClient._changeState({data:{state:A.AgentStatus.IDLE,state_name:"空闲"}})}putAgentState(){yt.sessionId="";const{post_call_process_time:A}=yt.agentInfo,e=A||0;yt.autoStateTimer&&(clearTimeout(yt.autoStateTimer),yt.autoStateTimer=null),e>0?yt.autoStateTimer=setTimeout(()=>{yt.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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:o}=t;if(0!==s&&console.warn(s),s===A.WebsocketTypeEnum.OUT_CALL&&(0!==r?(Dt.reset(),Ve.emit(A.CallSipCallEvent.OUT_FAILED,o),this.stateIdleChange()):0===r&&Ve.emit(A.CallSipCallEvent.OUT_SUCCESS)),s===A.WebsocketTypeEnum.AGENT_STATE){const{state:e,state_name:t}=i;yt.stateObject={state:e,state_name:t},"振铃中"===t&&Dt.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),yt.sessionId=i.session_id,Dt.updateActionConfigs(It)),s===A.WebsocketTypeEnum.OUT_CALL_END&&(1===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.OUT_HANGUP,i),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(Dt.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no!==yt.agentInfo.agent_no?(Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),Dt.updateActionConfigs(Mt)):3===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Dt.updateActionConfigs(Ct)):4===i.device_type&&i.agent_no===yt.agentInfo.agent_no&&(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),Dt.updateActionConfigs(Ct))),s===A.WebsocketTypeEnum.OUT_CALL_RINGING&&1===i.type&&(Ve.emit(A.CallSipCallEvent.OUT_RINGING,i),Dt.updateDisplayText(A.DisplayTextEnum.RINGING)),s===A.WebsocketTypeEnum.OUT_CALL_ANSWER&&(Ve.emit(A.CallSipCallEvent.OUT_OFF_ANSWER,i),Dt.updateOutCallIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(Mt)),s===A.WebsocketTypeEnum.CONSULT_RINGING&&(Ve.emit(A.CallSipCallEvent.CONSULT_RINGING),Dt.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),Dt.updateActionConfigs([])),s===A.WebsocketTypeEnum.CONSULT_ANSWER&&(Ve.emit(A.CallSipCallEvent.CONSULT_OFF_HOOK,i),Dt.updateConsultIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CONSULTING),Dt.updateActionConfigs(wt)),s===A.WebsocketTypeEnum.CONSULT_FAIL&&(Ve.emit(A.CallSipCallEvent.CONSULT_FAILED,{custom_reason:i.custom_reason}),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(Mt)),s===A.WebsocketTypeEnum.CONSULT_CALL_IN&&(Ve.emit(A.CallSipCallEvent.CONSULT_INCOMING,i),Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.CONSULT),Dt.updateDisplayText(A.DisplayTextEnum.CONSULT_CALL_IN),Dt.updateActionConfigs(Qt),yt.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===A.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(yt.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),Dt.updateConsultIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(ft)),s===A.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(Ve.emit(A.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),Dt.updateActionConfigs(Mt)),s===A.WebsocketTypeEnum.MUTE&&(0===r?(Dt.updateIsMuted(!0),Ve.emit(A.CallSipCallEvent.MUTE_SUCCESS),Dt.updateDisplayText(A.DisplayTextEnum.MUTING)):Ve.emit(A.CallSipCallEvent.MUTE_FAILED,o)),s===A.WebsocketTypeEnum.UNMUTE&&(0===r?(Dt.updateIsMuted(!1),Ve.emit(A.CallSipCallEvent.UNMUTE_SUCCESS),Dt.updateDisplayText(A.DisplayTextEnum.CALLING)):Ve.emit(A.CallSipCallEvent.UNMUTE_FAILED,o)),s===A.WebsocketTypeEnum.CALL_HOLD&&(0===r?(Dt.updateIsHold(!0),Dt.updateDisplayText(A.DisplayTextEnum.HOLDING),Ve.emit(A.CallSipCallEvent.HOLD_SUCCESS)):Ve.emit(A.CallSipCallEvent.HOLD_FAILED,o)),s===A.WebsocketTypeEnum.CALL_UNHOLD&&(0===r?(Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateIsHold(!1),Ve.emit(A.CallSipCallEvent.UNHOLD_SUCCESS)):Ve.emit(A.CallSipCallEvent.UNHOLD_FAILED,o)),s===A.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===r?Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,o)),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,i.status),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(Dt.updateDirection(A.DirectionEnum.INCOMING),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),Dt.updateActionConfigs(St),Dt.updateIncomingIsAnswer(!0),Dt.updateConsultIsAnswer(!1)),s===A.WebsocketTypeEnum.INCOMING_CALL&&(yt.sessionId=i.session_id,Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.INCOMING),Dt.updateDisplayText(A.DisplayTextEnum.INCOMING_CALL),Ve.emit(A.CallSipCallEvent.INCOMING_CALL,{customer_phone:i.customer_phone}),Dt.updateActionConfigs(Qt),yt.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===A.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(Dt.updateIncomingIsAnswer(!0),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),Dt.updateActionConfigs(St),Dt.updateDisplayText(A.DisplayTextEnum.CALLING)),s===A.WebsocketTypeEnum.INCOMING_CALL_END&&(1===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_END),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(Dt.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no!==yt.agentInfo.agent_no?(Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),Dt.updateActionConfigs(Mt)):3===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Dt.updateActionConfigs(Ct)):4===i.device_type&&i.agent_no===yt.agentInfo.agent_no&&(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),Dt.updateActionConfigs(Ct))),s===A.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===r?Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,o)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==r?Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,o):0===r&&Dt.updateIsMeeting(!0)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===i.status?(Dt.updateDirection(A.DirectionEnum.MEETING),Dt.updateDisplayText(A.DisplayTextEnum.MEETING),Dt.updateActionConfigs(Bt),Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:i.conf_name}),Dt.updateIsMeeting(!1))),s===A.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(i.agent_no===yt.agentInfo.agent_no?(Dt.updateDisplayText(A.DisplayTextEnum.TRANSFERRING),Ve.emit(A.CallSipCallEvent.TRANSFER_PROGRESS),Dt.updateActionConfigs([]),Dt.updateTransferIsAnswer(!0)):(Ve.emit(A.CallSipCallEvent.TRANSFER_INCOMING_CALL,i),Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.TRANSFER),Dt.updateDisplayText(A.DisplayTextEnum.TRANSFER_INCOMING_CALL),Dt.updateActionConfigs(Qt),yt.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${i.agent_no}] 正在转接...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_no})}))),s===A.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(yt.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.TRANSFER_OFF_HOOK),Dt.updateTransferIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(St)),s===A.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===i.status){Ve.emit(A.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const e=Dt.get("direction");e===A.DirectionEnum.OUTGOING?Dt.updateActionConfigs(Mt):e===A.DirectionEnum.INCOMING&&Dt.updateActionConfigs(St)}0!==s&&xs.emit("ws-message",t)},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?this.ws.send(JSON.stringify(A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Os&&(Os.close(),Os=null)}static __internalSend(A){if(!Os)throw new Error("WebSocket 尚未初始化");Os.sendMessage(A)}}class bs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=Dt.get("isCalling"),e=yt.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=Dt.get("isHold"),{sessionId:t}=yt;if(!t)return;if(!Dt.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CALL_HOLD,data:{session_id:t}})}unholdCall(){this.roleMute();const{isHold:e}=Dt.getState(),{sessionId:t}=yt;if(!Dt.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(t){if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:t}})}}sendDTMF(A){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Dt.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=Dt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Dt.get("actionConfigs").includes("reject"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用拒接"}));const{isCalling:e,direction:t,outCallIsAnswer:s}=Dt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));s||(t===A.DirectionEnum.INCOMING?this.rejectInCall():t===A.DirectionEnum.OUTGOING&&this.rejectOutCall())}async consultCall(e){this.roleMute();const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=Dt.getState(),o=yt.sessionId;if(!Dt.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(!o)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:o,consultation_agent_no:e}})}async answerCall(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=Dt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(e){if(Dt.getState().isCalling)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.OUTGOING),Ns.__internalSend({type:A.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:e}})}async rejectOutCall(){const{isCalling:A}=Dt.getState();if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectOutCall()}async hangup(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Dt.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.hangup()}mute(){this.roleMute();const e=Dt.get("actionConfigs"),t=Dt.get("isMuted"),s=yt.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!e.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:A.WebsocketTypeEnum.MUTE,data:{session_id:s}})}unmute(){this.roleMute();const e=Dt.get("actionConfigs"),t=Dt.get("isMuted"),s=yt.sessionId;if(!t)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!e.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:A.WebsocketTypeEnum.UNMUTE,data:{session_id:s}})}consultTransfer(){this.roleMute();const e=Dt.get("consultIsAnswer"),t=yt.sessionId;if(!Dt.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:t}})}satisfactionEvaluation(){this.roleMute();const e=yt.sessionId;if(!Dt.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Ns.__internalSend({type:A.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:e}})}startConference(){this.roleMute();if(!Dt.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const e=yt.sessionId;if(!Dt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:e}})}consultRetrieve(){this.roleMute();if(!Dt.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const e=yt.sessionId;if(!Dt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:e}})}async transferAgent(e){this.roleMute();if(!Dt.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:t}=Dt.getState(),s=yt.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:0,transfer_dest:e}})}async transferOutline(e){this.roleMute();if(!Dt.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}=Dt.getState(),s=yt.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:2,transfer_dest:e}})}}A.default=class{#A=null;#e=new Us;#t;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();ds.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=Dt.subscribeKey("answerDevice",A=>{1===A&&this.initWebRtc()})}async initWebRtc(){const A=yt.agentInfo.sip_account_list.find(A=>1===A.device_type);if(A){const e=A.sip_register_addr;this.#A=new us({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#n),await this.#A.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:o}){try{const{viewHtmlElement:n,rttHTML:a}=e||{},V=t||"https://aicc.yescloudy.com";cs=V,hs=s,ls=i;const c=ns(s,i);await this.#e._agentLogin(r);const{agent_no:h,current_answer_device:l,init_state:g}=yt.agentInfo;g===A.AgentStatus.IDLE?(Dt.updateActionConfigs(Ct),yt.stateObject={state:g,state_name:"空闲"}):g===A.AgentStatus.BUSY&&(Dt.updateActionConfigs(Et),yt.stateObject={state:g,state_name:"忙碌"});let q="";const d=new URL(V).host;q=V.includes("https")?`wss://${d}`:`ws://${d}`,Ns.getInstance(`${q}/ccs-ws/api/v1/ws/call/${h}?Authorization=${c}`),Dt.updateAnswerDevice(l),1===l&&await this.initWebRtc(),this.#t=new bs(this.#A),e&&n&&(this.#i=!0,new vs({container:n,rttHTML:a,statusParams:{state:A.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),yt.enableBrowserAlert=o,o&&Ks.requestPermission()}catch(A){this.#i&&Fs("初始化失败"),console.log(A)}}#n=A=>{const{type:e,data:t}=A;Ve.emit(e,t)};#a=A=>{};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())}destroy(){this.destroyRtc(),clearInterval(this.#s),xs.off("ws-message",this.#a),Ns.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#e=null,this.#i=!1}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(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))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,init_state:s,default_device:i}=yt.agentInfo,{stateObject:r}=yt,o={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:s,default_device:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:o[Number(A)]})),stateObject:r}}},Object.defineProperty(A,"__esModule",{value:!0})});
|
|
876
|
+
`;qt(s,this.rttHTML)}}const xs=new class{constructor(){this.events={}}on(A,e){this.events[A]=this.events[A]||[],this.events[A].push(e)}off(A,e){this.events[A]=(this.events[A]||[]).filter(A=>A!==e)}emit(A,...e){(this.events[A]||[]).forEach(A=>A(...e))}};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 console.log("已授权麦克风权限"),null;const e=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),e}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}}}let Os=null;class Ns{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Os){if(!A)throw new Error("WebSocket 尚未初始化");Os=new Ns(A)}return Os}stateIdleChange(){const{state:e}=yt.stateObject;e!==A.AgentStatus.IDLE&&this.apiClient._changeState({data:{state:A.AgentStatus.IDLE,state_name:"空闲"}})}putAgentState(){yt.sessionId="";const{post_call_process_time:A}=yt.agentInfo,e=A||0;yt.autoStateTimer&&(clearTimeout(yt.autoStateTimer),yt.autoStateTimer=null),e>0?yt.autoStateTimer=setTimeout(()=>{yt.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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:o}=t;if(0!==s&&console.warn(s),s===A.WebsocketTypeEnum.OUT_CALL&&(0!==r?(Dt.reset(),Ve.emit(A.CallSipCallEvent.OUT_FAILED,o),this.stateIdleChange()):0===r&&Ve.emit(A.CallSipCallEvent.OUT_SUCCESS)),s===A.WebsocketTypeEnum.AGENT_STATE){const{state:e,state_name:t}=i;yt.stateObject={state:e,state_name:t},"振铃中"===t&&Dt.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),yt.sessionId=i.session_id,Dt.updateActionConfigs(It)),s===A.WebsocketTypeEnum.OUT_CALL_END&&(Dt.updateDisplayText(""),1===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.OUT_HANGUP,i),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(Dt.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no!==yt.agentInfo.agent_no?(Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),Dt.updateActionConfigs(Mt)):3===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Dt.updateActionConfigs(Ct)):4===i.device_type&&i.agent_no===yt.agentInfo.agent_no&&(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),Dt.updateActionConfigs(Ct))),s===A.WebsocketTypeEnum.OUT_CALL_RINGING&&1===i.type&&(Ve.emit(A.CallSipCallEvent.OUT_RINGING,i),Dt.updateDisplayText(A.DisplayTextEnum.RINGING)),s===A.WebsocketTypeEnum.OUT_CALL_ANSWER&&(Ve.emit(A.CallSipCallEvent.OUT_OFF_ANSWER,i),Dt.updateOutCallIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(Mt)),s===A.WebsocketTypeEnum.CONSULT_RINGING&&(Ve.emit(A.CallSipCallEvent.CONSULT_RINGING),Dt.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),Dt.updateActionConfigs([])),s===A.WebsocketTypeEnum.CONSULT_ANSWER&&(Ve.emit(A.CallSipCallEvent.CONSULT_OFF_HOOK,i),Dt.updateConsultIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CONSULTING),Dt.updateActionConfigs(wt)),s===A.WebsocketTypeEnum.CONSULT_FAIL&&(Ve.emit(A.CallSipCallEvent.CONSULT_FAILED,{custom_reason:i.custom_reason}),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(Mt)),s===A.WebsocketTypeEnum.CONSULT_CALL_IN&&(Ve.emit(A.CallSipCallEvent.CONSULT_INCOMING,i),Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.CONSULT),Dt.updateDisplayText(A.DisplayTextEnum.CONSULT_CALL_IN),Dt.updateActionConfigs(Qt),yt.enableBrowserAlert&&Ks.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===A.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(yt.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),Dt.updateConsultIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(ft)),s===A.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(Ve.emit(A.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),Dt.updateActionConfigs(Mt)),s===A.WebsocketTypeEnum.MUTE&&(0===r?(Dt.updateIsMuted(!0),Ve.emit(A.CallSipCallEvent.MUTE_SUCCESS),Dt.updateDisplayText(A.DisplayTextEnum.MUTING)):Ve.emit(A.CallSipCallEvent.MUTE_FAILED,o)),s===A.WebsocketTypeEnum.UNMUTE&&(0===r?(Dt.updateIsMuted(!1),Ve.emit(A.CallSipCallEvent.UNMUTE_SUCCESS),Dt.updateDisplayText(A.DisplayTextEnum.CALLING)):Ve.emit(A.CallSipCallEvent.UNMUTE_FAILED,o)),s===A.WebsocketTypeEnum.CALL_HOLD&&(0===r?(Dt.updateIsHold(!0),Dt.updateDisplayText(A.DisplayTextEnum.HOLDING),Ve.emit(A.CallSipCallEvent.HOLD_SUCCESS)):Ve.emit(A.CallSipCallEvent.HOLD_FAILED,o)),s===A.WebsocketTypeEnum.CALL_UNHOLD&&(0===r?(Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateIsHold(!1),Ve.emit(A.CallSipCallEvent.UNHOLD_SUCCESS)):Ve.emit(A.CallSipCallEvent.UNHOLD_FAILED,o)),s===A.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===r?Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,o)),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,i.status),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(Dt.updateDirection(A.DirectionEnum.INCOMING),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),Dt.updateActionConfigs(St),Dt.updateIncomingIsAnswer(!0),Dt.updateConsultIsAnswer(!1)),s===A.WebsocketTypeEnum.INCOMING_CALL&&(yt.sessionId=i.session_id,Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.INCOMING),Dt.updateDisplayText(A.DisplayTextEnum.INCOMING_CALL),Ve.emit(A.CallSipCallEvent.INCOMING_CALL,{customer_phone:i.customer_phone}),Dt.updateActionConfigs(Qt),yt.enableBrowserAlert&&Ks.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===A.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(Dt.updateIncomingIsAnswer(!0),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),Dt.updateActionConfigs(St),Dt.updateDisplayText(A.DisplayTextEnum.CALLING)),s===A.WebsocketTypeEnum.INCOMING_CALL_END&&(Dt.updateDisplayText(""),1===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_END),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(Dt.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),Dt.updateActionConfigs(Ct)):2===i.device_type&&i.agent_no!==yt.agentInfo.agent_no?(Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),Dt.updateActionConfigs(Mt)):3===i.device_type&&i.agent_no===yt.agentInfo.agent_no?(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),Dt.updateActionConfigs(Ct)):4===i.device_type&&i.agent_no===yt.agentInfo.agent_no&&(this.putAgentState(),Dt.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),Dt.updateActionConfigs(Ct))),s===A.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===r?Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,o)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==r?Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,o):0===r&&Dt.updateIsMeeting(!0)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===i.status?(Dt.updateDirection(A.DirectionEnum.MEETING),Dt.updateDisplayText(A.DisplayTextEnum.MEETING),Dt.updateActionConfigs(Bt),Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:i.conf_name}),Dt.updateIsMeeting(!1))),s===A.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(i.agent_no===yt.agentInfo.agent_no?(Dt.updateDisplayText(A.DisplayTextEnum.TRANSFERRING),Ve.emit(A.CallSipCallEvent.TRANSFER_PROGRESS),Dt.updateActionConfigs([]),Dt.updateTransferIsAnswer(!0)):(Ve.emit(A.CallSipCallEvent.TRANSFER_INCOMING_CALL,i),Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.TRANSFER),Dt.updateDisplayText(A.DisplayTextEnum.TRANSFER_INCOMING_CALL),Dt.updateActionConfigs(Qt),yt.enableBrowserAlert&&Ks.show("📞 转接来电",`坐席 [${i.agent_no}] 正在转接...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_no})}))),s===A.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(yt.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.TRANSFER_OFF_HOOK),Dt.updateTransferIsAnswer(!0),Dt.updateDisplayText(A.DisplayTextEnum.CALLING),Dt.updateActionConfigs(St)),s===A.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===i.status){Ve.emit(A.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const e=Dt.get("direction");e===A.DirectionEnum.OUTGOING?Dt.updateActionConfigs(Mt):e===A.DirectionEnum.INCOMING&&Dt.updateActionConfigs(St)}0!==s&&xs.emit("ws-message",t)},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?this.ws.send(JSON.stringify(A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Os&&(Os.close(),Os=null)}static __internalSend(A){if(!Os)throw new Error("WebSocket 尚未初始化");Os.sendMessage(A)}}class bs{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=Dt.get("isCalling"),e=yt.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=Dt.get("isHold"),{sessionId:t}=yt;if(!t)return;if(!Dt.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CALL_HOLD,data:{session_id:t}})}unholdCall(){this.roleMute();const{isHold:e}=Dt.getState(),{sessionId:t}=yt;if(!Dt.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(t){if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:t}})}}sendDTMF(A){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Dt.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=Dt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Dt.get("actionConfigs").includes("reject"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用拒接"}));const{isCalling:e,direction:t,outCallIsAnswer:s}=Dt.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));s||(t===A.DirectionEnum.INCOMING?this.rejectInCall():t===A.DirectionEnum.OUTGOING&&this.rejectOutCall())}async consultCall(e){this.roleMute();const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=Dt.getState(),o=yt.sessionId;if(!Dt.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(!o)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:o,consultation_agent_no:e}})}async answerCall(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=Dt.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(e){if(Dt.getState().isCalling)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));Dt.updateIsCalling(!0),Dt.updateDirection(A.DirectionEnum.OUTGOING),Ns.__internalSend({type:A.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:e}})}async rejectOutCall(){const{isCalling:A}=Dt.getState();if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectOutCall()}async hangup(){if(1!==Dt.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!Dt.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.hangup()}mute(){this.roleMute();const e=Dt.get("actionConfigs"),t=Dt.get("isMuted"),s=yt.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!e.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:A.WebsocketTypeEnum.MUTE,data:{session_id:s}})}unmute(){this.roleMute();const e=Dt.get("actionConfigs"),t=Dt.get("isMuted"),s=yt.sessionId;if(!t)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!e.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));Ns.__internalSend({type:A.WebsocketTypeEnum.UNMUTE,data:{session_id:s}})}consultTransfer(){this.roleMute();const e=Dt.get("consultIsAnswer"),t=yt.sessionId;if(!Dt.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:t}})}satisfactionEvaluation(){this.roleMute();const e=yt.sessionId;if(!Dt.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));Ns.__internalSend({type:A.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:e}})}startConference(){this.roleMute();if(!Dt.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const e=yt.sessionId;if(!Dt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:e}})}consultRetrieve(){this.roleMute();if(!Dt.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const e=yt.sessionId;if(!Dt.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));Ns.__internalSend({type:A.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:e}})}async transferAgent(e){this.roleMute();if(!Dt.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:t}=Dt.getState(),s=yt.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:0,transfer_dest:e}})}async transferOutline(e){this.roleMute();if(!Dt.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}=Dt.getState(),s=yt.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));Ns.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:2,transfer_dest:e}})}}A.default=class{#A=null;#e=new Us;#t;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();ds.updateRttObject(A)},2e3),Ks.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=Dt.subscribeKey("answerDevice",A=>{1===A&&this.initWebRtc()})}async initWebRtc(){const A=yt.agentInfo.sip_account_list.find(A=>1===A.device_type);if(A){const e=A.sip_register_addr;this.#A=new us({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#n),await this.#A.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:o}){try{const{viewHtmlElement:n,rttHTML:a}=e||{},V=t||"https://aicc.yescloudy.com";cs=V,hs=s,ls=i;const c=ns(s,i);await this.#e._agentLogin(r);const{agent_no:h,current_answer_device:l,init_state:g}=yt.agentInfo;g===A.AgentStatus.IDLE?(Dt.updateActionConfigs(Ct),yt.stateObject={state:g,state_name:"空闲"}):g===A.AgentStatus.BUSY&&(Dt.updateActionConfigs(Et),yt.stateObject={state:g,state_name:"忙碌"});let q="";const d=new URL(V).host;q=V.includes("https")?`wss://${d}`:`ws://${d}`,Ns.getInstance(`${q}/ccs-ws/api/v1/ws/call/${h}?Authorization=${c}`),Dt.updateAnswerDevice(l),1===l&&await this.initWebRtc(),this.#t=new bs(this.#A),e&&n&&(this.#i=!0,new vs({container:n,rttHTML:a,statusParams:{state:A.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),yt.enableBrowserAlert=o,o&&Ks.requestPermission()}catch(A){this.#i&&Fs("初始化失败"),console.log(A)}}#n=A=>{const{type:e,data:t}=A;Ve.emit(e,t)};#a=A=>{};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())}destroy(){this.destroyRtc(),clearInterval(this.#s),xs.off("ws-message",this.#a),Ns.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#e=null,this.#i=!1}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(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))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,init_state:s,default_device:i}=yt.agentInfo,{stateObject:r}=yt,o={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:s,default_device:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:o[Number(A)]})),stateObject:r}}},Object.defineProperty(A,"__esModule",{value:!0})});
|