Skip to content

Commit

Permalink
Symetri RTD module: OnBidResponse method added (#12214)
Browse files Browse the repository at this point in the history
* OnBidResponse listener added to add pixel for deals matching to the user deals stored in local storage

* Adding support for simpleId, compositeId & hashedId

* Solved Linter errors. Made some changes to reduce integration errors

* Rolled back the default case as it was generating test errors.

* Testing onBidResponseEvent

* Pass pixel URL as module config parameter

* Added extra attributes to Pixel URL.
Documentation Updated.

* Bidder Name & Code both added

* Fixed Tests
Fixed Linter Errors
Updated Example

---------

Co-authored-by: Manan <manan.patel@intersection.com>
Co-authored-by: Jeff Palladino <1226357+jpalladino84@users.noreply.github.com>
  • Loading branch information
3 people committed Sep 9, 2024
1 parent 1d2b583 commit 123d8aa
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
3 changes: 2 additions & 1 deletion integrationExamples/gpt/symitridap_segments_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
apiVersion: "x1",
domain: "prebid.org",
identityValue: "test@invalid.com",
identityType: "hid"
identityType: "simpleid",
pixelUrl: 'https://www.test.com/pixel'
}
}
]
Expand Down
30 changes: 27 additions & 3 deletions modules/symitriDapRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,30 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) {
return true;
}

function onBidResponse(bidResponse, config, userConsent) {
if (bidResponse.dealId && typeof (bidResponse.dealId) != typeof (undefined)) {
let membership = dapUtils.dapGetMembershipFromLocalStorage(); // Get Membership details from Local Storage
let deals = membership.deals; // Get list of Deals the user is mapped to
deals.forEach((deal) => {
deal = JSON.parse(deal);
if (bidResponse.dealId == deal.id) { // Check if the bid response deal Id matches to the deals mapped to the user
let token = dapUtils.dapGetTokenFromLocalStorage();
let url = config.params.pixelUrl + '?token=' + token + '&ad_id=' + bidResponse.adId + '&bidder=' + bidResponse.bidder + '&bidder_code=' + bidResponse.bidderCode + '&cpm=' + bidResponse.cpm + '&creative_id=' + bidResponse.creativeId + '&deal_id=' + bidResponse.dealId + '&media_type=' + bidResponse.mediaType + '&response_timestamp=' + bidResponse.responseTimestamp;
bidResponse.ad = `${bidResponse.ad}<script src="${url}"/>`;
}
});
}
}

const rtdSubmodule = {
name: SUBMODULE_NAME,
getBidRequestData: getRealTimeData,
onBidResponseEvent: onBidResponse,
init: init
};

submodule(MODULE_NAME, rtdSubmodule);

const dapUtils = {

callDapAPIs: function(bidConfig, onDone, rtdConfig, userConsent) {
Expand Down Expand Up @@ -254,6 +271,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) {
membership = {
said: item.said,
cohorts: item.cohorts,
deals: item.deals,
attributes: null
};
}
Expand All @@ -274,6 +292,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) {
}
item.said = membership.said;
item.cohorts = membership.cohorts;
item.deals = membership.deals ? membership.deals : [];
storage.setDataInLocalStorage(DAP_MEMBERSHIP, JSON.stringify(item));
dapUtils.dapLog('Successfully updated and stored membership:');
dapUtils.dapLog(item);
Expand Down Expand Up @@ -609,13 +628,18 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) {
}

let apiParams = {
'type': identity.type,
'type': identity.type.toLowerCase(),
'identity': identity.value
};

if (identity.type === 'hid') {
if (identity.type === 'simpleid') {
this.addIdentifier(identity, apiParams).then((apiParams) => {
this.callTokenize(config, identity, apiParams, onDone, onSuccess, onError);
});
} else if (identity.type === 'compositeid') {
identity = JSON.stringify(identity);
this.callTokenize(config, identity, apiParams, onDone, onSuccess, onError);
} else if (identity.type === 'hashedid') {
this.callTokenize(config, identity, apiParams, onDone, onSuccess, onError);
} else {
this.callTokenize(config, identity, apiParams, onDone, onSuccess, onError);
}
Expand Down
15 changes: 12 additions & 3 deletions modules/symitriDapRtdProvider.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ pbjs.setConfig({
apiVersion: "x1",
apiAuthToken: '<see your Symitri account rep>',
domain: 'your-domain.com',
identityType: 'hid'| ... | 'dap-signature:1.0.0',
identityType: 'simpleid'|'compositeid'|'hashedid'|'dap-signature:1.0.0',
identityValue: '<user hid>',
segtax: 501,
dapEntropyUrl: 'https://sym-dist.symitri.net/dapentropy.js',
dapEntropyTimeout: 1500
dapEntropyTimeout: 1500,
pixelUrl: '<see your Symitri account rep>',
}
}
]
Expand All @@ -70,11 +71,19 @@ Please reach out to your Symitri account representative(<Prebid@symitri.com>) to
| apiVersion | String | This holds the API version | It should be "x1" always |
| apiAuthToken | String | Symitri API AuthToken | Please reach out to your Symitri account representative(<Prebid@symitri.com>) for this value |
| domain | String | The domain name of your webpage | |
| identityType | String | Something like this 'hid', ... 'dap-signature:1.0.0' | |
| identityType | String | 'simpleid' or 'compositeid' or 'hashedid' or 'dap-signature:1.0.0' | Use 'simpleid' to pass email or other plain text ids and SymitriRTD Module will hash it.
Use 'hashedid' to pass in single already hashed id. Use 'compositeid' to pass in multiple identifiers as key-value pairs as shown below:
{
"identityType1": "identityValue1",
"identityType2": "identityValue2",
...
}
|
| identityValue | String | This is optional field to pass user hid. Will be used only if identityType is hid | |
| segtax | Integer | The taxonomy for Symitri | The value should be 501 |
| dapEntropyUrl | String | URL to dap entropy script | Optional if the script is directly included on the webpage. Contact your Symitri account rep for more details |
| dapEntropyTimeout | Integer | Maximum time allotted for the entropy calculation to happen | |
| pixelUrl | String | Pixel URL provided by Symitri which will be triggered when bid matching with Symitri dealid wins and creative gets rendered | |

### Testing

Expand Down
16 changes: 15 additions & 1 deletion test/spec/modules/symitriDapRtdProvider_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ describe('symitriDapRtdProvider', function() {
'apiVersion': 'x1',
'domain': 'prebid.org',
'identityType': 'dap-signature:1.0.0',
'segtax': 504
'segtax': 504,
'pixelUrl': 'https://www.test.com/pixel'
}
}

Expand All @@ -84,6 +85,7 @@ describe('symitriDapRtdProvider', function() {
const sampleCachedToken = {'expires_at': cacheExpiry, 'token': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..6buzBd2BjtgoyaNbHN8YnQ.l38avCfm3sYNy798-ETYOugz0cOx1cCkjACkAhYszxzrZ0sUJ0AiF-NdDXVTiTyp2Ih3vCWKzS0rKJ8lbS1zhyEVWVu91QwtwseM2fBbwA5ggAgBEo5wV-IXqDLPxVnxsPF0D3hP6cNCiH9Q2c-vULfsLhMhG5zvvZDPBbn4hUY5fKB8LoCBTF9rbuuWGYK1nramnb4AlS5UK82wBsHQea1Ou_Kp5wWCMNZ6TZk5qKIuRBfPIAhQblWvHECaHXkg1wyoM9VASs_yNhne7RR-qkwzbFiPFiMJibNOt9hF3_vPDJO5-06ZBjRTP1BllYGWxI-uQX6InzN18Wtun2WHqg.63sH0SNlIRcsK57v0pMujfB_nhU8Y5CuQbsHqH5MGoM'};
const cachedEncryptedMembership = {'expires_at': cacheExpiry, 'encryptedSegments': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoic29tZXNlY3JldGludmF1bHQifQ..IvnIUQDqWBVYIS0gbcE9bw.Z4NZGvtogWaWlGH4e-GdYKe_PUc15M2x3Bj85rMWsN1A17mIxQIMOfg2hsQ2tgieLu5LggWPmsFu1Wbph6P0k3kOu1dVReoIhOHzxw50rP0DLHKaEZ5mLMJ7Lcosvwh4miIfFuCHlsX7J0sFgOTAp0zGo1S_UsHLtev1JflhjoSB0AoX95ALbAnyctirPuLJM8gZ1vXTiZ01jpvucGyR1lM4cWjPOeD8jPtgwaPGgSRZXE-3X2Cqy7z4Giam5Uqu74LPWTBuKtUQTGyAXA5QJoP7xwTbsU4O1f69lu3fWNqC92GijeTH1A4Zd_C-WXxWuQlDEURjlkWQoaqTHka2OqlnwukEQIf_v0r5KQQX64CTLhEUH91jeD0-E9ClcIP7pwOLxxqiKoaBmx8Mrnm_6Agj5DtTA1rusy3AL63sI_rsUxrmLrVt0Wft4aCfRkW8QpQxu8clFdOmce0NNCGeBCyCPVw9d9izrILlXJ6rItU2cpFrcbz8uw2otamF5eOFCOY3IzHedWVNNuKHFIUVC_xYSlsYvQ8f2QIP1eiMbmukcuPzmTzjw1h1_7IKaj-jJkXrnrY-TdDgX_4-_Z3rmbpXK2yTR7dBrsg-ubqFbgbKic1b4zlQEO_LbBlgPl3DYdWEuJ8CY2NUt1GfpATQGsufS2FTY1YGw_gkPe3q04l_cgLafDoxHvHh_t_0ZgPjciW82gThB_kN4RP7Mc3krVcXl_P6N1VbV07xyx0hCyVsrrxbLslI8q9wYDiLGci7mNmByM5j7SXV9jPwwPkHtn0HfMJlw2PFbIDPjgG3h7sOyLcBIJTTvuUIgpHPIkRWLIl_4FlIucXbJ7orW2nt5BWleBVHgumzGcnl9ZNcZb3W-dsdYPSOmuj0CY28MRTP2oJ1rzLInbDDpIRffJBtR7SS4nYyy7Vi09PtBigod5YNz1Q0WDSJxr8zeH_aKFaXInw7Bfo_U0IAcLiRgcT0ogsMLeQRjRFy27mr4XNJv3NtHhbdjDAwF2aClCktXyXbQaVdsPH2W71v6m2Q9rB5GQWOktw2s5f-4N1-_EBPGq6TgjF-aJZP22MJVwp1pimT50DfOzoeEqDwi862NNwNNoHmcObH0ZfwAXlhRxsgupNBe20-MNNABj2Phlfv4DUrtQbMdfCnNiypzNCmoTb7G7c_o5_JUwoV_GVkwUtvmi_IUm05P4GeMASSUw8zDKVRAj9h31C2cabM8RjMHGhkbCWpUP2pcz9zlJ7Y76Dh3RLnctfTw7DG9U4w4UlaxNZOgLUiSrGwfyapuSiuGUpuOJkBBLiHmEqAGI5C8oJpcVRccNlHxJAYowgXyFopD5Fr-FkXmv8KMkS0h5C9F6KihmDt5sqDD0qnjM0hHJgq01l7wjVnhEmPpyD-6auFQ-xDnbh1uBOJ_0gCVbRad--FSa5p-dXenggegRxOvZXJ0iAtM6Fal5Og-RCjexIHa9WhVbXhQBJpkSTWwAajZJ64eQ.yih49XB51wE-Xob7COT9OYqBrzBmIMVCQbLFx2UdzkI'};
const cachedMembership = {'expires_at': cacheExpiry, 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..QwvU5h0NVJYaJbs5EqWCKA.XNaJHSlnsH8P-yBIr3gIEqavLONWDIFyj7QCHFwJVkwXH_EYkxrk0_26b0uMPzfJp5URnqxKZusMH9DzEJsmj8EMrKQv1y3IYYMsW5_0BdP5bcAWfG6fzOqtMOwLiYRkYiQOqn1ZVGzhovheHWEmNr2_oCY0LvAr3iN1eG_K-l-bBKvBWnwvuuGKquUfCqO8NMMq6wtkecEXM9blqFRZ7oNYmW2aIG7qcHUsrUW7HMr9Ev2Ik0sIeEUsOYrgf_X_VA64RgKSTRugS9FupMv1p54JkHokwduF9pOFmW8QLQi8itFogKGbbgvOTNnmahxQUX5FcrjjYLqHwKqC8htLdlHnO5LWU9l4A7vLXrRurvoSnh0cAJy0GsdoyEwTqR9bwVFHoPquxlJjQ4buEd7PIxpBj9Qg9oOPH3b2upbMTu5CQ9oj526eXPhP5G54nwGklm2AZ3Vggd7jCQJn45Jjiq0iIfsXAtpqS2BssCLBN8WhmUTnStK8m5sux6WUBdrpDESQjPj-EEHVS-DB5rA7icRUh6EzRxzen2rndvHvnwVhSG_l6cwPYuJ0HE0KBmYHOoqNpKwzoGiKFHrf4ReA06iWB3V2TEGJucGujhtQ9_18WwHCeJ1XtQiiO1eqa3tp5MwAbFXawVFl3FFOBgadrPyvGmkmUJ6FCLU2MSwHiYZmANMnJsokFX_6DwoAgO3U_QnvEHIVSvefc7ReeJ8fBDdmrH3LtuLrUpXsvLvEIMQdWQ_SXhjKIi7tOODR8CfrhUcdIjsp3PZs1DpuOcDB6YJKbGnKZTluLUJi3TyHgyi-DHXdTm-jSE5i_DYJGW-t2Gf23FoQhexv4q7gdrfsKfcRJNrZLp6Gd6jl4zHhUtY.nprKBsy9taQBk6dCPbA7BFF0CiGhQOEF_MazZ2bedqk', 'cohorts': ['9', '11', '13']};
const cachedMembershipWithDeals = {'expires_at': cacheExpiry, 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..QwvU5h0NVJYaJbs5EqWCKA.XNaJHSlnsH8P-yBIr3gIEqavLONWDIFyj7QCHFwJVkwXH_EYkxrk0_26b0uMPzfJp5URnqxKZusMH9DzEJsmj8EMrKQv1y3IYYMsW5_0BdP5bcAWfG6fzOqtMOwLiYRkYiQOqn1ZVGzhovheHWEmNr2_oCY0LvAr3iN1eG_K-l-bBKvBWnwvuuGKquUfCqO8NMMq6wtkecEXM9blqFRZ7oNYmW2aIG7qcHUsrUW7HMr9Ev2Ik0sIeEUsOYrgf_X_VA64RgKSTRugS9FupMv1p54JkHokwduF9pOFmW8QLQi8itFogKGbbgvOTNnmahxQUX5FcrjjYLqHwKqC8htLdlHnO5LWU9l4A7vLXrRurvoSnh0cAJy0GsdoyEwTqR9bwVFHoPquxlJjQ4buEd7PIxpBj9Qg9oOPH3b2upbMTu5CQ9oj526eXPhP5G54nwGklm2AZ3Vggd7jCQJn45Jjiq0iIfsXAtpqS2BssCLBN8WhmUTnStK8m5sux6WUBdrpDESQjPj-EEHVS-DB5rA7icRUh6EzRxzen2rndvHvnwVhSG_l6cwPYuJ0HE0KBmYHOoqNpKwzoGiKFHrf4ReA06iWB3V2TEGJucGujhtQ9_18WwHCeJ1XtQiiO1eqa3tp5MwAbFXawVFl3FFOBgadrPyvGmkmUJ6FCLU2MSwHiYZmANMnJsokFX_6DwoAgO3U_QnvEHIVSvefc7ReeJ8fBDdmrH3LtuLrUpXsvLvEIMQdWQ_SXhjKIi7tOODR8CfrhUcdIjsp3PZs1DpuOcDB6YJKbGnKZTluLUJi3TyHgyi-DHXdTm-jSE5i_DYJGW-t2Gf23FoQhexv4q7gdrfsKfcRJNrZLp6Gd6jl4zHhUtY.nprKBsy9taQBk6dCPbA7BFF0CiGhQOEF_MazZ2bedqk', 'cohorts': ['9', '11', '13'], 'deals': ['{"id":"DEMODEAL555","bidfloor":5.0,"at":1,"guar":0}', '{"id":"DEMODEAL111","bidfloor":5.0,"at":1,"guar":0}', '{"id":"DEMODEAL123","bidfloor":5.0,"at":1,"guar":0}']};
const rtdUserObj = {
name: 'www.dataprovider3.com',
ext: {
Expand Down Expand Up @@ -644,4 +646,16 @@ describe('symitriDapRtdProvider', function() {
expect(hid.identity).is.undefined;
});
});

describe('onBidResponseEvent', function () {
const bidResponse = {adId: 'ad_123', bidder: 'test_bidder', bidderCode: 'test_bidder_code', cpm: '1.5', creativeId: 'creative_123', dealId: 'DEMODEAL555', mediaType: 'banner', responseTimestamp: '1725892736147', ad: ''};
let url = emoduleConfig.params.pixelUrl + '?token=' + sampleCachedToken.token + '&ad_id=' + bidResponse.adId + '&bidder=' + bidResponse.bidder + '&bidder_code=' + bidResponse.bidderCode + '&cpm=' + bidResponse.cpm + '&creative_id=' + bidResponse.creativeId + '&deal_id=' + bidResponse.dealId + '&media_type=' + bidResponse.mediaType + '&response_timestamp=' + bidResponse.responseTimestamp;
let adPixel = `${bidResponse.ad}<script src="${url}"/>`;
it('should add pixel to "BidResponse" ad', function () {
storage.setDataInLocalStorage(DAP_MEMBERSHIP, JSON.stringify(cachedMembershipWithDeals));
storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(sampleCachedToken));
symitriDapRtdSubmodule.onBidResponseEvent(bidResponse, emoduleConfig);
expect(bidResponse.ad).to.equal(adPixel);
});
});
});

0 comments on commit 123d8aa

Please sign in to comment.