-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathgoogle-analytics-provider.ts
132 lines (112 loc) · 4.28 KB
/
google-analytics-provider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import * as uuid from "uuid";
import * as ua from "universal-analytics";
import { AnalyticsClients } from "../../common/constants";
export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider {
private static GA_TRACKING_ID = "UA-111455-44";
private static GA_CROSS_CLIENT_TRACKING_ID = "UA-111455-51";
private currentPage: string;
constructor(private clientId: string,
private $staticConfig: IStaticConfig,
private $analyticsSettingsService: IAnalyticsSettingsService,
private $logger: ILogger,
private $proxyService: IProxyService) {
}
public async trackHit(trackInfo: IGoogleAnalyticsData): Promise<void> {
const trackingIds = [GoogleAnalyticsProvider.GA_TRACKING_ID, GoogleAnalyticsProvider.GA_CROSS_CLIENT_TRACKING_ID];
const sessionId = uuid.v4();
for (const gaTrackingId of trackingIds) {
try {
await this.track(gaTrackingId, trackInfo, sessionId);
} catch (e) {
this.$logger.trace("Analytics exception: ", e);
}
}
}
private async track(gaTrackingId: string, trackInfo: IGoogleAnalyticsData, sessionId: string): Promise<void> {
const proxySettings = await this.$proxyService.getCache();
const proxy = proxySettings && proxySettings.proxy;
const visitor = ua({
tid: gaTrackingId,
cid: this.clientId,
headers: {
["User-Agent"]: this.$analyticsSettingsService.getUserAgentString(`tnsCli/${this.$staticConfig.version}`)
},
requestOptions: {
proxy
}
});
switch (gaTrackingId) {
case GoogleAnalyticsProvider.GA_CROSS_CLIENT_TRACKING_ID:
this.setCrossClientCustomDimensions(visitor, sessionId);
break;
default:
await this.setCustomDimensions(visitor, trackInfo.customDimensions, sessionId);
break;
}
switch (trackInfo.googleAnalyticsDataType) {
case GoogleAnalyticsDataType.Page:
await this.trackPageView(visitor, <IGoogleAnalyticsPageviewData>trackInfo);
break;
case GoogleAnalyticsDataType.Event:
await this.trackEvent(visitor, <IGoogleAnalyticsEventData>trackInfo);
break;
}
}
private async setCustomDimensions(visitor: ua.Visitor, customDimensions: IStringDictionary, sessionId: string): Promise<void> {
const defaultValues: IStringDictionary = {
[GoogleAnalyticsCustomDimensions.cliVersion]: this.$staticConfig.version,
[GoogleAnalyticsCustomDimensions.nodeVersion]: process.version,
[GoogleAnalyticsCustomDimensions.clientID]: this.clientId,
[GoogleAnalyticsCustomDimensions.projectType]: null,
[GoogleAnalyticsCustomDimensions.sessionID]: sessionId,
[GoogleAnalyticsCustomDimensions.client]: AnalyticsClients.Unknown
};
const playgrounInfo = await this.$analyticsSettingsService.getPlaygroundInfo();
if (playgrounInfo && playgrounInfo.id) {
defaultValues[GoogleAnalyticsCustomDimensions.playgroundId] = playgrounInfo.id;
defaultValues[GoogleAnalyticsCustomDimensions.usedTutorial] = playgrounInfo.usedTutorial.toString();
}
customDimensions = _.merge(defaultValues, customDimensions);
_.each(customDimensions, (value, key) => {
visitor.set(key, value);
});
}
private async setCrossClientCustomDimensions(visitor: ua.Visitor, sessionId: string): Promise<void> {
const customDimensions: IStringDictionary = {
[GoogleAnalyticsCrossClientCustomDimensions.sessionId]: sessionId,
[GoogleAnalyticsCrossClientCustomDimensions.clientId]: this.clientId,
[GoogleAnalyticsCrossClientCustomDimensions.crossClientId]: this.clientId,
};
_.each(customDimensions, (value, key) => {
visitor.set(key, value);
});
}
private trackEvent(visitor: ua.Visitor, trackInfo: IGoogleAnalyticsEventData): Promise<void> {
return new Promise<void>((resolve, reject) => {
visitor.event(trackInfo.category, trackInfo.action, trackInfo.label, trackInfo.value, { p: this.currentPage }, (err: Error) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
}
private trackPageView(visitor: ua.Visitor, trackInfo: IGoogleAnalyticsPageviewData): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.currentPage = trackInfo.path;
const pageViewData: ua.PageviewParams = {
dp: trackInfo.path,
dt: trackInfo.title
};
visitor.pageview(pageViewData, (err) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
}
}
$injector.register("googleAnalyticsProvider", GoogleAnalyticsProvider);