Skip to content

Commit

Permalink
fix: add comments in isNewCampaign() (#941)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mercy811 authored Dec 31, 2024
1 parent 3ed0dfe commit a14a68c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 24 deletions.
16 changes: 14 additions & 2 deletions packages/analytics-client-common/src/attribution/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createIdentifyEvent, Identify } from '@amplitude/analytics-core';
import { Campaign } from '@amplitude/analytics-types';
import { Campaign, Logger } from '@amplitude/analytics-types';
import { BASE_CAMPAIGN } from './constants';

export interface Options {
Expand Down Expand Up @@ -27,25 +27,37 @@ export const isNewCampaign = (
current: Campaign,
previous: Campaign | undefined,
options: Options,
logger: Logger,
isNewSession = true,
) => {
const { referrer, referring_domain, ...currentCampaign } = current;
const { referrer: _previous_referrer, referring_domain: prevReferringDomain, ...previousCampaign } = previous || {};

if (isExcludedReferrer(options.excludeReferrers, current.referring_domain)) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
logger.debug(`This is not a new campaign because ${current.referring_domain} is in the exclude referrer list.`);
return false;
}

//In the same session, direct traffic should not override or unset any persisting query params
if (!isNewSession && isDirectTraffic(current) && previous) {
logger.debug('This is not a new campaign because this is a direct traffic in the same session.');
return false;
}

const hasNewCampaign = JSON.stringify(currentCampaign) !== JSON.stringify(previousCampaign);
const hasNewDomain =
domainWithoutSubdomain(referring_domain || '') !== domainWithoutSubdomain(prevReferringDomain || '');

return !previous || hasNewCampaign || hasNewDomain;
const result = !previous || hasNewCampaign || hasNewDomain;

if (!result) {
logger.debug("This is not a new campaign because it's the same as the previous one.");
} else {
logger.debug(`This is a new campaign. An $identify event will be sent.`);
}

return result;
};

export const isExcludedReferrer = (excludeReferrers: (string | RegExp)[] = [], referringDomain = '') => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BrowserConfig } from '@amplitude/analytics-types';
import { BrowserConfig, Logger } from '@amplitude/analytics-types';
import { Campaign, Storage } from '@amplitude/analytics-types';
import { Options, getDefaultExcludedReferrers, createCampaignEvent, isNewCampaign } from './helpers';
import { getStorageKey } from '../storage/helpers';
Expand All @@ -15,6 +15,7 @@ export class WebAttribution {
shouldTrackNewCampaign = false;
sessionTimeout: number;
lastEventTime?: number;
logger: Logger;

constructor(options: Options, config: BrowserConfig) {
this.options = {
Expand All @@ -28,14 +29,15 @@ export class WebAttribution {
this.currentCampaign = BASE_CAMPAIGN;
this.sessionTimeout = config.sessionTimeout;
this.lastEventTime = config.lastEventTime;
this.logger = config.loggerProvider;
config.loggerProvider.log('Installing web attribution tracking.');
}

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

if (isNewCampaign(this.currentCampaign, this.previousCampaign, this.options, isEventInNewSession)) {
if (isNewCampaign(this.currentCampaign, this.previousCampaign, this.options, this.logger, isEventInNewSession)) {
this.shouldTrackNewCampaign = true;
await this.storage.set(this.storageKey, this.currentCampaign);
}
Expand Down
72 changes: 53 additions & 19 deletions packages/analytics-client-common/test/attribution/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import {

import { getStorageKey } from '../../src/storage/helpers';

const loggerProvider = {
log: jest.fn(),
debug: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
enable: jest.fn(),
disable: jest.fn(),
};

describe('getStorageKey', () => {
test('should return storage key without explicit suffix and limit', () => {
expect(getStorageKey('API_KEY')).toBe('AMP_API_KEY');
Expand All @@ -27,7 +36,7 @@ describe('isNewCampaign', () => {
...BASE_CAMPAIGN,
utm_campaign: 'utm_campaign',
};
expect(isNewCampaign(currentCampaign, previousCampaign, {})).toBe(true);
expect(isNewCampaign(currentCampaign, previousCampaign, {}, loggerProvider)).toBe(true);
});

test('should return true for new referrer', () => {
Expand All @@ -41,7 +50,7 @@ describe('isNewCampaign', () => {
utm_campaign: 'utm_campaign',
referring_domain: 'b.c.d.e',
};
expect(isNewCampaign(currentCampaign, previousCampaign, {})).toBe(true);
expect(isNewCampaign(currentCampaign, previousCampaign, {}, loggerProvider)).toBe(true);
});

test('should return false for string excluded referrer', () => {
Expand All @@ -53,9 +62,14 @@ describe('isNewCampaign', () => {
referring_domain: 'amplitude.com',
};
expect(
isNewCampaign(currentCampaign, previousCampaign, {
excludeReferrers: ['amplitude.com'],
}),
isNewCampaign(
currentCampaign,
previousCampaign,
{
excludeReferrers: ['amplitude.com'],
},
loggerProvider,
),
).toBe(false);
});

Expand All @@ -68,9 +82,14 @@ describe('isNewCampaign', () => {
referring_domain: 'amplitude.com',
};
expect(
isNewCampaign(currentCampaign, previousCampaign, {
excludeReferrers: getDefaultExcludedReferrers('.amplitude.com'),
}),
isNewCampaign(
currentCampaign,
previousCampaign,
{
excludeReferrers: getDefaultExcludedReferrers('.amplitude.com'),
},
loggerProvider,
),
).toBe(false);
});

Expand All @@ -83,9 +102,14 @@ describe('isNewCampaign', () => {
referring_domain: 'analytics.amplitude.com',
};
expect(
isNewCampaign(currentCampaign, previousCampaign, {
excludeReferrers: getDefaultExcludedReferrers('.amplitude.com'),
}),
isNewCampaign(
currentCampaign,
previousCampaign,
{
excludeReferrers: getDefaultExcludedReferrers('.amplitude.com'),
},
loggerProvider,
),
).toBe(false);
});

Expand All @@ -95,9 +119,14 @@ describe('isNewCampaign', () => {
...BASE_CAMPAIGN,
};
expect(
isNewCampaign(currentCampaign, previousCampaign, {
excludeReferrers: ['a'],
}),
isNewCampaign(
currentCampaign,
previousCampaign,
{
excludeReferrers: ['a'],
},
loggerProvider,
),
).toBe(true);
});

Expand All @@ -108,9 +137,14 @@ describe('isNewCampaign', () => {
referring_domain: 'a',
};
expect(
isNewCampaign(currentCampaign, previousCampaign, {
excludeReferrers: ['a'],
}),
isNewCampaign(
currentCampaign,
previousCampaign,
{
excludeReferrers: ['a'],
},
loggerProvider,
),
).toBe(false);
});

Expand All @@ -124,7 +158,7 @@ describe('isNewCampaign', () => {
...BASE_CAMPAIGN,
};

expect(isNewCampaign(currentCampaign, previousCampaign, {}, false)).toBe(false);
expect(isNewCampaign(currentCampaign, previousCampaign, {}, loggerProvider, false)).toBe(false);
});

test('should return true for no referrer with any new campaign in the same session', () => {
Expand All @@ -138,7 +172,7 @@ describe('isNewCampaign', () => {
utm_source: 'utm_source',
};

expect(isNewCampaign(currentCampaign, previousCampaign, {}, false)).toBe(true);
expect(isNewCampaign(currentCampaign, previousCampaign, {}, loggerProvider, false)).toBe(true);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { isNewCampaign } from '@amplitude/analytics-client-common';
import { CreateWebAttributionPlugin, Options } from './typings/web-attribution';
import { isNewSession } from '@amplitude/analytics-client-common';

/**
* @deprecated
* This plugin is not used by @amplitude/analytics-browser and
* is replaced by WebAttribution in @amplitude/analytics-client-common to
* be able to send identify events before session start.
*/
export const webAttributionPlugin: CreateWebAttributionPlugin = function (options: Options = {}) {
const plugin: BeforePlugin = {
name: '@amplitude/plugin-web-attribution-browser',
Expand All @@ -19,7 +25,7 @@ export const webAttributionPlugin: CreateWebAttributionPlugin = function (option

const isEventInNewSession = isNewSession(config.sessionTimeout, config.lastEventTime);

if (isNewCampaign(currentCampaign, previousCampaign, pluginConfig, isEventInNewSession)) {
if (isNewCampaign(currentCampaign, previousCampaign, pluginConfig, config.loggerProvider, isEventInNewSession)) {
if (pluginConfig.resetSessionOnNewCampaign) {
amplitude.setSessionId(Date.now());
config.loggerProvider.log('Created a new session for new campaign.');
Expand Down

0 comments on commit a14a68c

Please sign in to comment.