diff --git a/projects/common/src/telemetry/providers/freshpaint/freshpaint-provider.ts b/projects/common/src/telemetry/providers/freshpaint/freshpaint-provider.ts index 8e212581a..387179505 100644 --- a/projects/common/src/telemetry/providers/freshpaint/freshpaint-provider.ts +++ b/projects/common/src/telemetry/providers/freshpaint/freshpaint-provider.ts @@ -6,11 +6,13 @@ import { FreshPaint, loadFreshPaint } from './load-snippet'; @Injectable({ providedIn: 'root' }) export class FreshPaintTelemetry implements UserTelemetryProvider { - private freshPaint?: FreshPaint; + private get freshPaint(): FreshPaint | undefined { + return window.freshpaint; + } public initialize(config: InitConfig): void { - this.freshPaint = loadFreshPaint(); - this.freshPaint.init(config.orgId); + loadFreshPaint(); + this.freshPaint?.init(config.orgId); } public identify(userTraits: UserTraits): void { @@ -23,7 +25,9 @@ export class FreshPaintTelemetry } public trackPage(name: string, eventData: Dictionary): void { - this.freshPaint?.page(name, name, eventData); + this.freshPaint?.addPageviewProperties({ url: name, ...eventData }); + this.freshPaint?.page('product-ui', name, eventData); + this.freshPaint?.track(name, eventData); } public trackError(name: string, eventData: Dictionary): void { diff --git a/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.d.ts b/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.d.ts index d44b545ec..df7e91f79 100644 --- a/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.d.ts +++ b/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.d.ts @@ -1,14 +1,22 @@ -export function loadFreshPaint(): FreshPaint; +export function loadFreshPaint(): void; export interface FreshPaint { init(orgId: string): void; + ready(callback: () => void): void; identify(uid?: string, userVars?: UserVars): void; identify(userVars?: UserVars): void; track(eventName: string, properties?: {}): void; addEventProperties(userVars?: UserVars): void; + addPageviewProperties(properties: { [key: string]: any }): void; page(category?: string, name?: string, userVars?: UserVars): void; } +declare global { + interface Window { + freshpaint?: FreshPaint; + } +} + interface UserVars { displayName?: string; email?: string; diff --git a/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.js b/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.js index 0a4cf061c..1c5729db7 100644 --- a/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.js +++ b/projects/common/src/telemetry/providers/freshpaint/load-snippet/index.js @@ -2,8 +2,9 @@ const loadFreshPaint = () => { if (window.freshpaint) { - return window.freshpaint; + return getFreshPaint; } + (function (c, a) { if (!a.__SV) { var b = window; @@ -77,7 +78,7 @@ const loadFreshPaint = () => { } })(document, window.freshpaint || []); - return freshpaint; + return window.freshpaint; }; module.exports = { diff --git a/projects/common/src/telemetry/user-telemetry-impl.service.test.ts b/projects/common/src/telemetry/user-telemetry-impl.service.test.ts index 9f1583ef5..62bd5f46f 100644 --- a/projects/common/src/telemetry/user-telemetry-impl.service.test.ts +++ b/projects/common/src/telemetry/user-telemetry-impl.service.test.ts @@ -58,15 +58,21 @@ describe('User Telemetry helper service', () => { // TrackEvent spectator.service.trackEvent('eventA', { target: 'unknown' }); - expect(telemetryProvider.trackEvent).toHaveBeenCalledWith('eventA', { target: 'unknown' }); + expect(telemetryProvider.trackEvent).toHaveBeenCalledWith('eventA', { + target: 'unknown', + eventCategory: 'user-action' + }); // TrackPage spectator.service.trackPageEvent('/abs', { target: 'unknown' }); - expect(telemetryProvider.trackPage).toHaveBeenCalledWith('/abs', { target: 'unknown' }); + expect(telemetryProvider.trackPage).toHaveBeenCalledWith('/abs', { target: 'unknown', eventCategory: 'page-view' }); // TrackError spectator.service.trackErrorEvent('console error', { target: 'unknown' }); - expect(telemetryProvider.trackError).toHaveBeenCalledWith('Error: console error', { target: 'unknown' }); + expect(telemetryProvider.trackError).toHaveBeenCalledWith('Error: console error', { + target: 'unknown', + eventCategory: 'error' + }); }); test('should not capture events if event tracking is disabled', () => { @@ -112,11 +118,14 @@ describe('User Telemetry helper service', () => { // TrackPage spectator.service.trackPageEvent('/abs', { target: 'unknown' }); - expect(telemetryProvider.trackPage).toHaveBeenCalledWith('/abs', { target: 'unknown' }); + expect(telemetryProvider.trackPage).toHaveBeenCalledWith('/abs', { target: 'unknown', eventCategory: 'page-view' }); // TrackError spectator.service.trackErrorEvent('console error', { target: 'unknown' }); - expect(telemetryProvider.trackError).toHaveBeenCalledWith('Error: console error', { target: 'unknown' }); + expect(telemetryProvider.trackError).toHaveBeenCalledWith('Error: console error', { + target: 'unknown', + eventCategory: 'error' + }); }); test('should not capture page events if page event tracking is disabled', () => { @@ -158,7 +167,10 @@ describe('User Telemetry helper service', () => { // TrackEvent spectator.service.trackEvent('eventA', { target: 'unknown' }); - expect(telemetryProvider.trackEvent).toHaveBeenCalledWith('eventA', { target: 'unknown' }); + expect(telemetryProvider.trackEvent).toHaveBeenCalledWith('eventA', { + target: 'unknown', + eventCategory: 'user-action' + }); // TrackPage spectator.service.trackPageEvent('/abs', { target: 'unknown' }); @@ -166,7 +178,10 @@ describe('User Telemetry helper service', () => { // TrackError spectator.service.trackErrorEvent('console error', { target: 'unknown' }); - expect(telemetryProvider.trackError).toHaveBeenCalledWith('Error: console error', { target: 'unknown' }); + expect(telemetryProvider.trackError).toHaveBeenCalledWith('Error: console error', { + target: 'unknown', + eventCategory: 'error' + }); }); test('should not capture error events if eror event tracking is disabled', () => { @@ -208,11 +223,14 @@ describe('User Telemetry helper service', () => { // TrackEvent spectator.service.trackEvent('eventA', { target: 'unknown' }); - expect(telemetryProvider.trackEvent).toHaveBeenCalledWith('eventA', { target: 'unknown' }); + expect(telemetryProvider.trackEvent).toHaveBeenCalledWith('eventA', { + target: 'unknown', + eventCategory: 'user-action' + }); // TrackPage spectator.service.trackPageEvent('/abs', { target: 'unknown' }); - expect(telemetryProvider.trackPage).toHaveBeenCalledWith('/abs', { target: 'unknown' }); + expect(telemetryProvider.trackPage).toHaveBeenCalledWith('/abs', { target: 'unknown', eventCategory: 'page-view' }); // TrackError spectator.service.trackPageEvent('console error', { target: 'unknown' }); diff --git a/projects/common/src/telemetry/user-telemetry-impl.service.ts b/projects/common/src/telemetry/user-telemetry-impl.service.ts index 69ded973b..8fafde5b3 100644 --- a/projects/common/src/telemetry/user-telemetry-impl.service.ts +++ b/projects/common/src/telemetry/user-telemetry-impl.service.ts @@ -1,6 +1,6 @@ import { Injectable, Injector, Optional } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; -import { filter } from 'rxjs/operators'; +import { delay, filter } from 'rxjs/operators'; import { Dictionary } from '../utilities/types/types'; import { UserTelemetryProvider, UserTelemetryRegistrationConfig, UserTraits } from './telemetry'; import { UserTelemetryService } from './user-telemetry.service'; @@ -46,19 +46,21 @@ export class UserTelemetryImplService extends UserTelemetryService { public trackEvent(name: string, data: Dictionary): void { this.initializedTelemetryProviders .filter(provider => provider.enableEventTracking) - .forEach(provider => provider.telemetryProvider.trackEvent?.(name, data)); + .forEach(provider => provider.telemetryProvider.trackEvent?.(name, { ...data, eventCategory: 'user-action' })); } public trackPageEvent(url: string, data: Dictionary): void { this.initializedTelemetryProviders .filter(provider => provider.enablePageTracking) - .forEach(provider => provider.telemetryProvider.trackPage?.(url, data)); + .forEach(provider => provider.telemetryProvider.trackPage?.(url, { ...data, eventCategory: 'page-view' })); } public trackErrorEvent(error: string, data: Dictionary): void { this.initializedTelemetryProviders .filter(provider => provider.enableErrorTracking) - .forEach(provider => provider.telemetryProvider.trackError?.(`Error: ${error}`, data)); + .forEach(provider => + provider.telemetryProvider.trackError?.(`Error: ${error}`, { ...data, eventCategory: 'error' }) + ); } private buildTelemetryProvider(config: UserTelemetryRegistrationConfig): UserTelemetryInternalConfig { @@ -72,7 +74,10 @@ export class UserTelemetryImplService extends UserTelemetryService { private setupAutomaticPageTracking(): void { this.router?.events - .pipe(filter((event): event is NavigationEnd => event instanceof NavigationEnd)) + .pipe( + filter((event): event is NavigationEnd => event instanceof NavigationEnd), + delay(50) + ) .subscribe(route => this.trackPageEvent(`Visited: ${route.url}`, { url: route.url })); } }