Skip to content

Commit 73e9696

Browse files
feat: Add Extensions to Rokt Kit (#26)
1 parent 0f36fac commit 73e9696

2 files changed

Lines changed: 123 additions & 8 deletions

File tree

src/Rokt-Kit.js

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,28 @@ var constructor = function () {
2626
self.launcher = null;
2727
self.filters = {};
2828
self.userAttributes = {};
29+
self.testHelpers = null;
2930

3031
/**
31-
* Generates the Rokt launcher script URL with optional domain override
32+
* Generates the Rokt launcher script URL with optional domain override and extensions
3233
* @param {string} domain - The CNAME domain to use for overriding the launcher url
34+
* @param {Array<string>} extensions - List of extension query parameters to append
3335
* @returns {string} The complete launcher script URL
3436
*/
35-
function generateLauncherScript(_domain) {
37+
function generateLauncherScript(_domain, extensions) {
3638
// Override domain if a customer is using a CNAME
3739
// If a customer is using a CNAME, a domain will be passed. If not, we use the default domain.
3840
var domain = typeof _domain !== 'undefined' ? _domain : 'apps.rokt.com';
3941
var protocol = 'https://';
4042
var launcherPath = '/wsdk/integrations/launcher.js';
43+
var baseUrl = [protocol, domain, launcherPath].join('');
4144

42-
return [protocol, domain, launcherPath].join('');
45+
if (!extensions || extensions.length === 0) {
46+
return baseUrl;
47+
}
48+
return baseUrl + '?extensions=' + extensions.join(',');
4349
}
50+
4451
/**
4552
* Passes attributes to the Rokt Web SDK for client-side hashing
4653
* @see https://docs.rokt.com/developers/integration-guides/web/library/integration-launcher#hash-attributes
@@ -64,6 +71,7 @@ var constructor = function () {
6471
filteredUserAttributes
6572
) {
6673
var accountId = settings.accountId;
74+
var roktExtensions = extractRoktExtensions(settings.roktExtensions);
6775
self.userAttributes = filteredUserAttributes;
6876
self.onboardingExpProvider = settings.onboardingExpProvider;
6977
var domain = window.mParticle.Rokt.domain;
@@ -78,6 +86,7 @@ var constructor = function () {
7886
if (testMode) {
7987
self.testHelpers = {
8088
generateLauncherScript: generateLauncherScript,
89+
extractRoktExtensions: extractRoktExtensions,
8190
};
8291
attachLauncher(accountId, launcherOptions);
8392
return;
@@ -87,7 +96,7 @@ var constructor = function () {
8796
var target = document.head || document.body;
8897
var script = document.createElement('script');
8998
script.type = 'text/javascript';
90-
script.src = generateLauncherScript(domain);
99+
script.src = generateLauncherScript(domain, roktExtensions);
91100
script.async = true;
92101
script.crossOrigin = 'anonymous';
93102
script.fetchPriority = 'high';
@@ -192,6 +201,22 @@ var constructor = function () {
192201
return self.launcher.selectPlacements(selectPlacementsOptions);
193202
}
194203

204+
/**
205+
* Sets extension data for Rokt Web SDK
206+
* @param {Object} partnerExtensionData - The extension data object containing:
207+
* - [extensionName] {string}: Name of the extension
208+
* - [extensionName].options {Object}: Key-value pairs of options for the extension
209+
* @returns {void} Nothing is returned
210+
*/
211+
function setExtensionData(partnerExtensionData) {
212+
if (!isInitialized()) {
213+
console.error('Rokt Kit: Not initialized');
214+
return;
215+
}
216+
217+
window.Rokt.setExtensionData(partnerExtensionData);
218+
}
219+
195220
function onUserIdentified(filteredUser) {
196221
self.filters.filteredUser = filteredUser;
197222
self.userAttributes = filteredUser.getAllUserAttributes();
@@ -290,6 +315,7 @@ var constructor = function () {
290315

291316
// Kit Callback Methods
292317
this.init = initForwarder;
318+
this.setExtensionData = setExtensionData;
293319
this.setUserAttribute = setUserAttribute;
294320
this.onUserIdentified = onUserIdentified;
295321
this.removeUserAttribute = removeUserAttribute;
@@ -368,6 +394,25 @@ function mergeObjects() {
368394
return resObj;
369395
}
370396

397+
function parseSettingsString(settingsString) {
398+
try {
399+
return JSON.parse(settingsString.replace(/&quot;/g, '"'));
400+
} catch (error) {
401+
throw new Error('Settings string contains invalid JSON');
402+
}
403+
}
404+
405+
function extractRoktExtensions(settingsString) {
406+
var settings = settingsString ? parseSettingsString(settingsString) : [];
407+
408+
var roktExtensions = [];
409+
for (var i = 0; i < settings.length; i++) {
410+
roktExtensions.push(settings[i].value);
411+
}
412+
413+
return roktExtensions;
414+
}
415+
371416
if (window && window.mParticle && window.mParticle.addForwarder) {
372417
window.mParticle.addForwarder({
373418
name: name,

test/src/tests.js

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,11 @@ describe('Rokt Forwarder', () => {
6767

6868
this.initializeCalled = false;
6969
this.isInitialized = false;
70-
7170
this.accountId = null;
7271
this.sandbox = null;
7372
this.integrationName = null;
74-
this.noFunctional = null;
75-
this.noTargeting = null;
76-
7773
this.createLauncherCalled = false;
74+
7875
this.createLauncher = function (options) {
7976
self.accountId = options.accountId;
8077
self.integrationName = options.integrationName;
@@ -1210,5 +1207,78 @@ describe('Rokt Forwarder', () => {
12101207
'https://cname.rokt.com/wsdk/integrations/launcher.js'
12111208
);
12121209
});
1210+
1211+
it('should return base URL when no extensions are provided', () => {
1212+
const url =
1213+
window.mParticle.forwarder.testHelpers.generateLauncherScript();
1214+
url.should.equal(baseUrl);
1215+
});
1216+
1217+
it('should return base URL when extensions is null or undefined', () => {
1218+
window.mParticle.forwarder.testHelpers
1219+
.generateLauncherScript(undefined, null)
1220+
.should.equal(baseUrl);
1221+
1222+
window.mParticle.forwarder.testHelpers
1223+
.generateLauncherScript(undefined, undefined)
1224+
.should.equal(baseUrl);
1225+
});
1226+
1227+
it('should correctly append a single extension', () => {
1228+
const url =
1229+
window.mParticle.forwarder.testHelpers.generateLauncherScript(
1230+
undefined,
1231+
['cos-extension-detection']
1232+
);
1233+
url.should.equal(baseUrl + '?extensions=cos-extension-detection');
1234+
});
1235+
1236+
it('should correctly append multiple extensions', () => {
1237+
const url =
1238+
window.mParticle.forwarder.testHelpers.generateLauncherScript(
1239+
undefined,
1240+
[
1241+
'cos-extension-detection',
1242+
'experiment-monitoring',
1243+
'sponsored-payments-apple-pay',
1244+
]
1245+
);
1246+
url.should.equal(
1247+
baseUrl +
1248+
'?extensions=cos-extension-detection,' +
1249+
'experiment-monitoring,' +
1250+
'sponsored-payments-apple-pay'
1251+
);
1252+
});
1253+
});
1254+
1255+
describe('#roktExtensions', () => {
1256+
beforeEach(async () => {
1257+
window.Rokt = new MockRoktForwarder();
1258+
window.mParticle.Rokt = window.Rokt;
1259+
1260+
await window.mParticle.forwarder.init(
1261+
{
1262+
accountId: '123456',
1263+
},
1264+
reportService.cb,
1265+
true
1266+
);
1267+
});
1268+
1269+
describe('extractRoktExtensions', () => {
1270+
it('should correctly map known extension names to their query parameters', async () => {
1271+
const settingsString =
1272+
'[{&quot;jsmap&quot;:null,&quot;map&quot;:null,&quot;maptype&quot;:&quot;StaticList&quot;,&quot;value&quot;:&quot;cos-extension-detection&quot;},{&quot;jsmap&quot;:null,&quot;map&quot;:null,&quot;maptype&quot;:&quot;StaticList&quot;,&quot;value&quot;:&quot;experiment-monitoring&quot;}]';
1273+
const expectedExtensions = [
1274+
'cos-extension-detection',
1275+
'experiment-monitoring',
1276+
];
1277+
1278+
window.mParticle.forwarder.testHelpers
1279+
.extractRoktExtensions(settingsString)
1280+
.should.deepEqual(expectedExtensions);
1281+
});
1282+
});
12131283
});
12141284
});

0 commit comments

Comments
 (0)