Skip to content

Commit df04e1d

Browse files
BrettBloxantoinfiveSkitelman
authored
Concert Bid Adapter : remove Access to bidderRequest.{}.userId for Prebid 10 (prebid#13194)
* collect EIDs for bid request * add ad slot positioning to payload * RPO-2012: Update local storage name-spacing for c_uid (#8) * Updates c_uid namespacing to be more specific for concert * fixes unit tests * remove console.log * RPO-2012: Add check for shared id (#9) * Adds check for sharedId * Updates cookie name * remove trailing comma * [RPO-3152] Enable Support for GPP Consent (#12) * Adds gpp consent integration to concert bid adapter * Update tests to check for gpp consent string param * removes user sync endpoint and tests * updates comment * cleans up consentAllowsPpid function * comment fix * rename variables for clarity * fixes conditional logic for consent allows function (#13) * [RPO-3262] Update getUid function to check for pubcid and sharedid (#14) * Update getUid function to check for pubcid and sharedid * updates adapter version * [RPO-3405] Add browserLanguage to request meta object * ConcertBidAdapter: Add TDID (#20) * Add tdid to meta object * Fix null handling and add tests * Concert Bid Adapter: Add dealId Property to Bid Responses (#22) * adds dealid property to bid responses * updates tests * use first bid for tests * adds dealid at the correct level * [RPO-4220] Removes Access to Deprecated userId Object (#23) * extracts eids * cleanup * updates tests and fixes typo * fix type defs * use single quotes * remove whitespace * bumps adapter version * removes formatting change --------- Co-authored-by: antoin <[email protected]> Co-authored-by: Antoin <[email protected]> Co-authored-by: Sam Ghitelman <[email protected]> Co-authored-by: Sam Ghitelman <[email protected]>
1 parent 36d7454 commit df04e1d

File tree

2 files changed

+81
-72
lines changed

2 files changed

+81
-72
lines changed

modules/concertBidAdapter.js

Lines changed: 47 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import { getViewportCoordinates } from '../libraries/viewport/viewport.js';
99
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
1010
* @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid
1111
* @typedef {import('../src/adapters/bidderFactory.js').ServerResponse} ServerResponse
12-
* @typedef {import('../src/adapters/bidderFactory.js').validBidRequests} validBidRequests
13-
* @typedef {import('../src/adapters/bidderFactory.js').BidderRequest} BidderRequest
12+
* @typedef {import('../src/adapters/bidderFactory.js').ServerRequest} ServerRequest
1413
*/
1514

1615
const BIDDER_CODE = 'concert';
@@ -22,7 +21,6 @@ export const spec = {
2221
* Determines whether or not the given bid request is valid.
2322
*
2423
* @param {BidRequest} bid The bid params to validate.
25-
* @return boolean True if this is a valid bid, and false otherwise.
2624
*/
2725
isBidRequestValid: function(bid) {
2826
if (!bid.params.partnerId) {
@@ -36,9 +34,9 @@ export const spec = {
3634
/**
3735
* Make a server request from the list of BidRequests.
3836
*
39-
* @param {validBidRequests[]} validBidRequests an array of bids
40-
* @param {BidderRequest} bidderRequest
41-
* @return ServerRequest Info describing the request to the server.
37+
* @param {BidRequest[]} validBidRequests - an array of bids
38+
* @param {Object} bidderRequest - the bidder request object
39+
* @return {ServerRequest} Info describing the request to the server.
4240
*/
4341
buildRequests: function(validBidRequests, bidderRequest) {
4442
logMessage(validBidRequests);
@@ -55,25 +53,25 @@ export const spec = {
5553
debug: debugTurnedOn(),
5654
uid: getUid(bidderRequest, validBidRequests),
5755
optedOut: hasOptedOutOfPersonalization(),
58-
adapterVersion: '1.2.0',
56+
adapterVersion: '1.3.0',
5957
uspConsent: bidderRequest.uspConsent,
6058
gdprConsent: bidderRequest.gdprConsent,
6159
gppConsent: bidderRequest.gppConsent,
6260
tdid: getTdid(bidderRequest, validBidRequests),
63-
}
61+
},
6462
};
6563

6664
if (!payload.meta.gppConsent && bidderRequest.ortb2?.regs?.gpp) {
6765
payload.meta.gppConsent = {
6866
gppString: bidderRequest.ortb2.regs.gpp,
69-
applicableSections: bidderRequest.ortb2.regs.gpp_sid
70-
}
67+
applicableSections: bidderRequest.ortb2.regs.gpp_sid,
68+
};
7169
}
7270

73-
payload.slots = validBidRequests.map(bidRequest => {
74-
collectEid(eids, bidRequest);
75-
const adUnitElement = document.getElementById(bidRequest.adUnitCode)
76-
const coordinates = getOffset(adUnitElement)
71+
payload.slots = validBidRequests.map((bidRequest) => {
72+
eids.push(...(bidRequest.userIdAsEids || []));
73+
const adUnitElement = document.getElementById(bidRequest.adUnitCode);
74+
const coordinates = getOffset(adUnitElement);
7775

7876
let slot = {
7977
name: bidRequest.adUnitCode,
@@ -86,8 +84,8 @@ export const spec = {
8684
placementId: bidRequest.params.placementId || '',
8785
site: bidRequest.params.site || bidderRequest.refererInfo.page,
8886
ref: bidderRequest.refererInfo.ref,
89-
offsetCoordinates: { x: coordinates?.left, y: coordinates?.top }
90-
}
87+
offsetCoordinates: { x: coordinates?.left, y: coordinates?.top },
88+
};
9189

9290
return slot;
9391
});
@@ -99,7 +97,7 @@ export const spec = {
9997
return {
10098
method: 'POST',
10199
url: `${CONCERT_ENDPOINT}/bids/prebid`,
102-
data: JSON.stringify(payload)
100+
data: JSON.stringify(payload),
103101
};
104102
},
105103
/**
@@ -120,7 +118,7 @@ export const spec = {
120118

121119
let bidResponses = [];
122120

123-
bidResponses = serverBody.bids.map(bid => {
121+
bidResponses = serverBody.bids.map((bid) => {
124122
return {
125123
requestId: bid.bidId,
126124
cpm: bid.cpm,
@@ -146,7 +144,6 @@ export const spec = {
146144

147145
/**
148146
* Register bidder specific code, which will execute if bidder timed out after an auction
149-
* @param {Object} data Containing timeout specific data
150147
*/
151148
onTimeout: function(data) {
152149
logMessage('concert bidder timed out');
@@ -160,13 +157,12 @@ export const spec = {
160157
onBidWon: function(bid) {
161158
logMessage('concert bidder won bid');
162159
logMessage(bid);
163-
}
164-
165-
}
160+
},
161+
};
166162

167163
registerBidder(spec);
168164

169-
export const storage = getStorageManager({bidderCode: BIDDER_CODE});
165+
export const storage = getStorageManager({ bidderCode: BIDDER_CODE });
170166

171167
/**
172168
* Check or generate a UID for the current user.
@@ -176,31 +172,17 @@ function getUid(bidderRequest, validBidRequests) {
176172
return false;
177173
}
178174

179-
/**
180-
* check for shareId or pubCommonId before generating a new one
181-
* sharedId: @see https://docs.prebid.org/dev-docs/modules/userId.html
182-
* pubCid (no longer supported): @see https://docs.prebid.org/dev-docs/modules/pubCommonId.html#adapter-integration
183-
*/
184-
const sharedId =
185-
deepAccess(validBidRequests[0], 'userId.sharedid.id') ||
186-
deepAccess(validBidRequests[0], 'userId.pubcid')
187-
const pubCid = deepAccess(validBidRequests[0], 'crumbs.pubcid');
175+
const { sharedId, pubcId } = getUserIdsFromEids(validBidRequests[0]);
188176

189177
if (sharedId) return sharedId;
190-
if (pubCid) return pubCid;
178+
if (pubcId) return pubcId;
179+
if (deepAccess(validBidRequests[0], 'crumbs.pubcid')) {
180+
return deepAccess(validBidRequests[0], 'crumbs.pubcid');
181+
}
191182

192-
const LEGACY_CONCERT_UID_KEY = 'c_uid';
193183
const CONCERT_UID_KEY = 'vmconcert_uid';
194-
195-
const legacyUid = storage.getDataFromLocalStorage(LEGACY_CONCERT_UID_KEY);
196184
let uid = storage.getDataFromLocalStorage(CONCERT_UID_KEY);
197185

198-
if (legacyUid) {
199-
uid = legacyUid;
200-
storage.setDataInLocalStorage(CONCERT_UID_KEY, uid);
201-
storage.removeDataFromLocalStorage(LEGACY_CONCERT_UID_KEY);
202-
}
203-
204186
if (!uid) {
205187
uid = generateUUID();
206188
storage.setDataInLocalStorage(CONCERT_UID_KEY, uid);
@@ -209,6 +191,26 @@ function getUid(bidderRequest, validBidRequests) {
209191
return uid;
210192
}
211193

194+
function getUserIdsFromEids(bid) {
195+
const sourceMapping = {
196+
'sharedid.org': 'sharedId',
197+
'pubcid.org': 'pubcId',
198+
'adserver.org': 'tdid',
199+
};
200+
201+
const defaultUserIds = { sharedId: null, pubcId: null, tdid: null };
202+
203+
if (!bid?.userIdAsEids) return defaultUserIds;
204+
205+
return bid.userIdAsEids.reduce((userIds, eid) => {
206+
const key = sourceMapping[eid.source];
207+
if (key && eid.uids?.[0]?.id) {
208+
userIds[key] = eid.uids[0].id;
209+
}
210+
return userIds;
211+
}, defaultUserIds);
212+
}
213+
212214
/**
213215
* Whether the user has opted out of personalization.
214216
*/
@@ -221,7 +223,7 @@ function hasOptedOutOfPersonalization() {
221223
/**
222224
* Whether the privacy consent strings allow personalization.
223225
*
224-
* @param {BidderRequest} bidderRequest Object which contains any data consent signals
226+
* @param {Object} bidderRequest Object which contains any data consent signals
225227
*/
226228
function consentAllowsPpid(bidderRequest) {
227229
let uspConsentAllows = true;
@@ -241,29 +243,7 @@ function consentAllowsPpid(bidderRequest) {
241243
*/
242244
const gdprConsentAllows = hasPurpose1Consent(bidderRequest?.gdprConsent);
243245

244-
return (uspConsentAllows && gdprConsentAllows);
245-
}
246-
247-
function collectEid(eids, bid) {
248-
if (bid.userId) {
249-
const eid = getUserId(bid.userId.uid2 && bid.userId.uid2.id, 'uidapi.com', undefined, 3)
250-
eids.push(eid)
251-
}
252-
}
253-
254-
function getUserId(id, source, uidExt, atype) {
255-
if (id) {
256-
const uid = { id, atype };
257-
258-
if (uidExt) {
259-
uid.ext = uidExt;
260-
}
261-
262-
return {
263-
source,
264-
uids: [ uid ]
265-
};
266-
}
246+
return uspConsentAllows && gdprConsentAllows;
267247
}
268248

269249
function getOffset(el) {
@@ -282,5 +262,5 @@ function getTdid(bidderRequest, validBidRequests) {
282262
return null;
283263
}
284264

285-
return deepAccess(validBidRequests[0], 'userId.tdid') || null;
265+
return getUserIdsFromEids(validBidRequests[0]).tdid;
286266
}

test/spec/modules/concertBidAdapter_spec.js

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,18 @@ describe('ConcertAdapter', function () {
166166

167167
it('should use sharedid if it exists', function() {
168168
storage.removeDataFromLocalStorage('c_nap');
169-
const bidRequestsWithSharedId = [{ ...bidRequests[0], userId: { sharedid: { id: '123abc' } } }]
169+
const bidRequestsWithSharedId = [{
170+
...bidRequests[0],
171+
userIdAsEids: [{
172+
source: 'sharedid.org',
173+
uids: [{ id: '123abc' }]
174+
}]
175+
}];
170176
const request = spec.buildRequests(bidRequestsWithSharedId, bidRequest);
171177
const payload = JSON.parse(request.data);
172178

173179
expect(payload.meta.uid).to.equal('123abc');
174-
})
180+
});
175181

176182
it('should grab uid from local storage if it exists and sharedid does not', function() {
177183
storage.setDataInLocalStorage('vmconcert_uid', 'foo');
@@ -183,7 +189,10 @@ describe('ConcertAdapter', function () {
183189
});
184190

185191
it('should add uid2 to eids list if available', function() {
186-
bidRequests[0].userId = { uid2: { id: 'uid123' } }
192+
bidRequests[0].userIdAsEids = [{
193+
source: 'uidapi.com',
194+
uids: [{ id: 'uid123', atype: 3 }]
195+
}];
187196

188197
const request = spec.buildRequests(bidRequests, bidRequest);
189198
const payload = JSON.parse(request.data);
@@ -195,7 +204,6 @@ describe('ConcertAdapter', function () {
195204
})
196205

197206
it('should return empty eids list if none are available', function() {
198-
bidRequests[0].userId = { testId: { id: 'uid123' } }
199207
const request = spec.buildRequests(bidRequests, bidRequest);
200208
const payload = JSON.parse(request.data);
201209
const meta = payload.meta
@@ -232,11 +240,32 @@ describe('ConcertAdapter', function () {
232240
it('should pass along tdid if the user has not opted out', function() {
233241
storage.removeDataFromLocalStorage('c_nap', 'true');
234242
const tdid = '123abc';
235-
const bidRequestsWithTdid = [{ ...bidRequests[0], userId: { tdid } }]
243+
const bidRequestsWithTdid = [{
244+
...bidRequests[0],
245+
userIdAsEids: [{
246+
source: 'adserver.org',
247+
uids: [{ id: tdid }]
248+
}]
249+
}];
236250
const request = spec.buildRequests(bidRequestsWithTdid, bidRequest);
237251
const payload = JSON.parse(request.data);
238252
expect(payload.meta.tdid).to.equal(tdid);
239253
});
254+
255+
it('should use pubcId if it exists and sharedId does not', function() {
256+
storage.removeDataFromLocalStorage('c_nap');
257+
const bidRequestsWithPubcId = [{
258+
...bidRequests[0],
259+
userIdAsEids: [{
260+
source: 'pubcid.org',
261+
uids: [{ id: 'pubcid123' }]
262+
}]
263+
}];
264+
const request = spec.buildRequests(bidRequestsWithPubcId, bidRequest);
265+
const payload = JSON.parse(request.data);
266+
267+
expect(payload.meta.uid).to.equal('pubcid123');
268+
});
240269
});
241270

242271
describe('spec.interpretResponse', function() {

0 commit comments

Comments
 (0)