@webex/contact-center 3.12.0-llmrefactor.8 → 3.12.0-llmrefactor.9
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.
- package/.sdd/manifest.json +3 -2
- package/ai-docs/CONTRACTS.md +2 -1
- package/dist/cc.js +108 -6
- package/dist/cc.js.map +1 -1
- package/dist/metrics/MetricsManager.js +16 -0
- package/dist/metrics/MetricsManager.js.map +1 -1
- package/dist/metrics/behavioral-events.js +91 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +16 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AnswerCallOnWebexService.js +34 -6
- package/dist/services/AnswerCallOnWebexService.js.map +1 -1
- package/dist/services/WebexCrossClientService.js +54 -3
- package/dist/services/WebexCrossClientService.js.map +1 -1
- package/dist/services/WxAppTelephonyMercurySync.js +21 -6
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -1
- package/dist/services/task/voice/Voice.js +81 -14
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js +154 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -1
- package/dist/services/wxAppDiagnosticLogging.js +122 -0
- package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
- package/dist/types/cc.d.ts +1 -0
- package/dist/types/metrics/MetricsManager.d.ts +6 -0
- package/dist/types/metrics/constants.d.ts +15 -0
- package/dist/types/services/AnswerCallOnWebexService.d.ts +1 -0
- package/dist/types/services/WebexCrossClientService.d.ts +4 -0
- package/dist/types/services/task/voice/Voice.d.ts +5 -1
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +3 -0
- package/dist/types/services/wxAppDiagnosticLogging.d.ts +51 -0
- package/dist/webex.js +1 -1
- package/package.json +8 -8
- package/src/cc.ts +155 -7
- package/src/metrics/MetricsManager.ts +16 -0
- package/src/metrics/ai-docs/metrics-spec.md +71 -9
- package/src/metrics/behavioral-events.ts +92 -0
- package/src/metrics/constants.ts +18 -0
- package/src/services/AnswerCallOnWebexService.ts +41 -8
- package/src/services/WebexCrossClientService.ts +85 -4
- package/src/services/WxAppTelephonyMercurySync.ts +31 -4
- package/src/services/agent/ai-docs/agent-spec.md +1 -0
- package/src/services/task/ai-docs/task-spec.md +2 -0
- package/src/services/task/voice/Voice.ts +115 -26
- package/src/services/task/voice/wxAppVoiceMethods.ts +211 -2
- package/src/services/wxAppDiagnosticLogging.ts +174 -0
- package/test/unit/spec/cc.ts +251 -22
- package/test/unit/spec/metrics/MetricsManager.ts +25 -0
- package/test/unit/spec/metrics/behavioral-events.ts +42 -0
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +41 -0
- package/test/unit/spec/services/WebexCrossClientService.ts +207 -1
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +23 -0
- package/test/unit/spec/services/task/voice/Voice.ts +380 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +145 -1
- package/test/unit/spec/services/wxAppDiagnosticLogging.ts +143 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","_types","_Utils","_wxAppTelephonyUtils","e","__esModule","default","ANSWER_CALL_ON_WEBEX_FILE","markWxAppTelephonyError","error","source","marked","isWxAppTelephonyError","sourceObj","trackingId","details","status","statusCode","undefined","AnswerCallOnWebexService","constructor","webex","getTelephonyBaseUrl","services","internal","hydraUrl","_serviceUrls","hydra","get","Error","replace","telephonyRequest","resource","method","body","logMethod","uri","LoggerProxy","info","module","data","bodyKeys","Object","keys","request","addAuthHeader","detailedError","getErrorDetails","CC_FILE","answerCall","params","callId","endpointId","lineOwnerId","HTTP_METHODS","POST","METHODS","ACCEPT","rejectCall","REJECT","muteCall","TOGGLE_MUTE","unmuteCall","transmitDtmf","dtmf","TRANSMIT_DTMF","getCallDetails","lineOwnerIdQuery","encodeURIComponent","GET_CALL_DETAILS_ON_WEBEX","response","GET","isWxAppCallNotFoundError","err","String","message","exports"],"sources":["AnswerCallOnWebexService.ts"],"sourcesContent":["import LoggerProxy from '../logger-proxy';\nimport {CC_FILE, METHODS} from '../constants';\nimport {HTTP_METHODS, IHttpResponse, WebexSDK} from '../types';\nimport {getErrorDetails} from './core/Utils';\nimport {isWxAppCallNotFoundError} from './wxAppTelephonyUtils';\n\nconst ANSWER_CALL_ON_WEBEX_FILE = 'AnswerCallOnWebexService';\n\nexport type WxAppTelephonyError = Error & {\n isWxAppTelephonyError: true;\n trackingId?: string;\n status?: number | string;\n};\n\nconst markWxAppTelephonyError = (error: Error, source: unknown): WxAppTelephonyError => {\n const marked = error as WxAppTelephonyError;\n marked.isWxAppTelephonyError = true;\n const sourceObj = source as {\n details?: {trackingId?: string; status?: number | string};\n statusCode?: number;\n status?: number | string;\n };\n const trackingId = sourceObj?.details?.trackingId;\n if (trackingId) {\n marked.trackingId = trackingId;\n }\n const status = sourceObj?.statusCode ?? sourceObj?.details?.status ?? sourceObj?.status;\n if (status !== undefined) {\n marked.status = status;\n }\n\n return marked;\n};\n\nexport type AnswerCallParams = {\n callId: string;\n endpointId: string;\n lineOwnerId?: string;\n};\n\nexport type CallIdParams = {\n callId: string;\n lineOwnerId?: string;\n};\n\nexport type TransmitDtmfParams = CallIdParams & {\n dtmf: string;\n};\n\nexport type CallDetailsResponse = {\n muted?: boolean;\n};\n\n/**\n * REST telephony client for wxApp thick-client answer (WXCC-6026).\n * Separate from WebCallingService (WebRTC/Mobius).\n */\nexport default class AnswerCallOnWebexService {\n private webex: WebexSDK;\n\n constructor(webex: WebexSDK) {\n this.webex = webex;\n }\n\n private getTelephonyBaseUrl(): string {\n const services = this.webex.internal.services;\n const hydraUrl = services._serviceUrls?.hydra || services.get('hydra');\n\n if (!hydraUrl) {\n throw new Error('Telephony base URL is unavailable');\n }\n\n return `${hydraUrl.replace(/\\/$/, '')}/telephony/calls`;\n }\n\n private async telephonyRequest(\n resource: string,\n method: HTTP_METHODS,\n body: Record<string, unknown>,\n logMethod: string\n ): Promise<IHttpResponse> {\n try {\n const uri = `${this.getTelephonyBaseUrl()}${resource}`;\n\n LoggerProxy.info(`AnswerCallOnWebexService.${logMethod} request`, {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: logMethod,\n data: {uri, bodyKeys: Object.keys(body)},\n });\n\n return (await this.webex.request({\n uri,\n method,\n body,\n addAuthHeader: true,\n })) as IHttpResponse;\n } catch (error) {\n LoggerProxy.error(`AnswerCallOnWebexService.${logMethod} failed: ${error}`, {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: logMethod,\n });\n const {error: detailedError} = getErrorDetails(error, logMethod, CC_FILE);\n throw markWxAppTelephonyError(detailedError, error);\n }\n }\n\n public answerCall(params: AnswerCallParams): Promise<IHttpResponse> {\n const {callId, endpointId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/answer',\n HTTP_METHODS.POST,\n {\n callId,\n endpointId,\n ...(lineOwnerId ? {lineOwnerId} : {}),\n },\n METHODS.ACCEPT\n );\n }\n\n public rejectCall(params: CallIdParams): Promise<IHttpResponse> {\n const {callId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/reject',\n HTTP_METHODS.POST,\n {callId, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.REJECT\n );\n }\n\n public muteCall(params: CallIdParams): Promise<IHttpResponse> {\n const {callId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/mute',\n HTTP_METHODS.POST,\n {callId, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.TOGGLE_MUTE\n );\n }\n\n public unmuteCall(params: CallIdParams): Promise<IHttpResponse> {\n const {callId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/unmute',\n HTTP_METHODS.POST,\n {callId, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.TOGGLE_MUTE\n );\n }\n\n public transmitDtmf(params: TransmitDtmfParams): Promise<IHttpResponse> {\n const {callId, dtmf, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/transmitDtmf',\n HTTP_METHODS.POST,\n {callId, dtmf, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.TRANSMIT_DTMF\n );\n }\n\n public async getCallDetails(params: CallIdParams): Promise<CallDetailsResponse> {\n const {callId, lineOwnerId} = params;\n const lineOwnerIdQuery = lineOwnerId ? `?lineOwnerId=${encodeURIComponent(lineOwnerId)}` : '';\n const uri = `${this.getTelephonyBaseUrl()}/${callId}${lineOwnerIdQuery}`;\n\n try {\n LoggerProxy.info('AnswerCallOnWebexService.getCallDetails request', {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: METHODS.GET_CALL_DETAILS_ON_WEBEX,\n data: {callId},\n });\n\n const response = (await this.webex.request({\n uri,\n method: HTTP_METHODS.GET,\n addAuthHeader: true,\n })) as IHttpResponse;\n\n return (response.body ?? {}) as CallDetailsResponse;\n } catch (error) {\n if (isWxAppCallNotFoundError(error)) {\n const err =\n error instanceof Error\n ? error\n : new Error(String((error as {message?: string})?.message ?? error));\n throw markWxAppTelephonyError(err, error);\n }\n\n LoggerProxy.error(`AnswerCallOnWebexService.getCallDetails failed: ${error}`, {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: METHODS.GET_CALL_DETAILS_ON_WEBEX,\n });\n const {error: detailedError} = getErrorDetails(\n error,\n METHODS.GET_CALL_DETAILS_ON_WEBEX,\n CC_FILE\n );\n throw markWxAppTelephonyError(detailedError, error);\n }\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AACA,IAAAI,oBAAA,GAAAJ,OAAA;AAA+D,SAAAD,uBAAAM,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE/D,MAAMG,yBAAyB,GAAG,0BAA0B;AAQ5D,MAAMC,uBAAuB,GAAGA,CAACC,KAAY,EAAEC,MAAe,KAA0B;EACtF,MAAMC,MAAM,GAAGF,KAA4B;EAC3CE,MAAM,CAACC,qBAAqB,GAAG,IAAI;EACnC,MAAMC,SAAS,GAAGH,MAIjB;EACD,MAAMI,UAAU,GAAGD,SAAS,EAAEE,OAAO,EAAED,UAAU;EACjD,IAAIA,UAAU,EAAE;IACdH,MAAM,CAACG,UAAU,GAAGA,UAAU;EAChC;EACA,MAAME,MAAM,GAAGH,SAAS,EAAEI,UAAU,IAAIJ,SAAS,EAAEE,OAAO,EAAEC,MAAM,IAAIH,SAAS,EAAEG,MAAM;EACvF,IAAIA,MAAM,KAAKE,SAAS,EAAE;IACxBP,MAAM,CAACK,MAAM,GAAGA,MAAM;EACxB;EAEA,OAAOL,MAAM;AACf,CAAC;AAqBD;AACA;AACA;AACA;AACe,MAAMQ,wBAAwB,CAAC;EAG5CC,WAAWA,CAACC,KAAe,EAAE;IAC3B,IAAI,CAACA,KAAK,GAAGA,KAAK;EACpB;EAEQC,mBAAmBA,CAAA,EAAW;IACpC,MAAMC,QAAQ,GAAG,IAAI,CAACF,KAAK,CAACG,QAAQ,CAACD,QAAQ;IAC7C,MAAME,QAAQ,GAAGF,QAAQ,CAACG,YAAY,EAAEC,KAAK,IAAIJ,QAAQ,CAACK,GAAG,CAAC,OAAO,CAAC;IAEtE,IAAI,CAACH,QAAQ,EAAE;MACb,MAAM,IAAII,KAAK,CAAC,mCAAmC,CAAC;IACtD;IAEA,OAAO,GAAGJ,QAAQ,CAACK,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB;EACzD;EAEA,MAAcC,gBAAgBA,CAC5BC,QAAgB,EAChBC,MAAoB,EACpBC,IAA6B,EAC7BC,SAAiB,EACO;IACxB,IAAI;MACF,MAAMC,GAAG,GAAG,GAAG,IAAI,CAACd,mBAAmB,CAAC,CAAC,GAAGU,QAAQ,EAAE;MAEtDK,oBAAW,CAACC,IAAI,CAAC,4BAA4BH,SAAS,UAAU,EAAE;QAChEI,MAAM,EAAEhC,yBAAyB;QACjC0B,MAAM,EAAEE,SAAS;QACjBK,IAAI,EAAE;UAACJ,GAAG;UAAEK,QAAQ,EAAEC,MAAM,CAACC,IAAI,CAACT,IAAI;QAAC;MACzC,CAAC,CAAC;MAEF,OAAQ,MAAM,IAAI,CAACb,KAAK,CAACuB,OAAO,CAAC;QAC/BR,GAAG;QACHH,MAAM;QACNC,IAAI;QACJW,aAAa,EAAE;MACjB,CAAC,CAAC;IACJ,CAAC,CAAC,OAAOpC,KAAK,EAAE;MACd4B,oBAAW,CAAC5B,KAAK,CAAC,4BAA4B0B,SAAS,YAAY1B,KAAK,EAAE,EAAE;QAC1E8B,MAAM,EAAEhC,yBAAyB;QACjC0B,MAAM,EAAEE;MACV,CAAC,CAAC;MACF,MAAM;QAAC1B,KAAK,EAAEqC;MAAa,CAAC,GAAG,IAAAC,sBAAe,EAACtC,KAAK,EAAE0B,SAAS,EAAEa,kBAAO,CAAC;MACzE,MAAMxC,uBAAuB,CAACsC,aAAa,EAAErC,KAAK,CAAC;IACrD;EACF;EAEOwC,UAAUA,CAACC,MAAwB,EAA0B;IAClE,MAAM;MAACC,MAAM;MAAEC,UAAU;MAAEC;IAAW,CAAC,GAAGH,MAAM;IAEhD,OAAO,IAAI,CAACnB,gBAAgB,CAC1B,SAAS,EACTuB,mBAAY,CAACC,IAAI,EACjB;MACEJ,MAAM;MACNC,UAAU;MACV,IAAIC,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC,EACDG,kBAAO,CAACC,MACV,CAAC;EACH;EAEOC,UAAUA,CAACR,MAAoB,EAA0B;IAC9D,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IAEpC,OAAO,IAAI,CAACnB,gBAAgB,CAC1B,SAAS,EACTuB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAE,IAAIE,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EAC/CG,kBAAO,CAACG,MACV,CAAC;EACH;EAEOC,QAAQA,CAACV,MAAoB,EAA0B;IAC5D,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IAEpC,OAAO,IAAI,CAACnB,gBAAgB,CAC1B,OAAO,EACPuB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAE,IAAIE,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EAC/CG,kBAAO,CAACK,WACV,CAAC;EACH;EAEOC,UAAUA,CAACZ,MAAoB,EAA0B;IAC9D,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IAEpC,OAAO,IAAI,CAACnB,gBAAgB,CAC1B,SAAS,EACTuB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAE,IAAIE,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EAC/CG,kBAAO,CAACK,WACV,CAAC;EACH;EAEOE,YAAYA,CAACb,MAA0B,EAA0B;IACtE,MAAM;MAACC,MAAM;MAAEa,IAAI;MAAEX;IAAW,CAAC,GAAGH,MAAM;IAE1C,OAAO,IAAI,CAACnB,gBAAgB,CAC1B,eAAe,EACfuB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAEa,IAAI;MAAE,IAAIX,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EACrDG,kBAAO,CAACS,aACV,CAAC;EACH;EAEA,MAAaC,cAAcA,CAAChB,MAAoB,EAAgC;IAC9E,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IACpC,MAAMiB,gBAAgB,GAAGd,WAAW,GAAG,gBAAgBe,kBAAkB,CAACf,WAAW,CAAC,EAAE,GAAG,EAAE;IAC7F,MAAMjB,GAAG,GAAG,GAAG,IAAI,CAACd,mBAAmB,CAAC,CAAC,IAAI6B,MAAM,GAAGgB,gBAAgB,EAAE;IAExE,IAAI;MACF9B,oBAAW,CAACC,IAAI,CAAC,iDAAiD,EAAE;QAClEC,MAAM,EAAEhC,yBAAyB;QACjC0B,MAAM,EAAEuB,kBAAO,CAACa,yBAAyB;QACzC7B,IAAI,EAAE;UAACW;QAAM;MACf,CAAC,CAAC;MAEF,MAAMmB,QAAQ,GAAI,MAAM,IAAI,CAACjD,KAAK,CAACuB,OAAO,CAAC;QACzCR,GAAG;QACHH,MAAM,EAAEqB,mBAAY,CAACiB,GAAG;QACxB1B,aAAa,EAAE;MACjB,CAAC,CAAmB;MAEpB,OAAQyB,QAAQ,CAACpC,IAAI,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,OAAOzB,KAAK,EAAE;MACd,IAAI,IAAA+D,6CAAwB,EAAC/D,KAAK,CAAC,EAAE;QACnC,MAAMgE,GAAG,GACPhE,KAAK,YAAYoB,KAAK,GAClBpB,KAAK,GACL,IAAIoB,KAAK,CAAC6C,MAAM,CAAEjE,KAAK,EAAyBkE,OAAO,IAAIlE,KAAK,CAAC,CAAC;QACxE,MAAMD,uBAAuB,CAACiE,GAAG,EAAEhE,KAAK,CAAC;MAC3C;MAEA4B,oBAAW,CAAC5B,KAAK,CAAC,mDAAmDA,KAAK,EAAE,EAAE;QAC5E8B,MAAM,EAAEhC,yBAAyB;QACjC0B,MAAM,EAAEuB,kBAAO,CAACa;MAClB,CAAC,CAAC;MACF,MAAM;QAAC5D,KAAK,EAAEqC;MAAa,CAAC,GAAG,IAAAC,sBAAe,EAC5CtC,KAAK,EACL+C,kBAAO,CAACa,yBAAyB,EACjCrB,kBACF,CAAC;MACD,MAAMxC,uBAAuB,CAACsC,aAAa,EAAErC,KAAK,CAAC;IACrD;EACF;AACF;AAACmE,OAAA,CAAAtE,OAAA,GAAAa,wBAAA","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","_types","_Utils","_wxAppTelephonyUtils","e","__esModule","default","ANSWER_CALL_ON_WEBEX_FILE","extractWxAppTrackingId","source","sourceObj","details","trackingId","extractWxAppHttpStatus","obj","statusCode","status","markWxAppTelephonyError","error","marked","isWxAppTelephonyError","undefined","AnswerCallOnWebexService","constructor","webex","getTelephonyBaseUrl","services","internal","hydraUrl","_serviceUrls","hydra","get","Error","replace","extractTrackingId","telephonyRequest","resource","method","body","logMethod","uri","LoggerProxy","info","module","data","bodyKeys","Object","keys","response","request","addAuthHeader","detailedError","getErrorDetails","CC_FILE","answerCall","params","callId","endpointId","lineOwnerId","HTTP_METHODS","POST","METHODS","ACCEPT","rejectCall","REJECT","muteCall","TOGGLE_MUTE","unmuteCall","transmitDtmf","dtmf","TRANSMIT_DTMF","getCallDetails","lineOwnerIdQuery","encodeURIComponent","GET_CALL_DETAILS_ON_WEBEX","GET","isWxAppCallNotFoundError","err","String","message","exports"],"sources":["AnswerCallOnWebexService.ts"],"sourcesContent":["import LoggerProxy from '../logger-proxy';\nimport {CC_FILE, METHODS} from '../constants';\nimport {HTTP_METHODS, IHttpResponse, WebexSDK} from '../types';\nimport {getErrorDetails} from './core/Utils';\nimport {isWxAppCallNotFoundError} from './wxAppTelephonyUtils';\n\nconst ANSWER_CALL_ON_WEBEX_FILE = 'AnswerCallOnWebexService';\n\nexport type WxAppTelephonyError = Error & {\n isWxAppTelephonyError: true;\n trackingId?: string;\n status?: number | string;\n};\n\nconst extractWxAppTrackingId = (source: unknown): string | undefined => {\n const sourceObj = source as {details?: {trackingId?: string}; trackingId?: string};\n\n return sourceObj?.details?.trackingId || sourceObj?.trackingId;\n};\n\nconst extractWxAppHttpStatus = (source: unknown): number | string | undefined => {\n const obj = source as {\n statusCode?: number;\n status?: number | string;\n details?: {status?: number | string};\n };\n\n return obj?.statusCode ?? obj?.status ?? obj?.details?.status;\n};\n\nconst markWxAppTelephonyError = (error: Error, source: unknown): WxAppTelephonyError => {\n const marked = error as WxAppTelephonyError;\n marked.isWxAppTelephonyError = true;\n const trackingId = extractWxAppTrackingId(source);\n if (trackingId) {\n marked.trackingId = trackingId;\n }\n const status = extractWxAppHttpStatus(source);\n if (status !== undefined) {\n marked.status = status;\n }\n\n return marked;\n};\n\nexport type AnswerCallParams = {\n callId: string;\n endpointId: string;\n lineOwnerId?: string;\n};\n\nexport type CallIdParams = {\n callId: string;\n lineOwnerId?: string;\n};\n\nexport type TransmitDtmfParams = CallIdParams & {\n dtmf: string;\n};\n\nexport type CallDetailsResponse = {\n muted?: boolean;\n};\n\n/**\n * REST telephony client for wxApp thick-client answer (WXCC-6026).\n * Separate from WebCallingService (WebRTC/Mobius).\n */\nexport default class AnswerCallOnWebexService {\n private webex: WebexSDK;\n\n constructor(webex: WebexSDK) {\n this.webex = webex;\n }\n\n private getTelephonyBaseUrl(): string {\n const services = this.webex.internal.services;\n const hydraUrl = services._serviceUrls?.hydra || services.get('hydra');\n\n if (!hydraUrl) {\n throw new Error('Telephony base URL is unavailable');\n }\n\n return `${hydraUrl.replace(/\\/$/, '')}/telephony/calls`;\n }\n\n private extractTrackingId(source: unknown): string | undefined {\n return extractWxAppTrackingId(source);\n }\n\n private async telephonyRequest(\n resource: string,\n method: HTTP_METHODS,\n body: Record<string, unknown>,\n logMethod: string\n ): Promise<IHttpResponse> {\n try {\n const uri = `${this.getTelephonyBaseUrl()}${resource}`;\n\n LoggerProxy.info(`AnswerCallOnWebexService.${logMethod} request`, {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: logMethod,\n data: {uri, bodyKeys: Object.keys(body)},\n });\n\n const response = (await this.webex.request({\n uri,\n method,\n body,\n addAuthHeader: true,\n })) as IHttpResponse;\n\n LoggerProxy.info(`AnswerCallOnWebexService.${logMethod} success`, {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: logMethod,\n data: {statusCode: response.statusCode},\n });\n\n return response;\n } catch (error) {\n const trackingId = this.extractTrackingId(error);\n LoggerProxy.error(`AnswerCallOnWebexService.${logMethod} failed: ${error}`, {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: logMethod,\n data: {\n trackingId,\n status: extractWxAppHttpStatus(error),\n },\n });\n const {error: detailedError} = getErrorDetails(error, logMethod, CC_FILE);\n throw markWxAppTelephonyError(detailedError, error);\n }\n }\n\n public answerCall(params: AnswerCallParams): Promise<IHttpResponse> {\n const {callId, endpointId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/answer',\n HTTP_METHODS.POST,\n {\n callId,\n endpointId,\n ...(lineOwnerId ? {lineOwnerId} : {}),\n },\n METHODS.ACCEPT\n );\n }\n\n public rejectCall(params: CallIdParams): Promise<IHttpResponse> {\n const {callId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/reject',\n HTTP_METHODS.POST,\n {callId, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.REJECT\n );\n }\n\n public muteCall(params: CallIdParams): Promise<IHttpResponse> {\n const {callId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/mute',\n HTTP_METHODS.POST,\n {callId, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.TOGGLE_MUTE\n );\n }\n\n public unmuteCall(params: CallIdParams): Promise<IHttpResponse> {\n const {callId, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/unmute',\n HTTP_METHODS.POST,\n {callId, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.TOGGLE_MUTE\n );\n }\n\n public transmitDtmf(params: TransmitDtmfParams): Promise<IHttpResponse> {\n const {callId, dtmf, lineOwnerId} = params;\n\n return this.telephonyRequest(\n '/transmitDtmf',\n HTTP_METHODS.POST,\n {callId, dtmf, ...(lineOwnerId ? {lineOwnerId} : {})},\n METHODS.TRANSMIT_DTMF\n );\n }\n\n public async getCallDetails(params: CallIdParams): Promise<CallDetailsResponse> {\n const {callId, lineOwnerId} = params;\n const lineOwnerIdQuery = lineOwnerId ? `?lineOwnerId=${encodeURIComponent(lineOwnerId)}` : '';\n const uri = `${this.getTelephonyBaseUrl()}/${callId}${lineOwnerIdQuery}`;\n\n try {\n LoggerProxy.info('AnswerCallOnWebexService.getCallDetails request', {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: METHODS.GET_CALL_DETAILS_ON_WEBEX,\n data: {callId},\n });\n\n const response = (await this.webex.request({\n uri,\n method: HTTP_METHODS.GET,\n addAuthHeader: true,\n })) as IHttpResponse;\n\n return (response.body ?? {}) as CallDetailsResponse;\n } catch (error) {\n if (isWxAppCallNotFoundError(error)) {\n const err =\n error instanceof Error\n ? error\n : new Error(String((error as {message?: string})?.message ?? error));\n throw markWxAppTelephonyError(err, error);\n }\n\n const trackingId = this.extractTrackingId(error);\n LoggerProxy.error(`AnswerCallOnWebexService.getCallDetails failed: ${error}`, {\n module: ANSWER_CALL_ON_WEBEX_FILE,\n method: METHODS.GET_CALL_DETAILS_ON_WEBEX,\n data: {\n trackingId,\n status: extractWxAppHttpStatus(error),\n },\n });\n const {error: detailedError} = getErrorDetails(\n error,\n METHODS.GET_CALL_DETAILS_ON_WEBEX,\n CC_FILE\n );\n throw markWxAppTelephonyError(detailedError, error);\n }\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AACA,IAAAI,oBAAA,GAAAJ,OAAA;AAA+D,SAAAD,uBAAAM,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE/D,MAAMG,yBAAyB,GAAG,0BAA0B;AAQ5D,MAAMC,sBAAsB,GAAIC,MAAe,IAAyB;EACtE,MAAMC,SAAS,GAAGD,MAAgE;EAElF,OAAOC,SAAS,EAAEC,OAAO,EAAEC,UAAU,IAAIF,SAAS,EAAEE,UAAU;AAChE,CAAC;AAED,MAAMC,sBAAsB,GAAIJ,MAAe,IAAkC;EAC/E,MAAMK,GAAG,GAAGL,MAIX;EAED,OAAOK,GAAG,EAAEC,UAAU,IAAID,GAAG,EAAEE,MAAM,IAAIF,GAAG,EAAEH,OAAO,EAAEK,MAAM;AAC/D,CAAC;AAED,MAAMC,uBAAuB,GAAGA,CAACC,KAAY,EAAET,MAAe,KAA0B;EACtF,MAAMU,MAAM,GAAGD,KAA4B;EAC3CC,MAAM,CAACC,qBAAqB,GAAG,IAAI;EACnC,MAAMR,UAAU,GAAGJ,sBAAsB,CAACC,MAAM,CAAC;EACjD,IAAIG,UAAU,EAAE;IACdO,MAAM,CAACP,UAAU,GAAGA,UAAU;EAChC;EACA,MAAMI,MAAM,GAAGH,sBAAsB,CAACJ,MAAM,CAAC;EAC7C,IAAIO,MAAM,KAAKK,SAAS,EAAE;IACxBF,MAAM,CAACH,MAAM,GAAGA,MAAM;EACxB;EAEA,OAAOG,MAAM;AACf,CAAC;AAqBD;AACA;AACA;AACA;AACe,MAAMG,wBAAwB,CAAC;EAG5CC,WAAWA,CAACC,KAAe,EAAE;IAC3B,IAAI,CAACA,KAAK,GAAGA,KAAK;EACpB;EAEQC,mBAAmBA,CAAA,EAAW;IACpC,MAAMC,QAAQ,GAAG,IAAI,CAACF,KAAK,CAACG,QAAQ,CAACD,QAAQ;IAC7C,MAAME,QAAQ,GAAGF,QAAQ,CAACG,YAAY,EAAEC,KAAK,IAAIJ,QAAQ,CAACK,GAAG,CAAC,OAAO,CAAC;IAEtE,IAAI,CAACH,QAAQ,EAAE;MACb,MAAM,IAAII,KAAK,CAAC,mCAAmC,CAAC;IACtD;IAEA,OAAO,GAAGJ,QAAQ,CAACK,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB;EACzD;EAEQC,iBAAiBA,CAACzB,MAAe,EAAsB;IAC7D,OAAOD,sBAAsB,CAACC,MAAM,CAAC;EACvC;EAEA,MAAc0B,gBAAgBA,CAC5BC,QAAgB,EAChBC,MAAoB,EACpBC,IAA6B,EAC7BC,SAAiB,EACO;IACxB,IAAI;MACF,MAAMC,GAAG,GAAG,GAAG,IAAI,CAACf,mBAAmB,CAAC,CAAC,GAAGW,QAAQ,EAAE;MAEtDK,oBAAW,CAACC,IAAI,CAAC,4BAA4BH,SAAS,UAAU,EAAE;QAChEI,MAAM,EAAEpC,yBAAyB;QACjC8B,MAAM,EAAEE,SAAS;QACjBK,IAAI,EAAE;UAACJ,GAAG;UAAEK,QAAQ,EAAEC,MAAM,CAACC,IAAI,CAACT,IAAI;QAAC;MACzC,CAAC,CAAC;MAEF,MAAMU,QAAQ,GAAI,MAAM,IAAI,CAACxB,KAAK,CAACyB,OAAO,CAAC;QACzCT,GAAG;QACHH,MAAM;QACNC,IAAI;QACJY,aAAa,EAAE;MACjB,CAAC,CAAmB;MAEpBT,oBAAW,CAACC,IAAI,CAAC,4BAA4BH,SAAS,UAAU,EAAE;QAChEI,MAAM,EAAEpC,yBAAyB;QACjC8B,MAAM,EAAEE,SAAS;QACjBK,IAAI,EAAE;UAAC7B,UAAU,EAAEiC,QAAQ,CAACjC;QAAU;MACxC,CAAC,CAAC;MAEF,OAAOiC,QAAQ;IACjB,CAAC,CAAC,OAAO9B,KAAK,EAAE;MACd,MAAMN,UAAU,GAAG,IAAI,CAACsB,iBAAiB,CAAChB,KAAK,CAAC;MAChDuB,oBAAW,CAACvB,KAAK,CAAC,4BAA4BqB,SAAS,YAAYrB,KAAK,EAAE,EAAE;QAC1EyB,MAAM,EAAEpC,yBAAyB;QACjC8B,MAAM,EAAEE,SAAS;QACjBK,IAAI,EAAE;UACJhC,UAAU;UACVI,MAAM,EAAEH,sBAAsB,CAACK,KAAK;QACtC;MACF,CAAC,CAAC;MACF,MAAM;QAACA,KAAK,EAAEiC;MAAa,CAAC,GAAG,IAAAC,sBAAe,EAAClC,KAAK,EAAEqB,SAAS,EAAEc,kBAAO,CAAC;MACzE,MAAMpC,uBAAuB,CAACkC,aAAa,EAAEjC,KAAK,CAAC;IACrD;EACF;EAEOoC,UAAUA,CAACC,MAAwB,EAA0B;IAClE,MAAM;MAACC,MAAM;MAAEC,UAAU;MAAEC;IAAW,CAAC,GAAGH,MAAM;IAEhD,OAAO,IAAI,CAACpB,gBAAgB,CAC1B,SAAS,EACTwB,mBAAY,CAACC,IAAI,EACjB;MACEJ,MAAM;MACNC,UAAU;MACV,IAAIC,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC,EACDG,kBAAO,CAACC,MACV,CAAC;EACH;EAEOC,UAAUA,CAACR,MAAoB,EAA0B;IAC9D,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IAEpC,OAAO,IAAI,CAACpB,gBAAgB,CAC1B,SAAS,EACTwB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAE,IAAIE,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EAC/CG,kBAAO,CAACG,MACV,CAAC;EACH;EAEOC,QAAQA,CAACV,MAAoB,EAA0B;IAC5D,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IAEpC,OAAO,IAAI,CAACpB,gBAAgB,CAC1B,OAAO,EACPwB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAE,IAAIE,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EAC/CG,kBAAO,CAACK,WACV,CAAC;EACH;EAEOC,UAAUA,CAACZ,MAAoB,EAA0B;IAC9D,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IAEpC,OAAO,IAAI,CAACpB,gBAAgB,CAC1B,SAAS,EACTwB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAE,IAAIE,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EAC/CG,kBAAO,CAACK,WACV,CAAC;EACH;EAEOE,YAAYA,CAACb,MAA0B,EAA0B;IACtE,MAAM;MAACC,MAAM;MAAEa,IAAI;MAAEX;IAAW,CAAC,GAAGH,MAAM;IAE1C,OAAO,IAAI,CAACpB,gBAAgB,CAC1B,eAAe,EACfwB,mBAAY,CAACC,IAAI,EACjB;MAACJ,MAAM;MAAEa,IAAI;MAAE,IAAIX,WAAW,GAAG;QAACA;MAAW,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,EACrDG,kBAAO,CAACS,aACV,CAAC;EACH;EAEA,MAAaC,cAAcA,CAAChB,MAAoB,EAAgC;IAC9E,MAAM;MAACC,MAAM;MAAEE;IAAW,CAAC,GAAGH,MAAM;IACpC,MAAMiB,gBAAgB,GAAGd,WAAW,GAAG,gBAAgBe,kBAAkB,CAACf,WAAW,CAAC,EAAE,GAAG,EAAE;IAC7F,MAAMlB,GAAG,GAAG,GAAG,IAAI,CAACf,mBAAmB,CAAC,CAAC,IAAI+B,MAAM,GAAGgB,gBAAgB,EAAE;IAExE,IAAI;MACF/B,oBAAW,CAACC,IAAI,CAAC,iDAAiD,EAAE;QAClEC,MAAM,EAAEpC,yBAAyB;QACjC8B,MAAM,EAAEwB,kBAAO,CAACa,yBAAyB;QACzC9B,IAAI,EAAE;UAACY;QAAM;MACf,CAAC,CAAC;MAEF,MAAMR,QAAQ,GAAI,MAAM,IAAI,CAACxB,KAAK,CAACyB,OAAO,CAAC;QACzCT,GAAG;QACHH,MAAM,EAAEsB,mBAAY,CAACgB,GAAG;QACxBzB,aAAa,EAAE;MACjB,CAAC,CAAmB;MAEpB,OAAQF,QAAQ,CAACV,IAAI,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,OAAOpB,KAAK,EAAE;MACd,IAAI,IAAA0D,6CAAwB,EAAC1D,KAAK,CAAC,EAAE;QACnC,MAAM2D,GAAG,GACP3D,KAAK,YAAYc,KAAK,GAClBd,KAAK,GACL,IAAIc,KAAK,CAAC8C,MAAM,CAAE5D,KAAK,EAAyB6D,OAAO,IAAI7D,KAAK,CAAC,CAAC;QACxE,MAAMD,uBAAuB,CAAC4D,GAAG,EAAE3D,KAAK,CAAC;MAC3C;MAEA,MAAMN,UAAU,GAAG,IAAI,CAACsB,iBAAiB,CAAChB,KAAK,CAAC;MAChDuB,oBAAW,CAACvB,KAAK,CAAC,mDAAmDA,KAAK,EAAE,EAAE;QAC5EyB,MAAM,EAAEpC,yBAAyB;QACjC8B,MAAM,EAAEwB,kBAAO,CAACa,yBAAyB;QACzC9B,IAAI,EAAE;UACJhC,UAAU;UACVI,MAAM,EAAEH,sBAAsB,CAACK,KAAK;QACtC;MACF,CAAC,CAAC;MACF,MAAM;QAACA,KAAK,EAAEiC;MAAa,CAAC,GAAG,IAAAC,sBAAe,EAC5ClC,KAAK,EACL2C,kBAAO,CAACa,yBAAyB,EACjCrB,kBACF,CAAC;MACD,MAAMpC,uBAAuB,CAACkC,aAAa,EAAEjC,KAAK,CAAC;IACrD;EACF;AACF;AAAC8D,OAAA,CAAA1E,OAAA,GAAAgB,wBAAA","ignoreList":[]}
|
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _loggerProxy = _interopRequireDefault(require("../logger-proxy"));
|
|
8
8
|
var _constants = require("../constants");
|
|
9
|
+
var _MetricsManager = _interopRequireDefault(require("../metrics/MetricsManager"));
|
|
10
|
+
var _constants2 = require("../metrics/constants");
|
|
9
11
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
12
|
const WEBEX_CROSS_CLIENT_FILE = 'WebexCrossClientService';
|
|
11
13
|
const DEFAULT_CROSS_CLIENT_STATE_TTL = 900;
|
|
@@ -22,6 +24,8 @@ class WebexCrossClientService {
|
|
|
22
24
|
appName = DEFAULT_APP_NAME;
|
|
23
25
|
/** Incremented on teardown/disable to ignore stale refresh timer callbacks. */
|
|
24
26
|
refreshGeneration = 0;
|
|
27
|
+
/** Monotonic id for usersub publish metrics timers; stale publishes cancel only their own timer. */
|
|
28
|
+
usersubPublishMetricsId = 0;
|
|
25
29
|
constructor(webex) {
|
|
26
30
|
this.webex = webex;
|
|
27
31
|
}
|
|
@@ -118,13 +122,18 @@ class WebexCrossClientService {
|
|
|
118
122
|
const userId = options?.userId ?? this.webex.internal.device?.userId;
|
|
119
123
|
const ttl = options?.ttl ?? DEFAULT_CROSS_CLIENT_STATE_TTL;
|
|
120
124
|
const appName = options?.appName ?? DEFAULT_APP_NAME;
|
|
125
|
+
const trackPublishMetrics = options?.trackPublishMetrics ?? false;
|
|
121
126
|
this.appName = appName;
|
|
122
127
|
if (!userId) {
|
|
123
|
-
|
|
128
|
+
const error = 'User ID is unavailable for cross-client publish';
|
|
129
|
+
this.trackUsersubPreflightFailure(enable, 'user_id_unavailable', error, trackPublishMetrics);
|
|
130
|
+
throw new Error(error);
|
|
124
131
|
}
|
|
125
132
|
const deviceUrl = this.getDeviceUrl();
|
|
126
133
|
if (!deviceUrl) {
|
|
127
|
-
|
|
134
|
+
const error = 'Device URL is unavailable for cross-client publish';
|
|
135
|
+
this.trackUsersubPreflightFailure(enable, 'device_url_unavailable', error, trackPublishMetrics);
|
|
136
|
+
throw new Error(error);
|
|
128
137
|
}
|
|
129
138
|
const composition = {
|
|
130
139
|
devices: [{
|
|
@@ -135,8 +144,35 @@ class WebexCrossClientService {
|
|
|
135
144
|
}
|
|
136
145
|
}]
|
|
137
146
|
};
|
|
138
|
-
|
|
147
|
+
const metricsManager = _MetricsManager.default.getInstance();
|
|
148
|
+
const usersubPublishEventKeys = [_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS, _constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED];
|
|
149
|
+
let publishMetricsId = 0;
|
|
150
|
+
if (trackPublishMetrics) {
|
|
151
|
+
this.usersubPublishMetricsId += 1;
|
|
152
|
+
publishMetricsId = this.usersubPublishMetricsId;
|
|
153
|
+
metricsManager.timeEvent(usersubPublishEventKeys);
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
await this.publishCrossClientState([userId], ttl, composition, 'setManageWebexCallingInWxcc');
|
|
157
|
+
} catch (error) {
|
|
158
|
+
if (trackPublishMetrics) {
|
|
159
|
+
if (operationGeneration !== this.refreshGeneration) {
|
|
160
|
+
if (publishMetricsId === this.usersubPublishMetricsId) {
|
|
161
|
+
metricsManager.cancelTimedEvent(usersubPublishEventKeys);
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
metricsManager.trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED, {
|
|
165
|
+
enableWxBetterTogether: enable,
|
|
166
|
+
error: error instanceof Error ? error.toString() : String(error)
|
|
167
|
+
}, ['operational', 'behavioral']);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
139
172
|
if (operationGeneration !== this.refreshGeneration) {
|
|
173
|
+
if (trackPublishMetrics && publishMetricsId === this.usersubPublishMetricsId) {
|
|
174
|
+
metricsManager.cancelTimedEvent(usersubPublishEventKeys);
|
|
175
|
+
}
|
|
140
176
|
return;
|
|
141
177
|
}
|
|
142
178
|
this.answerCallsState = enable;
|
|
@@ -146,6 +182,11 @@ class WebexCrossClientService {
|
|
|
146
182
|
this.refreshGeneration += 1;
|
|
147
183
|
this.clearRefreshTimer();
|
|
148
184
|
}
|
|
185
|
+
if (trackPublishMetrics) {
|
|
186
|
+
metricsManager.trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS, {
|
|
187
|
+
enableWxBetterTogether: enable
|
|
188
|
+
}, ['operational', 'behavioral']);
|
|
189
|
+
}
|
|
149
190
|
_loggerProxy.default.info(`Cross-client answer-calls-on-wxcc set to ${enable}`, {
|
|
150
191
|
module: WEBEX_CROSS_CLIENT_FILE,
|
|
151
192
|
method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,
|
|
@@ -156,6 +197,16 @@ class WebexCrossClientService {
|
|
|
156
197
|
}
|
|
157
198
|
});
|
|
158
199
|
}
|
|
200
|
+
trackUsersubPreflightFailure(enable, skipReason, error, trackPublishMetrics) {
|
|
201
|
+
if (!trackPublishMetrics) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
_MetricsManager.default.getInstance().trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED, {
|
|
205
|
+
enableWxBetterTogether: enable,
|
|
206
|
+
skipReason,
|
|
207
|
+
error
|
|
208
|
+
}, ['operational', 'behavioral']);
|
|
209
|
+
}
|
|
159
210
|
teardown() {
|
|
160
211
|
this.refreshGeneration += 1;
|
|
161
212
|
this.clearRefreshTimer();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","e","__esModule","default","WEBEX_CROSS_CLIENT_FILE","DEFAULT_CROSS_CLIENT_STATE_TTL","EXPIRATION_OFFSET_MS","DEFAULT_APP_NAME","REFRESH_RETRY_DELAY_MS","MAX_REFRESH_RETRIES","WebexCrossClientService","answerCallsState","appName","refreshGeneration","constructor","webex","extractDeviceIdFromUrl","url","match","getDeviceUrl","internal","device","clearRefreshTimer","refreshTimer","clearTimeout","undefined","refreshRetryTimer","scheduleRefreshRetry","userId","ttl","scheduledGeneration","retryAttempt","setTimeout","setManageWebexCallingInWxcc","error","LoggerProxy","module","method","METHODS","SET_MANAGE_WEBEX_CALLING_IN_WXCC","startRefreshTimer","refreshTime","publishCrossClientState","users","composition","logContext","body","compositions","type","request","service","resource","then","response","catch","Promise","reject","enable","options","operationGeneration","Error","deviceUrl","devices","deviceId","state","info","data","teardown","isAnswerCallsStateActive","exports"],"sources":["WebexCrossClientService.ts"],"sourcesContent":["import LoggerProxy from '../logger-proxy';\nimport {METHODS} from '../constants';\nimport {WebexSDK} from '../types';\n\nconst WEBEX_CROSS_CLIENT_FILE = 'WebexCrossClientService';\nconst DEFAULT_CROSS_CLIENT_STATE_TTL = 900;\nconst EXPIRATION_OFFSET_MS = 60_000;\n/** Must match Agent Desktop usersub publish — Webex App reads `wxcc` cross-client state. */\nconst DEFAULT_APP_NAME = 'wxcc';\nconst REFRESH_RETRY_DELAY_MS = 30_000;\nconst MAX_REFRESH_RETRIES = 3;\n\ntype RefreshTimer = ReturnType<typeof setTimeout>;\n\n/**\n * Publishes usersub cross-client state so Webex App suppresses native calling toasts (WXCC-6026).\n */\nexport default class WebexCrossClientService {\n private webex: WebexSDK;\n private refreshTimer?: RefreshTimer;\n private refreshRetryTimer?: RefreshTimer;\n private answerCallsState = false;\n private appName = DEFAULT_APP_NAME;\n /** Incremented on teardown/disable to ignore stale refresh timer callbacks. */\n private refreshGeneration = 0;\n\n constructor(webex: WebexSDK) {\n this.webex = webex;\n }\n\n private extractDeviceIdFromUrl(url: string): string {\n const match = url.match(/\\/devices\\/([^/?]+)/);\n\n return match ? match[1] : '';\n }\n\n private getDeviceUrl(): string | undefined {\n return this.webex.internal.device?.url;\n }\n\n private clearRefreshTimer(): void {\n if (this.refreshTimer) {\n clearTimeout(this.refreshTimer);\n this.refreshTimer = undefined;\n }\n\n if (this.refreshRetryTimer) {\n clearTimeout(this.refreshRetryTimer);\n this.refreshRetryTimer = undefined;\n }\n }\n\n private scheduleRefreshRetry(\n userId: string,\n ttl: number,\n scheduledGeneration: number,\n retryAttempt: number\n ): void {\n if (\n retryAttempt >= MAX_REFRESH_RETRIES ||\n scheduledGeneration !== this.refreshGeneration ||\n !this.answerCallsState\n ) {\n return;\n }\n\n this.refreshRetryTimer = setTimeout(async () => {\n if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {\n return;\n }\n\n try {\n await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});\n } catch (error) {\n LoggerProxy.error(`WebexCrossClientService refresh retry failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, retryAttempt + 1);\n }\n }, REFRESH_RETRY_DELAY_MS);\n }\n\n private startRefreshTimer(userId: string, ttl: number): void {\n this.clearRefreshTimer();\n\n if (!this.answerCallsState) {\n return;\n }\n\n const refreshTime = ttl * 1000 - EXPIRATION_OFFSET_MS;\n const scheduledGeneration = this.refreshGeneration;\n this.refreshTimer = setTimeout(async () => {\n if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {\n return;\n }\n\n try {\n await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});\n } catch (error) {\n LoggerProxy.error(`WebexCrossClientService refresh failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, 0);\n }\n }, refreshTime);\n }\n\n private publishCrossClientState(\n users: string[],\n ttl: number,\n composition: Record<string, unknown>,\n logContext: string\n ): Promise<unknown> {\n const body = {\n users,\n compositions: [\n {\n type: 'cross-client-state',\n ttl,\n composition,\n },\n ],\n };\n\n return this.webex\n .request({\n method: 'POST',\n service: 'usersub',\n resource: 'publish',\n body,\n })\n .then((response: {body?: unknown}) => response?.body)\n .catch((error: unknown) => {\n LoggerProxy.error(`WebexCrossClientService.${logContext} failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n\n return Promise.reject(error);\n });\n }\n\n public async setManageWebexCallingInWxcc(\n enable: boolean,\n options?: {userId?: string; ttl?: number; appName?: string}\n ): Promise<void> {\n const operationGeneration = this.refreshGeneration;\n const userId = options?.userId ?? this.webex.internal.device?.userId;\n const ttl = options?.ttl ?? DEFAULT_CROSS_CLIENT_STATE_TTL;\n const appName = options?.appName ?? DEFAULT_APP_NAME;\n this.appName = appName;\n\n if (!userId) {\n throw new Error('User ID is unavailable for cross-client publish');\n }\n\n const deviceUrl = this.getDeviceUrl();\n if (!deviceUrl) {\n throw new Error('Device URL is unavailable for cross-client publish');\n }\n\n const composition = {\n devices: [\n {\n deviceId: this.extractDeviceIdFromUrl(deviceUrl),\n appName,\n state: {\n 'answer-calls-on-wxcc': enable,\n },\n },\n ],\n };\n\n await this.publishCrossClientState([userId], ttl, composition, 'setManageWebexCallingInWxcc');\n\n if (operationGeneration !== this.refreshGeneration) {\n return;\n }\n\n this.answerCallsState = enable;\n\n if (enable) {\n this.startRefreshTimer(userId, ttl);\n } else {\n this.refreshGeneration += 1;\n this.clearRefreshTimer();\n }\n\n LoggerProxy.info(`Cross-client answer-calls-on-wxcc set to ${enable}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n data: {\n appName,\n deviceId: this.extractDeviceIdFromUrl(deviceUrl),\n ttl,\n },\n });\n }\n\n public teardown(): void {\n this.refreshGeneration += 1;\n this.clearRefreshTimer();\n this.answerCallsState = false;\n }\n\n /** Whether usersub `answer-calls-on-wxcc: true` was successfully published this session. */\n public isAnswerCallsStateActive(): boolean {\n return this.answerCallsState;\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AAAqC,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAGrC,MAAMG,uBAAuB,GAAG,yBAAyB;AACzD,MAAMC,8BAA8B,GAAG,GAAG;AAC1C,MAAMC,oBAAoB,GAAG,MAAM;AACnC;AACA,MAAMC,gBAAgB,GAAG,MAAM;AAC/B,MAAMC,sBAAsB,GAAG,MAAM;AACrC,MAAMC,mBAAmB,GAAG,CAAC;AAI7B;AACA;AACA;AACe,MAAMC,uBAAuB,CAAC;EAInCC,gBAAgB,GAAG,KAAK;EACxBC,OAAO,GAAGL,gBAAgB;EAClC;EACQM,iBAAiB,GAAG,CAAC;EAE7BC,WAAWA,CAACC,KAAe,EAAE;IAC3B,IAAI,CAACA,KAAK,GAAGA,KAAK;EACpB;EAEQC,sBAAsBA,CAACC,GAAW,EAAU;IAClD,MAAMC,KAAK,GAAGD,GAAG,CAACC,KAAK,CAAC,qBAAqB,CAAC;IAE9C,OAAOA,KAAK,GAAGA,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE;EAC9B;EAEQC,YAAYA,CAAA,EAAuB;IACzC,OAAO,IAAI,CAACJ,KAAK,CAACK,QAAQ,CAACC,MAAM,EAAEJ,GAAG;EACxC;EAEQK,iBAAiBA,CAAA,EAAS;IAChC,IAAI,IAAI,CAACC,YAAY,EAAE;MACrBC,YAAY,CAAC,IAAI,CAACD,YAAY,CAAC;MAC/B,IAAI,CAACA,YAAY,GAAGE,SAAS;IAC/B;IAEA,IAAI,IAAI,CAACC,iBAAiB,EAAE;MAC1BF,YAAY,CAAC,IAAI,CAACE,iBAAiB,CAAC;MACpC,IAAI,CAACA,iBAAiB,GAAGD,SAAS;IACpC;EACF;EAEQE,oBAAoBA,CAC1BC,MAAc,EACdC,GAAW,EACXC,mBAA2B,EAC3BC,YAAoB,EACd;IACN,IACEA,YAAY,IAAItB,mBAAmB,IACnCqB,mBAAmB,KAAK,IAAI,CAACjB,iBAAiB,IAC9C,CAAC,IAAI,CAACF,gBAAgB,EACtB;MACA;IACF;IAEA,IAAI,CAACe,iBAAiB,GAAGM,UAAU,CAAC,YAAY;MAC9C,IAAIF,mBAAmB,KAAK,IAAI,CAACjB,iBAAiB,IAAI,CAAC,IAAI,CAACF,gBAAgB,EAAE;QAC5E;MACF;MAEA,IAAI;QACF,MAAM,IAAI,CAACsB,2BAA2B,CAAC,IAAI,EAAE;UAACL,MAAM;UAAEC,GAAG;UAAEjB,OAAO,EAAE,IAAI,CAACA;QAAO,CAAC,CAAC;MACpF,CAAC,CAAC,OAAOsB,KAAK,EAAE;QACdC,oBAAW,CAACD,KAAK,CAAC,iDAAiDA,KAAK,EAAE,EAAE;UAC1EE,MAAM,EAAEhC,uBAAuB;UAC/BiC,MAAM,EAAEC,kBAAO,CAACC;QAClB,CAAC,CAAC;QACF,IAAI,CAACZ,oBAAoB,CAACC,MAAM,EAAEC,GAAG,EAAEC,mBAAmB,EAAEC,YAAY,GAAG,CAAC,CAAC;MAC/E;IACF,CAAC,EAAEvB,sBAAsB,CAAC;EAC5B;EAEQgC,iBAAiBA,CAACZ,MAAc,EAAEC,GAAW,EAAQ;IAC3D,IAAI,CAACP,iBAAiB,CAAC,CAAC;IAExB,IAAI,CAAC,IAAI,CAACX,gBAAgB,EAAE;MAC1B;IACF;IAEA,MAAM8B,WAAW,GAAGZ,GAAG,GAAG,IAAI,GAAGvB,oBAAoB;IACrD,MAAMwB,mBAAmB,GAAG,IAAI,CAACjB,iBAAiB;IAClD,IAAI,CAACU,YAAY,GAAGS,UAAU,CAAC,YAAY;MACzC,IAAIF,mBAAmB,KAAK,IAAI,CAACjB,iBAAiB,IAAI,CAAC,IAAI,CAACF,gBAAgB,EAAE;QAC5E;MACF;MAEA,IAAI;QACF,MAAM,IAAI,CAACsB,2BAA2B,CAAC,IAAI,EAAE;UAACL,MAAM;UAAEC,GAAG;UAAEjB,OAAO,EAAE,IAAI,CAACA;QAAO,CAAC,CAAC;MACpF,CAAC,CAAC,OAAOsB,KAAK,EAAE;QACdC,oBAAW,CAACD,KAAK,CAAC,2CAA2CA,KAAK,EAAE,EAAE;UACpEE,MAAM,EAAEhC,uBAAuB;UAC/BiC,MAAM,EAAEC,kBAAO,CAACC;QAClB,CAAC,CAAC;QACF,IAAI,CAACZ,oBAAoB,CAACC,MAAM,EAAEC,GAAG,EAAEC,mBAAmB,EAAE,CAAC,CAAC;MAChE;IACF,CAAC,EAAEW,WAAW,CAAC;EACjB;EAEQC,uBAAuBA,CAC7BC,KAAe,EACfd,GAAW,EACXe,WAAoC,EACpCC,UAAkB,EACA;IAClB,MAAMC,IAAI,GAAG;MACXH,KAAK;MACLI,YAAY,EAAE,CACZ;QACEC,IAAI,EAAE,oBAAoB;QAC1BnB,GAAG;QACHe;MACF,CAAC;IAEL,CAAC;IAED,OAAO,IAAI,CAAC7B,KAAK,CACdkC,OAAO,CAAC;MACPZ,MAAM,EAAE,MAAM;MACda,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,SAAS;MACnBL;IACF,CAAC,CAAC,CACDM,IAAI,CAAEC,QAA0B,IAAKA,QAAQ,EAAEP,IAAI,CAAC,CACpDQ,KAAK,CAAEpB,KAAc,IAAK;MACzBC,oBAAW,CAACD,KAAK,CAAC,2BAA2BW,UAAU,YAAYX,KAAK,EAAE,EAAE;QAC1EE,MAAM,EAAEhC,uBAAuB;QAC/BiC,MAAM,EAAEC,kBAAO,CAACC;MAClB,CAAC,CAAC;MAEF,OAAOgB,OAAO,CAACC,MAAM,CAACtB,KAAK,CAAC;IAC9B,CAAC,CAAC;EACN;EAEA,MAAaD,2BAA2BA,CACtCwB,MAAe,EACfC,OAA2D,EAC5C;IACf,MAAMC,mBAAmB,GAAG,IAAI,CAAC9C,iBAAiB;IAClD,MAAMe,MAAM,GAAG8B,OAAO,EAAE9B,MAAM,IAAI,IAAI,CAACb,KAAK,CAACK,QAAQ,CAACC,MAAM,EAAEO,MAAM;IACpE,MAAMC,GAAG,GAAG6B,OAAO,EAAE7B,GAAG,IAAIxB,8BAA8B;IAC1D,MAAMO,OAAO,GAAG8C,OAAO,EAAE9C,OAAO,IAAIL,gBAAgB;IACpD,IAAI,CAACK,OAAO,GAAGA,OAAO;IAEtB,IAAI,CAACgB,MAAM,EAAE;MACX,MAAM,IAAIgC,KAAK,CAAC,iDAAiD,CAAC;IACpE;IAEA,MAAMC,SAAS,GAAG,IAAI,CAAC1C,YAAY,CAAC,CAAC;IACrC,IAAI,CAAC0C,SAAS,EAAE;MACd,MAAM,IAAID,KAAK,CAAC,oDAAoD,CAAC;IACvE;IAEA,MAAMhB,WAAW,GAAG;MAClBkB,OAAO,EAAE,CACP;QACEC,QAAQ,EAAE,IAAI,CAAC/C,sBAAsB,CAAC6C,SAAS,CAAC;QAChDjD,OAAO;QACPoD,KAAK,EAAE;UACL,sBAAsB,EAAEP;QAC1B;MACF,CAAC;IAEL,CAAC;IAED,MAAM,IAAI,CAACf,uBAAuB,CAAC,CAACd,MAAM,CAAC,EAAEC,GAAG,EAAEe,WAAW,EAAE,6BAA6B,CAAC;IAE7F,IAAIe,mBAAmB,KAAK,IAAI,CAAC9C,iBAAiB,EAAE;MAClD;IACF;IAEA,IAAI,CAACF,gBAAgB,GAAG8C,MAAM;IAE9B,IAAIA,MAAM,EAAE;MACV,IAAI,CAACjB,iBAAiB,CAACZ,MAAM,EAAEC,GAAG,CAAC;IACrC,CAAC,MAAM;MACL,IAAI,CAAChB,iBAAiB,IAAI,CAAC;MAC3B,IAAI,CAACS,iBAAiB,CAAC,CAAC;IAC1B;IAEAa,oBAAW,CAAC8B,IAAI,CAAC,4CAA4CR,MAAM,EAAE,EAAE;MACrErB,MAAM,EAAEhC,uBAAuB;MAC/BiC,MAAM,EAAEC,kBAAO,CAACC,gCAAgC;MAChD2B,IAAI,EAAE;QACJtD,OAAO;QACPmD,QAAQ,EAAE,IAAI,CAAC/C,sBAAsB,CAAC6C,SAAS,CAAC;QAChDhC;MACF;IACF,CAAC,CAAC;EACJ;EAEOsC,QAAQA,CAAA,EAAS;IACtB,IAAI,CAACtD,iBAAiB,IAAI,CAAC;IAC3B,IAAI,CAACS,iBAAiB,CAAC,CAAC;IACxB,IAAI,CAACX,gBAAgB,GAAG,KAAK;EAC/B;;EAEA;EACOyD,wBAAwBA,CAAA,EAAY;IACzC,OAAO,IAAI,CAACzD,gBAAgB;EAC9B;AACF;AAAC0D,OAAA,CAAAlE,OAAA,GAAAO,uBAAA","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","_MetricsManager","_constants2","e","__esModule","default","WEBEX_CROSS_CLIENT_FILE","DEFAULT_CROSS_CLIENT_STATE_TTL","EXPIRATION_OFFSET_MS","DEFAULT_APP_NAME","REFRESH_RETRY_DELAY_MS","MAX_REFRESH_RETRIES","WebexCrossClientService","answerCallsState","appName","refreshGeneration","usersubPublishMetricsId","constructor","webex","extractDeviceIdFromUrl","url","match","getDeviceUrl","internal","device","clearRefreshTimer","refreshTimer","clearTimeout","undefined","refreshRetryTimer","scheduleRefreshRetry","userId","ttl","scheduledGeneration","retryAttempt","setTimeout","setManageWebexCallingInWxcc","error","LoggerProxy","module","method","METHODS","SET_MANAGE_WEBEX_CALLING_IN_WXCC","startRefreshTimer","refreshTime","publishCrossClientState","users","composition","logContext","body","compositions","type","request","service","resource","then","response","catch","Promise","reject","enable","options","operationGeneration","trackPublishMetrics","trackUsersubPreflightFailure","Error","deviceUrl","devices","deviceId","state","metricsManager","MetricsManager","getInstance","usersubPublishEventKeys","METRIC_EVENT_NAMES","WXAPP_USERSUB_PUBLISH_SUCCESS","WXAPP_USERSUB_PUBLISH_FAILED","publishMetricsId","timeEvent","cancelTimedEvent","trackEvent","enableWxBetterTogether","toString","String","info","data","skipReason","teardown","isAnswerCallsStateActive","exports"],"sources":["WebexCrossClientService.ts"],"sourcesContent":["import LoggerProxy from '../logger-proxy';\nimport {METHODS} from '../constants';\nimport {WebexSDK} from '../types';\nimport MetricsManager from '../metrics/MetricsManager';\nimport {METRIC_EVENT_NAMES} from '../metrics/constants';\n\nconst WEBEX_CROSS_CLIENT_FILE = 'WebexCrossClientService';\nconst DEFAULT_CROSS_CLIENT_STATE_TTL = 900;\nconst EXPIRATION_OFFSET_MS = 60_000;\n/** Must match Agent Desktop usersub publish — Webex App reads `wxcc` cross-client state. */\nconst DEFAULT_APP_NAME = 'wxcc';\nconst REFRESH_RETRY_DELAY_MS = 30_000;\nconst MAX_REFRESH_RETRIES = 3;\n\ntype RefreshTimer = ReturnType<typeof setTimeout>;\n\n/**\n * Publishes usersub cross-client state so Webex App suppresses native calling toasts (WXCC-6026).\n */\nexport default class WebexCrossClientService {\n private webex: WebexSDK;\n private refreshTimer?: RefreshTimer;\n private refreshRetryTimer?: RefreshTimer;\n private answerCallsState = false;\n private appName = DEFAULT_APP_NAME;\n /** Incremented on teardown/disable to ignore stale refresh timer callbacks. */\n private refreshGeneration = 0;\n /** Monotonic id for usersub publish metrics timers; stale publishes cancel only their own timer. */\n private usersubPublishMetricsId = 0;\n\n constructor(webex: WebexSDK) {\n this.webex = webex;\n }\n\n private extractDeviceIdFromUrl(url: string): string {\n const match = url.match(/\\/devices\\/([^/?]+)/);\n\n return match ? match[1] : '';\n }\n\n private getDeviceUrl(): string | undefined {\n return this.webex.internal.device?.url;\n }\n\n private clearRefreshTimer(): void {\n if (this.refreshTimer) {\n clearTimeout(this.refreshTimer);\n this.refreshTimer = undefined;\n }\n\n if (this.refreshRetryTimer) {\n clearTimeout(this.refreshRetryTimer);\n this.refreshRetryTimer = undefined;\n }\n }\n\n private scheduleRefreshRetry(\n userId: string,\n ttl: number,\n scheduledGeneration: number,\n retryAttempt: number\n ): void {\n if (\n retryAttempt >= MAX_REFRESH_RETRIES ||\n scheduledGeneration !== this.refreshGeneration ||\n !this.answerCallsState\n ) {\n return;\n }\n\n this.refreshRetryTimer = setTimeout(async () => {\n if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {\n return;\n }\n\n try {\n await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});\n } catch (error) {\n LoggerProxy.error(`WebexCrossClientService refresh retry failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, retryAttempt + 1);\n }\n }, REFRESH_RETRY_DELAY_MS);\n }\n\n private startRefreshTimer(userId: string, ttl: number): void {\n this.clearRefreshTimer();\n\n if (!this.answerCallsState) {\n return;\n }\n\n const refreshTime = ttl * 1000 - EXPIRATION_OFFSET_MS;\n const scheduledGeneration = this.refreshGeneration;\n this.refreshTimer = setTimeout(async () => {\n if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {\n return;\n }\n\n try {\n await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});\n } catch (error) {\n LoggerProxy.error(`WebexCrossClientService refresh failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, 0);\n }\n }, refreshTime);\n }\n\n private publishCrossClientState(\n users: string[],\n ttl: number,\n composition: Record<string, unknown>,\n logContext: string\n ): Promise<unknown> {\n const body = {\n users,\n compositions: [\n {\n type: 'cross-client-state',\n ttl,\n composition,\n },\n ],\n };\n\n return this.webex\n .request({\n method: 'POST',\n service: 'usersub',\n resource: 'publish',\n body,\n })\n .then((response: {body?: unknown}) => response?.body)\n .catch((error: unknown) => {\n LoggerProxy.error(`WebexCrossClientService.${logContext} failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n\n return Promise.reject(error);\n });\n }\n\n public async setManageWebexCallingInWxcc(\n enable: boolean,\n options?: {userId?: string; ttl?: number; appName?: string; trackPublishMetrics?: boolean}\n ): Promise<void> {\n const operationGeneration = this.refreshGeneration;\n const userId = options?.userId ?? this.webex.internal.device?.userId;\n const ttl = options?.ttl ?? DEFAULT_CROSS_CLIENT_STATE_TTL;\n const appName = options?.appName ?? DEFAULT_APP_NAME;\n const trackPublishMetrics = options?.trackPublishMetrics ?? false;\n this.appName = appName;\n\n if (!userId) {\n const error = 'User ID is unavailable for cross-client publish';\n this.trackUsersubPreflightFailure(enable, 'user_id_unavailable', error, trackPublishMetrics);\n throw new Error(error);\n }\n\n const deviceUrl = this.getDeviceUrl();\n if (!deviceUrl) {\n const error = 'Device URL is unavailable for cross-client publish';\n this.trackUsersubPreflightFailure(\n enable,\n 'device_url_unavailable',\n error,\n trackPublishMetrics\n );\n throw new Error(error);\n }\n\n const composition = {\n devices: [\n {\n deviceId: this.extractDeviceIdFromUrl(deviceUrl),\n appName,\n state: {\n 'answer-calls-on-wxcc': enable,\n },\n },\n ],\n };\n\n const metricsManager = MetricsManager.getInstance();\n const usersubPublishEventKeys = [\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS,\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED,\n ];\n\n let publishMetricsId = 0;\n if (trackPublishMetrics) {\n this.usersubPublishMetricsId += 1;\n publishMetricsId = this.usersubPublishMetricsId;\n metricsManager.timeEvent(usersubPublishEventKeys);\n }\n\n try {\n await this.publishCrossClientState([userId], ttl, composition, 'setManageWebexCallingInWxcc');\n } catch (error) {\n if (trackPublishMetrics) {\n if (operationGeneration !== this.refreshGeneration) {\n if (publishMetricsId === this.usersubPublishMetricsId) {\n metricsManager.cancelTimedEvent(usersubPublishEventKeys);\n }\n } else {\n metricsManager.trackEvent(\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED,\n {\n enableWxBetterTogether: enable,\n error: error instanceof Error ? error.toString() : String(error),\n },\n ['operational', 'behavioral']\n );\n }\n }\n\n throw error;\n }\n\n if (operationGeneration !== this.refreshGeneration) {\n if (trackPublishMetrics && publishMetricsId === this.usersubPublishMetricsId) {\n metricsManager.cancelTimedEvent(usersubPublishEventKeys);\n }\n\n return;\n }\n\n this.answerCallsState = enable;\n\n if (enable) {\n this.startRefreshTimer(userId, ttl);\n } else {\n this.refreshGeneration += 1;\n this.clearRefreshTimer();\n }\n\n if (trackPublishMetrics) {\n metricsManager.trackEvent(\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS,\n {enableWxBetterTogether: enable},\n ['operational', 'behavioral']\n );\n }\n\n LoggerProxy.info(`Cross-client answer-calls-on-wxcc set to ${enable}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n data: {\n appName,\n deviceId: this.extractDeviceIdFromUrl(deviceUrl),\n ttl,\n },\n });\n }\n\n private trackUsersubPreflightFailure(\n enable: boolean,\n skipReason: 'user_id_unavailable' | 'device_url_unavailable',\n error: string,\n trackPublishMetrics: boolean\n ): void {\n if (!trackPublishMetrics) {\n return;\n }\n\n MetricsManager.getInstance().trackEvent(\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED,\n {\n enableWxBetterTogether: enable,\n skipReason,\n error,\n },\n ['operational', 'behavioral']\n );\n }\n\n public teardown(): void {\n this.refreshGeneration += 1;\n this.clearRefreshTimer();\n this.answerCallsState = false;\n }\n\n /** Whether usersub `answer-calls-on-wxcc: true` was successfully published this session. */\n public isAnswerCallsStateActive(): boolean {\n return this.answerCallsState;\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AAEA,IAAAE,eAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,WAAA,GAAAH,OAAA;AAAwD,SAAAD,uBAAAK,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAExD,MAAMG,uBAAuB,GAAG,yBAAyB;AACzD,MAAMC,8BAA8B,GAAG,GAAG;AAC1C,MAAMC,oBAAoB,GAAG,MAAM;AACnC;AACA,MAAMC,gBAAgB,GAAG,MAAM;AAC/B,MAAMC,sBAAsB,GAAG,MAAM;AACrC,MAAMC,mBAAmB,GAAG,CAAC;AAI7B;AACA;AACA;AACe,MAAMC,uBAAuB,CAAC;EAInCC,gBAAgB,GAAG,KAAK;EACxBC,OAAO,GAAGL,gBAAgB;EAClC;EACQM,iBAAiB,GAAG,CAAC;EAC7B;EACQC,uBAAuB,GAAG,CAAC;EAEnCC,WAAWA,CAACC,KAAe,EAAE;IAC3B,IAAI,CAACA,KAAK,GAAGA,KAAK;EACpB;EAEQC,sBAAsBA,CAACC,GAAW,EAAU;IAClD,MAAMC,KAAK,GAAGD,GAAG,CAACC,KAAK,CAAC,qBAAqB,CAAC;IAE9C,OAAOA,KAAK,GAAGA,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE;EAC9B;EAEQC,YAAYA,CAAA,EAAuB;IACzC,OAAO,IAAI,CAACJ,KAAK,CAACK,QAAQ,CAACC,MAAM,EAAEJ,GAAG;EACxC;EAEQK,iBAAiBA,CAAA,EAAS;IAChC,IAAI,IAAI,CAACC,YAAY,EAAE;MACrBC,YAAY,CAAC,IAAI,CAACD,YAAY,CAAC;MAC/B,IAAI,CAACA,YAAY,GAAGE,SAAS;IAC/B;IAEA,IAAI,IAAI,CAACC,iBAAiB,EAAE;MAC1BF,YAAY,CAAC,IAAI,CAACE,iBAAiB,CAAC;MACpC,IAAI,CAACA,iBAAiB,GAAGD,SAAS;IACpC;EACF;EAEQE,oBAAoBA,CAC1BC,MAAc,EACdC,GAAW,EACXC,mBAA2B,EAC3BC,YAAoB,EACd;IACN,IACEA,YAAY,IAAIvB,mBAAmB,IACnCsB,mBAAmB,KAAK,IAAI,CAAClB,iBAAiB,IAC9C,CAAC,IAAI,CAACF,gBAAgB,EACtB;MACA;IACF;IAEA,IAAI,CAACgB,iBAAiB,GAAGM,UAAU,CAAC,YAAY;MAC9C,IAAIF,mBAAmB,KAAK,IAAI,CAAClB,iBAAiB,IAAI,CAAC,IAAI,CAACF,gBAAgB,EAAE;QAC5E;MACF;MAEA,IAAI;QACF,MAAM,IAAI,CAACuB,2BAA2B,CAAC,IAAI,EAAE;UAACL,MAAM;UAAEC,GAAG;UAAElB,OAAO,EAAE,IAAI,CAACA;QAAO,CAAC,CAAC;MACpF,CAAC,CAAC,OAAOuB,KAAK,EAAE;QACdC,oBAAW,CAACD,KAAK,CAAC,iDAAiDA,KAAK,EAAE,EAAE;UAC1EE,MAAM,EAAEjC,uBAAuB;UAC/BkC,MAAM,EAAEC,kBAAO,CAACC;QAClB,CAAC,CAAC;QACF,IAAI,CAACZ,oBAAoB,CAACC,MAAM,EAAEC,GAAG,EAAEC,mBAAmB,EAAEC,YAAY,GAAG,CAAC,CAAC;MAC/E;IACF,CAAC,EAAExB,sBAAsB,CAAC;EAC5B;EAEQiC,iBAAiBA,CAACZ,MAAc,EAAEC,GAAW,EAAQ;IAC3D,IAAI,CAACP,iBAAiB,CAAC,CAAC;IAExB,IAAI,CAAC,IAAI,CAACZ,gBAAgB,EAAE;MAC1B;IACF;IAEA,MAAM+B,WAAW,GAAGZ,GAAG,GAAG,IAAI,GAAGxB,oBAAoB;IACrD,MAAMyB,mBAAmB,GAAG,IAAI,CAAClB,iBAAiB;IAClD,IAAI,CAACW,YAAY,GAAGS,UAAU,CAAC,YAAY;MACzC,IAAIF,mBAAmB,KAAK,IAAI,CAAClB,iBAAiB,IAAI,CAAC,IAAI,CAACF,gBAAgB,EAAE;QAC5E;MACF;MAEA,IAAI;QACF,MAAM,IAAI,CAACuB,2BAA2B,CAAC,IAAI,EAAE;UAACL,MAAM;UAAEC,GAAG;UAAElB,OAAO,EAAE,IAAI,CAACA;QAAO,CAAC,CAAC;MACpF,CAAC,CAAC,OAAOuB,KAAK,EAAE;QACdC,oBAAW,CAACD,KAAK,CAAC,2CAA2CA,KAAK,EAAE,EAAE;UACpEE,MAAM,EAAEjC,uBAAuB;UAC/BkC,MAAM,EAAEC,kBAAO,CAACC;QAClB,CAAC,CAAC;QACF,IAAI,CAACZ,oBAAoB,CAACC,MAAM,EAAEC,GAAG,EAAEC,mBAAmB,EAAE,CAAC,CAAC;MAChE;IACF,CAAC,EAAEW,WAAW,CAAC;EACjB;EAEQC,uBAAuBA,CAC7BC,KAAe,EACfd,GAAW,EACXe,WAAoC,EACpCC,UAAkB,EACA;IAClB,MAAMC,IAAI,GAAG;MACXH,KAAK;MACLI,YAAY,EAAE,CACZ;QACEC,IAAI,EAAE,oBAAoB;QAC1BnB,GAAG;QACHe;MACF,CAAC;IAEL,CAAC;IAED,OAAO,IAAI,CAAC7B,KAAK,CACdkC,OAAO,CAAC;MACPZ,MAAM,EAAE,MAAM;MACda,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,SAAS;MACnBL;IACF,CAAC,CAAC,CACDM,IAAI,CAAEC,QAA0B,IAAKA,QAAQ,EAAEP,IAAI,CAAC,CACpDQ,KAAK,CAAEpB,KAAc,IAAK;MACzBC,oBAAW,CAACD,KAAK,CAAC,2BAA2BW,UAAU,YAAYX,KAAK,EAAE,EAAE;QAC1EE,MAAM,EAAEjC,uBAAuB;QAC/BkC,MAAM,EAAEC,kBAAO,CAACC;MAClB,CAAC,CAAC;MAEF,OAAOgB,OAAO,CAACC,MAAM,CAACtB,KAAK,CAAC;IAC9B,CAAC,CAAC;EACN;EAEA,MAAaD,2BAA2BA,CACtCwB,MAAe,EACfC,OAA0F,EAC3E;IACf,MAAMC,mBAAmB,GAAG,IAAI,CAAC/C,iBAAiB;IAClD,MAAMgB,MAAM,GAAG8B,OAAO,EAAE9B,MAAM,IAAI,IAAI,CAACb,KAAK,CAACK,QAAQ,CAACC,MAAM,EAAEO,MAAM;IACpE,MAAMC,GAAG,GAAG6B,OAAO,EAAE7B,GAAG,IAAIzB,8BAA8B;IAC1D,MAAMO,OAAO,GAAG+C,OAAO,EAAE/C,OAAO,IAAIL,gBAAgB;IACpD,MAAMsD,mBAAmB,GAAGF,OAAO,EAAEE,mBAAmB,IAAI,KAAK;IACjE,IAAI,CAACjD,OAAO,GAAGA,OAAO;IAEtB,IAAI,CAACiB,MAAM,EAAE;MACX,MAAMM,KAAK,GAAG,iDAAiD;MAC/D,IAAI,CAAC2B,4BAA4B,CAACJ,MAAM,EAAE,qBAAqB,EAAEvB,KAAK,EAAE0B,mBAAmB,CAAC;MAC5F,MAAM,IAAIE,KAAK,CAAC5B,KAAK,CAAC;IACxB;IAEA,MAAM6B,SAAS,GAAG,IAAI,CAAC5C,YAAY,CAAC,CAAC;IACrC,IAAI,CAAC4C,SAAS,EAAE;MACd,MAAM7B,KAAK,GAAG,oDAAoD;MAClE,IAAI,CAAC2B,4BAA4B,CAC/BJ,MAAM,EACN,wBAAwB,EACxBvB,KAAK,EACL0B,mBACF,CAAC;MACD,MAAM,IAAIE,KAAK,CAAC5B,KAAK,CAAC;IACxB;IAEA,MAAMU,WAAW,GAAG;MAClBoB,OAAO,EAAE,CACP;QACEC,QAAQ,EAAE,IAAI,CAACjD,sBAAsB,CAAC+C,SAAS,CAAC;QAChDpD,OAAO;QACPuD,KAAK,EAAE;UACL,sBAAsB,EAAET;QAC1B;MACF,CAAC;IAEL,CAAC;IAED,MAAMU,cAAc,GAAGC,uBAAc,CAACC,WAAW,CAAC,CAAC;IACnD,MAAMC,uBAAuB,GAAG,CAC9BC,8BAAkB,CAACC,6BAA6B,EAChDD,8BAAkB,CAACE,4BAA4B,CAChD;IAED,IAAIC,gBAAgB,GAAG,CAAC;IACxB,IAAId,mBAAmB,EAAE;MACvB,IAAI,CAAC/C,uBAAuB,IAAI,CAAC;MACjC6D,gBAAgB,GAAG,IAAI,CAAC7D,uBAAuB;MAC/CsD,cAAc,CAACQ,SAAS,CAACL,uBAAuB,CAAC;IACnD;IAEA,IAAI;MACF,MAAM,IAAI,CAAC5B,uBAAuB,CAAC,CAACd,MAAM,CAAC,EAAEC,GAAG,EAAEe,WAAW,EAAE,6BAA6B,CAAC;IAC/F,CAAC,CAAC,OAAOV,KAAK,EAAE;MACd,IAAI0B,mBAAmB,EAAE;QACvB,IAAID,mBAAmB,KAAK,IAAI,CAAC/C,iBAAiB,EAAE;UAClD,IAAI8D,gBAAgB,KAAK,IAAI,CAAC7D,uBAAuB,EAAE;YACrDsD,cAAc,CAACS,gBAAgB,CAACN,uBAAuB,CAAC;UAC1D;QACF,CAAC,MAAM;UACLH,cAAc,CAACU,UAAU,CACvBN,8BAAkB,CAACE,4BAA4B,EAC/C;YACEK,sBAAsB,EAAErB,MAAM;YAC9BvB,KAAK,EAAEA,KAAK,YAAY4B,KAAK,GAAG5B,KAAK,CAAC6C,QAAQ,CAAC,CAAC,GAAGC,MAAM,CAAC9C,KAAK;UACjE,CAAC,EACD,CAAC,aAAa,EAAE,YAAY,CAC9B,CAAC;QACH;MACF;MAEA,MAAMA,KAAK;IACb;IAEA,IAAIyB,mBAAmB,KAAK,IAAI,CAAC/C,iBAAiB,EAAE;MAClD,IAAIgD,mBAAmB,IAAIc,gBAAgB,KAAK,IAAI,CAAC7D,uBAAuB,EAAE;QAC5EsD,cAAc,CAACS,gBAAgB,CAACN,uBAAuB,CAAC;MAC1D;MAEA;IACF;IAEA,IAAI,CAAC5D,gBAAgB,GAAG+C,MAAM;IAE9B,IAAIA,MAAM,EAAE;MACV,IAAI,CAACjB,iBAAiB,CAACZ,MAAM,EAAEC,GAAG,CAAC;IACrC,CAAC,MAAM;MACL,IAAI,CAACjB,iBAAiB,IAAI,CAAC;MAC3B,IAAI,CAACU,iBAAiB,CAAC,CAAC;IAC1B;IAEA,IAAIsC,mBAAmB,EAAE;MACvBO,cAAc,CAACU,UAAU,CACvBN,8BAAkB,CAACC,6BAA6B,EAChD;QAACM,sBAAsB,EAAErB;MAAM,CAAC,EAChC,CAAC,aAAa,EAAE,YAAY,CAC9B,CAAC;IACH;IAEAtB,oBAAW,CAAC8C,IAAI,CAAC,4CAA4CxB,MAAM,EAAE,EAAE;MACrErB,MAAM,EAAEjC,uBAAuB;MAC/BkC,MAAM,EAAEC,kBAAO,CAACC,gCAAgC;MAChD2C,IAAI,EAAE;QACJvE,OAAO;QACPsD,QAAQ,EAAE,IAAI,CAACjD,sBAAsB,CAAC+C,SAAS,CAAC;QAChDlC;MACF;IACF,CAAC,CAAC;EACJ;EAEQgC,4BAA4BA,CAClCJ,MAAe,EACf0B,UAA4D,EAC5DjD,KAAa,EACb0B,mBAA4B,EACtB;IACN,IAAI,CAACA,mBAAmB,EAAE;MACxB;IACF;IAEAQ,uBAAc,CAACC,WAAW,CAAC,CAAC,CAACQ,UAAU,CACrCN,8BAAkB,CAACE,4BAA4B,EAC/C;MACEK,sBAAsB,EAAErB,MAAM;MAC9B0B,UAAU;MACVjD;IACF,CAAC,EACD,CAAC,aAAa,EAAE,YAAY,CAC9B,CAAC;EACH;EAEOkD,QAAQA,CAAA,EAAS;IACtB,IAAI,CAACxE,iBAAiB,IAAI,CAAC;IAC3B,IAAI,CAACU,iBAAiB,CAAC,CAAC;IACxB,IAAI,CAACZ,gBAAgB,GAAG,KAAK;EAC/B;;EAEA;EACO2E,wBAAwBA,CAAA,EAAY;IACzC,OAAO,IAAI,CAAC3E,gBAAgB;EAC9B;AACF;AAAC4E,OAAA,CAAApF,OAAA,GAAAO,uBAAA","ignoreList":[]}
|
|
@@ -6,6 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = exports.TELEPHONY_CALL_UNMUTED = exports.TELEPHONY_CALL_MUTED = void 0;
|
|
7
7
|
var _loggerProxy = _interopRequireDefault(require("../logger-proxy"));
|
|
8
8
|
var _constants = require("../constants");
|
|
9
|
+
var _MetricsManager = _interopRequireDefault(require("../metrics/MetricsManager"));
|
|
10
|
+
var _constants2 = require("../metrics/constants");
|
|
11
|
+
var _wxAppDiagnosticLogging = require("./wxAppDiagnosticLogging");
|
|
9
12
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
13
|
const WXAPP_TELEPHONY_MERCURY_SYNC_FILE = 'WxAppTelephonyMercurySync';
|
|
11
14
|
const TELEPHONY_CALL_MUTED = exports.TELEPHONY_CALL_MUTED = 'event:telephony_calls.muted';
|
|
@@ -31,19 +34,27 @@ class WxAppTelephonyMercurySync {
|
|
|
31
34
|
muted
|
|
32
35
|
} = event?.data ?? {};
|
|
33
36
|
if (!actorId || !callId || muted === undefined) {
|
|
37
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
38
|
+
phase: 'dropped',
|
|
39
|
+
dropReason: 'missing_mercury_event_fields'
|
|
40
|
+
});
|
|
34
41
|
return;
|
|
35
42
|
}
|
|
36
43
|
const decodedActorId = this.decodeBase64(actorId);
|
|
37
44
|
const decodedCallId = this.decodeBase64(callId);
|
|
38
45
|
if (!decodedActorId.endsWith(agentId)) {
|
|
46
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
47
|
+
phase: 'dropped',
|
|
48
|
+
muted,
|
|
49
|
+
callIdSuffix: (0, _wxAppDiagnosticLogging.callIdSuffix)(decodedCallId),
|
|
50
|
+
dropReason: 'actor_id_mismatch'
|
|
51
|
+
});
|
|
39
52
|
return;
|
|
40
53
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
muted
|
|
46
|
-
}
|
|
54
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
55
|
+
phase: 'received',
|
|
56
|
+
muted,
|
|
57
|
+
callIdSuffix: (0, _wxAppDiagnosticLogging.callIdSuffix)(decodedCallId)
|
|
47
58
|
});
|
|
48
59
|
this.muteChangeHandler?.(decodedCallId, muted);
|
|
49
60
|
};
|
|
@@ -55,6 +66,9 @@ class WxAppTelephonyMercurySync {
|
|
|
55
66
|
module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,
|
|
56
67
|
method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
|
|
57
68
|
});
|
|
69
|
+
_MetricsManager.default.getInstance().trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_FAILED, {
|
|
70
|
+
error: 'Mercury is unavailable for wxApp mute sync'
|
|
71
|
+
}, ['operational', 'behavioral']);
|
|
58
72
|
return;
|
|
59
73
|
}
|
|
60
74
|
this.subscribedAgentId = agentId;
|
|
@@ -67,6 +81,7 @@ class WxAppTelephonyMercurySync {
|
|
|
67
81
|
};
|
|
68
82
|
mercury.on(TELEPHONY_CALL_MUTED, this.boundMuteHandler);
|
|
69
83
|
mercury.on(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);
|
|
84
|
+
_MetricsManager.default.getInstance().trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_SUCCESS, {}, ['operational', 'behavioral']);
|
|
70
85
|
_loggerProxy.default.info('Subscribed to wxApp telephony Mercury mute sync', {
|
|
71
86
|
module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,
|
|
72
87
|
method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","e","__esModule","default","WXAPP_TELEPHONY_MERCURY_SYNC_FILE","TELEPHONY_CALL_MUTED","exports","TELEPHONY_CALL_UNMUTED","WxAppTelephonyMercurySync","constructor","webex","decodeBase64","value","atob","handleMuteStateEvent","agentId","event","actorId","callId","muted","data","undefined","decodedActorId","decodedCallId","endsWith","LoggerProxy","
|
|
1
|
+
{"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","_MetricsManager","_constants2","_wxAppDiagnosticLogging","e","__esModule","default","WXAPP_TELEPHONY_MERCURY_SYNC_FILE","TELEPHONY_CALL_MUTED","exports","TELEPHONY_CALL_UNMUTED","WxAppTelephonyMercurySync","constructor","webex","decodeBase64","value","atob","handleMuteStateEvent","agentId","event","actorId","callId","muted","data","undefined","logWxAppMercuryMuteSync","phase","dropReason","decodedActorId","decodedCallId","endsWith","callIdSuffix","muteChangeHandler","subscribe","onMuteChange","unsubscribe","mercury","internal","LoggerProxy","error","module","method","METHODS","SYNC_WXAPP_MUTE_FROM_MERCURY","MetricsManager","getInstance","trackEvent","METRIC_EVENT_NAMES","WXAPP_MERCURY_SUBSCRIBE_FAILED","subscribedAgentId","boundMuteHandler","boundUnmuteHandler","on","WXAPP_MERCURY_SUBSCRIBE_SUCCESS","info","off","isSubscribed","Boolean"],"sources":["WxAppTelephonyMercurySync.ts"],"sourcesContent":["import LoggerProxy from '../logger-proxy';\nimport {METHODS} from '../constants';\nimport {WebexSDK} from '../types';\nimport MetricsManager from '../metrics/MetricsManager';\nimport {METRIC_EVENT_NAMES} from '../metrics/constants';\nimport {callIdSuffix, logWxAppMercuryMuteSync} from './wxAppDiagnosticLogging';\n\nconst WXAPP_TELEPHONY_MERCURY_SYNC_FILE = 'WxAppTelephonyMercurySync';\n\nexport const TELEPHONY_CALL_MUTED = 'event:telephony_calls.muted';\nexport const TELEPHONY_CALL_UNMUTED = 'event:telephony_calls.unmuted';\n\nexport type UpdatedCallMuteStateEvent = {\n data: {\n actorId: string;\n callId: string;\n muted: boolean;\n };\n};\n\ntype MuteChangeHandler = (callId: string, muted: boolean) => void;\n\n/**\n * Subscribes to Mercury telephony mute/unmute events for wxApp thick-client sync (AD parity).\n */\nexport default class WxAppTelephonyMercurySync {\n private webex: WebexSDK;\n private subscribedAgentId?: string;\n private muteChangeHandler?: MuteChangeHandler;\n private boundMuteHandler?: (event: UpdatedCallMuteStateEvent) => void;\n private boundUnmuteHandler?: (event: UpdatedCallMuteStateEvent) => void;\n\n constructor(webex: WebexSDK) {\n this.webex = webex;\n }\n\n private decodeBase64(value: string): string {\n try {\n return atob(value);\n } catch {\n return value;\n }\n }\n\n private handleMuteStateEvent = (agentId: string, event: UpdatedCallMuteStateEvent): void => {\n const {actorId, callId, muted} = event?.data ?? {};\n if (!actorId || !callId || muted === undefined) {\n logWxAppMercuryMuteSync({\n phase: 'dropped',\n dropReason: 'missing_mercury_event_fields',\n });\n\n return;\n }\n\n const decodedActorId = this.decodeBase64(actorId);\n const decodedCallId = this.decodeBase64(callId);\n\n if (!decodedActorId.endsWith(agentId)) {\n logWxAppMercuryMuteSync({\n phase: 'dropped',\n muted,\n callIdSuffix: callIdSuffix(decodedCallId),\n dropReason: 'actor_id_mismatch',\n });\n\n return;\n }\n\n logWxAppMercuryMuteSync({\n phase: 'received',\n muted,\n callIdSuffix: callIdSuffix(decodedCallId),\n });\n\n this.muteChangeHandler?.(decodedCallId, muted);\n };\n\n public subscribe(agentId: string, onMuteChange: MuteChangeHandler): void {\n this.unsubscribe();\n\n const mercury = this.webex.internal.mercury;\n if (!mercury) {\n LoggerProxy.error('Mercury is unavailable for wxApp mute sync', {\n module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,\n method: METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY,\n });\n\n MetricsManager.getInstance().trackEvent(\n METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_FAILED,\n {error: 'Mercury is unavailable for wxApp mute sync'},\n ['operational', 'behavioral']\n );\n\n return;\n }\n\n this.subscribedAgentId = agentId;\n this.muteChangeHandler = onMuteChange;\n\n this.boundMuteHandler = (event: UpdatedCallMuteStateEvent) => {\n this.handleMuteStateEvent(agentId, event);\n };\n this.boundUnmuteHandler = (event: UpdatedCallMuteStateEvent) => {\n this.handleMuteStateEvent(agentId, event);\n };\n\n mercury.on(TELEPHONY_CALL_MUTED, this.boundMuteHandler);\n mercury.on(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);\n\n MetricsManager.getInstance().trackEvent(\n METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_SUCCESS,\n {},\n ['operational', 'behavioral']\n );\n\n LoggerProxy.info('Subscribed to wxApp telephony Mercury mute sync', {\n module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,\n method: METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY,\n });\n }\n\n public unsubscribe(): void {\n const mercury = this.webex.internal.mercury;\n\n if (mercury && this.boundMuteHandler) {\n mercury.off(TELEPHONY_CALL_MUTED, this.boundMuteHandler);\n }\n if (mercury && this.boundUnmuteHandler) {\n mercury.off(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);\n }\n\n this.subscribedAgentId = undefined;\n this.muteChangeHandler = undefined;\n this.boundMuteHandler = undefined;\n this.boundUnmuteHandler = undefined;\n }\n\n public isSubscribed(): boolean {\n return Boolean(this.subscribedAgentId && this.muteChangeHandler);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -15,6 +15,7 @@ var _stateMachine = require("../state-machine");
|
|
|
15
15
|
var _TaskUtils = require("../TaskUtils");
|
|
16
16
|
var _wxAppTelephonyUtils = require("../../wxAppTelephonyUtils");
|
|
17
17
|
var _wxAppVoiceMethods = require("./wxAppVoiceMethods");
|
|
18
|
+
var _wxAppDiagnosticLogging = require("../../wxAppDiagnosticLogging");
|
|
18
19
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
20
|
class Voice extends _Task.default {
|
|
20
21
|
static WXAPP_MUTE_SYNC_RETRY_DELAY_MS = 50;
|
|
@@ -23,6 +24,8 @@ class Voice extends _Task.default {
|
|
|
23
24
|
wxAppMuted = false;
|
|
24
25
|
wxAppAnswerPending = false;
|
|
25
26
|
wxAppAcceptInFlight = false;
|
|
27
|
+
wxAppMuteToggleTail = Promise.resolve();
|
|
28
|
+
wxAppDtmfTail = Promise.resolve();
|
|
26
29
|
constructor(contact, data, callOptions, wrapupData, agentId) {
|
|
27
30
|
const resolvedOptions = {
|
|
28
31
|
isEndTaskEnabled: callOptions?.isEndTaskEnabled ?? true,
|
|
@@ -43,6 +46,7 @@ class Voice extends _Task.default {
|
|
|
43
46
|
enableWxBetterTogether: this.enableWxBetterTogether,
|
|
44
47
|
answerCallOnWebexService: this.answerCallOnWebexService,
|
|
45
48
|
agentId: this.agentId,
|
|
49
|
+
metricsManager: this.metricsManager,
|
|
46
50
|
getTaskData: () => this.data,
|
|
47
51
|
getTaskState: () => this.stateMachineService?.getSnapshot?.()?.value,
|
|
48
52
|
getWxAppMuted: () => this.wxAppMuted,
|
|
@@ -86,15 +90,84 @@ class Voice extends _Task.default {
|
|
|
86
90
|
};
|
|
87
91
|
this.updateUiControls(true);
|
|
88
92
|
}
|
|
93
|
+
updateUiControls(forceEmit = false) {
|
|
94
|
+
super.updateUiControls(forceEmit);
|
|
95
|
+
this.logWxAppOfferDecisionIfNeeded();
|
|
96
|
+
}
|
|
97
|
+
logWxAppOfferDecisionIfNeeded() {
|
|
98
|
+
if (!this.enableWxBetterTogether) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const state = this.stateMachineService?.getSnapshot?.()?.value;
|
|
102
|
+
if (state !== _stateMachine.TaskState.OFFERED) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const accept = this.currentUiControls?.main?.accept;
|
|
106
|
+
if (!accept?.isVisible) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const deps = this.getWxAppVoiceDependencies();
|
|
110
|
+
const isOutdial = this.data?.interaction?.outboundType === 'OUTDIAL';
|
|
111
|
+
const isWxAppInboundOffer = this.isWebexAppInboundCallingOffer();
|
|
112
|
+
const isWxAppOutdialOffer = this.isWebexAppCallingOffer() && isOutdial;
|
|
113
|
+
const deviceDetails = (0, _wxAppVoiceMethods.getCallingDeviceDetails)(deps);
|
|
114
|
+
const acceptReason = (0, _wxAppDiagnosticLogging.deriveWxAppAcceptReason)({
|
|
115
|
+
isWxAppInboundOffer,
|
|
116
|
+
isWxAppOutdialOffer,
|
|
117
|
+
isWebrtc: this.uiControlConfig.voiceVariant === _types.VOICE_VARIANT.WEBRTC,
|
|
118
|
+
isOutdial,
|
|
119
|
+
wxAppAcceptInFlight: this.wxAppAcceptInFlight,
|
|
120
|
+
wxAppAnswerPending: this.wxAppAnswerPending,
|
|
121
|
+
enableWxBetterTogether: this.enableWxBetterTogether,
|
|
122
|
+
hasDeviceCallId: Boolean(deviceDetails?.deviceCallId)
|
|
123
|
+
});
|
|
124
|
+
if (acceptReason === this.lastLoggedWxAppAcceptReason) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
this.lastLoggedWxAppAcceptReason = acceptReason;
|
|
128
|
+
(0, _wxAppDiagnosticLogging.logWxAppOfferDecision)({
|
|
129
|
+
interactionId: this.data.interactionId,
|
|
130
|
+
acceptVisible: accept.isVisible,
|
|
131
|
+
acceptEnabled: accept.isEnabled,
|
|
132
|
+
acceptReason,
|
|
133
|
+
wxAppParticipantDeviceType: deviceDetails?.deviceType,
|
|
134
|
+
hasDeviceCallId: Boolean(deviceDetails?.deviceCallId)
|
|
135
|
+
});
|
|
136
|
+
}
|
|
89
137
|
applyWxAppMuteStateFromSync(incomingCallId, muted) {
|
|
90
138
|
if (!this.enableWxBetterTogether) {
|
|
91
139
|
return;
|
|
92
140
|
}
|
|
93
141
|
const activeCallId = this.getWebexCallingCallId();
|
|
94
|
-
|
|
142
|
+
const incomingSuffix = (0, _wxAppDiagnosticLogging.callIdSuffix)(incomingCallId);
|
|
143
|
+
const activeSuffix = (0, _wxAppDiagnosticLogging.callIdSuffix)(activeCallId);
|
|
144
|
+
if (!activeCallId || !incomingCallId.endsWith(activeCallId)) {
|
|
145
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
146
|
+
phase: 'dropped',
|
|
147
|
+
muted,
|
|
148
|
+
callIdSuffix: incomingSuffix,
|
|
149
|
+
interactionId: this.data.interactionId,
|
|
150
|
+
dropReason: !activeCallId ? 'no_active_wxApp_call' : 'call_id_mismatch'
|
|
151
|
+
});
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (this.wxAppMuted === muted) {
|
|
155
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
156
|
+
phase: 'dropped',
|
|
157
|
+
muted,
|
|
158
|
+
callIdSuffix: incomingSuffix,
|
|
159
|
+
interactionId: this.data.interactionId,
|
|
160
|
+
dropReason: 'mute_state_unchanged'
|
|
161
|
+
});
|
|
95
162
|
return;
|
|
96
163
|
}
|
|
97
164
|
this.wxAppMuted = muted;
|
|
165
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
166
|
+
phase: 'applied',
|
|
167
|
+
muted,
|
|
168
|
+
callIdSuffix: activeSuffix,
|
|
169
|
+
interactionId: this.data.interactionId
|
|
170
|
+
});
|
|
98
171
|
this.emit(_types.TASK_EVENTS.TASK_WXAPP_MUTE_STATE_UPDATED, {
|
|
99
172
|
muted
|
|
100
173
|
});
|
|
@@ -261,9 +334,9 @@ class Voice extends _Task.default {
|
|
|
261
334
|
try {
|
|
262
335
|
this.metricsManager.timeEvent([_constants2.METRIC_EVENT_NAMES.TASK_DECLINE_SUCCESS, _constants2.METRIC_EVENT_NAMES.TASK_DECLINE_FAILED]);
|
|
263
336
|
this.setWxAppAnswerPending(false);
|
|
264
|
-
const response = await this.contact.cancelTask({
|
|
337
|
+
const response = await (0, _wxAppVoiceMethods.runWxAppOutdialDecline)(this.getWxAppVoiceDependencies(), () => this.contact.cancelTask({
|
|
265
338
|
interactionId
|
|
266
|
-
});
|
|
339
|
+
}));
|
|
267
340
|
this.metricsManager.trackEvent(_constants2.METRIC_EVENT_NAMES.TASK_DECLINE_SUCCESS, {
|
|
268
341
|
taskId: interactionId,
|
|
269
342
|
..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
|
|
@@ -287,16 +360,8 @@ class Voice extends _Task.default {
|
|
|
287
360
|
*/
|
|
288
361
|
async toggleMute(options) {
|
|
289
362
|
if (this.enableWxBetterTogether && this.getWebexCallingCallId()) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
const togglePromise = (0, _wxAppVoiceMethods.runWxAppToggleMute)(this.getWxAppVoiceDependencies(), this.createWxAppLifecycle(), options);
|
|
294
|
-
this.wxAppMuteToggleInFlight = togglePromise;
|
|
295
|
-
togglePromise.finally(() => {
|
|
296
|
-
if (this.wxAppMuteToggleInFlight === togglePromise) {
|
|
297
|
-
this.wxAppMuteToggleInFlight = undefined;
|
|
298
|
-
}
|
|
299
|
-
}).catch(() => undefined);
|
|
363
|
+
const togglePromise = this.wxAppMuteToggleTail.catch(() => undefined).then(() => (0, _wxAppVoiceMethods.runWxAppToggleMute)(this.getWxAppVoiceDependencies(), this.createWxAppLifecycle(), options));
|
|
364
|
+
this.wxAppMuteToggleTail = togglePromise.catch(() => undefined);
|
|
300
365
|
await togglePromise;
|
|
301
366
|
return;
|
|
302
367
|
}
|
|
@@ -308,7 +373,9 @@ class Voice extends _Task.default {
|
|
|
308
373
|
*/
|
|
309
374
|
async transmitDtmf(options) {
|
|
310
375
|
if (this.enableWxBetterTogether && this.getWebexCallingCallId()) {
|
|
311
|
-
|
|
376
|
+
const dtmfPromise = this.wxAppDtmfTail.catch(() => undefined).then(() => (0, _wxAppVoiceMethods.runWxAppTransmitDtmf)(this.getWxAppVoiceDependencies(), this.createWxAppLifecycle(), options));
|
|
377
|
+
this.wxAppDtmfTail = dtmfPromise.catch(() => undefined);
|
|
378
|
+
await dtmfPromise;
|
|
312
379
|
return;
|
|
313
380
|
}
|
|
314
381
|
super.unsupportedMethodError(_constants.METHODS.TRANSMIT_DTMF);
|