Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symitri RTD module: OnBidResponse method added #12214

Merged
merged 11 commits into from
Sep 9, 2024
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: "[email protected]",
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may want to also check for deals that match a particular pattern

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(<[email protected]>) 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(<[email protected]>) 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);
});
});
});