Skip to content

Commit e9fd3d4

Browse files
authored
feat: SDKE-123 Support hashedEmailUserIdentityType for "other" identity type (#40)
1 parent 6ace437 commit e9fd3d4

2 files changed

Lines changed: 229 additions & 16 deletions

File tree

src/Rokt-Kit.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@ var moduleId = 181;
1818

1919
var constructor = function () {
2020
var self = this;
21-
var EMAIL_SHA256_IDENTITY = 'emailsha256';
22-
var OTHER_IDENTITY = 'other';
2321
var PerformanceMarks = {
2422
RoktScriptAppended: 'mp:RoktScriptAppended',
2523
};
2624

25+
var EMAIL_SHA256_KEY = 'emailsha256';
26+
var EMAIL_KEY = 'email';
27+
28+
// Dynamic identity type for Rokt's emailsha256 identity value which MP doesn't natively support - will be set during initialization
29+
var mappedEmailSha256Key;
30+
2731
self.name = name;
2832
self.moduleId = moduleId;
2933
self.isInitialized = false;
@@ -89,6 +93,13 @@ var constructor = function () {
8993
placementEventMapping
9094
);
9195

96+
// Set dynamic OTHER_IDENTITY based on server settings
97+
// Convert to lowercase since server sends TitleCase (e.g., 'Other' -> 'other')
98+
if (settings.hashedEmailUserIdentityType) {
99+
mappedEmailSha256Key =
100+
settings.hashedEmailUserIdentityType.toLowerCase();
101+
}
102+
92103
var domain = window.mParticle.Rokt.domain;
93104
var launcherOptions = mergeObjects(
94105
{},
@@ -157,7 +168,7 @@ var constructor = function () {
157168

158169
var userIdentities = filteredUser.getUserIdentities().userIdentities;
159170

160-
return replaceOtherWithEmailsha256(userIdentities);
171+
return replaceOtherIdentityWithEmailsha256(userIdentities);
161172
}
162173

163174
function returnLocalSessionAttributes() {
@@ -172,11 +183,21 @@ var constructor = function () {
172183
return window.mParticle.Rokt.getLocalSessionAttributes();
173184
}
174185

175-
function replaceOtherWithEmailsha256(_data) {
186+
function replaceOtherIdentityWithEmailsha256(userIdentities) {
187+
var newUserIdentities = mergeObjects({}, userIdentities || {});
188+
if (userIdentities.hasOwnProperty(mappedEmailSha256Key)) {
189+
newUserIdentities[EMAIL_SHA256_KEY] =
190+
userIdentities[mappedEmailSha256Key];
191+
delete newUserIdentities[mappedEmailSha256Key];
192+
}
193+
194+
return newUserIdentities;
195+
}
196+
197+
function sanitizeEmailIdentities(_data) {
176198
var data = mergeObjects({}, _data || {});
177-
if (_data.hasOwnProperty(OTHER_IDENTITY)) {
178-
data[EMAIL_SHA256_IDENTITY] = _data[OTHER_IDENTITY];
179-
delete data[OTHER_IDENTITY];
199+
if (_data.hasOwnProperty(EMAIL_SHA256_KEY)) {
200+
delete data[EMAIL_KEY];
180201
}
181202

182203
return data;
@@ -232,7 +253,7 @@ var constructor = function () {
232253

233254
var selectPlacementsAttributes = mergeObjects(
234255
filteredUserIdentities,
235-
replaceOtherWithEmailsha256(filteredAttributes),
256+
filteredAttributes,
236257
optimizelyAttributes,
237258
localSessionAttributes,
238259
{
@@ -241,7 +262,7 @@ var constructor = function () {
241262
);
242263

243264
var selectPlacementsOptions = mergeObjects(options, {
244-
attributes: selectPlacementsAttributes,
265+
attributes: sanitizeEmailIdentities(selectPlacementsAttributes),
245266
});
246267

247268
return self.launcher.selectPlacements(selectPlacementsOptions);

test/src/tests.js

Lines changed: 199 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,7 @@ describe('Rokt Forwarder', () => {
13441344
await window.mParticle.forwarder.init(
13451345
{
13461346
accountId: '123456',
1347+
hashedEmailUserIdentityType: 'Other',
13471348
},
13481349
reportService.cb,
13491350
true,
@@ -1420,21 +1421,21 @@ describe('Rokt Forwarder', () => {
14201421
await window.mParticle.forwarder.selectPlacements({
14211422
identifier: 'test-placement',
14221423
attributes: {
1423-
other: 'sha256-test@gmail.com',
1424+
other: 'other-attribute',
14241425
},
14251426
});
14261427

14271428
window.Rokt.selectPlacementsOptions.attributes.should.deepEqual(
14281429
{
14291430
'test-attribute': 'test-value',
14301431
customerid: 'customer123',
1431-
emailsha256: 'sha256-test@gmail.com',
1432+
other: 'other-attribute',
14321433
mpid: '123',
14331434
}
14341435
);
14351436
});
14361437

1437-
it('should prioritize other passed to selectPlacements over other in userIdentities', async () => {
1438+
it('should pass the attribute `other` in selectPlacements directly to Rokt', async () => {
14381439
window.mParticle.Rokt.filters = {
14391440
userAttributeFilters: [],
14401441
filterUserAttributes: function (attributes) {
@@ -1448,7 +1449,7 @@ describe('Rokt Forwarder', () => {
14481449
return {
14491450
userIdentities: {
14501451
customerid: 'customer123',
1451-
other: 'not-prioritized-from-userIdentities@gmail.com',
1452+
other: 'other-id',
14521453
},
14531454
};
14541455
},
@@ -1486,20 +1487,211 @@ describe('Rokt Forwarder', () => {
14861487
await window.mParticle.forwarder.selectPlacements({
14871488
identifier: 'test-placement',
14881489
attributes: {
1489-
other: 'prioritized-from-selectPlacements@gmail.com',
1490+
other: 'continues-to-exist',
14901491
},
14911492
});
14921493

14931494
window.Rokt.selectPlacementsOptions.attributes.should.deepEqual(
14941495
{
14951496
'test-attribute': 'test-value',
14961497
customerid: 'customer123',
1497-
emailsha256:
1498-
'prioritized-from-selectPlacements@gmail.com',
1498+
other: 'continues-to-exist',
1499+
emailsha256: 'other-id',
14991500
mpid: '123',
15001501
}
15011502
);
15021503
});
1504+
1505+
it('should use custom hashedEmailUserIdentityType when provided in settings', async () => {
1506+
window.mParticle.Rokt.filters = {
1507+
userAttributeFilters: [],
1508+
filterUserAttributes: function (attributes) {
1509+
return attributes;
1510+
},
1511+
filteredUser: {
1512+
getMPID: function () {
1513+
return '789';
1514+
},
1515+
getUserIdentities: function () {
1516+
return {
1517+
userIdentities: {
1518+
// Using 'customerid' as the identity type instead of 'other'
1519+
other5: 'hashed-customer-id-value',
1520+
},
1521+
};
1522+
},
1523+
},
1524+
};
1525+
1526+
// Set up the createLauncher to properly resolve asynchronously
1527+
window.Rokt.createLauncher = async function () {
1528+
return Promise.resolve({
1529+
selectPlacements: function (options) {
1530+
window.mParticle.Rokt.selectPlacementsOptions =
1531+
options;
1532+
window.mParticle.Rokt.selectPlacementsCalled = true;
1533+
},
1534+
});
1535+
};
1536+
1537+
await window.mParticle.forwarder.init(
1538+
{
1539+
accountId: '123456',
1540+
hashedEmailUserIdentityType: 'Other5', // TitleCase from server
1541+
},
1542+
reportService.cb,
1543+
true,
1544+
null,
1545+
{}
1546+
);
1547+
1548+
// Wait for initialization to complete (after launcher is created)
1549+
await waitForCondition(() => {
1550+
return window.mParticle.forwarder.isInitialized;
1551+
});
1552+
1553+
await window.mParticle.forwarder.selectPlacements({
1554+
identifier: 'test-placement',
1555+
attributes: {
1556+
'test-attribute': 'test-value',
1557+
},
1558+
});
1559+
1560+
// Should map customerid from userIdentities to emailsha256 since hashedEmailUserIdentityType was set to 'CustomerID'
1561+
window.Rokt.selectPlacementsOptions.attributes.should.deepEqual(
1562+
{
1563+
'test-attribute': 'test-value',
1564+
emailsha256: 'hashed-customer-id-value', // mapped from customerid in userIdentities
1565+
mpid: '789',
1566+
}
1567+
);
1568+
});
1569+
1570+
it('should NOT set emailsha256 on final select placements attributes when hashedEmailUserIdentityType is Unassigned', async () => {
1571+
window.mParticle.Rokt.filters = {
1572+
userAttributeFilters: [],
1573+
filterUserAttributes: function (attributes) {
1574+
return attributes;
1575+
},
1576+
filteredUser: {
1577+
getMPID: function () {
1578+
return '999';
1579+
},
1580+
getUserIdentities: function () {
1581+
return {
1582+
userIdentities: {
1583+
// Using lowercase identity name that matches the converted OTHER_IDENTITY
1584+
other: 'hashed-custom-identity-value',
1585+
},
1586+
};
1587+
},
1588+
},
1589+
};
1590+
1591+
// Set up the createLauncher to properly resolve asynchronously
1592+
window.Rokt.createLauncher = async function () {
1593+
return Promise.resolve({
1594+
selectPlacements: function (options) {
1595+
window.mParticle.Rokt.selectPlacementsOptions =
1596+
options;
1597+
window.mParticle.Rokt.selectPlacementsCalled = true;
1598+
},
1599+
});
1600+
};
1601+
1602+
await window.mParticle.forwarder.init(
1603+
{
1604+
accountId: '123456',
1605+
hashedEmailUserIdentityType: 'Unassigned', // Mixed case from server
1606+
},
1607+
reportService.cb,
1608+
true,
1609+
null,
1610+
{}
1611+
);
1612+
1613+
// Wait for initialization to complete (after launcher is created)
1614+
await waitForCondition(() => {
1615+
return window.mParticle.forwarder.isInitialized;
1616+
});
1617+
1618+
await window.mParticle.forwarder.selectPlacements({
1619+
identifier: 'test-placement',
1620+
attributes: {
1621+
'test-attr': 'test-value',
1622+
},
1623+
});
1624+
1625+
// Should map customidentity from userIdentities to emailsha256 (TitleCase converted to lowercase)
1626+
window.Rokt.selectPlacementsOptions.attributes.should.deepEqual(
1627+
{
1628+
'test-attr': 'test-value',
1629+
other: 'hashed-custom-identity-value',
1630+
mpid: '999',
1631+
}
1632+
);
1633+
});
1634+
1635+
it('should remove email identity if emailsha256 is passed through selectPlacements', async () => {
1636+
window.mParticle.Rokt.filters = {
1637+
userAttributeFilters: [],
1638+
filterUserAttributes: function (attributes) {
1639+
return attributes;
1640+
},
1641+
filteredUser: {
1642+
getMPID: function () {
1643+
return '456';
1644+
},
1645+
getUserIdentities: function () {
1646+
return {
1647+
userIdentities: {
1648+
email: 'test@example.com',
1649+
},
1650+
};
1651+
},
1652+
},
1653+
};
1654+
1655+
// Set up the createLauncher to properly resolve asynchronously
1656+
window.Rokt.createLauncher = async function () {
1657+
return Promise.resolve({
1658+
selectPlacements: function (options) {
1659+
window.mParticle.Rokt.selectPlacementsOptions =
1660+
options;
1661+
window.mParticle.Rokt.selectPlacementsCalled = true;
1662+
},
1663+
});
1664+
};
1665+
1666+
await window.mParticle.forwarder.init(
1667+
{
1668+
accountId: '123456',
1669+
},
1670+
reportService.cb,
1671+
true,
1672+
null,
1673+
{}
1674+
);
1675+
1676+
// Wait for initialization to complete (after launcher is created)
1677+
await waitForCondition(() => {
1678+
return window.mParticle.forwarder.isInitialized;
1679+
});
1680+
1681+
await window.mParticle.forwarder.selectPlacements({
1682+
identifier: 'test-placement',
1683+
attributes: {
1684+
emailsha256: 'hashed-email-value',
1685+
},
1686+
});
1687+
1688+
window.Rokt.selectPlacementsOptions.attributes.should.deepEqual(
1689+
{
1690+
emailsha256: 'hashed-email-value',
1691+
mpid: '456',
1692+
}
1693+
);
1694+
});
15031695
});
15041696
});
15051697

0 commit comments

Comments
 (0)