diff --git a/packages/adapter-ameyo/lib/main.ts b/packages/adapter-ameyo/lib/main.ts index 1859e7b..a4bb45a 100644 --- a/packages/adapter-ameyo/lib/main.ts +++ b/packages/adapter-ameyo/lib/main.ts @@ -31,6 +31,7 @@ import { } from "./assets/js/sip5ml.service.ts"; import registerEventProcessor from "./eventsProcessor.ts"; import MetricsProcessor from "@universal-call-sdk/common/lib/utils/metricsProcessor.ts"; +import ClickStreamProcessor from "@universal-call-sdk/common/lib/utils/clickStreamProcessor.ts"; class AmeyoAdapter implements IAdapter { private callbacks: { @@ -54,13 +55,8 @@ class AmeyoAdapter implements IAdapter { private currentCallMetadata: GenericObject; private sipAccountInfo: GenericObject; private isAgentAvailable: boolean; - private isMetricsEnabled : boolean - private metricFlowName: string - private metricMetadata: GenericObject - private metricProcessor: any - private metricUrl: string - private metricTransporter: ((metricData: GenericObject)=>void ) | undefined - + private clickStreamProcessor: ClickStreamProcessor ; + private metricProcessor: MetricsProcessor; constructor(options: AmeyoInitializationOptions) { if(document.readyState === 'loading') { @@ -100,26 +96,19 @@ class AmeyoAdapter implements IAdapter { this.sipAccountInfo = {}; this.currentCallMetadata = {}; this.isAgentAvailable = false; - this.isMetricsEnabled = options?.isMetricEnabled || false; - this.metricFlowName = options?.metricFlowName || ''; - this.metricMetadata = options?.metricMetadata || {} - this.metricUrl = options?.metricUrl || '' - if(options?.metricTransporter) { - this.metricTransporter = options?.metricTransporter || undefined - } + this.clickStreamProcessor = {} as ClickStreamProcessor; + this.metricProcessor={} as MetricsProcessor; window.BASE_AMEYO_URL = this.baseUrl; window.AMEYO_LOGIN_URL = options.loginUrl } - init() { + init(metricProcessor: MetricsProcessor, clickStreamProcessor: ClickStreamProcessor) { window.addEventListener('message', this._registerMessageListener); this._initializeAmeyo(); - if(this.isMetricsEnabled) { - this.metricProcessor = new MetricsProcessor(this.metricUrl, this.metricFlowName, this.metricTransporter); - - } - this.metricProcessor.pushCounterMetric({metricName: 'initSdk', flow: "sdk_init_count", metaData: this.metricMetadata}) + this.metricProcessor = metricProcessor; + this.clickStreamProcessor = clickStreamProcessor; + this.metricProcessor.pushCounterMetric({metricName: 'initSdk', flow: "sdk_init_count"}) } @@ -130,7 +119,7 @@ class AmeyoAdapter implements IAdapter { loadCredentials({accountName, userName, domain, password}); loadCallOptions(); sipRegister({domain: domainOnly, port}); - this.metricProcessor.pushCounterMetric({metricName: 'sipStackInitialised',flow: 'ameyo-sip-stack_init_count', metaData: this.metricMetadata}) + this.metricProcessor.pushCounterMetric({metricName: 'sipStackInitialised',flow: 'ameyo-sip-stack_init_count'}) } @@ -141,16 +130,15 @@ class AmeyoAdapter implements IAdapter { } _onListenForCorsBypassResponse = (payload: GenericObject) => { - if(payload?.data?.requestKey !== RequestKeys.AMEYO_HEARTBEAT) { + if(payload?.data?.requestKey !== RequestKeys.AMEYO_HEARTBEAT && !payload?.data?.err) { + this.clickStreamProcessor.sendClickStreamEvent({type: 'api-response', data: payload?.data}) this.metricProcessor.pushCounterMetric({ metricName: `ameyo-api-call-count`, - metaData: this.metricMetadata, flow: 'api-call-count', subFlow: payload?.data?.requestKey }) this.metricProcessor.pushHistogramMetric({ metricName: `ameyo-api-latency-${payload?.data?.requestKey}`, - metaData: this.metricMetadata, flow: 'api-latency', subFlow: payload?.data?.requestKey, value: payload?.data?.time @@ -158,7 +146,9 @@ class AmeyoAdapter implements IAdapter { } if(payload?.data?.err) { - this.metricProcessor.pushCounterMetric({metricName: `ameyo-api-err-count`, metaData: this.metricMetadata, flow: 'api-error-count', subFlow: payload?.data?.requestKey}) + this.clickStreamProcessor.sendClickStreamEvent({type: 'api-error', data: payload?.data?.err}) + this.metricProcessor.pushCounterMetric({metricName: `ameyo-api-err-count`, flow: 'api-error-count', subFlow: payload?.data?.requestKey}) + this.clickStreamProcessor.sendClickStreamEvent({type: 'api-error', err: payload?.data?.err}) } if (payload?.data?.requestKey === RequestKeys.AMEYO_LOGIN) { @@ -220,12 +210,11 @@ class AmeyoAdapter implements IAdapter { } _registerMessageListener = async ({data}: GenericObject) => { - if(data?.type !== MessagingType.SET_RESPONSE_WITHOUT_CORS) { + if(data?.type !== MessagingType.SET_RESPONSE_WITHOUT_CORS && data?.type !== MessagingType.GET_RESPONSE_WITHOUT_CORS) { this.metricProcessor.pushCounterMetric({ metricName: `ameyo-events-count`, - metaData: this.metricMetadata, flow: 'api-events-count', - subFlow: data?.type + subFlow:`universal-call-sdk-${data?.type}` }) } diff --git a/packages/adapter-ameyo/lib/types.ts b/packages/adapter-ameyo/lib/types.ts index 544d19c..65fb378 100644 --- a/packages/adapter-ameyo/lib/types.ts +++ b/packages/adapter-ameyo/lib/types.ts @@ -39,6 +39,7 @@ export type AmeyoInitializationOptions = { metricMetadata ?:GenericObject, metricUrl ?:string, metricTransporter ?:(metricPayload: GenericObject)=>void + clickStreamTransporter ?:(clickStreamPayload: GenericObject)=>void } declare global { diff --git a/packages/common/lib/Interfaces/IAdapter.ts b/packages/common/lib/Interfaces/IAdapter.ts index 6e6e828..ca5dec9 100644 --- a/packages/common/lib/Interfaces/IAdapter.ts +++ b/packages/common/lib/Interfaces/IAdapter.ts @@ -1,4 +1,6 @@ import GenericObject from "../types/GenericObject.ts"; +import MetricsProcessor from "../utils/metricsProcessor.ts"; +import ClickStreamProcessor from "../utils/clickStreamProcessor.ts"; class IAdapter { registerOnCallIncoming(callback: (callState: GenericObject)=>void) {callback({})} @@ -18,7 +20,10 @@ class IAdapter { setOnBreak() {} setAvailable() {} - init() {} + + //@ts-expect-error these values will be used by adapters not by interface + init(metricProcessor: (MetricsProcessor) | undefined, clickStreamProcessor: (ClickStreamProcessor)| undefined) { + } getAgentAvailability(): boolean {return false} diff --git a/packages/common/lib/utils/clickStreamProcessor.ts b/packages/common/lib/utils/clickStreamProcessor.ts new file mode 100644 index 0000000..b3d589b --- /dev/null +++ b/packages/common/lib/utils/clickStreamProcessor.ts @@ -0,0 +1,19 @@ +import GenericObject from "../types/GenericObject.ts"; + +class ClickStreamProcessor{ + private clickStreamProcessor: ((payload: GenericObject)=>void) | undefined + + constructor(clickStreamProcessor: ((payload: GenericObject)=>void) | undefined) { + this.clickStreamProcessor = clickStreamProcessor; + } + + sendClickStreamEvent(payload: GenericObject) { + if(this.clickStreamProcessor){ + this.clickStreamProcessor(payload) + return; + } + } +} + + +export default ClickStreamProcessor; diff --git a/packages/common/lib/utils/noop.ts b/packages/common/lib/utils/noop.ts new file mode 100644 index 0000000..77787df --- /dev/null +++ b/packages/common/lib/utils/noop.ts @@ -0,0 +1,3 @@ +const noop = () => {}; + +export default noop; diff --git a/packages/core/lib/useCallSdk.ts b/packages/core/lib/useCallSdk.ts index 639e3ec..2baa93b 100644 --- a/packages/core/lib/useCallSdk.ts +++ b/packages/core/lib/useCallSdk.ts @@ -1,6 +1,9 @@ import {useEffect, useReducer} from 'react'; import {GenericObject, StateType} from "./types.ts"; import IAdapter from "@universal-call-sdk/common/lib/Interfaces/IAdapter.ts"; +import MetricsProcessor from "@universal-call-sdk/common/lib/utils/metricsProcessor.ts"; +import ClickStreamProcessor from "@universal-call-sdk/common/lib/utils/clickStreamProcessor.ts"; +import noop from "@universal-call-sdk/common/lib/utils/noop.ts"; enum actionTypes { @@ -72,9 +75,19 @@ const initialState: StateType = { let adapter: IAdapter; -function UseCallSdk({AdapterClass, adapterOptions}: { +function UseCallSdk({AdapterClass, adapterOptions, metricsConfig, clickStreamConfig}: { AdapterClass: new (adapterOptions: IAdapter) => IAdapter, - adapterOptions: IAdapter + adapterOptions: IAdapter, + metricsConfig?: { + isMetricEnabled: boolean, + metricFlowName: string, + metricMetadata: GenericObject, + metricUrl: string, + metricTransporter: (metricPayload: GenericObject) => void + }, + clickStreamConfig?: { + clickStreamTransporter: (clickStreamPayload: GenericObject) => void + } }) { useEffect(() => { adapter = new AdapterClass(adapterOptions); @@ -141,7 +154,16 @@ function UseCallSdk({AdapterClass, adapterOptions}: { } function initialize() { - adapter.init(); + let metricProcessor; + let clickStreamProcessor; + if(metricsConfig && metricsConfig?.isMetricEnabled) { + metricProcessor = new MetricsProcessor(metricsConfig?.metricUrl || '', metricsConfig?.metricFlowName || '', metricsConfig?.metricTransporter || noop); + + } + if(clickStreamConfig?.clickStreamTransporter) { + clickStreamProcessor = new ClickStreamProcessor(clickStreamConfig?.clickStreamTransporter || noop); + } + adapter.init(metricProcessor, clickStreamProcessor); } function setOnBreak() {