Skip to content

Commit c0c9a9d

Browse files
authored
fix: add logic to escape campaign tracking for direct traffic in session (#726)
1 parent 6bbb69d commit c0c9a9d

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

packages/analytics-client-common/src/attribution/web-attribution.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Options, getDefaultExcludedReferrers, createCampaignEvent, isNewCampaig
44
import { getStorageKey } from '../storage/helpers';
55
import { CampaignParser } from './campaign-parser';
66
import { BASE_CAMPAIGN } from './constants';
7+
import { isNewSession } from '../session';
78

89
export class WebAttribution {
910
options: Options;
@@ -12,6 +13,8 @@ export class WebAttribution {
1213
previousCampaign?: Campaign;
1314
currentCampaign: Campaign;
1415
shouldTrackNewCampaign = false;
16+
sessionTimeout: number;
17+
lastEventTime?: number;
1518

1619
constructor(options: Options, config: BrowserConfig) {
1720
this.options = {
@@ -23,13 +26,16 @@ export class WebAttribution {
2326
this.storage = config.cookieStorage as unknown as Storage<Campaign>;
2427
this.storageKey = getStorageKey(config.apiKey, 'MKTG');
2528
this.currentCampaign = BASE_CAMPAIGN;
29+
this.sessionTimeout = config.sessionTimeout;
30+
this.lastEventTime = config.lastEventTime;
2631
config.loggerProvider.log('Installing web attribution tracking.');
2732
}
2833

2934
async init() {
3035
[this.currentCampaign, this.previousCampaign] = await this.fetchCampaign();
36+
const isEventInNewSession = !this.lastEventTime ? true : isNewSession(this.sessionTimeout, this.lastEventTime);
3137

32-
if (isNewCampaign(this.currentCampaign, this.previousCampaign, this.options)) {
38+
if (isNewCampaign(this.currentCampaign, this.previousCampaign, this.options, isEventInNewSession)) {
3339
this.shouldTrackNewCampaign = true;
3440
await this.storage.set(this.storageKey, this.currentCampaign);
3541
}

packages/analytics-client-common/test/attribution/web-attribution.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,49 @@ describe('shouldTrackNewCampaign', () => {
9797
webAttribution.generateCampaignEvent();
9898
expect(webAttribution.shouldSetSessionIdOnNewCampaign()).toBe(false);
9999
});
100+
101+
test('should ignore the campaign for direct traffic in session', async () => {
102+
const lastEventTime = Date.now();
103+
104+
const overrideMockConfig = {
105+
...mockConfig,
106+
// In session event
107+
lastEventTime,
108+
};
109+
const webAttribution = new WebAttribution({}, overrideMockConfig);
110+
const previousCampaign = {
111+
...BASE_CAMPAIGN,
112+
referrer: 'https://www.google.com',
113+
referring_domain: 'www.google.com',
114+
};
115+
116+
jest.spyOn(CampaignParser.prototype, 'parse').mockResolvedValue(BASE_CAMPAIGN); // Direct Traffic
117+
jest.spyOn(webAttribution.storage, 'get').mockResolvedValue(previousCampaign);
118+
119+
await webAttribution.init();
120+
expect(webAttribution.shouldTrackNewCampaign).toBe(false);
121+
});
122+
123+
test('should not ignore the campaign for direct traffic in new session', async () => {
124+
const lastEventTime = Date.now() - 2 * 30 * 60 * 1000;
125+
126+
const overrideMockConfig = {
127+
...mockConfig,
128+
// Out of session event
129+
lastEventTime,
130+
};
131+
132+
const webAttribution = new WebAttribution({}, overrideMockConfig);
133+
const previousCampaign = {
134+
...BASE_CAMPAIGN,
135+
referrer: 'https://www.google.com',
136+
referring_domain: 'www.google.com',
137+
};
138+
139+
jest.spyOn(CampaignParser.prototype, 'parse').mockResolvedValue(BASE_CAMPAIGN); // Direct Traffic
140+
jest.spyOn(webAttribution.storage, 'get').mockResolvedValue(previousCampaign);
141+
142+
await webAttribution.init();
143+
expect(webAttribution.shouldTrackNewCampaign).toBe(true);
144+
});
100145
});

0 commit comments

Comments
 (0)