Skip to content

Instantly share code, notes, and snippets.

@simonihmig
Created June 7, 2022 10:53
Show Gist options
  • Save simonihmig/bd12bcf4ebd443281013561402c23b1d to your computer and use it in GitHub Desktop.
Save simonihmig/bd12bcf4ebd443281013561402c23b1d to your computer and use it in GitHub Desktop.
import EmbeddedService from 'ember-embedded-snippet/services/embedded';
import BaseAdapter from 'ember-metrics/metrics-adapters/base';
import fetch from 'fetch';
import { inject as service } from '@ember/service';
export interface Config {
identificationCode: string;
apiUrlForHit?: string;
apiUrlForEvent?: string;
trackUrlBase?: string;
}
export default class Pirsch extends BaseAdapter<Config> {
@service embedded!: EmbeddedService;
toStringExtension(): 'Pirsch' {
return 'Pirsch';
}
// These two hooks are required by ember-metrics
// eslint-disable-next-line ember/classic-decorator-hooks, @typescript-eslint/no-empty-function
init(): void {}
// eslint-disable-next-line ember/classic-decorator-hooks, @typescript-eslint/no-empty-function
willDestroy(): void {}
async trackPage(hit: { page: string; title?: string }): Promise<void> {
// Skip tracking silently when no code is provided
if (!this.config.identificationCode) return;
try {
const apiUrl = this._makeHitURL(hit);
await fetch(apiUrl);
} catch (e) {
console.error('Failed to track page hit with ember-metrics', e);
}
}
async trackEvent(event: {
page: string;
title?: string;
eventName: string;
eventDuration?: number;
eventMeta?: Record<string, string>;
}): Promise<void> {
// Skip tracking silently when no code is provided
if (!this.config.identificationCode) return;
try {
const apiUrl = this._makeEventURL();
const body = this._makeEventParams(event);
await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
body,
});
} catch (e) {
console.error('Failed to track event with ember-metrics', e);
}
}
_makeHitURL({ page, title }: { page: string; title?: string }): string {
const apiUrlBase = this.config.apiUrlForHit ?? 'https://api.pirsch.io/hit';
const trackUrl = `${this.config.trackUrlBase ?? location.origin}${page}`;
const queryParams = new URLSearchParams({
nc: new Date().getTime().toString(),
code: this.config.identificationCode,
url: trackUrl,
t: title ?? 'unknown',
ref: this.embedded.args.client ?? '',
w: screen.width.toString(),
h: screen.height.toString(),
}).toString();
return `${apiUrlBase}?${queryParams}`;
}
_makeEventURL(): string {
return this.config.apiUrlForEvent ?? 'https://api.pirsch.io/event';
}
_makeEventParams({
page,
title,
eventName,
eventDuration = 0,
eventMeta,
}: {
page: string;
title?: string;
eventName: string;
eventDuration?: number;
eventMeta?: Record<string, unknown>;
}): string {
const trackUrl = `${this.config.trackUrlBase ?? location.origin}${page}`;
const eventMetaSafe =
eventMeta &&
Object.keys(eventMeta).reduce((result, key) => {
result[key] = String(eventMeta[key]);
return result;
}, {} as Record<string, string>);
try {
return JSON.stringify({
client_id: this.config.identificationCode,
identification_code: this.config.identificationCode,
url: trackUrl,
title: title ?? 'unknown',
referrer: this.embedded.args.client,
screen_width: screen.width,
screen_height: screen.height,
event_name: eventName,
event_duration: eventDuration,
event_meta: eventMetaSafe,
});
} catch (e) {
console.error('Failed to serialize payload for Pirsch.io event tracking');
throw e;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment