Skip to content

Commit 2c8c3be

Browse files
authored
feat(analytics-js-integrations): onboard ga4 v2 hybrid mode (#1802)
1 parent 7dd90a6 commit 2c8c3be

File tree

10 files changed

+133
-3
lines changed

10 files changed

+133
-3
lines changed

packages/analytics-js-common/src/constants/destDisplayNamesToFileNamesMap.ts

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import {
4040
TVSquaredDirectoryName,
4141
GA4DisplayName,
4242
GA4DirectoryName,
43+
GA4_V2DisplayName,
44+
GA4_V2DirectoryName,
4345
MoEngageDisplayName,
4446
MoEngageDirectoryName,
4547
AmplitudeDisplayName,
@@ -180,6 +182,7 @@ const destDisplayNamesToFileNamesMap: Record<string, string> = {
180182
[FullstoryDisplayName]: FullstoryDirectoryName,
181183
[TVSquaredDisplayName]: TVSquaredDirectoryName,
182184
[GA4DisplayName]: GA4DirectoryName,
185+
[GA4_V2DisplayName]: GA4_V2DirectoryName,
183186
[MoEngageDisplayName]: MoEngageDirectoryName,
184187
[AmplitudeDisplayName]: AmplitudeDirectoryName,
185188
[PendoDisplayName]: PendoDirectoryName,

packages/analytics-js-common/src/constants/destinationNames.ts

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export {
6262
DISPLAY_NAME as GA4DisplayName,
6363
DIR_NAME as GA4DirectoryName,
6464
} from './integrations/GA4/constants';
65+
export {
66+
DISPLAY_NAME as GA4_V2DisplayName,
67+
DIR_NAME as GA4_V2DirectoryName,
68+
} from './integrations/GA4_V2/constants';
6569
export {
6670
DISPLAY_NAME as GoogleAdsDisplayName,
6771
DIR_NAME as GoogleAdsDirectoryName,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const DIR_NAME = 'GA4_V2';
2+
const NAME = 'GA4_V2';
3+
const DISPLAY_NAME = 'Google Analytics 4 (GA4) V2';
4+
5+
const DISPLAY_NAME_TO_DIR_NAME_MAP = { [DISPLAY_NAME]: DIR_NAME };
6+
const CNameMapping = {
7+
[NAME]: NAME,
8+
'Google Analytics 4 V2': NAME,
9+
'Google analytics 4 V2': NAME,
10+
'google analytics 4 V2': NAME,
11+
'Google Analytics4 V2': NAME,
12+
'Google analytics4 V2': NAME,
13+
'google analytics4 V2': NAME,
14+
'Google Analytics 4 (GA4) V2': NAME,
15+
'google analytics 4 (ga4) V2': NAME,
16+
GoogleAnalytics4V2: NAME,
17+
};
18+
19+
export { NAME, CNameMapping, DISPLAY_NAME_TO_DIR_NAME_MAP, DISPLAY_NAME, DIR_NAME };

packages/analytics-js-common/src/v1.1/utils/client_server_name.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const clientToServerNames = {
2222
FULLSTORY: 'Fullstory',
2323
TVSQUARED: 'TVSquared',
2424
GA4: 'Google Analytics 4 (GA4)',
25+
GA4_V2: 'Google Analytics 4 (GA4) V2',
2526
MOENGAGE: 'MoEngage',
2627
AM: 'Amplitude',
2728
PENDO: 'Pendo',

packages/analytics-js-common/src/v1.1/utils/config_to_integration_names.js

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const configToIntNames = {
2020
FULLSTORY: 'Fullstory',
2121
TVSQUARED: 'TVSquared',
2222
GA4: 'GA4',
23+
GA4_V2: 'GA4_V2',
2324
MOENGAGE: 'MoEngage',
2425
AM: 'Amplitude',
2526
PENDO: 'Pendo',

packages/analytics-js-common/src/v1.1/utils/integration_cname.js

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { CNameMapping as FacebookPixel } from '../../constants/integrations/Face
1414
import { CNameMapping as Fullstory } from '../../constants/integrations/Fullstory/constants';
1515
import { CNameMapping as GA } from '../../constants/integrations/GA/constants';
1616
import { CNameMapping as GA4 } from '../../constants/integrations/GA4/constants';
17+
import { CNameMapping as GA4_V2 } from '../../constants/integrations/GA4_V2/constants';
1718
import { CNameMapping as GoogleAds } from '../../constants/integrations/GoogleAds/constants';
1819
import { CNameMapping as GoogleOptimize } from '../../constants/integrations/GoogleOptimize/constants';
1920
import { CNameMapping as GoogleTagManager } from '../../constants/integrations/GoogleTagManager/constants';
@@ -98,6 +99,7 @@ const commonNames = {
9899
...Fullstory,
99100
...GA,
100101
...GA4,
102+
...GA4_V2,
101103
...GA360,
102104
...GoogleAds,
103105
...GoogleOptimize,

packages/analytics-js-integrations/.size-limit.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ module.exports = [
66
{
77
name: 'All Integrations - Legacy - CDN',
88
path: 'dist/cdn/legacy/js-integrations/*.min.js',
9-
limit: '93 KiB',
9+
limit: '95.3 KiB',
1010
},
1111
{
1212
name: 'All Integrations - Modern - CDN',
1313
path: 'dist/cdn/modern/js-integrations/*.min.js',
14-
limit: '88 KiB',
14+
limit: '91 KiB',
1515
},
1616
];

packages/analytics-js-integrations/src/integrations/GA4/browser.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default class GA4 {
3939
this.overrideClientAndSessionId = config.overrideClientAndSessionId || false;
4040
this.sdkBaseUrl =
4141
removeTrailingSlashes(config.sdkBaseUrl) || 'https://www.googletagmanager.com';
42+
this.isExtendedGa4_V2 = config.isExtendedGa4_V2 || false;
4243
({
4344
shouldApplyDeviceModeTransformation: this.shouldApplyDeviceModeTransformation,
4445
propagateEventsUntransformedOnError: this.propagateEventsUntransformedOnError,
@@ -70,7 +71,7 @@ export default class GA4 {
7071
gtagParameterObject.cookie_prefix = 'rs';
7172
gtagParameterObject.client_id = this.analytics.getAnonymousId();
7273
gtagParameterObject.session_id = this.analytics.getSessionId();
73-
} else {
74+
} else if(!this.isExtendedGa4_V2){
7475
// Cookie migration logic
7576
const clientCookie = this.cookie.get('rs_ga');
7677
const defaultGA4Cookie = this.cookie.get('_ga');
@@ -260,4 +261,15 @@ export default class GA4 {
260261
},
261262
};
262263
}
264+
265+
// Is used in GA4_V2
266+
getClientDetails() {
267+
return {
268+
clientId: this.clientId,
269+
sessionId: this.sessionId,
270+
sessionNumber: this.sessionNumber,
271+
};
272+
}
263273
}
274+
275+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import {
2+
NAME,
3+
DISPLAY_NAME,
4+
} from '@rudderstack/analytics-js-common/constants/integrations/GA4_V2/constants';
5+
import { isDefinedAndNotNull } from '../../utils/commonUtils';
6+
import Logger from '../../utils/logger';
7+
import { GA4 } from '../GA4';
8+
9+
const logger = new Logger(DISPLAY_NAME);
10+
11+
// eslint-disable-next-line @typescript-eslint/naming-convention
12+
export default class GA4_V2 extends GA4 {
13+
constructor(config, analytics, destinationInfo) {
14+
if (analytics.logLevel) {
15+
logger.setLogLevel(analytics.logLevel);
16+
}
17+
18+
const newConfig = { ...config };
19+
/**
20+
* Sample configData
21+
* "{\"ACCOUNT\":\"321500532\",\"PROPERTY\":\"449999397\",\"DATA_STREAM\":{\"value\":\"G-Q3C88MMDW1\",\"type\":\"gtag\"},\"MEASUREMENT_PROTOCOL_SECRET\":\"sample_secret\"}";
22+
*/
23+
24+
if (isDefinedAndNotNull(config.configData)) {
25+
const configDetails = JSON.parse(config.configData);
26+
newConfig.propertyId = configDetails.PROPERTY;
27+
newConfig.typesOfClient = configDetails.DATA_STREAM.type;
28+
if (newConfig.typesOfClient !== 'gtag') {
29+
logger.error('Invalid typesOfClient. Please select gtag');
30+
}
31+
newConfig.measurementId = configDetails.DATA_STREAM.value;
32+
}
33+
34+
if (!isDefinedAndNotNull(newConfig.measurementId)) {
35+
logger.error('Measurement ID is required for GA4');
36+
}
37+
38+
newConfig.isExtendedGa4_V2 = true;
39+
super(newConfig, analytics, destinationInfo);
40+
this.analytics = analytics;
41+
this.name = NAME;
42+
({
43+
shouldApplyDeviceModeTransformation: this.shouldApplyDeviceModeTransformation,
44+
propagateEventsUntransformedOnError: this.propagateEventsUntransformedOnError,
45+
destinationId: this.destinationId,
46+
} = destinationInfo ?? {});
47+
}
48+
49+
init() {
50+
return super.init();
51+
}
52+
53+
isLoaded() {
54+
return super.isLoaded();
55+
}
56+
57+
isReady() {
58+
return super.isReady();
59+
}
60+
61+
identify(rudderElement) {
62+
return super.identify(rudderElement);
63+
}
64+
65+
track(rudderElement) {
66+
return super.track(rudderElement);
67+
}
68+
69+
page(rudderElement) {
70+
return super.page(rudderElement);
71+
}
72+
73+
group(rudderElement) {
74+
return super.group(rudderElement);
75+
}
76+
77+
getDataForIntegrationsObject() {
78+
const { clientId, sessionId, sessionNumber } = super.getClientDetails();
79+
return {
80+
[DISPLAY_NAME]: {
81+
clientId,
82+
sessionId,
83+
sessionNumber,
84+
},
85+
};
86+
}
87+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as GA4_V2 } from './browser';

0 commit comments

Comments
 (0)