Skip to content

Instantly share code, notes, and snippets.

@max-lt
Last active December 15, 2023 08:45
Show Gist options
  • Save max-lt/2cf14e53ad479eaaa7b416223d195868 to your computer and use it in GitHub Desktop.
Save max-lt/2cf14e53ad479eaaa7b416223d195868 to your computer and use it in GitHub Desktop.
Angular + Piano Analytics
import { Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter, map } from 'rxjs/operators';
import { logger } from '~/logger';
import { Config } from '~/config';
const log = logger.getLogger('AnalyticsService');
// Global variables used by piano analytics
declare global {
interface Window {
_pac: any;
_paqueue: any[];
}
}
interface IPianoConfig {
site: number | string;
collectDomain: string;
}
@Injectable({ providedIn: 'root' })
export class AnalyticsService {
constructor(router: Router, globalConfig: Config) {
log.debug(`Init Analytics service on ${router.routerState}`);
// Check piano analytics configuration
const config: IPianoConfig = globalConfig.getPianoAnalyticsConfig();
if (!config.site || !config.collectDomain) {
log.warn('Missing piano analytics configuration');
return;
}
// Inject piano analytics script asynchronously
const script = document.createElement('script');
script.src = 'https://tag.aticdn.net/js-sdk/piano-analytics-6.13.0.js';
script.type = 'text/javascript';
script.async = true;
script.crossOrigin = 'anonymous';
script.integrity = 'sha384-hZSi/V4z1wvN+Z/idXMbMuZ9zVoqApJTwCXGxajicf3LI4kEF51eH1c/38wV6Dln';
document.head.appendChild(script);
// Init piano analytics context
window._pac = window._pac || {};
window._pac.queueVarName = '_paqueue';
// Init piano analytics queue
const dataLayer = (window._paqueue = []);
// Init piano analytics configuration
dataLayer.push(['setConfigurations', config]);
// Send page display event on each navigation end
router.events
.pipe(filter((event): event is NavigationEnd => event instanceof NavigationEnd))
.pipe(map((event) => event.urlAfterRedirects))
.subscribe((page) => dataLayer.push(['sendEvent', 'page.display', { page }]));
}
}
// ...
@NgModule({
// ...
providers: [
{
provide: APP_INITIALIZER,
useFactory: () => () => {},
deps: [AnalyticsService],
multi: true
}
// ...
import { Injectable } from '@angular/core';
// Global variables used for config
declare global {
interface Window {
_config: () => IGlobalConfig;
}
}
interface IGlobalConfig {
// ...
pianoAnalyticsSiteIdentifier: number;
pianoAnalyticsCollectDomain: string;
}
@Injectable({ providedIn: 'root' })
export class Config {
private conf: IGlobalConfig;
// ...
public getPianoAnalyticsConfig() {
return {
site: this.conf.pianoAnalyticsSiteIdentifier,
collectDomain: this.conf.pianoAnalyticsCollectDomain
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment