Skip to content

Commit 0f37a8b

Browse files
author
apryka
authored
Merge pull request #168 from keen/apryka-disable-tracking-option
disable tracking option
2 parents 3f09477 + 25176b2 commit 0f37a8b

File tree

11 files changed

+207
-9
lines changed

11 files changed

+207
-9
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,37 @@ Read more:
524524
- [How not to use Cassandra](https://opencredo.com/how-not-to-use-cassandra-like-an-rdbms-and-what-will-happen-if-you-do/)
525525
---
526526

527+
### Tracking Opt-Out
528+
529+
It's easy to build tracking opt-out functionality. If opt-out is set to true no data is recorded.
530+
531+
You can set up opt-out by defining client instance
532+
533+
```javascript
534+
const client = new KeenTracking({
535+
projectId: 'PROJECT_ID',
536+
writeKey: 'WRITE_KEY',
537+
optOut: true
538+
});
539+
```
540+
541+
or by invoking `client.setOptOut(true)` method
542+
543+
```javascript
544+
client.setOptOut(true);
545+
```
546+
547+
**Note:** The user can block tracking in the browser by [doNotTrack](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/doNotTrack) setting. We can respect or overwrite this setting by defining client instance
548+
```javascript
549+
const client = new KeenTracking({
550+
projectId: 'PROJECT_ID',
551+
writeKey: 'WRITE_KEY',
552+
respectDoNotTrack: true // it's false by default
553+
});
554+
```
555+
556+
---
557+
527558
### Contributing
528559

529560
This is an open source project and we love involvement from the community! Hit us up with pull requests and issues.

dist/keen-tracking.js

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/keen-tracking.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/keen-tracking.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/browser.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { cookie } from './utils/cookie';
2828
import { deepExtend } from './utils/deepExtend';
2929
import { serializeForm } from './utils/serializeForm';
3030
import { timer } from './utils/timer';
31+
import { setOptOut } from './utils/optOut';
3132

3233
// ------------------------
3334
// Methods
@@ -42,7 +43,8 @@ extend(KeenCore.prototype, {
4243
deferEvents,
4344
queueCapacity,
4445
queueInterval,
45-
recordDeferredEvents
46+
recordDeferredEvents,
47+
setOptOut
4648
});
4749
extend(KeenCore.prototype, {
4850
extendEvent,
@@ -99,6 +101,15 @@ if (typeof webpackKeenGlobals !== 'undefined') {
99101
keenGlobals = webpackKeenGlobals;
100102
}
101103

104+
if (localStorage && localStorage.getItem('optout')) {
105+
KeenCore.optedOut = true;
106+
}
107+
108+
if (getBrowserProfile().doNotTrack === '1'
109+
|| getBrowserProfile().doNotTrack === 'yes') {
110+
KeenCore.doNotTrack = true;
111+
}
112+
102113
export const Keen = KeenCore.extendLibrary(KeenCore); // deprecated, left for backward compatibility
103114
export const KeenTracking = Keen;
104115
export default Keen;

lib/helpers/getBrowserProfile.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export function getBrowserProfile() {
1212
'platform' : navigator.platform,
1313
'useragent' : navigator.userAgent,
1414
'version' : navigator.appVersion,
15+
'doNotTrack' : navigator.doNotTrack,
1516
'screen' : getScreenProfile(),
1617
'window' : getWindowProfile()
1718
}

lib/index.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import KeenCore from 'keen-core';
22
import each from 'keen-core/lib/utils/each';
33
import extend from 'keen-core/lib/utils/extend';
4-
import { queue } from'./utils/queue';
4+
import { queue } from './utils/queue';
5+
import { setOptOut } from './utils/optOut';
56
import pkg from '../package.json';
67

78
KeenCore.helpers = KeenCore.helpers || {};
@@ -13,6 +14,16 @@ KeenCore.on('client', function(client){
1314
events: [],
1415
collections: {}
1516
};
17+
18+
if (!client.config.respectDoNotTrack) {
19+
this.doNotTrack = false;
20+
}
21+
22+
if (typeof client.config.optOut !== 'undefined') {
23+
setOptOut(client.config.optOut);
24+
this.optedOut = client.config.optOut;
25+
}
26+
1627
client.queue = queue(client.config.queue);
1728
client.queue.on('flush', function(){
1829
client.recordDeferredEvents();

lib/record-events-browser.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,26 @@ export function recordEvent(eventCollectionOrConfigObject, eventBody, callback){
6969
}
7070

7171
this.emit('recordEvent', eventCollection, extendedEventsHash);
72-
72+
7373
if (!Keen.enabled) {
7474
handleValidationError.call(this, 'Keen.enabled is set to false.', callback);
7575
return false;
7676
}
7777

78+
if (Keen.optedOut) {
79+
return Promise.resolve({
80+
created: false,
81+
message: 'Keen.optedOut is set to true.'
82+
})
83+
}
84+
85+
if (Keen.doNotTrack) {
86+
return Promise.resolve({
87+
created: false,
88+
message: 'Keen.doNotTrack is set to true.'
89+
})
90+
}
91+
7892
return send.call(this, { url, extendedEventsHash, callback, configObject, eventCollection });
7993
}
8094

@@ -129,6 +143,20 @@ export function recordEvents(eventsHash, callback){
129143
return false;
130144
}
131145

146+
if (Keen.optedOut) {
147+
return Promise.resolve({
148+
created: false,
149+
message: 'Keen.optedOut is set to true.'
150+
})
151+
}
152+
153+
if (Keen.doNotTrack) {
154+
return Promise.resolve({
155+
created: false,
156+
message: 'Keen.doNotTrack is set to true.'
157+
})
158+
}
159+
132160
return send.call(this, { url, extendedEventsHash, callback });
133161
}
134162

lib/utils/optOut.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export function setOptOut(optOut = true) {
2+
if (optOut) {
3+
localStorage.setItem('optout', optOut);
4+
return;
5+
}
6+
7+
localStorage.removeItem('optout');
8+
};

test/setupJest.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,14 @@ global.IntersectionObserver.prototype.simulate = function(elements){
99
global.navigator = {
1010
sendBeacon: jest.mock()
1111
};
12+
const mockStorage = {};
13+
const localStorage = {
14+
setItem: (key, val) => Object.assign(mockStorage, {[key]: val}),
15+
getItem: key => mockStorage[key],
16+
removeItem: key => { delete mockStorage[key]; },
17+
clear: () => mockStorage,
18+
};
19+
global.localStorage = localStorage;
20+
1221
jest.mock('promise-polyfill', () => {});
1322
jest.mock('promise-polyfill/src/polyfill', () => {});

0 commit comments

Comments
 (0)