@webex/internal-plugin-metrics 3.0.0-beta.213 → 3.0.0-beta.215
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/dist/call-diagnostic/call-diagnostic-metrics.js +2 -2
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +8 -3
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/metrics.types.d.ts +1 -0
- package/package.json +8 -8
- package/src/call-diagnostic/call-diagnostic-metrics.ts +2 -1
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +7 -2
- package/src/index.ts +2 -0
- package/src/metrics.types.ts +1 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +13 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +59 -9
- package/test/unit/spec/new-metrics.ts +5 -3
|
@@ -363,8 +363,8 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
363
363
|
}, {
|
|
364
364
|
key: "generateClientEventErrorPayload",
|
|
365
365
|
value: function generateClientEventErrorPayload(rawError) {
|
|
366
|
-
var _rawError$body, _rawError$body2;
|
|
367
|
-
var serviceErrorCode = (rawError === null || rawError === void 0 ? void 0 : (_rawError$body = rawError.body) === null || _rawError$body === void 0 ? void 0 : _rawError$body.errorCode) || (rawError === null || rawError === void 0 ? void 0 : (_rawError$body2 = rawError.body) === null || _rawError$body2 === void 0 ? void 0 : _rawError$body2.code);
|
|
366
|
+
var _rawError$error, _rawError$error$body, _rawError$body, _rawError$body2;
|
|
367
|
+
var serviceErrorCode = (rawError === null || rawError === void 0 ? void 0 : (_rawError$error = rawError.error) === null || _rawError$error === void 0 ? void 0 : (_rawError$error$body = _rawError$error.body) === null || _rawError$error$body === void 0 ? void 0 : _rawError$error$body.errorCode) || (rawError === null || rawError === void 0 ? void 0 : (_rawError$body = rawError.body) === null || _rawError$body === void 0 ? void 0 : _rawError$body.errorCode) || (rawError === null || rawError === void 0 ? void 0 : (_rawError$body2 = rawError.body) === null || _rawError$body2 === void 0 ? void 0 : _rawError$body2.code);
|
|
368
368
|
if (serviceErrorCode) {
|
|
369
369
|
var clientErrorCode = _config2.SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];
|
|
370
370
|
if (clientErrorCode) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","webex","canAuthorize","credentials","isUnverifiedGuest","meetingId","meeting","meetings","meetingCollection","get","meetingInfo","enableConvergedArchitecture","undefined","options","defaultClientType","config","metrics","clientType","defaultSubClientType","subClientType","providedClientVersion","clientVersion","defaultSDKClientVersion","CLIENT_NAME","version","versionMetadata","extractVersionMetadata","origin","name","networkType","userAgent","userAgentToString","clientName","webexVersion","clientInfo","localNetworkPrefix","anonymizeIPAddress","geoHintInfo","clientAddress","osVersion","os","getOSNameInternal","browser","browserVersion","environment","Error","mediaConnections","correlationId","identifiers","internal","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","event","eventId","uuid","v4","originTime","triggered","Date","toISOString","sent","senderCountryCode","countryCode","clearEmptyKeysRecursively","payload","console","warn","submitClientMetrics","CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND","fields","getIdentifiers","clientEventObject","canProceed","webClientDomain","window","location","hostname","intervals","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","diagnosticEvent","prepareDiagnosticEvent","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","rawError","body","code","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","getErrorPayloadForClientErrorCode","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","errors","generatedError","generateClientEventErrorPayload","push","userType","getCurUserType","loginType","getCurLoginType","isConvergedArchitectureEnabled","getIsConvergedArchitectureEnabled","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","finalEvent","eventPayload","type","request","clientEvent","prepareDiagnosticMetricItem","prepareFetchOptions","method","service","resource","StatelessWebexPlugin"],"sources":["call-diagnostic-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport {BrowserDetection} from '@webex/common';\nimport uuid from 'uuid';\nimport {merge} from 'lodash';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {\n anonymizeIPAddress,\n clearEmptyKeysRecursively,\n isLocusServiceErrorCode,\n prepareDiagnosticMetricItem,\n userAgentToString,\n extractVersionMetadata,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n RecursivePartial,\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientEventError,\n ClientEventPayload,\n ClientInfo,\n} from '../metrics.types';\nimport CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';\nimport {\n CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,\n CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n} from './config';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n};\n\n/**\n * @description Util class to handle Call Analyzer Metrics\n * @export\n * @class CallDiagnosticMetrics\n */\nexport default class CallDiagnosticMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.callDiagnosticEventsBatcher = new CallDiagnosticEventsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the login type of the current user\n * @returns one of 'login-ci','unverified-guest', null\n */\n getCurLoginType() {\n // @ts-ignore\n if (this.webex.canAuthorize) {\n // @ts-ignore\n return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';\n }\n\n return null;\n }\n\n /**\n * Returns if the meeting has converged architecture enabled\n * @param options.meetingId\n */\n getIsConvergedArchitectureEnabled({meetingId}: {meetingId?: string}): boolean {\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n return meeting?.meetingInfo?.enableConvergedArchitecture;\n }\n\n return undefined;\n }\n\n /**\n * Get origin object for Call Diagnostic Event payload.\n * @param options\n * @param meetingId\n * @returns\n */\n getOrigin(options: GetOriginOptions, meetingId?: string) {\n const defaultClientType: ClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.clientType;\n const defaultSubClientType: SubClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.subClientType;\n // @ts-ignore\n const providedClientVersion: string = this.webex.meetings.config?.metrics?.clientVersion;\n // @ts-ignore\n const defaultSDKClientVersion = `${CLIENT_NAME}/${this.webex.version}`;\n\n let versionMetadata: Pick<ClientInfo, 'majorVersion' | 'minorVersion'> = {};\n\n // sdk version split doesn't really make sense for now...\n if (providedClientVersion) {\n versionMetadata = extractVersionMetadata(providedClientVersion);\n }\n\n if (\n (defaultClientType && defaultSubClientType) ||\n (options.clientType && options.subClientType)\n ) {\n const origin: Event['origin'] = {\n name: 'endpoint',\n networkType: options?.networkType || 'unknown',\n userAgent: userAgentToString({\n // @ts-ignore\n clientName: this.webex.meetings?.metrics?.clientName,\n // @ts-ignore\n webexVersion: this.webex.version,\n }),\n clientInfo: {\n clientType: options?.clientType || defaultClientType,\n clientVersion: providedClientVersion || defaultSDKClientVersion,\n ...versionMetadata,\n localNetworkPrefix:\n // @ts-ignore\n anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress) || undefined,\n osVersion: getOSVersion() || 'unknown',\n subClientType: options?.subClientType || defaultSubClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n };\n\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n if (meeting?.environment) {\n origin.environment = meeting.environment;\n }\n }\n\n return origin;\n }\n\n throw new Error(\"ClientType and SubClientType can't be undefined\");\n }\n\n /**\n * Gather identifier details for call diagnostic payload.\n * @throws Error if initialization fails.\n * @param options\n */\n getIdentifiers(options: GetIdentifiersOptions) {\n const {meeting, mediaConnections, correlationId} = options;\n const identifiers: Event['event']['identifiers'] = {correlationId: 'unknown'};\n\n if (meeting) {\n identifiers.correlationId = meeting.correlationId;\n }\n\n if (correlationId) {\n identifiers.correlationId = correlationId;\n }\n // @ts-ignore\n if (this.webex.internal) {\n // @ts-ignore\n const {device} = this.webex.internal;\n identifiers.userId = device.userId;\n identifiers.deviceId = device.url;\n identifiers.orgId = device.orgId;\n // @ts-ignore\n identifiers.locusUrl = this.webex.internal.services.get('locus');\n }\n\n if (meeting?.locusInfo?.fullState) {\n identifiers.locusUrl = meeting.locusUrl;\n identifiers.locusId = meeting.locusUrl && meeting.locusUrl.split('/').pop();\n identifiers.locusStartTime =\n meeting.locusInfo.fullState && meeting.locusInfo.fullState.lastActive;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (identifiers.correlationId === undefined) {\n throw new Error('Identifiers initialization failed.');\n }\n\n return identifiers;\n }\n\n /**\n * Create diagnostic event, which can hold client event, feature event or MQE event data.\n * This just initiates the shared properties that are required for all the 3 event categories.\n * @param eventData\n * @param options\n * @returns\n */\n prepareDiagnosticEvent(eventData: Event['event'], options: any) {\n const {meetingId} = options;\n const origin = this.getOrigin(options, meetingId);\n\n const event: Event = {\n eventId: uuid.v4(),\n version: 1,\n origin,\n originTime: {\n triggered: new Date().toISOString(),\n // is overridden in prepareRequest batcher\n sent: 'not_defined_yet',\n },\n // @ts-ignore\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: eventData,\n };\n\n // sanitize (remove empty properties, CA requires it)\n // but we don't want to sanitize MQE as most of the times\n // values will be 0, [] etc, and they are required.\n if (eventData.name !== 'client.mediaquality.event') {\n clearEmptyKeysRecursively(event);\n }\n\n return event;\n }\n\n /**\n * TODO: NOT IMPLEMENTED\n * Submit Feature Event\n * @returns\n */\n public submitFeatureEvent() {\n throw Error('Not implemented');\n }\n\n /**\n * Submit Media Quality Event\n * @param args - submit params\n * @param arg.name - event key\n * @param arg.payload - additional payload to be merge with the default payload\n * @param arg.options - options\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: SubmitMQEOptions;\n }) {\n const {meetingId, mediaConnections} = options;\n\n // events that will most likely happen in join phase\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send MQE but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return;\n }\n\n // merge identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting.mediaConnections || mediaConnections,\n });\n\n // create media quality event object\n let clientEventObject: MediaQualityEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n intervals: payload.intervals,\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n // @ts-ignore\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || 'unknown',\n startTime: new Date().toISOString(),\n },\n };\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append media quality event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n this.submitToCallDiagnostics(diagnosticEvent);\n } else {\n throw new Error(\n 'Media quality events cant be sent outside the context of a meeting. Meeting id is required.'\n );\n }\n }\n\n /**\n * Return Client Event payload by client error code\n * @param arg - get error arg\n * @param arg.clientErrorCode\n * @param arg.serviceErrorCode\n * @returns\n */\n public getErrorPayloadForClientErrorCode({\n clientErrorCode,\n serviceErrorCode,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n }): ClientEventError {\n let error: ClientEventError;\n\n if (clientErrorCode) {\n const partialParsedError = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n if (partialParsedError) {\n error = merge(\n {fatal: true, shownToUser: false, name: 'other', category: 'other'}, // default values\n {errorCode: clientErrorCode},\n {serviceErrorCode},\n partialParsedError\n );\n\n return error;\n }\n }\n\n return undefined;\n }\n\n /**\n * Generate error payload for Client Event\n * @param rawError\n */\n generateClientEventErrorPayload(rawError: any) {\n const serviceErrorCode = rawError?.body?.errorCode || rawError?.body?.code;\n if (serviceErrorCode) {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n if (clientErrorCode) {\n return this.getErrorPayloadForClientErrorCode({clientErrorCode, serviceErrorCode});\n }\n\n // by default, if it is locus error, return nre locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n // otherwise return meeting info\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n return undefined;\n }\n\n /**\n * Create client event object for in meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - options\n * @returns object\n */\n private createClientEventObjectInMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, mediaConnections, rawError} = options;\n\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send client event but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return undefined;\n }\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting?.mediaConnections || mediaConnections,\n });\n\n // check if we need to generate errors\n const errors: ClientEvent['payload']['errors'] = [];\n\n if (rawError) {\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n }\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n errors,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n userType: meeting.getCurUserType(),\n loginType: this.getCurLoginType(),\n isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({\n meetingId,\n }),\n };\n\n return clientEventObject;\n }\n\n /**\n * Create client event object for pre meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - payload\n * @returns object\n */\n private createClientEventObjectPreMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {correlationId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n return clientEventObject;\n }\n\n /**\n * Prepare Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @returns {any} options to be with fetch\n * @throws\n */\n private prepareClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, correlationId} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options});\n } else {\n throw new Error('Not implemented');\n }\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append client event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n\n return diagnosticEvent;\n }\n\n /**\n * Submit Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @throws\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n return this.submitToCallDiagnostics(diagnosticEvent);\n }\n\n /**\n * Prepare the event and send the request to metrics-a service.\n * @param event\n * @returns promise\n */\n submitToCallDiagnostics(event: Event): Promise<any> {\n // build metrics-a event type\n const finalEvent = {\n eventPayload: event,\n type: ['diagnostic-event'],\n };\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Builds a request options object to later be passed to fetch().\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - client event options\n * @returns {Promise<any>}\n * @throws\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n const clientEvent = this.prepareClientEvent({name, payload, options});\n\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: clientEvent,\n type: ['diagnostic-event'],\n });\n\n // @ts-ignore\n return this.webex.prepareFetchOptions({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","webex","canAuthorize","credentials","isUnverifiedGuest","meetingId","meeting","meetings","meetingCollection","get","meetingInfo","enableConvergedArchitecture","undefined","options","defaultClientType","config","metrics","clientType","defaultSubClientType","subClientType","providedClientVersion","clientVersion","defaultSDKClientVersion","CLIENT_NAME","version","versionMetadata","extractVersionMetadata","origin","name","networkType","userAgent","userAgentToString","clientName","webexVersion","clientInfo","localNetworkPrefix","anonymizeIPAddress","geoHintInfo","clientAddress","osVersion","os","getOSNameInternal","browser","browserVersion","environment","Error","mediaConnections","correlationId","identifiers","internal","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","event","eventId","uuid","v4","originTime","triggered","Date","toISOString","sent","senderCountryCode","countryCode","clearEmptyKeysRecursively","payload","console","warn","submitClientMetrics","CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND","fields","getIdentifiers","clientEventObject","canProceed","webClientDomain","window","location","hostname","intervals","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","diagnosticEvent","prepareDiagnosticEvent","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","rawError","body","code","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","getErrorPayloadForClientErrorCode","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","errors","generatedError","generateClientEventErrorPayload","push","userType","getCurUserType","loginType","getCurLoginType","isConvergedArchitectureEnabled","getIsConvergedArchitectureEnabled","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","finalEvent","eventPayload","type","request","clientEvent","prepareDiagnosticMetricItem","prepareFetchOptions","method","service","resource","StatelessWebexPlugin"],"sources":["call-diagnostic-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport {BrowserDetection} from '@webex/common';\nimport uuid from 'uuid';\nimport {merge} from 'lodash';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {\n anonymizeIPAddress,\n clearEmptyKeysRecursively,\n isLocusServiceErrorCode,\n prepareDiagnosticMetricItem,\n userAgentToString,\n extractVersionMetadata,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n RecursivePartial,\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientEventError,\n ClientEventPayload,\n ClientInfo,\n} from '../metrics.types';\nimport CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';\nimport {\n CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,\n CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n} from './config';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n};\n\n/**\n * @description Util class to handle Call Analyzer Metrics\n * @export\n * @class CallDiagnosticMetrics\n */\nexport default class CallDiagnosticMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.callDiagnosticEventsBatcher = new CallDiagnosticEventsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the login type of the current user\n * @returns one of 'login-ci','unverified-guest', null\n */\n getCurLoginType() {\n // @ts-ignore\n if (this.webex.canAuthorize) {\n // @ts-ignore\n return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';\n }\n\n return null;\n }\n\n /**\n * Returns if the meeting has converged architecture enabled\n * @param options.meetingId\n */\n getIsConvergedArchitectureEnabled({meetingId}: {meetingId?: string}): boolean {\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n return meeting?.meetingInfo?.enableConvergedArchitecture;\n }\n\n return undefined;\n }\n\n /**\n * Get origin object for Call Diagnostic Event payload.\n * @param options\n * @param meetingId\n * @returns\n */\n getOrigin(options: GetOriginOptions, meetingId?: string) {\n const defaultClientType: ClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.clientType;\n const defaultSubClientType: SubClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.subClientType;\n // @ts-ignore\n const providedClientVersion: string = this.webex.meetings.config?.metrics?.clientVersion;\n // @ts-ignore\n const defaultSDKClientVersion = `${CLIENT_NAME}/${this.webex.version}`;\n\n let versionMetadata: Pick<ClientInfo, 'majorVersion' | 'minorVersion'> = {};\n\n // sdk version split doesn't really make sense for now...\n if (providedClientVersion) {\n versionMetadata = extractVersionMetadata(providedClientVersion);\n }\n\n if (\n (defaultClientType && defaultSubClientType) ||\n (options.clientType && options.subClientType)\n ) {\n const origin: Event['origin'] = {\n name: 'endpoint',\n networkType: options?.networkType || 'unknown',\n userAgent: userAgentToString({\n // @ts-ignore\n clientName: this.webex.meetings?.metrics?.clientName,\n // @ts-ignore\n webexVersion: this.webex.version,\n }),\n clientInfo: {\n clientType: options?.clientType || defaultClientType,\n clientVersion: providedClientVersion || defaultSDKClientVersion,\n ...versionMetadata,\n localNetworkPrefix:\n // @ts-ignore\n anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress) || undefined,\n osVersion: getOSVersion() || 'unknown',\n subClientType: options?.subClientType || defaultSubClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n };\n\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n if (meeting?.environment) {\n origin.environment = meeting.environment;\n }\n }\n\n return origin;\n }\n\n throw new Error(\"ClientType and SubClientType can't be undefined\");\n }\n\n /**\n * Gather identifier details for call diagnostic payload.\n * @throws Error if initialization fails.\n * @param options\n */\n getIdentifiers(options: GetIdentifiersOptions) {\n const {meeting, mediaConnections, correlationId} = options;\n const identifiers: Event['event']['identifiers'] = {correlationId: 'unknown'};\n\n if (meeting) {\n identifiers.correlationId = meeting.correlationId;\n }\n\n if (correlationId) {\n identifiers.correlationId = correlationId;\n }\n // @ts-ignore\n if (this.webex.internal) {\n // @ts-ignore\n const {device} = this.webex.internal;\n identifiers.userId = device.userId;\n identifiers.deviceId = device.url;\n identifiers.orgId = device.orgId;\n // @ts-ignore\n identifiers.locusUrl = this.webex.internal.services.get('locus');\n }\n\n if (meeting?.locusInfo?.fullState) {\n identifiers.locusUrl = meeting.locusUrl;\n identifiers.locusId = meeting.locusUrl && meeting.locusUrl.split('/').pop();\n identifiers.locusStartTime =\n meeting.locusInfo.fullState && meeting.locusInfo.fullState.lastActive;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (identifiers.correlationId === undefined) {\n throw new Error('Identifiers initialization failed.');\n }\n\n return identifiers;\n }\n\n /**\n * Create diagnostic event, which can hold client event, feature event or MQE event data.\n * This just initiates the shared properties that are required for all the 3 event categories.\n * @param eventData\n * @param options\n * @returns\n */\n prepareDiagnosticEvent(eventData: Event['event'], options: any) {\n const {meetingId} = options;\n const origin = this.getOrigin(options, meetingId);\n\n const event: Event = {\n eventId: uuid.v4(),\n version: 1,\n origin,\n originTime: {\n triggered: new Date().toISOString(),\n // is overridden in prepareRequest batcher\n sent: 'not_defined_yet',\n },\n // @ts-ignore\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: eventData,\n };\n\n // sanitize (remove empty properties, CA requires it)\n // but we don't want to sanitize MQE as most of the times\n // values will be 0, [] etc, and they are required.\n if (eventData.name !== 'client.mediaquality.event') {\n clearEmptyKeysRecursively(event);\n }\n\n return event;\n }\n\n /**\n * TODO: NOT IMPLEMENTED\n * Submit Feature Event\n * @returns\n */\n public submitFeatureEvent() {\n throw Error('Not implemented');\n }\n\n /**\n * Submit Media Quality Event\n * @param args - submit params\n * @param arg.name - event key\n * @param arg.payload - additional payload to be merge with the default payload\n * @param arg.options - options\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: SubmitMQEOptions;\n }) {\n const {meetingId, mediaConnections} = options;\n\n // events that will most likely happen in join phase\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send MQE but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return;\n }\n\n // merge identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting.mediaConnections || mediaConnections,\n });\n\n // create media quality event object\n let clientEventObject: MediaQualityEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n intervals: payload.intervals,\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n // @ts-ignore\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || 'unknown',\n startTime: new Date().toISOString(),\n },\n };\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append media quality event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n this.submitToCallDiagnostics(diagnosticEvent);\n } else {\n throw new Error(\n 'Media quality events cant be sent outside the context of a meeting. Meeting id is required.'\n );\n }\n }\n\n /**\n * Return Client Event payload by client error code\n * @param arg - get error arg\n * @param arg.clientErrorCode\n * @param arg.serviceErrorCode\n * @returns\n */\n public getErrorPayloadForClientErrorCode({\n clientErrorCode,\n serviceErrorCode,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n }): ClientEventError {\n let error: ClientEventError;\n\n if (clientErrorCode) {\n const partialParsedError = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n if (partialParsedError) {\n error = merge(\n {fatal: true, shownToUser: false, name: 'other', category: 'other'}, // default values\n {errorCode: clientErrorCode},\n {serviceErrorCode},\n partialParsedError\n );\n\n return error;\n }\n }\n\n return undefined;\n }\n\n /**\n * Generate error payload for Client Event\n * @param rawError\n */\n generateClientEventErrorPayload(rawError: any) {\n const serviceErrorCode =\n rawError?.error?.body?.errorCode || rawError?.body?.errorCode || rawError?.body?.code;\n if (serviceErrorCode) {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n if (clientErrorCode) {\n return this.getErrorPayloadForClientErrorCode({clientErrorCode, serviceErrorCode});\n }\n\n // by default, if it is locus error, return nre locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n // otherwise return meeting info\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n return undefined;\n }\n\n /**\n * Create client event object for in meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - options\n * @returns object\n */\n private createClientEventObjectInMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, mediaConnections, rawError} = options;\n\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send client event but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return undefined;\n }\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting?.mediaConnections || mediaConnections,\n });\n\n // check if we need to generate errors\n const errors: ClientEvent['payload']['errors'] = [];\n\n if (rawError) {\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n }\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n errors,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n userType: meeting.getCurUserType(),\n loginType: this.getCurLoginType(),\n isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({\n meetingId,\n }),\n };\n\n return clientEventObject;\n }\n\n /**\n * Create client event object for pre meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - payload\n * @returns object\n */\n private createClientEventObjectPreMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {correlationId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n return clientEventObject;\n }\n\n /**\n * Prepare Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @returns {any} options to be with fetch\n * @throws\n */\n private prepareClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, correlationId} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options});\n } else {\n throw new Error('Not implemented');\n }\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append client event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n\n return diagnosticEvent;\n }\n\n /**\n * Submit Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @throws\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n return this.submitToCallDiagnostics(diagnosticEvent);\n }\n\n /**\n * Prepare the event and send the request to metrics-a service.\n * @param event\n * @returns promise\n */\n submitToCallDiagnostics(event: Event): Promise<any> {\n // build metrics-a event type\n const finalEvent = {\n eventPayload: event,\n type: ['diagnostic-event'],\n };\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Builds a request options object to later be passed to fetch().\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - client event options\n * @returns {Promise<any>}\n * @throws\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n const clientEvent = this.prepareClientEvent({name, payload, options});\n\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: clientEvent,\n type: ['diagnostic-event'],\n });\n\n // @ts-ignore\n return this.webex.prepareFetchOptions({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAGA;AACA;AACA;AAEA;AAEA;AAQA;AAgBA;AACA;AAMkB;AAAA;AAAA;AAAA;AAElB,wBAA0D,IAAAA,wBAAgB,GAAE;EAArEC,YAAY,qBAAZA,YAAY;EAAEC,cAAc,qBAAdA,cAAc;EAAEC,iBAAiB,qBAAjBA,iBAAiB;AActD;AACA;AACA;AACA;AACA;AAJA,IAKqBC,qBAAqB;EAAA;EAAA;EACxC;;EAGA;AACF;AACA;AACA;EACE,iCAAqB;IAAA;IAAA;IAAA,kCAANC,IAAI;MAAJA,IAAI;IAAA;IACjB,gDAASA,IAAI;IACb;IAAA;IACA,MAAKC,2BAA2B,GAAG,IAAIC,qCAA2B,CAAC,CAAC,CAAC,EAAE;MAACC,MAAM,EAAE,MAAKC;IAAK,CAAC,CAAC;IAAC;EAC/F;;EAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,2BAAkB;MAChB;MACA,IAAI,IAAI,CAACA,KAAK,CAACC,YAAY,EAAE;QAC3B;QACA,OAAO,IAAI,CAACD,KAAK,CAACE,WAAW,CAACC,iBAAiB,GAAG,kBAAkB,GAAG,UAAU;MACnF;MAEA,OAAO,IAAI;IACb;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,iDAA8E;MAAA,IAA3CC,SAAS,QAATA,SAAS;MAC1C,IAAIA,SAAS,EAAE;QAAA;QACb;QACA,IAAMC,OAAO,GAAG,IAAI,CAACL,KAAK,CAACM,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;QAEpE,OAAOC,OAAO,aAAPA,OAAO,+CAAPA,OAAO,CAAEI,WAAW,yDAApB,qBAAsBC,2BAA2B;MAC1D;MAEA,OAAOC,SAAS;IAClB;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAA;IAAA,OAMA,mBAAUC,OAAyB,EAAER,SAAkB,EAAE;MAAA;MACvD,IAAMS,iBAA6B,GACjC;MAAA,yBACA,IAAI,CAACb,KAAK,CAACM,QAAQ,CAACQ,MAAM,oFAA1B,sBAA4BC,OAAO,2DAAnC,uBAAqCC,UAAU;MACjD,IAAMC,oBAAmC,GACvC;MAAA,0BACA,IAAI,CAACjB,KAAK,CAACM,QAAQ,CAACQ,MAAM,qFAA1B,uBAA4BC,OAAO,2DAAnC,uBAAqCG,aAAa;MACpD;MACA,IAAMC,qBAA6B,6BAAG,IAAI,CAACnB,KAAK,CAACM,QAAQ,CAACQ,MAAM,qFAA1B,uBAA4BC,OAAO,2DAAnC,uBAAqCK,aAAa;MACxF;MACA,IAAMC,uBAAuB,aAAMC,mBAAW,cAAI,IAAI,CAACtB,KAAK,CAACuB,OAAO,CAAE;MAEtE,IAAIC,eAAkE,GAAG,CAAC,CAAC;;MAE3E;MACA,IAAIL,qBAAqB,EAAE;QACzBK,eAAe,GAAG,IAAAC,6CAAsB,EAACN,qBAAqB,CAAC;MACjE;MAEA,IACGN,iBAAiB,IAAII,oBAAoB,IACzCL,OAAO,CAACI,UAAU,IAAIJ,OAAO,CAACM,aAAc,EAC7C;QAAA;QACA,IAAMQ,MAAuB,GAAG;UAC9BC,IAAI,EAAE,UAAU;UAChBC,WAAW,EAAE,CAAAhB,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEgB,WAAW,KAAI,SAAS;UAC9CC,SAAS,EAAE,IAAAC,wCAAiB,EAAC;YAC3B;YACAC,UAAU,0BAAE,IAAI,CAAC/B,KAAK,CAACM,QAAQ,mFAAnB,qBAAqBS,OAAO,2DAA5B,uBAA8BgB,UAAU;YACpD;YACAC,YAAY,EAAE,IAAI,CAAChC,KAAK,CAACuB;UAC3B,CAAC,CAAC;UACFU,UAAU;YACRjB,UAAU,EAAE,CAAAJ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEI,UAAU,KAAIH,iBAAiB;YACpDO,aAAa,EAAED,qBAAqB,IAAIE;UAAuB,GAC5DG,eAAe;YAClBU,kBAAkB;YAChB;YACA,IAAAC,yCAAkB,4BAAC,IAAI,CAACnC,KAAK,CAACM,QAAQ,CAAC8B,WAAW,2DAA/B,uBAAiCC,aAAa,CAAC,IAAI1B,SAAS;YACjF2B,SAAS,EAAE9C,YAAY,EAAE,IAAI,SAAS;YACtC0B,aAAa,EAAE,CAAAN,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEM,aAAa,KAAID,oBAAoB;YAC7DsB,EAAE,EAAE,IAAAC,wCAAiB,GAAE;YACvBC,OAAO,EAAEhD,cAAc,EAAE;YACzBiD,cAAc,EAAEhD,iBAAiB;UAAE;QAEvC,CAAC;QAED,IAAIU,SAAS,EAAE;UACb;UACA,IAAMC,OAAO,GAAG,IAAI,CAACL,KAAK,CAACM,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;UACpE,IAAIC,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEsC,WAAW,EAAE;YACxBjB,MAAM,CAACiB,WAAW,GAAGtC,OAAO,CAACsC,WAAW;UAC1C;QACF;QAEA,OAAOjB,MAAM;MACf;MAEA,MAAM,IAAIkB,KAAK,CAAC,iDAAiD,CAAC;IACpE;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,wBAAehC,OAA8B,EAAE;MAAA;MAC7C,IAAOP,OAAO,GAAqCO,OAAO,CAAnDP,OAAO;QAAEwC,gBAAgB,GAAmBjC,OAAO,CAA1CiC,gBAAgB;QAAEC,aAAa,GAAIlC,OAAO,CAAxBkC,aAAa;MAC/C,IAAMC,WAA0C,GAAG;QAACD,aAAa,EAAE;MAAS,CAAC;MAE7E,IAAIzC,OAAO,EAAE;QACX0C,WAAW,CAACD,aAAa,GAAGzC,OAAO,CAACyC,aAAa;MACnD;MAEA,IAAIA,aAAa,EAAE;QACjBC,WAAW,CAACD,aAAa,GAAGA,aAAa;MAC3C;MACA;MACA,IAAI,IAAI,CAAC9C,KAAK,CAACgD,QAAQ,EAAE;QACvB;QACA,IAAOC,MAAM,GAAI,IAAI,CAACjD,KAAK,CAACgD,QAAQ,CAA7BC,MAAM;QACbF,WAAW,CAACG,MAAM,GAAGD,MAAM,CAACC,MAAM;QAClCH,WAAW,CAACI,QAAQ,GAAGF,MAAM,CAACG,GAAG;QACjCL,WAAW,CAACM,KAAK,GAAGJ,MAAM,CAACI,KAAK;QAChC;QACAN,WAAW,CAACO,QAAQ,GAAG,IAAI,CAACtD,KAAK,CAACgD,QAAQ,CAACO,QAAQ,CAAC/C,GAAG,CAAC,OAAO,CAAC;MAClE;MAEA,IAAIH,OAAO,aAAPA,OAAO,qCAAPA,OAAO,CAAEmD,SAAS,+CAAlB,mBAAoBC,SAAS,EAAE;QACjCV,WAAW,CAACO,QAAQ,GAAGjD,OAAO,CAACiD,QAAQ;QACvCP,WAAW,CAACW,OAAO,GAAGrD,OAAO,CAACiD,QAAQ,IAAIjD,OAAO,CAACiD,QAAQ,CAACK,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,EAAE;QAC3Eb,WAAW,CAACc,cAAc,GACxBxD,OAAO,CAACmD,SAAS,CAACC,SAAS,IAAIpD,OAAO,CAACmD,SAAS,CAACC,SAAS,CAACK,UAAU;MACzE;MAEA,IAAIjB,gBAAgB,EAAE;QAAA;QACpBE,WAAW,CAACgB,eAAe,GAAGlB,gBAAgB,aAAhBA,gBAAgB,6CAAhBA,gBAAgB,CAAG,CAAC,CAAC,uDAArB,mBAAuBkB,eAAe;QACpEhB,WAAW,CAACiB,iBAAiB,GAAGnB,gBAAgB,aAAhBA,gBAAgB,8CAAhBA,gBAAgB,CAAG,CAAC,CAAC,wDAArB,oBAAuBmB,iBAAiB;MAC1E;MAEA,IAAIjB,WAAW,CAACD,aAAa,KAAKnC,SAAS,EAAE;QAC3C,MAAM,IAAIiC,KAAK,CAAC,oCAAoC,CAAC;MACvD;MAEA,OAAOG,WAAW;IACpB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,gCAAuBkB,SAAyB,EAAErD,OAAY,EAAE;MAAA;MAC9D,IAAOR,SAAS,GAAIQ,OAAO,CAApBR,SAAS;MAChB,IAAMsB,MAAM,GAAG,IAAI,CAACwC,SAAS,CAACtD,OAAO,EAAER,SAAS,CAAC;MAEjD,IAAM+D,KAAY,GAAG;QACnBC,OAAO,EAAEC,aAAI,CAACC,EAAE,EAAE;QAClB/C,OAAO,EAAE,CAAC;QACVG,MAAM,EAANA,MAAM;QACN6C,UAAU,EAAE;UACVC,SAAS,EAAE,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;UACnC;UACAC,IAAI,EAAE;QACR,CAAC;QACD;QACAC,iBAAiB,4BAAE,IAAI,CAAC5E,KAAK,CAACM,QAAQ,CAAC8B,WAAW,2DAA/B,uBAAiCyC,WAAW;QAC/DV,KAAK,EAAEF;MACT,CAAC;;MAED;MACA;MACA;MACA,IAAIA,SAAS,CAACtC,IAAI,KAAK,2BAA2B,EAAE;QAClD,IAAAmD,gDAAyB,EAACX,KAAK,CAAC;MAClC;MAEA,OAAOA,KAAK;IACd;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,8BAA4B;MAC1B,MAAMvB,KAAK,CAAC,iBAAiB,CAAC;IAChC;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,0BAQG;MAAA,IAPDjB,IAAI,SAAJA,IAAI;QACJoD,OAAO,SAAPA,OAAO;QACPnE,OAAO,SAAPA,OAAO;MAMP,IAAOR,SAAS,GAAsBQ,OAAO,CAAtCR,SAAS;QAAEyC,gBAAgB,GAAIjC,OAAO,CAA3BiC,gBAAgB;;MAElC;MACA,IAAIzC,SAAS,EAAE;QACb;QACA,IAAMC,OAAO,GAAG,IAAI,CAACL,KAAK,CAACM,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;QAEpE,IAAI,CAACC,OAAO,EAAE;UACZ2E,OAAO,CAACC,IAAI,CACV,iDAAiD,mBACvCtD,IAAI,0BAAgBvB,SAAS,EACxC;UACD;UACA,IAAI,CAACJ,KAAK,CAACgD,QAAQ,CAACjC,OAAO,CAACmE,mBAAmB,CAACC,6CAAoC,EAAE;YACpFC,MAAM,EAAE;cACNhF,SAAS,EAATA,SAAS;cACTuB,IAAI,EAAJA;YACF;UACF,CAAC,CAAC;UAEF;QACF;;QAEA;QACA,IAAMoB,WAAW,GAAG,IAAI,CAACsC,cAAc,CAAC;UACtChF,OAAO,EAAPA,OAAO;UACPwC,gBAAgB,EAAExC,OAAO,CAACwC,gBAAgB,IAAIA;QAChD,CAAC,CAAC;;QAEF;QACA,IAAIyC,iBAA+C,GAAG;UACpD3D,IAAI,EAAJA,IAAI;UACJ4D,UAAU,EAAE,IAAI;UAChBxC,WAAW,EAAXA,WAAW;UACXkB,SAAS,EAAE;YACTuB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;UACnC,CAAC;UACDC,SAAS,EAAEb,OAAO,CAACa,SAAS;UAC5BC,cAAc,EAAE;YACdC,uBAAuB,EAAExE,mBAAW;YACpC;YACAyE,0BAA0B,EAAE,IAAI,CAAC/F,KAAK,CAACuB,OAAO;YAC9CyE,uBAAuB,EAAEvG,cAAc,EAAE,IAAI,SAAS;YACtDwG,0BAA0B,EAAEzG,YAAY,EAAE,IAAI,SAAS;YACvD0G,SAAS,EAAE,IAAIzB,IAAI,EAAE,CAACC,WAAW;UACnC;QACF,CAAC;;QAED;QACAY,iBAAiB,GAAG,qBAAMA,iBAAiB,EAAEP,OAAO,CAAC;;QAErD;QACA,IAAMoB,eAAe,GAAG,IAAI,CAACC,sBAAsB,CAACd,iBAAiB,EAAE1E,OAAO,CAAC;QAC/E,IAAI,CAACyF,uBAAuB,CAACF,eAAe,CAAC;MAC/C,CAAC,MAAM;QACL,MAAM,IAAIvD,KAAK,CACb,6FAA6F,CAC9F;MACH;IACF;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,kDAMqB;MAAA,IALnB0D,eAAe,SAAfA,eAAe;QACfC,gBAAgB,SAAhBA,gBAAgB;MAKhB,IAAIC,KAAuB;MAE3B,IAAIF,eAAe,EAAE;QACnB,IAAMG,kBAAkB,GAAGC,2CAAkC,CAACJ,eAAe,CAAC;QAE9E,IAAIG,kBAAkB,EAAE;UACtBD,KAAK,GAAG,qBACN;YAACG,KAAK,EAAE,IAAI;YAAEC,WAAW,EAAE,KAAK;YAAEjF,IAAI,EAAE,OAAO;YAAEkF,QAAQ,EAAE;UAAO,CAAC;UAAE;UACrE;YAACC,SAAS,EAAER;UAAe,CAAC,EAC5B;YAACC,gBAAgB,EAAhBA;UAAgB,CAAC,EAClBE,kBAAkB,CACnB;UAED,OAAOD,KAAK;QACd;MACF;MAEA,OAAO7F,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,yCAAgCoG,QAAa,EAAE;MAAA;MAC7C,IAAMR,gBAAgB,GACpB,CAAAQ,QAAQ,aAARA,QAAQ,0CAARA,QAAQ,CAAEP,KAAK,4EAAf,gBAAiBQ,IAAI,yDAArB,qBAAuBF,SAAS,MAAIC,QAAQ,aAARA,QAAQ,yCAARA,QAAQ,CAAEC,IAAI,mDAAd,eAAgBF,SAAS,MAAIC,QAAQ,aAARA,QAAQ,0CAARA,QAAQ,CAAEC,IAAI,oDAAd,gBAAgBC,IAAI;MACvF,IAAIV,gBAAgB,EAAE;QACpB,IAAMD,eAAe,GAAGY,sDAA6C,CAACX,gBAAgB,CAAC;QACvF,IAAID,eAAe,EAAE;UACnB,OAAO,IAAI,CAACa,iCAAiC,CAAC;YAACb,eAAe,EAAfA,eAAe;YAAEC,gBAAgB,EAAhBA;UAAgB,CAAC,CAAC;QACpF;;QAEA;QACA,IAAI,IAAAa,8CAAuB,EAACb,gBAAgB,CAAC,EAAE;UAC7C,OAAO,IAAI,CAACY,iCAAiC,CAAC;YAC5Cb,eAAe,EAAEe,oCAA2B;YAC5Cd,gBAAgB,EAAhBA;UACF,CAAC,CAAC;QACJ;;QAEA;QACA,OAAO,IAAI,CAACY,iCAAiC,CAAC;UAC5Cb,eAAe,EAAEgB,8CAAqC;UACtDf,gBAAgB,EAAhBA;QACF,CAAC,CAAC;MACJ;MAEA,OAAO5F,SAAS;IAClB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,iDAMG;MAAA,IALDgB,IAAI,SAAJA,IAAI;QACJf,OAAO,SAAPA,OAAO;MAKP,IAAOR,SAAS,GAAgCQ,OAAO,CAAhDR,SAAS;QAAEyC,gBAAgB,GAAcjC,OAAO,CAArCiC,gBAAgB;QAAEkE,QAAQ,GAAInG,OAAO,CAAnBmG,QAAQ;;MAE5C;MACA,IAAM1G,OAAO,GAAG,IAAI,CAACL,KAAK,CAACM,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;MAEpE,IAAI,CAACC,OAAO,EAAE;QACZ2E,OAAO,CAACC,IAAI,CACV,0DAA0D,mBAChDtD,IAAI,0BAAgBvB,SAAS,EACxC;QACD;QACA,IAAI,CAACJ,KAAK,CAACgD,QAAQ,CAACjC,OAAO,CAACmE,mBAAmB,CAACC,6CAAoC,EAAE;UACpFC,MAAM,EAAE;YACNhF,SAAS,EAATA,SAAS;YACTuB,IAAI,EAAJA;UACF;QACF,CAAC,CAAC;QAEF,OAAOhB,SAAS;MAClB;;MAEA;MACA,IAAMoC,WAAW,GAAG,IAAI,CAACsC,cAAc,CAAC;QACtChF,OAAO,EAAPA,OAAO;QACPwC,gBAAgB,EAAE,CAAAxC,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEwC,gBAAgB,KAAIA;MACjD,CAAC,CAAC;;MAEF;MACA,IAAM0E,MAAwC,GAAG,EAAE;MAEnD,IAAIR,QAAQ,EAAE;QACZ,IAAMS,cAAc,GAAG,IAAI,CAACC,+BAA+B,CAACV,QAAQ,CAAC;QACrE,IAAIS,cAAc,EAAE;UAClBD,MAAM,CAACG,IAAI,CAACF,cAAc,CAAC;QAC7B;MACF;;MAEA;MACA,IAAMlC,iBAAyC,GAAG;QAChD3D,IAAI,EAAJA,IAAI;QACJ4D,UAAU,EAAE,IAAI;QAChBxC,WAAW,EAAXA,WAAW;QACXwE,MAAM,EAANA,MAAM;QACNtD,SAAS,EAAE;UACTuB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;QACnC,CAAC;QACDgC,QAAQ,EAAEtH,OAAO,CAACuH,cAAc,EAAE;QAClCC,SAAS,EAAE,IAAI,CAACC,eAAe,EAAE;QACjCC,8BAA8B,EAAE,IAAI,CAACC,iCAAiC,CAAC;UACrE5H,SAAS,EAATA;QACF,CAAC;MACH,CAAC;MAED,OAAOkF,iBAAiB;IAC1B;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,kDAMG;MAAA,IALD3D,IAAI,SAAJA,IAAI;QACJf,OAAO,SAAPA,OAAO;MAKP,IAAOkC,aAAa,GAAIlC,OAAO,CAAxBkC,aAAa;;MAEpB;MACA,IAAMC,WAAW,GAAG,IAAI,CAACsC,cAAc,CAAC;QACtCvC,aAAa,EAAbA;MACF,CAAC,CAAC;;MAEF;MACA,IAAMwC,iBAAyC,GAAG;QAChD3D,IAAI,EAAJA,IAAI;QACJ4D,UAAU,EAAE,IAAI;QAChBxC,WAAW,EAAXA,WAAW;QACXkB,SAAS,EAAE;UACTuB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;QACnC,CAAC;QACDkC,SAAS,EAAE,IAAI,CAACC,eAAe;MACjC,CAAC;MAED,OAAOxC,iBAAiB;IAC1B;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAA;IAAA,OASA,mCAQG;MAAA,IAPD3D,IAAI,SAAJA,IAAI;QACJoD,OAAO,SAAPA,OAAO;QACPnE,OAAO,SAAPA,OAAO;MAMP,IAAOR,SAAS,GAAmBQ,OAAO,CAAnCR,SAAS;QAAE0C,aAAa,GAAIlC,OAAO,CAAxBkC,aAAa;MAC/B,IAAIwC,iBAAyC;;MAE7C;MACA,IAAIlF,SAAS,EAAE;QACbkF,iBAAiB,GAAG,IAAI,CAAC2C,gCAAgC,CAAC;UAACtG,IAAI,EAAJA,IAAI;UAAEf,OAAO,EAAPA;QAAO,CAAC,CAAC;MAC5E,CAAC,MAAM,IAAIkC,aAAa,EAAE;QACxB;QACAwC,iBAAiB,GAAG,IAAI,CAAC4C,iCAAiC,CAAC;UAACvG,IAAI,EAAJA,IAAI;UAAEf,OAAO,EAAPA;QAAO,CAAC,CAAC;MAC7E,CAAC,MAAM;QACL,MAAM,IAAIgC,KAAK,CAAC,iBAAiB,CAAC;MACpC;;MAEA;MACA0C,iBAAiB,GAAG,qBAAMA,iBAAiB,EAAEP,OAAO,CAAC;;MAErD;MACA,IAAMoB,eAAe,GAAG,IAAI,CAACC,sBAAsB,CAACd,iBAAiB,EAAE1E,OAAO,CAAC;MAE/E,OAAOuF,eAAe;IACxB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EAPE;IAAA;IAAA,OAQA,kCAQG;MAAA,IAPDxE,IAAI,SAAJA,IAAI;QACJoD,OAAO,SAAPA,OAAO;QACPnE,OAAO,SAAPA,OAAO;MAMP,IAAMuF,eAAe,GAAG,IAAI,CAACgC,kBAAkB,CAAC;QAACxG,IAAI,EAAJA,IAAI;QAAEoD,OAAO,EAAPA,OAAO;QAAEnE,OAAO,EAAPA;MAAO,CAAC,CAAC;MAEzE,OAAO,IAAI,CAACyF,uBAAuB,CAACF,eAAe,CAAC;IACtD;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,iCAAwBhC,KAAY,EAAgB;MAClD;MACA,IAAMiE,UAAU,GAAG;QACjBC,YAAY,EAAElE,KAAK;QACnBmE,IAAI,EAAE,CAAC,kBAAkB;MAC3B,CAAC;MAED,OAAO,IAAI,CAACzI,2BAA2B,CAAC0I,OAAO,CAACH,UAAU,CAAC;IAC7D;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAA;IAAA;MAAA,mHASA;QAAA;QAAA;UAAA;YAAA;cACEzG,IAAI,SAAJA,IAAI,EACJoD,OAAO,SAAPA,OAAO,EACPnE,OAAO,SAAPA,OAAO;cAMD4H,WAAW,GAAG,IAAI,CAACL,kBAAkB,CAAC;gBAACxG,IAAI,EAAJA,IAAI;gBAAEoD,OAAO,EAAPA,OAAO;gBAAEnE,OAAO,EAAPA;cAAO,CAAC,CAAC,EAErE;cACA;cACMuF,eAAe,GAAG,IAAAsC,kDAA2B,EAAC,IAAI,CAACzI,KAAK,EAAE;gBAC9DqI,YAAY,EAAEG,WAAW;gBACzBF,IAAI,EAAE,CAAC,kBAAkB;cAC3B,CAAC,CAAC,EAEF;cAAA,iCACO,IAAI,CAACtI,KAAK,CAAC0I,mBAAmB,CAAC;gBACpCC,MAAM,EAAE,MAAM;gBACdC,OAAO,EAAE,SAAS;gBAClBC,QAAQ,EAAE,eAAe;gBACzB7B,IAAI,EAAE;kBACJjG,OAAO,EAAE,CAACoF,eAAe;gBAC3B;cACF,CAAC,CAAC;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA,CACH;MAAA;QAAA;MAAA;MAAA;IAAA;EAAA;EAAA;AAAA,EAhjBgD2C,+BAAoB;AAAA"}
|
|
@@ -9,6 +9,7 @@ exports.userAgentToString = exports.setMetricTimings = exports.prepareDiagnostic
|
|
|
9
9
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
10
10
|
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
|
|
11
11
|
var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
|
|
12
|
+
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
12
13
|
var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-int"));
|
|
13
14
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
14
15
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
@@ -209,17 +210,21 @@ var prepareDiagnosticMetricItem = function prepareDiagnosticMetricItem(webex, it
|
|
|
209
210
|
*/
|
|
210
211
|
exports.prepareDiagnosticMetricItem = prepareDiagnosticMetricItem;
|
|
211
212
|
var setMetricTimings = function setMetricTimings(options) {
|
|
212
|
-
|
|
213
|
-
|
|
213
|
+
if (options.body && options.json) {
|
|
214
|
+
var _body$metrics;
|
|
215
|
+
var body = JSON.parse(options.body);
|
|
214
216
|
var now = new Date().toISOString();
|
|
215
|
-
|
|
217
|
+
(_body$metrics = body.metrics) === null || _body$metrics === void 0 ? void 0 : _body$metrics.forEach(function (metric) {
|
|
216
218
|
if (metric.eventPayload) {
|
|
219
|
+
// The event will effectively be triggered and sent at the same time.
|
|
220
|
+
// The existing triggered time is from when the options were built.
|
|
217
221
|
metric.eventPayload.originTime = {
|
|
218
222
|
triggered: now,
|
|
219
223
|
sent: now
|
|
220
224
|
};
|
|
221
225
|
}
|
|
222
226
|
});
|
|
227
|
+
options.body = (0, _stringify.default)(body);
|
|
223
228
|
}
|
|
224
229
|
return options;
|
|
225
230
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","getBuildType","webClientDomain","includes","prepareDiagnosticMetricItem","webex","item","origin","buildType","event","eventData","networkType","eventName","eventPayload","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","setMetricTimings","options","body","metrics","now","Date","toISOString","metric","originTime","triggered","sent","extractVersionMetadata","version","majorVersion","minorVersion"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (webClientDomain): Event['origin']['buildType'] => {\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body?.metrics) {\n const now = new Date().toISOString();\n options.body.metrics.forEach((metric) => {\n if (metric.eventPayload) {\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n }\n\n return options;\n};\n\nexport const extractVersionMetadata = (version: string) => {\n // extract major and minor version\n const [majorVersion, minorVersion] = version.split('.');\n\n return {\n majorVersion: parseInt(majorVersion, 10),\n minorVersion: parseInt(minorVersion, 10),\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","getBuildType","webClientDomain","includes","prepareDiagnosticMetricItem","webex","item","origin","buildType","event","eventData","networkType","eventName","eventPayload","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","setMetricTimings","options","body","json","JSON","parse","now","Date","toISOString","metrics","metric","originTime","triggered","sent","extractVersionMetadata","version","majorVersion","minorVersion"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (webClientDomain): Event['origin']['buildType'] => {\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body && options.json) {\n const body = JSON.parse(options.body);\n\n const now = new Date().toISOString();\n body.metrics?.forEach((metric) => {\n if (metric.eventPayload) {\n // The event will effectively be triggered and sent at the same time.\n // The existing triggered time is from when the options were built.\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n options.body = JSON.stringify(body);\n }\n\n return options;\n};\n\nexport const extractVersionMetadata = (version: string) => {\n // extract major and minor version\n const [majorVersion, minorVersion] = version.split('.');\n\n return {\n majorVersion: parseInt(majorVersion, 10),\n minorVersion: parseInt(minorVersion, 10),\n };\n};\n"],"mappings":"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"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["registerInternalPlugin","Metrics","config","NewMetrics"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport '@webex/internal-plugin-device';\n\nimport {registerInternalPlugin} from '@webex/webex-core';\n\nimport Metrics from './metrics';\nimport config from './config';\nimport NewMetrics from './new-metrics';\nimport {\n ClientEvent,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitOperationalEvent,\n SubmitMQE,\n} from './metrics.types';\nimport * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';\n\nregisterInternalPlugin('metrics', Metrics, {\n config,\n});\n\nregisterInternalPlugin('newMetrics', NewMetrics, {\n config,\n});\n\nexport {default, getOSNameInternal} from './metrics';\nexport {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics};\nexport type {\n ClientEvent,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitMQE,\n SubmitOperationalEvent,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;AAEA;AAEA;AACA;AACA;
|
|
1
|
+
{"version":3,"names":["registerInternalPlugin","Metrics","config","NewMetrics"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport '@webex/internal-plugin-device';\n\nimport {registerInternalPlugin} from '@webex/webex-core';\n\nimport Metrics from './metrics';\nimport config from './config';\nimport NewMetrics from './new-metrics';\nimport {\n ClientEvent,\n ClientEventLeaveReason,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitOperationalEvent,\n SubmitMQE,\n} from './metrics.types';\nimport * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';\n\nregisterInternalPlugin('metrics', Metrics, {\n config,\n});\n\nregisterInternalPlugin('newMetrics', NewMetrics, {\n config,\n});\n\nexport {default, getOSNameInternal} from './metrics';\nexport {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics};\nexport type {\n ClientEvent,\n ClientEventLeaveReason,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitMQE,\n SubmitOperationalEvent,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;AAEA;AAEA;AACA;AACA;AAUA;AAAmE;AAAA;AAAA;AApBnE;AACA;AACA;;AAoBA,IAAAA,iCAAsB,EAAC,SAAS,EAAEC,gBAAO,EAAE;EACzCC,MAAM,EAANA;AACF,CAAC,CAAC;AAEF,IAAAF,iCAAsB,EAAC,YAAY,EAAEG,mBAAU,EAAE;EAC/CD,MAAM,EAANA;AACF,CAAC,CAAC"}
|
package/dist/metrics.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {ClientEvent as RawClientEvent} from './call-diagnostic/generated-types-temp/ClientEvent';\nimport {Event as RawEvent} from './call-diagnostic/generated-types-temp/Event';\nimport {MediaQualityEvent as RawMediaQualityEvent} from './call-diagnostic/generated-types-temp/MediaQualityEvent';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n showToUser?: boolean;\n correlationId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.interstitial-window.launched'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.interstitial-window.click.joinbutton';\n payload?: never;\n options?: never;\n};\n\nexport interface ClientEvent {\n name: RawClientEvent['name'];\n payload?: RawClientEvent;\n options?: SubmitClientEventOptions;\n}\n\nexport interface BehavioralEvent {\n // TODO: not implemented\n name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';\n payload?: never;\n options?: never;\n}\n\nexport interface OperationalEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface FeatureEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface MediaQualityEvent {\n name: RawMediaQualityEvent['name'];\n payload?: RawMediaQualityEvent;\n options: SubmitMQEOptions;\n}\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? RecursivePartial<U>[]\n : T[P] extends object\n ? RecursivePartial<T[P]>\n : T[P];\n};\n\nexport type MetricEventNames =\n | InternalEvent['name']\n | ClientEvent['name']\n | BehavioralEvent['name']\n | OperationalEvent['name']\n | FeatureEvent['name']\n | MediaQualityEvent['name'];\n\nexport type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;\nexport type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];\nexport type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];\nexport type NetworkType = NonNullable<RawEvent['origin']>['networkType'];\n\nexport type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;\n\nexport type MediaQualityEventAudioSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['audioSetupDelay'];\nexport type MediaQualityEventVideoSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['videoSetupDelay'];\n\nexport type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];\n};\n\nexport type SubmitInternalEvent = (args: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitBehavioralEvent = (args: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitClientEvent = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type SubmitOperationalEvent = (args: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n"],"mappings":""}
|
|
1
|
+
{"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {ClientEvent as RawClientEvent} from './call-diagnostic/generated-types-temp/ClientEvent';\nimport {Event as RawEvent} from './call-diagnostic/generated-types-temp/Event';\nimport {MediaQualityEvent as RawMediaQualityEvent} from './call-diagnostic/generated-types-temp/MediaQualityEvent';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n showToUser?: boolean;\n correlationId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.interstitial-window.launched'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.interstitial-window.click.joinbutton';\n payload?: never;\n options?: never;\n};\n\nexport interface ClientEvent {\n name: RawClientEvent['name'];\n payload?: RawClientEvent;\n options?: SubmitClientEventOptions;\n}\n\nexport interface BehavioralEvent {\n // TODO: not implemented\n name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';\n payload?: never;\n options?: never;\n}\n\nexport interface OperationalEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface FeatureEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface MediaQualityEvent {\n name: RawMediaQualityEvent['name'];\n payload?: RawMediaQualityEvent;\n options: SubmitMQEOptions;\n}\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? RecursivePartial<U>[]\n : T[P] extends object\n ? RecursivePartial<T[P]>\n : T[P];\n};\n\nexport type MetricEventNames =\n | InternalEvent['name']\n | ClientEvent['name']\n | BehavioralEvent['name']\n | OperationalEvent['name']\n | FeatureEvent['name']\n | MediaQualityEvent['name'];\n\nexport type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;\nexport type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];\nexport type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];\nexport type NetworkType = NonNullable<RawEvent['origin']>['networkType'];\n\nexport type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;\nexport type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];\n\nexport type MediaQualityEventAudioSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['audioSetupDelay'];\nexport type MediaQualityEventVideoSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['videoSetupDelay'];\n\nexport type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];\n};\n\nexport type SubmitInternalEvent = (args: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitBehavioralEvent = (args: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitClientEvent = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type SubmitOperationalEvent = (args: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n"],"mappings":""}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import '@webex/internal-plugin-device';
|
|
5
5
|
import config from './config';
|
|
6
6
|
import NewMetrics from './new-metrics';
|
|
7
|
-
import { ClientEvent, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE } from './metrics.types';
|
|
7
|
+
import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE } from './metrics.types';
|
|
8
8
|
import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
|
|
9
9
|
export { default, getOSNameInternal } from './metrics';
|
|
10
10
|
export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics };
|
|
11
|
-
export type { ClientEvent, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, };
|
|
11
|
+
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, };
|
|
@@ -56,6 +56,7 @@ export type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientTy
|
|
|
56
56
|
export type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];
|
|
57
57
|
export type NetworkType = NonNullable<RawEvent['origin']>['networkType'];
|
|
58
58
|
export type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;
|
|
59
|
+
export type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];
|
|
59
60
|
export type MediaQualityEventAudioSetupDelayPayload = NonNullable<MediaQualityEvent['payload']>['audioSetupDelay'];
|
|
60
61
|
export type MediaQualityEventVideoSetupDelayPayload = NonNullable<MediaQualityEvent['payload']>['videoSetupDelay'];
|
|
61
62
|
export type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-metrics",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.215",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@webex/common": "3.0.0-beta.
|
|
32
|
-
"@webex/common-timers": "3.0.0-beta.
|
|
33
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
34
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
35
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
36
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
37
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
31
|
+
"@webex/common": "3.0.0-beta.215",
|
|
32
|
+
"@webex/common-timers": "3.0.0-beta.215",
|
|
33
|
+
"@webex/internal-plugin-device": "3.0.0-beta.215",
|
|
34
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.215",
|
|
35
|
+
"@webex/test-helper-chai": "3.0.0-beta.215",
|
|
36
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.215",
|
|
37
|
+
"@webex/webex-core": "3.0.0-beta.215"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -375,7 +375,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
375
375
|
* @param rawError
|
|
376
376
|
*/
|
|
377
377
|
generateClientEventErrorPayload(rawError: any) {
|
|
378
|
-
const serviceErrorCode =
|
|
378
|
+
const serviceErrorCode =
|
|
379
|
+
rawError?.error?.body?.errorCode || rawError?.body?.errorCode || rawError?.body?.code;
|
|
379
380
|
if (serviceErrorCode) {
|
|
380
381
|
const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];
|
|
381
382
|
if (clientErrorCode) {
|
|
@@ -218,16 +218,21 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
218
218
|
* @returns {any} the updated options object
|
|
219
219
|
*/
|
|
220
220
|
export const setMetricTimings = (options) => {
|
|
221
|
-
if (options.body
|
|
221
|
+
if (options.body && options.json) {
|
|
222
|
+
const body = JSON.parse(options.body);
|
|
223
|
+
|
|
222
224
|
const now = new Date().toISOString();
|
|
223
|
-
|
|
225
|
+
body.metrics?.forEach((metric) => {
|
|
224
226
|
if (metric.eventPayload) {
|
|
227
|
+
// The event will effectively be triggered and sent at the same time.
|
|
228
|
+
// The existing triggered time is from when the options were built.
|
|
225
229
|
metric.eventPayload.originTime = {
|
|
226
230
|
triggered: now,
|
|
227
231
|
sent: now,
|
|
228
232
|
};
|
|
229
233
|
}
|
|
230
234
|
});
|
|
235
|
+
options.body = JSON.stringify(body);
|
|
231
236
|
}
|
|
232
237
|
|
|
233
238
|
return options;
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import config from './config';
|
|
|
11
11
|
import NewMetrics from './new-metrics';
|
|
12
12
|
import {
|
|
13
13
|
ClientEvent,
|
|
14
|
+
ClientEventLeaveReason,
|
|
14
15
|
SubmitBehavioralEvent,
|
|
15
16
|
SubmitClientEvent,
|
|
16
17
|
SubmitInternalEvent,
|
|
@@ -31,6 +32,7 @@ export {default, getOSNameInternal} from './metrics';
|
|
|
31
32
|
export {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics};
|
|
32
33
|
export type {
|
|
33
34
|
ClientEvent,
|
|
35
|
+
ClientEventLeaveReason,
|
|
34
36
|
SubmitBehavioralEvent,
|
|
35
37
|
SubmitClientEvent,
|
|
36
38
|
SubmitInternalEvent,
|
package/src/metrics.types.ts
CHANGED
|
@@ -89,6 +89,7 @@ export type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subCl
|
|
|
89
89
|
export type NetworkType = NonNullable<RawEvent['origin']>['networkType'];
|
|
90
90
|
|
|
91
91
|
export type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;
|
|
92
|
+
export type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];
|
|
92
93
|
|
|
93
94
|
export type MediaQualityEventAudioSetupDelayPayload = NonNullable<
|
|
94
95
|
MediaQualityEvent['payload']
|
|
@@ -747,6 +747,19 @@ describe('internal-plugin-metrics', () => {
|
|
|
747
747
|
});
|
|
748
748
|
});
|
|
749
749
|
|
|
750
|
+
it('should generate event error payload correctly for nested error', () => {
|
|
751
|
+
const res = cd.generateClientEventErrorPayload({error: {body: {errorCode: 2409005}}});
|
|
752
|
+
assert.deepEqual(res, {
|
|
753
|
+
category: 'expected',
|
|
754
|
+
errorDescription: 'StartRecordingFailed',
|
|
755
|
+
fatal: true,
|
|
756
|
+
name: 'other',
|
|
757
|
+
shownToUser: false,
|
|
758
|
+
errorCode: 4029,
|
|
759
|
+
serviceErrorCode: 2409005,
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
|
|
750
763
|
it('should return default meeting info lookup error payload correctly if not locus error', () => {
|
|
751
764
|
const res = cd.generateClientEventErrorPayload({body: {errorCode: 9400000}});
|
|
752
765
|
assert.deepEqual(res, {
|
|
@@ -239,7 +239,8 @@ describe('internal-plugin-metrics', () => {
|
|
|
239
239
|
sinon.useFakeTimers(now.getTime());
|
|
240
240
|
|
|
241
241
|
const options = {
|
|
242
|
-
|
|
242
|
+
json: true,
|
|
243
|
+
body: JSON.stringify({
|
|
243
244
|
metrics: [
|
|
244
245
|
{
|
|
245
246
|
eventPayload: {
|
|
@@ -250,11 +251,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
250
251
|
},
|
|
251
252
|
},
|
|
252
253
|
],
|
|
253
|
-
},
|
|
254
|
+
}),
|
|
254
255
|
};
|
|
255
256
|
|
|
256
257
|
const expectedOptions = {
|
|
257
|
-
|
|
258
|
+
json: true,
|
|
259
|
+
body: JSON.stringify({
|
|
258
260
|
metrics: [
|
|
259
261
|
{
|
|
260
262
|
eventPayload: {
|
|
@@ -265,7 +267,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
265
267
|
},
|
|
266
268
|
},
|
|
267
269
|
],
|
|
268
|
-
},
|
|
270
|
+
}),
|
|
269
271
|
};
|
|
270
272
|
|
|
271
273
|
check(options, expectedOptions);
|
|
@@ -277,7 +279,8 @@ describe('internal-plugin-metrics', () => {
|
|
|
277
279
|
sinon.useFakeTimers(now.getTime());
|
|
278
280
|
|
|
279
281
|
const options = {
|
|
280
|
-
|
|
282
|
+
json: true,
|
|
283
|
+
body: JSON.stringify({
|
|
281
284
|
metrics: [
|
|
282
285
|
{
|
|
283
286
|
eventPayload: {
|
|
@@ -296,11 +299,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
296
299
|
},
|
|
297
300
|
},
|
|
298
301
|
],
|
|
299
|
-
},
|
|
302
|
+
}),
|
|
300
303
|
};
|
|
301
304
|
|
|
302
305
|
const expectedOptions = {
|
|
303
|
-
|
|
306
|
+
json: true,
|
|
307
|
+
body: JSON.stringify({
|
|
304
308
|
metrics: [
|
|
305
309
|
{
|
|
306
310
|
eventPayload: {
|
|
@@ -319,20 +323,66 @@ describe('internal-plugin-metrics', () => {
|
|
|
319
323
|
},
|
|
320
324
|
},
|
|
321
325
|
],
|
|
322
|
-
},
|
|
326
|
+
}),
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
check(options, expectedOptions);
|
|
330
|
+
sinon.restore();
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it(`returns expected options when json is falsey`, () => {
|
|
334
|
+
const now = new Date();
|
|
335
|
+
sinon.useFakeTimers(now.getTime());
|
|
336
|
+
|
|
337
|
+
const options = {
|
|
338
|
+
body: JSON.stringify({
|
|
339
|
+
metrics: [
|
|
340
|
+
{
|
|
341
|
+
eventPayload: {
|
|
342
|
+
originTime: {
|
|
343
|
+
triggered: 555,
|
|
344
|
+
sent: 666,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
}),
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const expectedOptions = {
|
|
353
|
+
body: JSON.stringify({
|
|
354
|
+
metrics: [
|
|
355
|
+
{
|
|
356
|
+
eventPayload: {
|
|
357
|
+
originTime: {
|
|
358
|
+
triggered: 555,
|
|
359
|
+
sent: 666,
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
}),
|
|
323
365
|
};
|
|
324
366
|
|
|
325
367
|
check(options, expectedOptions);
|
|
326
368
|
sinon.restore();
|
|
327
369
|
});
|
|
328
370
|
|
|
329
|
-
it(`does not throw when
|
|
371
|
+
it(`does not throw when there is no body`, () => {
|
|
330
372
|
const options = {};
|
|
331
373
|
|
|
332
374
|
const expectedOptions = {};
|
|
333
375
|
|
|
334
376
|
check(options, expectedOptions);
|
|
335
377
|
});
|
|
378
|
+
|
|
379
|
+
it(`does not throw when body is empty`, () => {
|
|
380
|
+
const options = {body: '"{}"'};
|
|
381
|
+
|
|
382
|
+
const expectedOptions = {body: '"{}"'};
|
|
383
|
+
|
|
384
|
+
check(options, expectedOptions);
|
|
385
|
+
});
|
|
336
386
|
});
|
|
337
387
|
|
|
338
388
|
describe('extractVersionMetadata', () => {
|
|
@@ -125,11 +125,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
125
125
|
sinon.useFakeTimers(now.getTime());
|
|
126
126
|
|
|
127
127
|
webex.internal.newMetrics.setMetricTimingsAndFetch({
|
|
128
|
-
|
|
128
|
+
json: true,
|
|
129
|
+
body: JSON.stringify({metrics: [{eventPayload: {}}]}),
|
|
129
130
|
});
|
|
130
131
|
|
|
131
132
|
const expected = {
|
|
132
|
-
|
|
133
|
+
json: true,
|
|
134
|
+
body: JSON.stringify({
|
|
133
135
|
metrics: [
|
|
134
136
|
{
|
|
135
137
|
eventPayload: {
|
|
@@ -140,7 +142,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
140
142
|
},
|
|
141
143
|
},
|
|
142
144
|
],
|
|
143
|
-
},
|
|
145
|
+
}),
|
|
144
146
|
};
|
|
145
147
|
|
|
146
148
|
sinon.assert.calledOnce(webex.setTimingsAndFetch);
|