Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3509d9e
fix: fix web attribution identify and session start order
yuhao900914 Mar 29, 2024
cb448e4
build: update other sdk dependency
yuhao900914 Mar 29, 2024
ff7f12a
fix: make campaign tracking order before page view tracking
yuhao900914 Apr 8, 2024
0151368
fix: fix the event id not right for web attribution identify
yuhao900914 Apr 8, 2024
45aa354
test: test
yuhao900914 Apr 9, 2024
0222d83
fix: clean up
yuhao900914 Apr 9, 2024
2ec62f5
fix: clean up
yuhao900914 Apr 9, 2024
cb3db32
fix: remove default web attribution plugin installation
yuhao900914 Apr 9, 2024
5ba44b1
build: revert the dependency in node and react-native
yuhao900914 Apr 9, 2024
d18e26a
test: clean the example
yuhao900914 Apr 9, 2024
7d7645f
fix: remove no-non-null-assertion
yuhao900914 Apr 9, 2024
9f6cfc8
fix: fix session event not fired
yuhao900914 Apr 9, 2024
1260a18
fix: merge with main
yuhao900914 Apr 10, 2024
a241181
fix: refine structure and fix test coverage
yuhao900914 Apr 10, 2024
f5a470c
fix: fixes based on commend
yuhao900914 Apr 10, 2024
ca2214d
test: fix test
yuhao900914 Apr 10, 2024
92e5ea5
fix: refine the logic
yuhao900914 Apr 10, 2024
847d367
test: fix the test
yuhao900914 Apr 11, 2024
e411381
fix: refactor move web attribution logic in analytics-client-common
yuhao900914 Apr 11, 2024
baff0c6
fix: nits
yuhao900914 Apr 13, 2024
7530205
fix: remove await on page view tracking
yuhao900914 Apr 16, 2024
b6b2ca3
feat: make setSessionId return promise
yuhao900914 Apr 17, 2024
5294eae
test: fix test
yuhao900914 Apr 17, 2024
feffbd3
fix: fix the track campaign event
yuhao900914 Apr 17, 2024
9c442c8
fix: fix event promise
yuhao900914 Apr 17, 2024
fb8630a
fix: add type
yuhao900914 Apr 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions packages/analytics-browser-test/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -907,22 +907,6 @@ describe('integration', () => {
{
device_id: uuid,
event_id: 101,
event_type: 'session_start',
insert_id: uuid,
ip: '$remote',
language: 'en-US',
library,
partner_id: undefined,
plan: undefined,
platform: 'Web',
session_id: number,
time: number,
user_agent: userAgent,
user_id: '[email protected]',
},
{
device_id: uuid,
event_id: 102,
event_type: '$identify',
insert_id: uuid,
ip: '$remote',
Expand Down Expand Up @@ -980,6 +964,22 @@ describe('integration', () => {
},
},
},
{
device_id: uuid,
event_id: 102,
event_type: 'session_start',
insert_id: uuid,
ip: '$remote',
language: 'en-US',
library,
partner_id: undefined,
plan: undefined,
platform: 'Web',
session_id: number,
time: number,
user_agent: userAgent,
user_id: '[email protected]',
},
{
device_id: uuid,
event_id: 103,
Expand Down Expand Up @@ -1115,22 +1115,6 @@ describe('integration', () => {
{
device_id: uuid,
event_id: 0,
event_type: 'session_start',
insert_id: uuid,
ip: '$remote',
language: 'en-US',
library,
partner_id: undefined,
plan: undefined,
platform: 'Web',
session_id: number,
time: number,
user_agent: userAgent,
user_id: '[email protected]',
},
{
device_id: uuid,
event_id: 1,
event_type: '$identify',
insert_id: uuid,
ip: '$remote',
Expand Down Expand Up @@ -1188,6 +1172,22 @@ describe('integration', () => {
},
},
},
{
device_id: uuid,
event_id: 1,
event_type: 'session_start',
insert_id: uuid,
ip: '$remote',
language: 'en-US',
library,
partner_id: undefined,
plan: undefined,
platform: 'Web',
session_id: number,
time: number,
user_agent: userAgent,
user_id: '[email protected]',
},
{
device_id: uuid,
event_id: 2,
Expand Down
1 change: 0 additions & 1 deletion packages/analytics-browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"@amplitude/analytics-core": "^2.2.4",
"@amplitude/analytics-types": "^2.5.0",
"@amplitude/plugin-page-view-tracking-browser": "^2.2.6",
"@amplitude/plugin-web-attribution-browser": "^2.1.7",
"tslib": "^2.4.1"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/analytics-browser/playground/amplitude.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion packages/analytics-browser/playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
<title>Amplitude SDK Playground</title>
</head>
<script src="./amplitude.js"></script>
<script>

<script>
amplitude.init('API_KEY', '[email protected]');
</script>
<body>
Expand Down
89 changes: 62 additions & 27 deletions packages/analytics-browser/src/browser-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
setConnectorUserId,
isNewSession,
isPageViewTrackingEnabled,
WebAttribution,
} from '@amplitude/analytics-client-common';
import {
BrowserClient,
Expand All @@ -23,11 +24,12 @@ import {
Revenue as IRevenue,
TransportType,
OfflineDisabled,
AmplitudeReturn,
Result,
} from '@amplitude/analytics-types';
import { convertProxyObjectToRealObject, isInstanceProxy } from './utils/snippet-helper';
import { Context } from './plugins/context';
import { useBrowserConfig, createTransport } from './config';
import { webAttributionPlugin } from '@amplitude/plugin-web-attribution-browser';
import { pageViewTrackingPlugin } from '@amplitude/plugin-page-view-tracking-browser';
import { formInteractionTracking } from './plugins/form-interaction-tracking';
import { fileDownloadTracking } from './plugins/file-download-tracking';
Expand All @@ -41,6 +43,7 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient {
config: BrowserConfig;
previousSessionDeviceId: string | undefined;
previousSessionUserId: string | undefined;
webAttribution: WebAttribution | undefined;

init(apiKey = '', userIdOrOptions?: string | BrowserOptions, maybeOptions?: BrowserOptions) {
let userId: string | undefined;
Expand Down Expand Up @@ -71,6 +74,14 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient {
const browserOptions = await useBrowserConfig(options.apiKey, options, this);
this.config = browserOptions;

// Add web attribution plugin
if (isAttributionTrackingEnabled(this.config.defaultTracking)) {
const attributionTrackingOptions = getAttributionTrackingConfig(this.config);
this.webAttribution = new WebAttribution(attributionTrackingOptions, this.config);
// Fetch the current campaign, check if need to track web attribution later
await this.webAttribution.init();
}

// Step 3: Set session ID
// Priority 1: `options.sessionId`
// Priority 2: last known sessionId from user identity storage
Expand Down Expand Up @@ -109,13 +120,6 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient {
await this.add(formInteractionTracking()).promise;
}

// Add web attribution plugin
if (isAttributionTrackingEnabled(this.config.defaultTracking)) {
const attributionTrackingOptions = getAttributionTrackingConfig(this.config);
const webAttribution = webAttributionPlugin(attributionTrackingOptions);
await this.add(webAttribution).promise;
}

// Add page view plugin
if (isPageViewTrackingEnabled(this.config.defaultTracking)) {
await this.add(pageViewTrackingPlugin(getPageViewTrackingConfig(this.config))).promise;
Expand Down Expand Up @@ -170,14 +174,14 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient {
}

setSessionId(sessionId: number) {
const promise = [];
if (!this.config) {
this.q.push(this.setSessionId.bind(this, sessionId));
return;
return returnWrapper(Promise.resolve());
}

// Prevents starting a new session with the same session ID
if (sessionId === this.config.sessionId) {
return;
return returnWrapper(Promise.resolve());
}

const previousSessionId = this.getSessionId();
Expand All @@ -190,25 +194,37 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient {

if (isSessionTrackingEnabled(this.config.defaultTracking)) {
if (previousSessionId && lastEventTime) {
this.track(DEFAULT_SESSION_END_EVENT, undefined, {
device_id: this.previousSessionDeviceId,
event_id: ++lastEventId,
session_id: previousSessionId,
time: lastEventTime + 1,
user_id: this.previousSessionUserId,
});
promise.push(
this.track(DEFAULT_SESSION_END_EVENT, undefined, {
device_id: this.previousSessionDeviceId,
event_id: ++lastEventId,
session_id: previousSessionId,
time: lastEventTime + 1,
user_id: this.previousSessionUserId,
}),
);
}

this.config.lastEventTime = this.config.sessionId;
this.track(DEFAULT_SESSION_START_EVENT, undefined, {
event_id: ++lastEventId,
session_id: this.config.sessionId,
time: this.config.lastEventTime,
});
}

// Fire web attribution event when enable webAttribution tracking
// 1. has new campaign (call setSessionId from init function)
// 2. or shouldTrackNewCampaign (call setSessionId from async process(event) when there has new campaign and resetSessionOnNewCampaign = true )
const isCampaignEventTracked = this.trackCampaignEventIfNeeded(++lastEventId, promise);

if (isSessionTrackingEnabled(this.config.defaultTracking)) {
promise.push(
this.track(DEFAULT_SESSION_START_EVENT, undefined, {
event_id: isCampaignEventTracked ? ++lastEventId : lastEventId,
session_id: this.config.sessionId,
time: this.config.lastEventTime,
}),
);
}

this.previousSessionDeviceId = this.config.deviceId;
this.previousSessionUserId = this.config.userId;
return returnWrapper(Promise.all(promise));
}

extendSession() {
Expand Down Expand Up @@ -260,17 +276,36 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient {
return super.revenue(revenue, eventOptions);
}

private trackCampaignEventIfNeeded(lastEventId?: number, eventsPromise?: AmplitudeReturn<Result>[]) {
if (!this.webAttribution || !this.webAttribution.shouldTrackNewCampaign) {
return false;
}
const campaignEvent = this.webAttribution.generateCampaignEvent(lastEventId);
eventsPromise?.push(this.track(campaignEvent));
this.config.loggerProvider.log('Tracking attribution.');
return true;
}

async process(event: Event) {
const currentTime = Date.now();
const isEventInNewSession = isNewSession(this.config.sessionTimeout, this.config.lastEventTime);
const shouldSetSessionIdOnNewCampaign =
this.webAttribution && this.webAttribution.shouldSetSessionIdOnNewCampaign();

if (
event.event_type !== DEFAULT_SESSION_START_EVENT &&
event.event_type !== DEFAULT_SESSION_END_EVENT &&
(!event.session_id || event.session_id === this.getSessionId()) &&
isEventInNewSession
(!event.session_id || event.session_id === this.getSessionId())
) {
this.setSessionId(currentTime);
if (isEventInNewSession || shouldSetSessionIdOnNewCampaign) {
this.setSessionId(currentTime);
if (shouldSetSessionIdOnNewCampaign) {
this.config.loggerProvider.log('Created a new session for new campaign.');
}
} else if (!isEventInNewSession) {
// web attribution should be track during the middle of the session if there has any new campaign
this.trackCampaignEventIfNeeded();
}
}

return super.process(event);
Expand Down
Loading