Skip to content

Commit e4f6d45

Browse files
author
Kevin Friedman
committed
Updated cookie handling
1 parent d8113ef commit e4f6d45

7 files changed

Lines changed: 74 additions & 61 deletions

File tree

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,29 @@ gap('send', 'pageview');
4848
The code should be added near the top of the `<head>` tag with the string `'UA-XXXXX-Y'`.
4949

5050
- Replace _UA-XXXXX-Y_ of the Google Analytics property you wish to track.
51-
- Replace _xxx.org_ with the location of your Proxy Service client-side JavaScript.
51+
- Replace _xxx.org_ with the location of your GAP client-side JavaScript.
52+
- Optionally, replace _auto_ with a cookie fields object (see below).
5253

5354
Adding this code will load GAP and track the current pageview.
5455

56+
### Specifying Cookie Fields
57+
58+
To optionally control how the client-side cookie is set, pass a cookie fields object:
59+
60+
```javascript
61+
ga('create', 'UA-XXXXX-Y', {
62+
'clientId': '76c24efd-ec42-492a-92df-c62cfd4540a3',
63+
'cookieDomain': 'example.org',
64+
'cookieExpires': 60 * 60 * 24 // Time in seconds (1 day)
65+
});
66+
```
67+
5568
### Initializing GAP Parameters
5669

5770
You can optionally specify GAP parameters:
5871

5972
```javascript
60-
gap('init', 'MetricNameSpace', '123456-abcde-123456-abcde');
73+
gap('init', 'MetricNameSpace');
6174
```
6275

6376
- Replace _MetricNameSpace_ with the namespace to be used for metrics.

api/controllers/javascript.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const fs = require('fs');
22

33
/**
4-
* create(req, res)
4+
* getJavascript(req, res)
55
*
66
* @param {req} HTTP request
77
* @param {res} HTTP response

api/controllers/send.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ const gaConfig = require('./../../config/ga_config.js');
55
const querystring = require('querystring');
66
const cloudwatch = require('./../helpers/cloudwatch')
77

8-
const logger = require('winston')
9-
108
/**
119
* checkRequiredParameters(req)
1210
*
@@ -52,10 +50,10 @@ function sendPageView (req, res) {
5250
headers: {}
5351
})
5452
.then(response => {
55-
logger.info('Successfully tracked page view (' + payLoad + ').');
53+
gaConfig.logger.info('Successfully tracked page view (' + req.query.page + ').');
5654
})
5755
.catch(response => {
58-
logger.error('Error tracking pageview: ' + response.message);
56+
gaConfig.logger.error('Error tracking pageview: ' + response.message);
5957
});
6058

6159
res
@@ -99,10 +97,10 @@ function sendEvent (req, res) {
9997
headers: {}
10098
})
10199
.then(response => {
102-
logger.info('Successfully tracked event (' + payLoad + ').');
100+
gaConfig.logger.info('Successfully tracked event (' + req.query.eventCategory + ').');
103101
})
104102
.catch(response => {
105-
logger.error('Error tracking event: ' + response.message);
103+
gaConfig.logger.error('Error tracking event: ' + response.message);
106104
});
107105

108106
res

api/helpers/cloudwatch.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
const logger = require('winston')
2-
31
const AWS = require('aws-sdk');
42
const cloudwatch = new AWS.CloudWatch();
3+
const gaConfig = require('./../../config/ga_config.js');
54

65
function recordMetric(req, metricName) {
76
if (!req.query.metricNameSpace) {
@@ -20,11 +19,11 @@ function recordMetric(req, metricName) {
2019

2120
cloudwatch.putMetricData(params, function(err, data) {
2221
if (err) {
23-
logger.error(err, err.stack);
22+
gaConfig.logger.error(err, err.stack);
2423
return false;
2524
}
2625

27-
logger.info('Recorded CloudWatch metric: ' + req.query.metricNameSpace + ':' + metricName);
26+
gaConfig.logger.info('Recorded CloudWatch metric: ' + req.query.metricNameSpace + ':' + metricName);
2827
return true;
2928
});
3029
}

config/ga_config.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
const winston = require('winston');
2+
13
module.exports = {
24
googleBaseUrl: 'https://www.google-analytics.com',
35
visitMetricName: 'Visit',
4-
pageViewMetricName: 'PageView'
6+
pageViewMetricName: 'PageView',
7+
logger: new winston.Logger({
8+
transports: [
9+
new winston.transports.Console({
10+
json: true
11+
})
12+
]
13+
})
514
};

swagger/v0.1.json

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,6 @@
9292
"required": true,
9393
"type": "string"
9494
},
95-
{
96-
"name": "cookieDomain",
97-
"in": "query",
98-
"required": true,
99-
"type": "string"
100-
},
10195
{
10296
"name": "clientId",
10397
"in": "query",
@@ -147,12 +141,6 @@
147141
"required": true,
148142
"type": "string"
149143
},
150-
{
151-
"name": "cookieDomain",
152-
"in": "query",
153-
"required": true,
154-
"type": "string"
155-
},
156144
{
157145
"name": "clientId",
158146
"in": "query",

views/gap.ejs

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
var gaProxyApp = {
2-
firstVisit: false,
32
clientId: '',
43
metricNameSpace: '',
4+
isFirstVisit: false,
55
trackingId: '',
66
clientIdCookieName: 'gap.clientId',
7-
cookieDomain: '',
8-
clientId: '',
97
serviceBaseUrl: '<%= serviceBaseUrl %>',
108

119
collect: function (action, data) {
1210
data.trackingId = this.trackingId;
13-
data.cookieDomain = this.cookieDomain;
1411
data.clientId = this.clientId;
1512
data.metricNameSpace = this.metricNameSpace;
1613

@@ -59,19 +56,19 @@ var gaProxyApp = {
5956
}
6057
},
6158

62-
setCookie: function createCookie (name, value, days) {
59+
setCookie: function (name, value, secondsExpire) {
6360
var expires = '';
6461

65-
if (days) {
62+
if (secondsExpire) {
6663
var date = new Date();
67-
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
64+
date.setTime(date.getTime() + (secondsExpire * 1000));
6865
expires = '; expires=' + date.toUTCString();
6966
}
7067

7168
document.cookie = name + '=' + value + expires + '; path=/';
7269
},
7370

74-
readCookie: function readCookie (name) {
71+
readCookie: function (name) {
7572
var nameEQ = name + '=';
7673
var ca = document.cookie.split(';');
7774
for (var i = 0; i < ca.length; i++) {
@@ -82,68 +79,77 @@ var gaProxyApp = {
8279
return null;
8380
},
8481

85-
createGuid: function guid() {
86-
function s4() {
82+
createGuid: function () {
83+
function s4 () {
8784
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
8885
}
86+
8987
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
9088
},
9189

9290
checkRequired: function () {
93-
if (!this.trackingId || !this.cookieDomain) {
94-
throw('Tracking ID and cookie domain was not set.');
91+
if (!this.trackingId) {
92+
throw('Tracking ID was not set.');
9593
}
9694

9795
return true;
9896
},
9997

100-
inferClientId: function(trackingId) {
98+
inferFirstVisit: function () {
99+
return !this.readCookie(this.clientIdCookieName);
100+
},
101+
102+
inferClientId: function (cookieFields) {
103+
if (cookieFields.clientId) {
104+
return cookieFields.clientId;
105+
}
106+
101107
if (this.readCookie(this.clientIdCookieName)) {
102108
return this.readCookie(this.clientIdCookieName);
103109
}
104110

105-
this.firstVisit = true;
106-
107-
this.setCookie(
108-
this.clientIdCookieName,
109-
this.generateTrackingId(trackingId)
110-
)
111+
return this.generateClientId();
111112
},
112113

113-
generateTrackingId: function (trackingId) {
114-
if (trackingId) {
115-
return trackingId;
114+
inferSecondsExpire: function (cookieFields) {
115+
if (typeof cookieFields === 'object') {
116+
return cookieFields.cookieExpires;
116117
}
118+
},
117119

120+
generateClientId: function () {
118121
return this.createGuid();
119122
},
120123

124+
init: function (element) {
125+
this.metricNameSpace = element[1];
126+
},
127+
121128
create: function (element) {
122129
if (!element[1]) {
123130
throw('Tracking ID was not specified');
124131
}
125132

126133
this.trackingId = element[1];
127134

128-
if (!this.clientId) {
129-
this.clientId = this.inferClientId();
130-
}
135+
this.clientId = this.inferClientId(element[2]);
131136

132-
this.cookieDomain = element[2];
137+
this.isFirstVisit = this.inferFirstVisit();
138+
139+
if (this.isFirstVisit) {
140+
this.setCookie(
141+
this.clientIdCookieName,
142+
this.clientId,
143+
this.inferSecondsExpire(element[2])
144+
);
145+
}
133146

134147
return {
135148
trackingId: element[1],
136-
cookieDomain: element[2],
137-
firstVisit: this.firstVisit
149+
firstVisit: this.isFirstVisit
138150
};
139151
},
140152

141-
init: function (element) {
142-
this.metricNameSpace = element[1];
143-
144-
this.clientId = this.inferClientId(element[2]);
145-
},
146-
147153
send: function (element) {
148154
this.checkRequired();
149155

@@ -196,7 +202,7 @@ var gaProxyApp = {
196202
(function () {
197203
// Check if GAProxy object is set
198204
if (!window.gap) {
199-
console.error('GAProxy object is not defined.');
205+
console.error('GA proxy object is not defined.');
200206
return false;
201207
}
202208

0 commit comments

Comments
 (0)