prebid.js 6.7.0 → 6.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +8 -1
- package/integrationExamples/gpt/{haloRtdProvider_example.html → hadronRtdProvider_example.html} +9 -9
- package/integrationExamples/gpt/idImportLibrary_example.html +2 -2
- package/integrationExamples/gpt/userId_example.html +2 -2
- package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
- package/integrationExamples/gpt/x-domain/creative.html +63 -29
- package/modules/.submodules.json +3 -0
- package/modules/adagioBidAdapter.js +0 -8
- package/modules/adagioBidAdapter.md +1 -1
- package/modules/adkernelBidAdapter.js +2 -1
- package/modules/adnuntiusRtdProvider.js +96 -0
- package/modules/adnuntiusRtdProvider.md +41 -0
- package/modules/adotBidAdapter.js +516 -567
- package/modules/adotBidAdapter.md +6 -44
- package/modules/adpod.js +12 -14
- package/modules/adyoulikeBidAdapter.js +2 -0
- package/modules/appnexusBidAdapter.js +14 -2
- package/modules/asealBidAdapter.js +58 -0
- package/modules/asealBidAdapter.md +52 -0
- package/modules/brandmetricsRtdProvider.js +168 -0
- package/modules/brandmetricsRtdProvider.md +40 -0
- package/modules/conversantBidAdapter.js +7 -0
- package/modules/criteoBidAdapter.js +9 -0
- package/modules/currency.js +27 -5
- package/modules/displayioBidAdapter.js +157 -0
- package/modules/displayioBidAdapter.md +148 -0
- package/modules/dspxBidAdapter.js +69 -29
- package/modules/dspxBidAdapter.md +2 -1
- package/modules/e_volutionBidAdapter.js +158 -0
- package/modules/gridBidAdapter.js +15 -1
- package/modules/gumgumBidAdapter.js +52 -38
- package/modules/hadronIdSystem.js +96 -0
- package/modules/hadronIdSystem.md +35 -0
- package/modules/hadronRtdProvider.js +254 -0
- package/modules/hadronRtdProvider.md +126 -0
- package/modules/haloIdSystem.md +4 -35
- package/modules/haloRtdProvider.md +3 -126
- package/modules/imRtdProvider.js +10 -0
- package/modules/improvedigitalBidAdapter.js +5 -0
- package/modules/interactiveOffersBidAdapter.js +9 -6
- package/modules/iqzoneBidAdapter.js +10 -3
- package/modules/iqzoneBidAdapter.md +16 -0
- package/modules/ixBidAdapter.js +2 -6
- package/modules/kubientBidAdapter.js +50 -19
- package/modules/lunamediahbBidAdapter.js +32 -4
- package/modules/malltvBidAdapter.js +7 -3
- package/modules/malltvBidAdapter.md +64 -51
- package/modules/mass.js +3 -5
- package/modules/mediakeysBidAdapter.js +0 -5
- package/modules/medianetAnalyticsAdapter.js +1 -1
- package/modules/mediasquareBidAdapter.js +9 -1
- package/modules/nextMillenniumBidAdapter.js +1 -0
- package/modules/oguryBidAdapter.js +7 -14
- package/modules/prebidServerBidAdapter/index.js +61 -39
- package/modules/priceFloors.js +20 -12
- package/modules/pubmaticBidAdapter.js +1 -1
- package/modules/richaudienceBidAdapter.js +8 -3
- package/modules/riseBidAdapter.js +17 -6
- package/modules/rtbhouseBidAdapter.js +2 -0
- package/modules/rubiconAnalyticsAdapter.js +5 -0
- package/modules/rubiconBidAdapter.js +2 -2
- package/modules/sizeMappingV2.js +1 -8
- package/modules/sortableAnalyticsAdapter.js +5 -4
- package/modules/sovrnBidAdapter.js +93 -18
- package/modules/sovrnBidAdapter.md +80 -2
- package/modules/sspBCBidAdapter.js +53 -20
- package/modules/telariaBidAdapter.js +22 -29
- package/modules/trustpidSystem.js +197 -0
- package/modules/trustpidSystem.md +45 -0
- package/modules/undertoneBidAdapter.js +17 -1
- package/modules/userId/eids.js +16 -1
- package/modules/userId/eids.md +10 -2
- package/modules/userId/userId.md +17 -2
- package/modules/vibrantmediaBidAdapter.js +220 -0
- package/modules/vibrantmediaBidAdapter.md +92 -0
- package/modules/vidoomyBidAdapter.js +8 -0
- package/modules/vidoomyBidAdapter.md +4 -2
- package/modules/weboramaRtdProvider.js +264 -34
- package/modules/weboramaRtdProvider.md +110 -40
- package/modules/yahoosspBidAdapter.js +3 -1
- package/modules/yieldoneBidAdapter.js +6 -0
- package/package.json +2 -1
- package/src/adRendering.js +38 -0
- package/src/adapterManager.js +24 -19
- package/src/adapters/bidderFactory.js +14 -11
- package/src/adloader.js +2 -1
- package/src/auction.js +138 -115
- package/src/auctionIndex.js +85 -0
- package/src/auctionManager.js +3 -0
- package/src/bidderSettings.js +69 -0
- package/src/bidfactory.js +18 -6
- package/src/native.js +29 -21
- package/src/prebid.js +3 -19
- package/src/secureCreatives.js +128 -45
- package/src/targeting.js +11 -2
- package/src/utils.js +14 -17
- package/src/video.js +10 -11
- package/src/videoCache.js +10 -9
- package/test/fixtures/fixtures.js +2 -1
- package/test/helpers/indexStub.js +28 -0
- package/test/helpers/syncPromise.js +71 -0
- package/test/spec/auctionmanager_spec.js +268 -89
- package/test/spec/config_spec.js +24 -1
- package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
- package/test/spec/modules/adnuntiusRtdProvider_spec.js +145 -0
- package/test/spec/modules/adotBidAdapter_spec.js +294 -3124
- package/test/spec/modules/adpod_spec.js +91 -156
- package/test/spec/modules/adyoulikeBidAdapter_spec.js +4 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
- package/test/spec/modules/asealBidAdapter_spec.js +144 -0
- package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
- package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
- package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
- package/test/spec/modules/currency_spec.js +36 -15
- package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
- package/test/spec/modules/dspxBidAdapter_spec.js +20 -15
- package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
- package/test/spec/modules/eids_spec.js +2 -2
- package/test/spec/modules/gridBidAdapter_spec.js +18 -0
- package/test/spec/modules/gumgumBidAdapter_spec.js +49 -3
- package/test/spec/modules/hadronIdSystem_spec.js +57 -0
- package/test/spec/modules/hadronRtdProvider_spec.js +762 -0
- package/test/spec/modules/imRtdProvider_spec.js +30 -1
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +19 -0
- package/test/spec/modules/iqzoneBidAdapter_spec.js +1 -0
- package/test/spec/modules/ixBidAdapter_spec.js +1 -1
- package/test/spec/modules/kubientBidAdapter_spec.js +182 -84
- package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
- package/test/spec/modules/mass_spec.js +2 -14
- package/test/spec/modules/mediakeysBidAdapter_spec.js +9 -5
- package/test/spec/modules/mediasquareBidAdapter_spec.js +25 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +63 -5
- package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -6
- package/test/spec/modules/priceFloors_spec.js +83 -24
- package/test/spec/modules/pubmaticBidAdapter_spec.js +40 -0
- package/test/spec/modules/riseBidAdapter_spec.js +30 -4
- package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +31 -1
- package/test/spec/modules/rubiconBidAdapter_spec.js +1 -1
- package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
- package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
- package/test/spec/modules/sspBCBidAdapter_spec.js +7 -7
- package/test/spec/modules/telariaBidAdapter_spec.js +1 -3
- package/test/spec/modules/trustpidSystem_spec.js +232 -0
- package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
- package/test/spec/modules/userId_spec.js +39 -39
- package/test/spec/modules/vibrantmediaBidAdapter_spec.js +1237 -0
- package/test/spec/modules/vidoomyBidAdapter_spec.js +7 -1
- package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
- package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
- package/test/spec/modules/yieldoneBidAdapter_spec.js +33 -0
- package/test/spec/native_spec.js +62 -40
- package/test/spec/unit/core/adapterManager_spec.js +22 -0
- package/test/spec/unit/core/auctionIndex_spec.js +129 -0
- package/test/spec/unit/core/bidderFactory_spec.js +65 -12
- package/test/spec/unit/core/bidderSettings_spec.js +123 -0
- package/test/spec/unit/core/targeting_spec.js +93 -0
- package/test/spec/unit/pbjs_api_spec.js +80 -42
- package/test/spec/unit/secureCreatives_spec.js +143 -24
- package/test/spec/videoCache_spec.js +18 -19
- package/test/spec/video_spec.js +51 -61
|
@@ -6,7 +6,7 @@ Adot Bidder Adapter is a module that enables the communication between the Prebi
|
|
|
6
6
|
|
|
7
7
|
- Module name: Adot Bidder Adapter
|
|
8
8
|
- Module type: Bidder Adapter
|
|
9
|
-
- Maintainer: `
|
|
9
|
+
- Maintainer: `alexandre.lorin@adotmob.com`
|
|
10
10
|
- Supported media types: `banner`, `video`, `native`
|
|
11
11
|
|
|
12
12
|
## Example ad units
|
|
@@ -34,9 +34,9 @@ const adUnit = {
|
|
|
34
34
|
|
|
35
35
|
### Video ad unit
|
|
36
36
|
|
|
37
|
-
####
|
|
37
|
+
#### Video ad unit
|
|
38
38
|
|
|
39
|
-
Adot Bidder Adapter accepts
|
|
39
|
+
Adot Bidder Adapter accepts video ad units using the following ad unit format:
|
|
40
40
|
|
|
41
41
|
```javascript
|
|
42
42
|
const adUnit = {
|
|
@@ -51,9 +51,9 @@ const adUnit = {
|
|
|
51
51
|
// Content MIME types supported by the ad unit.
|
|
52
52
|
mimes: ['video/mp4'],
|
|
53
53
|
// Minimum accepted video ad duration (in seconds).
|
|
54
|
-
|
|
54
|
+
minduration: 5,
|
|
55
55
|
// Maximum accepted video ad duration (in seconds).
|
|
56
|
-
|
|
56
|
+
maxduration: 35,
|
|
57
57
|
// Video protocols supported by the ad unit (see the OpenRTB 2.5 specifications,
|
|
58
58
|
// section 5.8).
|
|
59
59
|
protocols: [2, 3]
|
|
@@ -61,45 +61,7 @@ const adUnit = {
|
|
|
61
61
|
},
|
|
62
62
|
bids: [{
|
|
63
63
|
bidder: 'adot',
|
|
64
|
-
params: {
|
|
65
|
-
video: {}
|
|
66
|
-
}
|
|
67
|
-
}]
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
#### Instream video ad unit
|
|
72
|
-
|
|
73
|
-
Adot Bidder Adapter accepts instream video ad units using the following ad unit format:
|
|
74
|
-
|
|
75
|
-
```javascript
|
|
76
|
-
const adUnit = {
|
|
77
|
-
code: 'test-div',
|
|
78
|
-
mediaTypes: {
|
|
79
|
-
video: {
|
|
80
|
-
// Video context. Must be 'instream'.
|
|
81
|
-
context: 'instream',
|
|
82
|
-
// Video dimensions supported by the video ad unit.
|
|
83
|
-
// Each ad unit size is formatted as follows: [width, height].
|
|
84
|
-
playerSize: [[300, 250]],
|
|
85
|
-
// Content MIME types supported by the ad unit.
|
|
86
|
-
mimes: ['video/mp4'],
|
|
87
|
-
// Minimum accepted video ad duration (in seconds).
|
|
88
|
-
minDuration: 5,
|
|
89
|
-
// Maximum accepted video ad duration (in seconds).
|
|
90
|
-
maxDuration: 35,
|
|
91
|
-
// Video protocols supported by the ad unit (see the OpenRTB 2.5 specifications,
|
|
92
|
-
// section 5.8).
|
|
93
|
-
protocols: [2, 3]
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
bids: [{
|
|
97
|
-
bidder: 'adot',
|
|
98
|
-
params: {
|
|
99
|
-
video: {
|
|
100
|
-
instreamContext: 'pre-roll'
|
|
101
|
-
}
|
|
102
|
-
}
|
|
64
|
+
params: {}
|
|
103
65
|
}]
|
|
104
66
|
}
|
|
105
67
|
```
|
package/modules/adpod.js
CHANGED
|
@@ -122,7 +122,7 @@ function getPricePartForAdpodKey(bid) {
|
|
|
122
122
|
const adpodDealPrefix = config.getConfig(`adpod.dealTier.${bid.bidderCode}.prefix`);
|
|
123
123
|
pricePart = (adpodDealPrefix) ? adpodDealPrefix + deepAccess(bid, 'video.dealTier') : deepAccess(bid, 'video.dealTier');
|
|
124
124
|
} else {
|
|
125
|
-
const granularity = getPriceGranularity(bid
|
|
125
|
+
const granularity = getPriceGranularity(bid);
|
|
126
126
|
pricePart = getPriceByGranularity(granularity)(bid);
|
|
127
127
|
}
|
|
128
128
|
return pricePart
|
|
@@ -223,10 +223,9 @@ function firePrebidCacheCall(auctionInstance, bidList, afterBidAdded) {
|
|
|
223
223
|
* @param {*} auctionInstance running context of the auction
|
|
224
224
|
* @param {Object} bidResponse incoming bid; if adpod, will be processed through hook function. If not adpod, returns to original function.
|
|
225
225
|
* @param {Function} afterBidAdded callback function used when Prebid Cache responds
|
|
226
|
-
* @param {Object}
|
|
226
|
+
* @param {Object} videoConfig mediaTypes.video from the bid's adUnit
|
|
227
227
|
*/
|
|
228
|
-
export function callPrebidCacheHook(fn, auctionInstance, bidResponse, afterBidAdded,
|
|
229
|
-
let videoConfig = deepAccess(bidderRequest, 'mediaTypes.video');
|
|
228
|
+
export function callPrebidCacheHook(fn, auctionInstance, bidResponse, afterBidAdded, videoConfig) {
|
|
230
229
|
if (videoConfig && videoConfig.context === ADPOD) {
|
|
231
230
|
let brandCategoryExclusion = config.getConfig('adpod.brandCategoryExclusion');
|
|
232
231
|
let adServerCatId = deepAccess(bidResponse, 'meta.adServerCatId');
|
|
@@ -250,7 +249,7 @@ export function callPrebidCacheHook(fn, auctionInstance, bidResponse, afterBidAd
|
|
|
250
249
|
}
|
|
251
250
|
}
|
|
252
251
|
} else {
|
|
253
|
-
fn.call(this, auctionInstance, bidResponse, afterBidAdded,
|
|
252
|
+
fn.call(this, auctionInstance, bidResponse, afterBidAdded, videoConfig);
|
|
254
253
|
}
|
|
255
254
|
}
|
|
256
255
|
|
|
@@ -310,18 +309,17 @@ export function checkAdUnitSetupHook(fn, adUnits) {
|
|
|
310
309
|
* (eg if range was [5, 15, 30] -> 2s is rounded to 5s; 17s is rounded back to 15s; 18s is rounded up to 30s)
|
|
311
310
|
* - if the bid is above the range of the listed durations (and outside the buffer), reject the bid
|
|
312
311
|
* - set the rounded duration value in the `bid.video.durationBucket` field for accepted bids
|
|
313
|
-
* @param {Object}
|
|
312
|
+
* @param {Object} videoMediaType 'mediaTypes.video' associated to bidResponse
|
|
314
313
|
* @param {Object} bidResponse incoming bidResponse being evaluated by bidderFactory
|
|
315
314
|
* @returns {boolean} return false if bid duration is deemed invalid as per adUnit configuration; return true if fine
|
|
316
315
|
*/
|
|
317
|
-
function checkBidDuration(
|
|
316
|
+
function checkBidDuration(videoMediaType, bidResponse) {
|
|
318
317
|
const buffer = 2;
|
|
319
318
|
let bidDuration = deepAccess(bidResponse, 'video.durationSeconds');
|
|
320
|
-
let
|
|
321
|
-
let adUnitRanges = videoConfig.durationRangeSec;
|
|
319
|
+
let adUnitRanges = videoMediaType.durationRangeSec;
|
|
322
320
|
adUnitRanges.sort((a, b) => a - b); // ensure the ranges are sorted in numeric order
|
|
323
321
|
|
|
324
|
-
if (!
|
|
322
|
+
if (!videoMediaType.requireExactDuration) {
|
|
325
323
|
let max = Math.max(...adUnitRanges);
|
|
326
324
|
if (bidDuration <= (max + buffer)) {
|
|
327
325
|
let nextHighestRange = find(adUnitRanges, range => (range + buffer) >= bidDuration);
|
|
@@ -346,12 +344,12 @@ function checkBidDuration(bidderRequest, bidResponse) {
|
|
|
346
344
|
* If it's found to not be an adpod bid, it will return to original function via hook logic
|
|
347
345
|
* @param {Function} fn reference to original function (used by hook logic)
|
|
348
346
|
* @param {Object} bid incoming bid object
|
|
349
|
-
* @param {Object}
|
|
347
|
+
* @param {Object} adUnit adUnit object of associated bid
|
|
350
348
|
* @param {Object} videoMediaType copy of the `bidRequest.mediaTypes.video` object; used in original function
|
|
351
349
|
* @param {String} context value of the `bidRequest.mediaTypes.video.context` field; used in original function
|
|
352
350
|
* @returns {boolean} this return is only used for adpod bids
|
|
353
351
|
*/
|
|
354
|
-
export function checkVideoBidSetupHook(fn, bid,
|
|
352
|
+
export function checkVideoBidSetupHook(fn, bid, adUnit, videoMediaType, context) {
|
|
355
353
|
if (context === ADPOD) {
|
|
356
354
|
let result = true;
|
|
357
355
|
let brandCategoryExclusion = config.getConfig('adpod.brandCategoryExclusion');
|
|
@@ -367,7 +365,7 @@ export function checkVideoBidSetupHook(fn, bid, bidRequest, videoMediaType, cont
|
|
|
367
365
|
if (!deepAccess(bid, 'video.durationSeconds') || bid.video.durationSeconds <= 0) {
|
|
368
366
|
result = false;
|
|
369
367
|
} else {
|
|
370
|
-
let isBidGood = checkBidDuration(
|
|
368
|
+
let isBidGood = checkBidDuration(videoMediaType, bid);
|
|
371
369
|
if (!isBidGood) result = false;
|
|
372
370
|
}
|
|
373
371
|
}
|
|
@@ -382,7 +380,7 @@ export function checkVideoBidSetupHook(fn, bid, bidRequest, videoMediaType, cont
|
|
|
382
380
|
|
|
383
381
|
fn.bail(result);
|
|
384
382
|
} else {
|
|
385
|
-
fn.call(this, bid,
|
|
383
|
+
fn.call(this, bid, adUnit, videoMediaType, context);
|
|
386
384
|
}
|
|
387
385
|
}
|
|
388
386
|
|
|
@@ -9,6 +9,7 @@ const VERSION = '1.0';
|
|
|
9
9
|
const BIDDER_CODE = 'adyoulike';
|
|
10
10
|
const DEFAULT_DC = 'hb-api';
|
|
11
11
|
const CURRENCY = 'USD';
|
|
12
|
+
const GVLID = 259;
|
|
12
13
|
|
|
13
14
|
const NATIVE_IMAGE = {
|
|
14
15
|
image: {
|
|
@@ -36,6 +37,7 @@ const NATIVE_IMAGE = {
|
|
|
36
37
|
|
|
37
38
|
export const spec = {
|
|
38
39
|
code: BIDDER_CODE,
|
|
40
|
+
gvlid: GVLID,
|
|
39
41
|
supportedMediaTypes: [BANNER, NATIVE, VIDEO],
|
|
40
42
|
aliases: ['ayl'], // short code
|
|
41
43
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { convertCamelToUnderscore, isArray, isNumber, isPlainObject, logError, logInfo, deepAccess, logMessage, convertTypes, isStr, getParameterByName, deepClone, chunk, logWarn, getBidRequest, createTrackPixelHtml, isEmpty, transformBidderParamKeywords, getMaxValueFromArray, fill, getMinValueFromArray, isArrayOfNums, isFn
|
|
1
|
+
import { convertCamelToUnderscore, isArray, isNumber, isPlainObject, logError, logInfo, deepAccess, logMessage, convertTypes, isStr, getParameterByName, deepClone, chunk, logWarn, getBidRequest, createTrackPixelHtml, isEmpty, transformBidderParamKeywords, getMaxValueFromArray, fill, getMinValueFromArray, isArrayOfNums, isFn } from '../src/utils.js';
|
|
2
2
|
import { Renderer } from '../src/Renderer.js';
|
|
3
3
|
import { config } from '../src/config.js';
|
|
4
4
|
import { registerBidder, getIabSubCategory } from '../src/adapters/bidderFactory.js';
|
|
@@ -8,6 +8,7 @@ import find from 'core-js-pure/features/array/find.js';
|
|
|
8
8
|
import includes from 'core-js-pure/features/array/includes.js';
|
|
9
9
|
import { OUTSTREAM, INSTREAM } from '../src/video.js';
|
|
10
10
|
import { getStorageManager } from '../src/storageManager.js';
|
|
11
|
+
import { bidderSettings } from '../src/bidderSettings.js';
|
|
11
12
|
|
|
12
13
|
const BIDDER_CODE = 'appnexus';
|
|
13
14
|
const URL = 'https://ib.adnxs.com/ut/v3/prebid';
|
|
@@ -201,6 +202,17 @@ export const spec = {
|
|
|
201
202
|
payload.app = appIdObj;
|
|
202
203
|
}
|
|
203
204
|
|
|
205
|
+
let auctionKeywords = config.getConfig('appnexusAuctionKeywords');
|
|
206
|
+
if (isPlainObject(auctionKeywords)) {
|
|
207
|
+
let aucKeywords = transformBidderParamKeywords(auctionKeywords);
|
|
208
|
+
|
|
209
|
+
if (aucKeywords.length > 0) {
|
|
210
|
+
aucKeywords.forEach(deleteValues);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
payload.keywords = aucKeywords;
|
|
214
|
+
}
|
|
215
|
+
|
|
204
216
|
if (config.getConfig('adpod.brandCategoryExclusion')) {
|
|
205
217
|
payload.brand_category_uniqueness = true;
|
|
206
218
|
}
|
|
@@ -292,7 +304,7 @@ export const spec = {
|
|
|
292
304
|
serverResponse.tags.forEach(serverBid => {
|
|
293
305
|
const rtbBid = getRtbBid(serverBid);
|
|
294
306
|
if (rtbBid) {
|
|
295
|
-
const cpmCheck = (
|
|
307
|
+
const cpmCheck = (bidderSettings.get(bidderRequest.bidderCode, 'allowZeroCpmBids') === true) ? rtbBid.cpm >= 0 : rtbBid.cpm > 0;
|
|
296
308
|
if (cpmCheck && includes(this.supportedMediaTypes, rtbBid.ad_type)) {
|
|
297
309
|
const bid = newBid(serverBid, rtbBid, bidderRequest);
|
|
298
310
|
bid.mediaType = parseMediaType(rtbBid);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import { BANNER } from '../src/mediaTypes.js';
|
|
3
|
+
import { config } from '../src/config.js';
|
|
4
|
+
|
|
5
|
+
export const BIDDER_CODE = 'aseal';
|
|
6
|
+
const SUPPORTED_AD_TYPES = [BANNER];
|
|
7
|
+
export const API_ENDPOINT = 'https://tkprebid.aotter.net/prebid/adapter';
|
|
8
|
+
export const HEADER_AOTTER_VERSION = 'prebid_0.0.1';
|
|
9
|
+
|
|
10
|
+
export const spec = {
|
|
11
|
+
code: BIDDER_CODE,
|
|
12
|
+
aliases: ['aotter', 'trek'],
|
|
13
|
+
supportedMediaTypes: SUPPORTED_AD_TYPES,
|
|
14
|
+
|
|
15
|
+
isBidRequestValid: (bid) => !!bid.params.placeUid && typeof bid.params.placeUid === 'string',
|
|
16
|
+
|
|
17
|
+
buildRequests: (validBidRequests, bidderRequest) => {
|
|
18
|
+
if (validBidRequests.length === 0) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const clientId =
|
|
23
|
+
config.getConfig('aseal.clientId') || '';
|
|
24
|
+
|
|
25
|
+
const data = {
|
|
26
|
+
bids: validBidRequests,
|
|
27
|
+
refererInfo: bidderRequest.refererInfo,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const options = {
|
|
31
|
+
contentType: 'application/json',
|
|
32
|
+
withCredentials: true,
|
|
33
|
+
customHeaders: {
|
|
34
|
+
'x-aotter-clientid': clientId,
|
|
35
|
+
'x-aotter-version': HEADER_AOTTER_VERSION,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return [{
|
|
40
|
+
method: 'POST',
|
|
41
|
+
url: API_ENDPOINT,
|
|
42
|
+
data,
|
|
43
|
+
options,
|
|
44
|
+
}];
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
interpretResponse: (serverResponse, bidRequest) => {
|
|
48
|
+
if (!Array.isArray(serverResponse.body)) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const bidResponses = serverResponse.body;
|
|
53
|
+
|
|
54
|
+
return bidResponses;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
registerBidder(spec);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Aseal Bid Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
Maintainer: tech-service@aotter.net
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Module that connects to Aseal server for bids.
|
|
12
|
+
Supported Ad Formats:
|
|
13
|
+
|
|
14
|
+
- Banner
|
|
15
|
+
|
|
16
|
+
# Configuration
|
|
17
|
+
|
|
18
|
+
Following configuration is required:
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
pbjs.setConfig({
|
|
22
|
+
aseal: {
|
|
23
|
+
clientId: "YOUR_CLIENT_ID"
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
# Ad Unit Example
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
var adUnits = [
|
|
32
|
+
{
|
|
33
|
+
code: "banner-div",
|
|
34
|
+
mediaTypes: {
|
|
35
|
+
banner: {
|
|
36
|
+
sizes: [
|
|
37
|
+
[300, 250],
|
|
38
|
+
[300, 600]
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
bids: [
|
|
43
|
+
{
|
|
44
|
+
bidder: "aseal",
|
|
45
|
+
params: {
|
|
46
|
+
placeUid: "f4a74f73-9a74-4a87-91c9-545c6316c23d"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
```
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module adds brandmetrics provider to the real time data module
|
|
3
|
+
* The {@link module:modules/realTimeData} module is required
|
|
4
|
+
* The module will load load the brandmetrics script and set survey- targeting to ad units of specific bidders.
|
|
5
|
+
* @module modules/brandmetricsRtdProvider
|
|
6
|
+
* @requires module:modules/realTimeData
|
|
7
|
+
*/
|
|
8
|
+
import { config } from '../src/config.js'
|
|
9
|
+
import { submodule } from '../src/hook.js'
|
|
10
|
+
import { deepSetValue, mergeDeep, logError, deepAccess } from '../src/utils.js'
|
|
11
|
+
import {loadExternalScript} from '../src/adloader.js'
|
|
12
|
+
const MODULE_NAME = 'brandmetrics'
|
|
13
|
+
const MODULE_CODE = MODULE_NAME
|
|
14
|
+
const RECEIVED_EVENTS = []
|
|
15
|
+
const GVL_ID = 422
|
|
16
|
+
const TCF_PURPOSES = [1, 7]
|
|
17
|
+
|
|
18
|
+
function init (config, userConsent) {
|
|
19
|
+
const hasConsent = checkConsent(userConsent)
|
|
20
|
+
|
|
21
|
+
if (hasConsent) {
|
|
22
|
+
const moduleConfig = getMergedConfig(config)
|
|
23
|
+
initializeBrandmetrics(moduleConfig.params.scriptId)
|
|
24
|
+
}
|
|
25
|
+
return hasConsent
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Checks TCF and USP consents
|
|
30
|
+
* @param {Object} userConsent
|
|
31
|
+
* @returns {boolean}
|
|
32
|
+
*/
|
|
33
|
+
function checkConsent (userConsent) {
|
|
34
|
+
let consent = false
|
|
35
|
+
|
|
36
|
+
if (userConsent && userConsent.gdpr && userConsent.gdpr.gdprApplies) {
|
|
37
|
+
const gdpr = userConsent.gdpr
|
|
38
|
+
|
|
39
|
+
if (gdpr.vendorData) {
|
|
40
|
+
const vendor = gdpr.vendorData.vendor
|
|
41
|
+
const purpose = gdpr.vendorData.purpose
|
|
42
|
+
|
|
43
|
+
let vendorConsent = false
|
|
44
|
+
if (vendor.consents) {
|
|
45
|
+
vendorConsent = vendor.consents[GVL_ID]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (vendor.legitimateInterests) {
|
|
49
|
+
vendorConsent = vendorConsent || vendor.legitimateInterests[GVL_ID]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const purposes = TCF_PURPOSES.map(id => {
|
|
53
|
+
return (purpose.consents && purpose.consents[id]) || (purpose.legitimateInterests && purpose.legitimateInterests[id])
|
|
54
|
+
})
|
|
55
|
+
const purposesValid = purposes.filter(p => p === true).length === TCF_PURPOSES.length
|
|
56
|
+
consent = vendorConsent && purposesValid
|
|
57
|
+
}
|
|
58
|
+
} else if (userConsent.usp) {
|
|
59
|
+
const usp = userConsent.usp
|
|
60
|
+
consent = usp[1] !== 'N' && usp[2] !== 'Y'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return consent
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Add event- listeners to hook in to brandmetrics events
|
|
68
|
+
* @param {Object} reqBidsConfigObj
|
|
69
|
+
* @param {function} callback
|
|
70
|
+
*/
|
|
71
|
+
function processBrandmetricsEvents (reqBidsConfigObj, moduleConfig, callback) {
|
|
72
|
+
const callBidTargeting = (event) => {
|
|
73
|
+
if (event.available && event.conf) {
|
|
74
|
+
const targetingConf = event.conf.displayOption || {}
|
|
75
|
+
if (targetingConf.type === 'pbjs') {
|
|
76
|
+
setBidderTargeting(reqBidsConfigObj, moduleConfig, targetingConf.targetKey || 'brandmetrics_survey', event.survey.measurementId)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
callback()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (RECEIVED_EVENTS.length > 0) {
|
|
83
|
+
callBidTargeting(RECEIVED_EVENTS[RECEIVED_EVENTS.length - 1])
|
|
84
|
+
} else {
|
|
85
|
+
window._brandmetrics = window._brandmetrics || []
|
|
86
|
+
window._brandmetrics.push({
|
|
87
|
+
cmd: '_addeventlistener',
|
|
88
|
+
val: {
|
|
89
|
+
event: 'surveyloaded',
|
|
90
|
+
reEmitLast: true,
|
|
91
|
+
handler: (ev) => {
|
|
92
|
+
RECEIVED_EVENTS.push(ev)
|
|
93
|
+
if (RECEIVED_EVENTS.length === 1) {
|
|
94
|
+
// Call bid targeting only for the first received event, if called subsequently, last event from the RECEIVED_EVENTS array is used
|
|
95
|
+
callBidTargeting(ev)
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Sets bid targeting of specific bidders
|
|
105
|
+
* @param {Object} reqBidsConfigObj
|
|
106
|
+
* @param {string} key Targeting key
|
|
107
|
+
* @param {string} val Targeting value
|
|
108
|
+
*/
|
|
109
|
+
function setBidderTargeting (reqBidsConfigObj, moduleConfig, key, val) {
|
|
110
|
+
const bidders = deepAccess(moduleConfig, 'params.bidders')
|
|
111
|
+
if (bidders && bidders.length > 0) {
|
|
112
|
+
const ortb2 = {}
|
|
113
|
+
deepSetValue(ortb2, 'ortb2.user.ext.data.' + key, val)
|
|
114
|
+
config.setBidderConfig({
|
|
115
|
+
bidders: bidders,
|
|
116
|
+
config: ortb2
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Add the brandmetrics script to the page.
|
|
123
|
+
* @param {string} scriptId - The script- id provided by brandmetrics or brandmetrics partner
|
|
124
|
+
*/
|
|
125
|
+
function initializeBrandmetrics(scriptId) {
|
|
126
|
+
if (scriptId) {
|
|
127
|
+
const path = 'https://cdn.brandmetrics.com/survey/script/'
|
|
128
|
+
const file = scriptId + '.js'
|
|
129
|
+
const url = path + file
|
|
130
|
+
|
|
131
|
+
loadExternalScript(url, MODULE_CODE)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Merges a provided config with default values
|
|
137
|
+
* @param {Object} customConfig
|
|
138
|
+
* @returns
|
|
139
|
+
*/
|
|
140
|
+
function getMergedConfig(customConfig) {
|
|
141
|
+
return mergeDeep({
|
|
142
|
+
waitForIt: false,
|
|
143
|
+
params: {
|
|
144
|
+
bidders: [],
|
|
145
|
+
scriptId: undefined,
|
|
146
|
+
}
|
|
147
|
+
}, customConfig)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** @type {RtdSubmodule} */
|
|
151
|
+
export const brandmetricsSubmodule = {
|
|
152
|
+
name: MODULE_NAME,
|
|
153
|
+
getBidRequestData: function (reqBidsConfigObj, callback, customConfig) {
|
|
154
|
+
try {
|
|
155
|
+
const moduleConfig = getMergedConfig(customConfig)
|
|
156
|
+
if (moduleConfig.waitForIt) {
|
|
157
|
+
processBrandmetricsEvents(reqBidsConfigObj, moduleConfig, callback)
|
|
158
|
+
} else {
|
|
159
|
+
callback()
|
|
160
|
+
}
|
|
161
|
+
} catch (e) {
|
|
162
|
+
logError(e)
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
init: init
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
submodule('realTimeData', brandmetricsSubmodule)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Brandmetrics Real-time Data Submodule
|
|
2
|
+
This module is intended to be used by brandmetrics (https://brandmetrics.com) partners and sets targeting keywords to bids if the browser is eligeble to see a brandmetrics survey.
|
|
3
|
+
The module hooks in to brandmetrics events and requires a brandmetrics script to be running. The module can optionally load and initialize brandmetrics by providing the 'scriptId'- parameter.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
Compile the Brandmetrics RTD module into your Prebid build:
|
|
7
|
+
```
|
|
8
|
+
gulp build --modules=rtdModule,brandmetricsRtdProvider
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> Note that the global RTD module, `rtdModule`, is a prerequisite of the Brandmetrics RTD module.
|
|
12
|
+
|
|
13
|
+
Enable the Brandmetrics RTD in your Prebid configuration, using the below format:
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
pbjs.setConfig({
|
|
17
|
+
...,
|
|
18
|
+
realTimeData: {
|
|
19
|
+
auctionDelay: 500, // auction delay
|
|
20
|
+
dataProviders: [{
|
|
21
|
+
name: 'brandmetrics',
|
|
22
|
+
waitForIt: true // should be true if there's an `auctionDelay`,
|
|
23
|
+
params: {
|
|
24
|
+
scriptId: '00000000-0000-0000-0000-000000000000',
|
|
25
|
+
bidders: ['ozone']
|
|
26
|
+
}
|
|
27
|
+
}]
|
|
28
|
+
},
|
|
29
|
+
...
|
|
30
|
+
})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Parameters
|
|
34
|
+
| Name | Type | Description | Default |
|
|
35
|
+
| ----------------- | -------------------- | ------------------ | ------------------ |
|
|
36
|
+
| name | String | This should always be `brandmetrics` | - |
|
|
37
|
+
| waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (recommended) | `false` |
|
|
38
|
+
| params | Object | | - |
|
|
39
|
+
| params.bidders | String[] | An array of bidders which should receive targeting keys. | `[]` |
|
|
40
|
+
| params.scriptId | String | A script- id GUID if the brandmetrics- script should be initialized. | `undefined` |
|
|
@@ -2,6 +2,7 @@ import { logWarn, isStr, deepAccess, isArray, getBidIdParameter, deepSetValue, i
|
|
|
2
2
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
4
4
|
import {getStorageManager} from '../src/storageManager.js';
|
|
5
|
+
import { config } from '../src/config.js';
|
|
5
6
|
|
|
6
7
|
const GVLID = 24;
|
|
7
8
|
export const storage = getStorageManager(GVLID);
|
|
@@ -76,6 +77,9 @@ export const spec = {
|
|
|
76
77
|
displaymanager: 'Prebid.js',
|
|
77
78
|
displaymanagerver: '$prebid.version$'
|
|
78
79
|
};
|
|
80
|
+
if (bid.ortb2Imp) {
|
|
81
|
+
mergeDeep(imp, bid.ortb2Imp);
|
|
82
|
+
}
|
|
79
83
|
|
|
80
84
|
copyOptProperty(bid.params.tag_id, imp, 'tagid');
|
|
81
85
|
|
|
@@ -167,6 +171,9 @@ export const spec = {
|
|
|
167
171
|
payload.user = {ext: userExt};
|
|
168
172
|
}
|
|
169
173
|
|
|
174
|
+
const firstPartyData = config.getConfig('ortb2') || {};
|
|
175
|
+
mergeDeep(payload, firstPartyData);
|
|
176
|
+
|
|
170
177
|
return {
|
|
171
178
|
method: 'POST',
|
|
172
179
|
url: bidurl,
|
|
@@ -281,6 +281,7 @@ function checkNativeSendId(bidRequest) {
|
|
|
281
281
|
*/
|
|
282
282
|
function buildCdbRequest(context, bidRequests, bidderRequest) {
|
|
283
283
|
let networkId;
|
|
284
|
+
let schain;
|
|
284
285
|
const request = {
|
|
285
286
|
publisher: {
|
|
286
287
|
url: context.url,
|
|
@@ -288,6 +289,7 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
|
|
|
288
289
|
},
|
|
289
290
|
slots: bidRequests.map(bidRequest => {
|
|
290
291
|
networkId = bidRequest.params.networkId || networkId;
|
|
292
|
+
schain = bidRequest.schain || schain;
|
|
291
293
|
const slot = {
|
|
292
294
|
impid: bidRequest.adUnitCode,
|
|
293
295
|
transactionid: bidRequest.transactionId,
|
|
@@ -344,6 +346,13 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
|
|
|
344
346
|
if (networkId) {
|
|
345
347
|
request.publisher.networkid = networkId;
|
|
346
348
|
}
|
|
349
|
+
if (schain) {
|
|
350
|
+
request.source = {
|
|
351
|
+
ext: {
|
|
352
|
+
schain: schain
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
};
|
|
347
356
|
request.user = {
|
|
348
357
|
ext: bidderRequest.userExt
|
|
349
358
|
};
|
package/modules/currency.js
CHANGED
|
@@ -20,6 +20,25 @@ export var currencyRates = {};
|
|
|
20
20
|
var bidderCurrencyDefault = {};
|
|
21
21
|
var defaultRates;
|
|
22
22
|
|
|
23
|
+
export const ready = (() => {
|
|
24
|
+
let isDone, resolver, promise;
|
|
25
|
+
function reset() {
|
|
26
|
+
isDone = false;
|
|
27
|
+
resolver = null;
|
|
28
|
+
promise = new Promise((resolve) => {
|
|
29
|
+
resolver = resolve;
|
|
30
|
+
if (isDone) resolve();
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
function done() {
|
|
34
|
+
isDone = true;
|
|
35
|
+
if (resolver != null) { resolver() }
|
|
36
|
+
}
|
|
37
|
+
reset();
|
|
38
|
+
|
|
39
|
+
return {done, reset, promise: () => promise}
|
|
40
|
+
})();
|
|
41
|
+
|
|
23
42
|
/**
|
|
24
43
|
* Configuration function for currency
|
|
25
44
|
* @param {string} [config.adServerCurrency = 'USD']
|
|
@@ -138,11 +157,15 @@ function initCurrency(url) {
|
|
|
138
157
|
logInfo('currencyRates set to ' + JSON.stringify(currencyRates));
|
|
139
158
|
currencyRatesLoaded = true;
|
|
140
159
|
processBidResponseQueue();
|
|
160
|
+
ready.done();
|
|
141
161
|
} catch (e) {
|
|
142
162
|
errorSettingsRates('Failed to parse currencyRates response: ' + response);
|
|
143
163
|
}
|
|
144
164
|
},
|
|
145
|
-
error:
|
|
165
|
+
error: function (...args) {
|
|
166
|
+
errorSettingsRates(...args);
|
|
167
|
+
ready.done();
|
|
168
|
+
}
|
|
146
169
|
}
|
|
147
170
|
);
|
|
148
171
|
}
|
|
@@ -197,6 +220,8 @@ export function addBidResponseHook(fn, adUnitCode, bid) {
|
|
|
197
220
|
bidResponseQueue.push(wrapFunction(fn, this, [adUnitCode, bid]));
|
|
198
221
|
if (!currencySupportEnabled || currencyRatesLoaded) {
|
|
199
222
|
processBidResponseQueue();
|
|
223
|
+
} else {
|
|
224
|
+
fn.bail(ready.promise());
|
|
200
225
|
}
|
|
201
226
|
}
|
|
202
227
|
|
|
@@ -219,10 +244,7 @@ function wrapFunction(fn, context, params) {
|
|
|
219
244
|
}
|
|
220
245
|
} catch (e) {
|
|
221
246
|
logWarn('Returning NO_BID, getCurrencyConversion threw error: ', e);
|
|
222
|
-
params[1] = createBid(CONSTANTS.STATUS.NO_BID,
|
|
223
|
-
bidder: bid.bidderCode || bid.bidder,
|
|
224
|
-
bidId: bid.requestId
|
|
225
|
-
});
|
|
247
|
+
params[1] = createBid(CONSTANTS.STATUS.NO_BID, bid.getIdentifiers());
|
|
226
248
|
}
|
|
227
249
|
}
|
|
228
250
|
return fn.apply(context, params);
|