prebid.js 5.18.0 → 6.1.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/.babelrc.js +1 -10
- package/README.md +3 -1
- package/browsers.json +1 -8
- package/gulpfile.js +1 -0
- package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
- package/modules/.submodules.json +1 -0
- package/modules/adfBidAdapter.js +21 -16
- package/modules/adheseBidAdapter.js +7 -2
- package/modules/adkernelBidAdapter.js +1 -0
- package/modules/adlivetechBidAdapter.md +61 -0
- package/modules/adomikAnalyticsAdapter.js +10 -4
- package/modules/adtelligentBidAdapter.js +2 -1
- package/modules/airgridRtdProvider.js +1 -1
- package/modules/akamaiDapRtdProvider.js +474 -0
- package/modules/akamaiDapRtdProvider.md +47 -0
- package/modules/appnexusBidAdapter.js +9 -3
- package/modules/atsAnalyticsAdapter.js +67 -46
- package/modules/atsAnalyticsAdapter.md +1 -0
- package/modules/betweenBidAdapter.js +20 -3
- package/modules/browsiRtdProvider.js +106 -18
- package/modules/cleanioRtdProvider.js +192 -0
- package/modules/cleanioRtdProvider.md +59 -0
- package/modules/codefuelBidAdapter.js +181 -0
- package/modules/codefuelBidAdapter.md +111 -0
- package/modules/connectIdSystem.js +104 -0
- package/modules/connectIdSystem.md +33 -0
- package/modules/datablocksBidAdapter.js +3 -3
- package/modules/deepintentBidAdapter.js +107 -10
- package/modules/deepintentBidAdapter.md +36 -1
- package/modules/deltaprojectsBidAdapter.js +252 -0
- package/modules/deltaprojectsBidAdapter.md +32 -0
- package/modules/engageyaBidAdapter.js +171 -0
- package/modules/glimpseBidAdapter.js +31 -16
- package/modules/gptPreAuction.js +11 -5
- package/modules/gridBidAdapter.js +1 -0
- package/modules/gumgumBidAdapter.js +8 -0
- package/modules/id5IdSystem.md +6 -6
- package/modules/imRtdProvider.js +31 -0
- package/modules/inskinBidAdapter.js +7 -3
- package/modules/ixBidAdapter.js +174 -22
- package/modules/jixieBidAdapter.js +8 -2
- package/modules/justpremiumBidAdapter.js +6 -1
- package/modules/limelightDigitalBidAdapter.js +22 -2
- package/modules/livewrappedAnalyticsAdapter.js +49 -1
- package/modules/merkleIdSystem.js +5 -0
- package/modules/multibid/index.js +3 -3
- package/modules/nativoBidAdapter.js +32 -2
- package/modules/nextMillenniumBidAdapter.js +12 -3
- package/modules/oguryBidAdapter.js +16 -2
- package/modules/openxBidAdapter.js +40 -23
- package/modules/operaadsBidAdapter.js +21 -1
- package/modules/otmBidAdapter.js +146 -0
- package/modules/otmBidAdapter.md +27 -26
- package/modules/outbrainBidAdapter.js +5 -0
- package/modules/playwireBidAdapter.md +61 -0
- package/modules/prebidServerBidAdapter/index.js +3 -3
- package/modules/publinkIdSystem.js +11 -6
- package/modules/pubmaticBidAdapter.js +2 -0
- package/modules/rtdModule/index.js +2 -2
- package/modules/saambaaBidAdapter.js +420 -0
- package/modules/saambaaBidAdapter.md +65 -68
- package/modules/seedtagBidAdapter.js +6 -0
- package/modules/smaatoBidAdapter.js +6 -1
- package/modules/sonobiBidAdapter.js +7 -0
- package/modules/sortableBidAdapter.js +1 -0
- package/modules/sspBCBidAdapter.js +34 -3
- package/modules/teadsBidAdapter.js +3 -0
- package/modules/tripleliftBidAdapter.js +22 -5
- package/modules/trustxBidAdapter.js +18 -7
- package/modules/undertoneBidAdapter.js +9 -5
- package/modules/undertoneBidAdapter.md +5 -1
- package/modules/userId/eids.js +18 -0
- package/modules/userId/eids.md +7 -0
- package/modules/userId/userId.md +12 -0
- package/modules/ventesBidAdapter.js +370 -0
- package/modules/ventesBidAdapter.md +94 -0
- package/modules/videobyteBidAdapter.js +13 -6
- package/modules/videobyteBidAdapter.md +49 -0
- package/modules/vidoomyBidAdapter.js +51 -100
- package/modules/visxBidAdapter.js +1 -1
- package/modules/yahoosspBidAdapter.js +6 -6
- package/modules/yieldlabBidAdapter.js +41 -10
- package/modules/yieldlabBidAdapter.md +91 -48
- package/modules/yieldmoSyntheticInventoryModule.js +46 -0
- package/modules/yieldmoSyntheticInventoryModule.md +68 -0
- package/package.json +6 -1
- package/src/adapterManager.js +19 -8
- package/src/adapters/bidderFactory.js +4 -3
- package/src/auction.js +11 -11
- package/src/constants.json +1 -0
- package/src/secureCreatives.js +6 -7
- package/src/targeting.js +11 -9
- package/test/spec/modules/adfBidAdapter_spec.js +83 -29
- package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
- package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +16 -1
- package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
- package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
- package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
- package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
- package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
- package/test/spec/modules/connectIdSystem_spec.js +189 -0
- package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
- package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
- package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
- package/test/spec/modules/engageyaBidAdapter_spec.js +422 -0
- package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
- package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
- package/test/spec/modules/gptPreAuction_spec.js +58 -4
- package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
- package/test/spec/modules/imRtdProvider_spec.js +25 -0
- package/test/spec/modules/ixBidAdapter_spec.js +298 -5
- package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
- package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
- package/test/spec/modules/konduitWrapper_spec.js +0 -1
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
- package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +52 -7
- package/test/spec/modules/merkleIdSystem_spec.js +18 -0
- package/test/spec/modules/multibid_spec.js +31 -31
- package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +66 -23
- package/test/spec/modules/openxBidAdapter_spec.js +90 -13
- package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
- package/test/spec/modules/otmBidAdapter_spec.js +67 -0
- package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
- package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
- package/test/spec/modules/publinkIdSystem_spec.js +6 -6
- package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
- package/test/spec/modules/smaatoBidAdapter_spec.js +30 -0
- package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
- package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
- package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
- package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
- package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
- package/test/spec/modules/trustxBidAdapter_spec.js +45 -3
- package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
- package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
- package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
- package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
- package/test/spec/modules/visxBidAdapter_spec.js +1 -1
- package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
- package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
- package/test/spec/unit/core/adapterManager_spec.js +56 -6
- package/test/spec/unit/core/bidderFactory_spec.js +61 -1
- package/test/spec/unit/pbjs_api_spec.js +37 -2
- package/test/spec/unit/secureCreatives_spec.js +54 -25
- package/wdio.conf.js +1 -1
|
@@ -9,7 +9,17 @@ const ENDPOINT = `https://d.vidoomy.com/api/rtbserver/prebid/`;
|
|
|
9
9
|
const BIDDER_CODE = 'vidoomy';
|
|
10
10
|
const GVLID = 380;
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const COOKIE_SYNC_FALLBACK_URLS = [
|
|
13
|
+
'https://x.bidswitch.net/sync?ssp=vidoomy',
|
|
14
|
+
'https://ib.adnxs.com/getuid?https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dadnxs%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID',
|
|
15
|
+
'https://pixel-sync.sitescout.com/dmp/pixelSync?nid=120&redir=https%3A%2F%2Fa.vidoomy.com%2Fapi%2Frtbserver%2Fcookie%3Fi%3DCEN%26uid%3D%7BuserId%7D',
|
|
16
|
+
'https://sync.1rx.io/usersync2/vidoomy?redir=https%3A%2F%2Fa.vidoomy.com%2Fapi%2Frtbserver%2Fcookie%3Fi%3DUN%26uid%3D%5BRX_UUID%5D',
|
|
17
|
+
'https://rtb.openx.net/sync/prebid?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&r=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dopenx%26uid%3D$%7BUID%7D',
|
|
18
|
+
'https://ads.pubmatic.com/AdServer/js/user_sync.html?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&us_privacy=&predirect=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D',
|
|
19
|
+
'https://cm.adform.net/cookie?redirect_url=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dadf%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID',
|
|
20
|
+
'https://ups.analytics.yahoo.com/ups/58531/occ?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}',
|
|
21
|
+
'https://ap.lijit.com/pixel?redir=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dsovrn%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID'
|
|
22
|
+
];
|
|
13
23
|
|
|
14
24
|
const isBidRequestValid = bid => {
|
|
15
25
|
if (!bid.params) {
|
|
@@ -36,7 +46,7 @@ const isBidRequestValid = bid => {
|
|
|
36
46
|
};
|
|
37
47
|
|
|
38
48
|
const isBidResponseValid = bid => {
|
|
39
|
-
if (!bid.requestId || !bid.cpm || !bid.ttl || !bid.currency) {
|
|
49
|
+
if (!bid || !bid.requestId || !bid.cpm || !bid.ttl || !bid.currency) {
|
|
40
50
|
return false;
|
|
41
51
|
}
|
|
42
52
|
switch (bid.mediaType) {
|
|
@@ -67,35 +77,33 @@ const buildRequests = (validBidRequests, bidderRequest) => {
|
|
|
67
77
|
|
|
68
78
|
const videoContext = deepAccess(bid, 'mediaTypes.video.context');
|
|
69
79
|
|
|
70
|
-
const queryParams =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const queryParams = {
|
|
81
|
+
id: bid.params.id,
|
|
82
|
+
adtype: adType,
|
|
83
|
+
w,
|
|
84
|
+
h,
|
|
85
|
+
pos: parseInt(bid.params.position) || 1,
|
|
86
|
+
ua: navigator.userAgent,
|
|
87
|
+
l: navigator.language && navigator.language.indexOf('-') !== -1 ? navigator.language.split('-')[0] : '',
|
|
88
|
+
dt: /Mobi/.test(navigator.userAgent) ? 2 : 1,
|
|
89
|
+
pid: bid.params.pid,
|
|
90
|
+
requestId: bid.bidId,
|
|
91
|
+
d: getDomainWithoutSubdomain(hostname),
|
|
92
|
+
sp: encodeURIComponent(aElement.href),
|
|
93
|
+
usp: bidderRequest.uspConsent || '',
|
|
94
|
+
coppa: !!config.getConfig('coppa'),
|
|
95
|
+
videoContext: videoContext || ''
|
|
96
|
+
};
|
|
97
|
+
|
|
83
98
|
if (bidderRequest.gdprConsent) {
|
|
84
|
-
queryParams.
|
|
85
|
-
queryParams.
|
|
99
|
+
queryParams.gdpr = bidderRequest.gdprConsent.gdprApplies;
|
|
100
|
+
queryParams.gdprcs = bidderRequest.gdprConsent.consentString;
|
|
86
101
|
}
|
|
87
|
-
queryParams.push(['usp', bidderRequest.uspConsent || '']);
|
|
88
|
-
queryParams.push(['coppa', !!config.getConfig('coppa')]);
|
|
89
|
-
|
|
90
|
-
const rawQueryParams = queryParams.map(qp => qp.join('=')).join('&');
|
|
91
102
|
|
|
92
|
-
cookieSync(bidderRequest)
|
|
93
|
-
|
|
94
|
-
const url = `${ENDPOINT}?${rawQueryParams}`;
|
|
95
103
|
return {
|
|
96
104
|
method: 'GET',
|
|
97
|
-
url:
|
|
98
|
-
data:
|
|
105
|
+
url: ENDPOINT,
|
|
106
|
+
data: queryParams
|
|
99
107
|
}
|
|
100
108
|
});
|
|
101
109
|
return serverRequests;
|
|
@@ -117,6 +125,7 @@ const render = (bid) => {
|
|
|
117
125
|
const interpretResponse = (serverResponse, bidRequest) => {
|
|
118
126
|
try {
|
|
119
127
|
let responseBody = serverResponse.body;
|
|
128
|
+
if (!responseBody) return;
|
|
120
129
|
if (responseBody.mediaType === 'video') {
|
|
121
130
|
responseBody.ad = responseBody.vastUrl;
|
|
122
131
|
const videoContext = bidRequest.data.videoContext;
|
|
@@ -185,6 +194,21 @@ const interpretResponse = (serverResponse, bidRequest) => {
|
|
|
185
194
|
}
|
|
186
195
|
};
|
|
187
196
|
|
|
197
|
+
function getUserSyncs (syncOptions, responses, gdprConsent, uspConsent) {
|
|
198
|
+
if (syncOptions.iframeEnabled || syncOptions.pixelEnabled) {
|
|
199
|
+
const pixelType = syncOptions.pixelEnabled ? 'image' : 'iframe';
|
|
200
|
+
const urls = deepAccess(responses, '0.body.pixels') || COOKIE_SYNC_FALLBACK_URLS;
|
|
201
|
+
|
|
202
|
+
return [].concat(urls).map(url => ({
|
|
203
|
+
type: pixelType,
|
|
204
|
+
url: url
|
|
205
|
+
.replace('{{GDPR}}', gdprConsent ? gdprConsent.gdprApplies : '0')
|
|
206
|
+
.replace('{{GDPR_CONSENT}}', gdprConsent ? encodeURIComponent(gdprConsent.consentString) : '')
|
|
207
|
+
.replace('{{USP_CONSENT}}', uspConsent ? encodeURIComponent(uspConsent) : '')
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
188
212
|
export const spec = {
|
|
189
213
|
code: BIDDER_CODE,
|
|
190
214
|
supportedMediaTypes: [BANNER, VIDEO],
|
|
@@ -192,84 +216,11 @@ export const spec = {
|
|
|
192
216
|
buildRequests,
|
|
193
217
|
interpretResponse,
|
|
194
218
|
gvlid: GVLID,
|
|
219
|
+
getUserSyncs,
|
|
195
220
|
};
|
|
196
221
|
|
|
197
222
|
registerBidder(spec);
|
|
198
223
|
|
|
199
|
-
let cookieSynced = false;
|
|
200
|
-
function cookieSync(bidderRequest) {
|
|
201
|
-
if (cookieSynced) return;
|
|
202
|
-
const xhr = new XMLHttpRequest();
|
|
203
|
-
xhr.open('GET', COOKIE_SYNC_JSON)
|
|
204
|
-
xhr.addEventListener('load', function () {
|
|
205
|
-
const macro = Macro({
|
|
206
|
-
gpdr: bidderRequest.gdprConsent ? bidderRequest.gdprConsent.gdprApplies : '0',
|
|
207
|
-
gpdr_consent: bidderRequest.gdprConsent ? bidderRequest.gdprConsent.consentString : '',
|
|
208
|
-
});
|
|
209
|
-
JSON.parse(this.responseText).filter(Boolean).forEach(url => {
|
|
210
|
-
firePixel(macro.replace(url))
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
xhr.send()
|
|
214
|
-
cookieSynced = true;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function firePixel(url) {
|
|
218
|
-
const img = document.createElement('img');
|
|
219
|
-
img.width = 1;
|
|
220
|
-
img.height = 1;
|
|
221
|
-
img.src = url;
|
|
222
|
-
document.body.appendChild(img);
|
|
223
|
-
setTimeout(() => {
|
|
224
|
-
img.remove();
|
|
225
|
-
}, 10000)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function normalizeKey (x) {
|
|
229
|
-
return x.replace(/_/g, '').toLowerCase();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function Macro (obj) {
|
|
233
|
-
const macros = {};
|
|
234
|
-
for (const key in obj) {
|
|
235
|
-
macros[normalizeKey(key)] = obj[key];
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const set = (key, value) => {
|
|
239
|
-
macros[normalizeKey(key)] = typeof value === 'function' ? value : String(value);
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
set,
|
|
244
|
-
setAll (obj) {
|
|
245
|
-
for (const key in obj) {
|
|
246
|
-
macros[normalizeKey(key)] = set(obj[key]);
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
replace (string, extraMacros = {}) {
|
|
250
|
-
const allMacros = {
|
|
251
|
-
...macros,
|
|
252
|
-
...extraMacros,
|
|
253
|
-
};
|
|
254
|
-
const regexes = [
|
|
255
|
-
/{{\s*([a-zA-Z0-9_]+)\s*}}/g,
|
|
256
|
-
/\$\$\s*([a-zA-Z0-9_]+)\s*\$\$/g,
|
|
257
|
-
/\[\s*([a-zA-Z0-9_]+)\s*\]/g,
|
|
258
|
-
/\{\s*([a-zA-Z0-9_]+)\s*\}/g,
|
|
259
|
-
];
|
|
260
|
-
regexes.forEach(regex => {
|
|
261
|
-
string = string.replace(regex, (str, x) => {
|
|
262
|
-
x = normalizeKey(x);
|
|
263
|
-
let value = allMacros[x];
|
|
264
|
-
value = typeof value === 'function' ? value(allMacros) : value;
|
|
265
|
-
return !value && value !== 0 ? '' : value;
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
return string;
|
|
269
|
-
},
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
224
|
function getDomainWithoutSubdomain (hostname) {
|
|
274
225
|
const parts = hostname.split('.');
|
|
275
226
|
const newParts = [];
|
|
@@ -203,7 +203,7 @@ export const spec = {
|
|
|
203
203
|
},
|
|
204
204
|
onTimeout: function(timeoutData) {
|
|
205
205
|
// Call '/track/bid_timeout' with timeout data
|
|
206
|
-
triggerPixel(buildUrl(TRACK_TIMEOUT_PATH) + '
|
|
206
|
+
triggerPixel(buildUrl(TRACK_TIMEOUT_PATH) + '//' + JSON.stringify(timeoutData));
|
|
207
207
|
}
|
|
208
208
|
};
|
|
209
209
|
|
|
@@ -144,9 +144,9 @@ function getAdapterMode() {
|
|
|
144
144
|
|
|
145
145
|
function getResponseFormat(bid) {
|
|
146
146
|
const adm = bid.adm;
|
|
147
|
-
if (adm.
|
|
147
|
+
if (adm.indexOf('o2playerSettings') !== -1 || adm.indexOf('YAHOO.VideoPlatform.VideoPlayer') !== -1 || adm.indexOf('AdPlacement') !== -1) {
|
|
148
148
|
return BANNER;
|
|
149
|
-
} else if (adm.
|
|
149
|
+
} else if (adm.indexOf('VAST') !== -1) {
|
|
150
150
|
return VIDEO;
|
|
151
151
|
}
|
|
152
152
|
};
|
|
@@ -188,23 +188,23 @@ function validateAppendObject(validationType, allowedKeys, inputObject, appendTo
|
|
|
188
188
|
for (const objectKey in inputObject) {
|
|
189
189
|
switch (validationType) {
|
|
190
190
|
case 'string':
|
|
191
|
-
if (allowedKeys.
|
|
191
|
+
if (allowedKeys.indexOf(objectKey) !== -1 && isStr(inputObject[objectKey])) {
|
|
192
192
|
outputObject[objectKey] = inputObject[objectKey];
|
|
193
193
|
};
|
|
194
194
|
break;
|
|
195
195
|
case 'number':
|
|
196
|
-
if (allowedKeys.
|
|
196
|
+
if (allowedKeys.indexOf(objectKey) !== -1 && isNumber(inputObject[objectKey])) {
|
|
197
197
|
outputObject[objectKey] = inputObject[objectKey];
|
|
198
198
|
};
|
|
199
199
|
break;
|
|
200
200
|
|
|
201
201
|
case 'array':
|
|
202
|
-
if (allowedKeys.
|
|
202
|
+
if (allowedKeys.indexOf(objectKey) !== -1 && isArray(inputObject[objectKey])) {
|
|
203
203
|
outputObject[objectKey] = inputObject[objectKey];
|
|
204
204
|
};
|
|
205
205
|
break;
|
|
206
206
|
case 'object':
|
|
207
|
-
if (allowedKeys.
|
|
207
|
+
if (allowedKeys.indexOf(objectKey) !== -1 && isPlainObject(inputObject[objectKey])) {
|
|
208
208
|
outputObject[objectKey] = inputObject[objectKey];
|
|
209
209
|
};
|
|
210
210
|
break;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _each, isPlainObject, isArray, deepAccess } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js'
|
|
3
3
|
import find from 'core-js-pure/features/array/find.js'
|
|
4
|
-
import { VIDEO, BANNER } from '../src/mediaTypes.js'
|
|
4
|
+
import { VIDEO, BANNER, NATIVE } from '../src/mediaTypes.js'
|
|
5
5
|
import { Renderer } from '../src/Renderer.js'
|
|
6
6
|
import { config } from '../src/config.js';
|
|
7
7
|
|
|
@@ -15,7 +15,7 @@ const GVLID = 70
|
|
|
15
15
|
export const spec = {
|
|
16
16
|
code: BIDDER_CODE,
|
|
17
17
|
gvlid: GVLID,
|
|
18
|
-
supportedMediaTypes: [VIDEO, BANNER],
|
|
18
|
+
supportedMediaTypes: [VIDEO, BANNER, NATIVE],
|
|
19
19
|
|
|
20
20
|
isBidRequestValid: function (bid) {
|
|
21
21
|
if (bid && bid.params && bid.params.adslotId && bid.params.supplyId) {
|
|
@@ -149,6 +149,27 @@ export const spec = {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
if (isNative(bidRequest, adType)) {
|
|
153
|
+
const url = `${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}`
|
|
154
|
+
bidResponse.adUrl = url
|
|
155
|
+
bidResponse.mediaType = NATIVE
|
|
156
|
+
const nativeImageAssetObj = find(matchedBid.native.assets, e => e.id === 2)
|
|
157
|
+
const nativeImageAsset = nativeImageAssetObj ? nativeImageAssetObj.img : {url: '', w: 0, h: 0};
|
|
158
|
+
const nativeTitleAsset = find(matchedBid.native.assets, e => e.id === 1)
|
|
159
|
+
const nativeBodyAsset = find(matchedBid.native.assets, e => e.id === 3)
|
|
160
|
+
bidResponse.native = {
|
|
161
|
+
title: nativeTitleAsset ? nativeTitleAsset.title.text : '',
|
|
162
|
+
body: nativeBodyAsset ? nativeBodyAsset.data.value : '',
|
|
163
|
+
image: {
|
|
164
|
+
url: nativeImageAsset.url,
|
|
165
|
+
width: nativeImageAsset.w,
|
|
166
|
+
height: nativeImageAsset.h,
|
|
167
|
+
},
|
|
168
|
+
clickUrl: matchedBid.native.link.url,
|
|
169
|
+
impressionTrackers: matchedBid.native.imptrackers,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
152
173
|
bidResponses.push(bidResponse)
|
|
153
174
|
}
|
|
154
175
|
})
|
|
@@ -162,16 +183,26 @@ export const spec = {
|
|
|
162
183
|
* @param {String} adtype
|
|
163
184
|
* @returns {Boolean}
|
|
164
185
|
*/
|
|
165
|
-
function isVideo
|
|
186
|
+
function isVideo(format, adtype) {
|
|
166
187
|
return deepAccess(format, 'mediaTypes.video') && adtype.toLowerCase() === 'video'
|
|
167
188
|
}
|
|
168
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Is this a native format?
|
|
192
|
+
* @param {Object} format
|
|
193
|
+
* @param {String} adtype
|
|
194
|
+
* @returns {Boolean}
|
|
195
|
+
*/
|
|
196
|
+
function isNative(format, adtype) {
|
|
197
|
+
return deepAccess(format, 'mediaTypes.native') && adtype.toLowerCase() === 'native'
|
|
198
|
+
}
|
|
199
|
+
|
|
169
200
|
/**
|
|
170
201
|
* Is this an outstream context?
|
|
171
202
|
* @param {Object} format
|
|
172
203
|
* @returns {Boolean}
|
|
173
204
|
*/
|
|
174
|
-
function isOutstream
|
|
205
|
+
function isOutstream(format) {
|
|
175
206
|
let context = deepAccess(format, 'mediaTypes.video.context')
|
|
176
207
|
return (context === 'outstream')
|
|
177
208
|
}
|
|
@@ -181,7 +212,7 @@ function isOutstream (format) {
|
|
|
181
212
|
* @param {Object} format
|
|
182
213
|
* @returns {Array}
|
|
183
214
|
*/
|
|
184
|
-
function getPlayerSize
|
|
215
|
+
function getPlayerSize(format) {
|
|
185
216
|
let playerSize = deepAccess(format, 'mediaTypes.video.playerSize')
|
|
186
217
|
return (playerSize && isArray(playerSize[0])) ? playerSize[0] : playerSize
|
|
187
218
|
}
|
|
@@ -191,7 +222,7 @@ function getPlayerSize (format) {
|
|
|
191
222
|
* @param {String} size
|
|
192
223
|
* @returns {Array}
|
|
193
224
|
*/
|
|
194
|
-
function parseSize
|
|
225
|
+
function parseSize(size) {
|
|
195
226
|
return size.split('x').map(Number)
|
|
196
227
|
}
|
|
197
228
|
|
|
@@ -200,7 +231,7 @@ function parseSize (size) {
|
|
|
200
231
|
* @param {Array} eids
|
|
201
232
|
* @returns {String}
|
|
202
233
|
*/
|
|
203
|
-
function createUserIdString
|
|
234
|
+
function createUserIdString(eids) {
|
|
204
235
|
let str = []
|
|
205
236
|
for (let i = 0; i < eids.length; i++) {
|
|
206
237
|
str.push(eids[i].source + ':' + eids[i].uids[0].id)
|
|
@@ -213,7 +244,7 @@ function createUserIdString (eids) {
|
|
|
213
244
|
* @param {Object} obj
|
|
214
245
|
* @returns {String}
|
|
215
246
|
*/
|
|
216
|
-
function createQueryString
|
|
247
|
+
function createQueryString(obj) {
|
|
217
248
|
let str = []
|
|
218
249
|
for (var p in obj) {
|
|
219
250
|
if (obj.hasOwnProperty(p)) {
|
|
@@ -233,7 +264,7 @@ function createQueryString (obj) {
|
|
|
233
264
|
* @param {Object} obj
|
|
234
265
|
* @returns {String}
|
|
235
266
|
*/
|
|
236
|
-
function createTargetingString
|
|
267
|
+
function createTargetingString(obj) {
|
|
237
268
|
let str = []
|
|
238
269
|
for (var p in obj) {
|
|
239
270
|
if (obj.hasOwnProperty(p)) {
|
|
@@ -250,7 +281,7 @@ function createTargetingString (obj) {
|
|
|
250
281
|
* @param {Object} schain
|
|
251
282
|
* @returns {String}
|
|
252
283
|
*/
|
|
253
|
-
function createSchainString
|
|
284
|
+
function createSchainString(schain) {
|
|
254
285
|
const ver = schain.ver || ''
|
|
255
286
|
const complete = (schain.complete === 1 || schain.complete === 0) ? schain.complete : ''
|
|
256
287
|
const keys = ['asi', 'sid', 'hp', 'rid', 'name', 'domain', 'ext']
|
|
@@ -11,53 +11,96 @@ Maintainer: solutions@yieldlab.de
|
|
|
11
11
|
Module that connects to Yieldlab's demand sources
|
|
12
12
|
|
|
13
13
|
# Test Parameters
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
const adUnits = [
|
|
17
|
+
{
|
|
18
|
+
code: 'banner',
|
|
19
|
+
sizes: [ [ 728, 90 ] ],
|
|
20
|
+
bids: [{
|
|
21
|
+
bidder: 'yieldlab',
|
|
22
|
+
params: {
|
|
23
|
+
adslotId: '5220336',
|
|
24
|
+
supplyId: '1381604',
|
|
25
|
+
targeting: {
|
|
26
|
+
key1: 'value1',
|
|
27
|
+
key2: 'value2'
|
|
28
|
+
},
|
|
29
|
+
extId: 'abc',
|
|
30
|
+
iabContent: {
|
|
31
|
+
id: 'some_id',
|
|
32
|
+
episode: '1',
|
|
33
|
+
title: 'some title',
|
|
34
|
+
series: 'some series',
|
|
35
|
+
season: 's1',
|
|
36
|
+
artist: 'John Doe',
|
|
37
|
+
genre: 'some genre',
|
|
38
|
+
isrc: 'CC-XXX-YY-NNNNN',
|
|
39
|
+
url: 'http://foo_url.de',
|
|
40
|
+
cat: [ 'IAB1-1', 'IAB1-2', 'IAB2-10' ],
|
|
41
|
+
context: '7',
|
|
42
|
+
keywords: ['k1', 'k2'],
|
|
43
|
+
live: '0'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
code: 'video',
|
|
50
|
+
sizes: [ [ 640, 480 ] ],
|
|
51
|
+
mediaTypes: {
|
|
52
|
+
video: {
|
|
53
|
+
context: 'instream' // or 'outstream'
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
bids: [{
|
|
57
|
+
bidder: 'yieldlab',
|
|
58
|
+
params: {
|
|
59
|
+
adslotId: '5220339',
|
|
60
|
+
supplyId: '1381604'
|
|
61
|
+
}
|
|
62
|
+
}]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
code: 'native',
|
|
66
|
+
mediaTypes: {
|
|
67
|
+
native: {
|
|
68
|
+
// native config
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
bids: [{
|
|
72
|
+
bidder: 'yieldlab',
|
|
73
|
+
params: {
|
|
74
|
+
adslotId: '5220339',
|
|
75
|
+
supplyId: '1381604'
|
|
76
|
+
}
|
|
77
|
+
}]
|
|
78
|
+
}
|
|
79
|
+
];
|
|
14
80
|
```
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
context: "7",
|
|
41
|
-
keywords: ["k1", "k2"],
|
|
42
|
-
live: "0"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}]
|
|
46
|
-
}, {
|
|
47
|
-
code: "video",
|
|
48
|
-
sizes: [[640, 480]],
|
|
49
|
-
mediaTypes: {
|
|
50
|
-
video: {
|
|
51
|
-
context: "instream" // or "outstream"
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
bids: [{
|
|
55
|
-
bidder: "yieldlab",
|
|
56
|
-
params: {
|
|
57
|
-
adslotId: "5220339",
|
|
58
|
-
supplyId: "1381604"
|
|
59
|
-
}
|
|
60
|
-
}]
|
|
61
|
-
}
|
|
62
|
-
];
|
|
81
|
+
|
|
82
|
+
# Multi-Format Setup
|
|
83
|
+
|
|
84
|
+
A general overview of how to set up multi-format ads can be found in the offical Prebid.js docs. See: [show multi-format ads](https://docs.prebid.org/dev-docs/show-multi-format-ads.html)
|
|
85
|
+
|
|
86
|
+
When setting up multi-format ads with Yieldlab make sure to always add at least one eligible Adslot per given media type in the ad unit configuration.
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const adUnit = {
|
|
90
|
+
code: 'multi-format-adslot',
|
|
91
|
+
mediaTypes: {
|
|
92
|
+
banner: {
|
|
93
|
+
sizes: [ [ 728, 90 ] ]
|
|
94
|
+
},
|
|
95
|
+
native: {
|
|
96
|
+
// native config
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
bids: [
|
|
100
|
+
// banner Adslot
|
|
101
|
+
{ bidder: 'yieldlab', params: { adslotId: '1234', supplyId: '42' } },
|
|
102
|
+
// native Adslot
|
|
103
|
+
{ bidder: 'yieldlab', params: { adslotId: '2345', supplyId: '42' } }
|
|
104
|
+
]
|
|
105
|
+
};
|
|
63
106
|
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { config } from '../src/config.js';
|
|
2
|
+
import { isGptPubadsDefined } from '../src/utils.js';
|
|
3
|
+
|
|
4
|
+
export const MODULE_NAME = 'Yieldmo Synthetic Inventory Module';
|
|
5
|
+
|
|
6
|
+
export function init(config) {
|
|
7
|
+
validateConfig(config);
|
|
8
|
+
|
|
9
|
+
if (!isGptPubadsDefined()) {
|
|
10
|
+
window.googletag = window.googletag || {};
|
|
11
|
+
window.googletag.cmd = window.googletag.cmd || [];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const googletag = window.googletag;
|
|
15
|
+
const containerName = 'ym_sim_container_' + config.placementId;
|
|
16
|
+
|
|
17
|
+
googletag.cmd.push(() => {
|
|
18
|
+
if (window.document.body) {
|
|
19
|
+
googletagCmd(config, containerName, googletag);
|
|
20
|
+
} else {
|
|
21
|
+
window.document.addEventListener('DOMContentLoaded', () => googletagCmd(config, containerName, googletag));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function validateConfig(config) {
|
|
27
|
+
if (!('placementId' in config)) {
|
|
28
|
+
throw new Error(`${MODULE_NAME}: placementId required`);
|
|
29
|
+
}
|
|
30
|
+
if (!('adUnitPath' in config)) {
|
|
31
|
+
throw new Error(`${MODULE_NAME}: adUnitPath required`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function googletagCmd(config, containerName, googletag) {
|
|
36
|
+
const gamContainer = window.document.createElement('div');
|
|
37
|
+
gamContainer.id = containerName;
|
|
38
|
+
window.document.body.appendChild(gamContainer);
|
|
39
|
+
googletag.defineSlot(config.adUnitPath, [1, 1], containerName)
|
|
40
|
+
.addService(googletag.pubads())
|
|
41
|
+
.setTargeting('ym_sim_p_id', config.placementId);
|
|
42
|
+
googletag.enableServices();
|
|
43
|
+
googletag.display(containerName);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
config.getConfig('yieldmo_synthetic_inventory', config => init(config.yieldmo_synthetic_inventory));
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Yieldmo Synthetic Inventory Module
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This module enables publishers to set up Yieldmo Synthetic Outstream ads on their pages.
|
|
6
|
+
|
|
7
|
+
If publishers will enable this module and provide placementId and Google Ad Manager ad unit path, this module will create a placement on the page and inject Yieldmo SDK into this placement. Publisher will then need to get a placement id from their Yieldmo account manager (accounts email) and setup corresponding ad units on the GAM ad server.
|
|
8
|
+
|
|
9
|
+
## Integration
|
|
10
|
+
|
|
11
|
+
Build the Yieldmo Synthetic Inventory Module into the Prebid.js package with:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
gulp build --modules=yieldmoSyntheticInventoryModule,...
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Module Configuration
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
pbjs.que.push(function() {
|
|
21
|
+
pbjs.setConfig({
|
|
22
|
+
yieldmo_synthetic_inventory: {
|
|
23
|
+
placementId: '1234567890',
|
|
24
|
+
adUnitPath: '/1234567/ad_unit_name_used_in_gam'
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Configuration Parameters
|
|
31
|
+
|
|
32
|
+
|Name |Scope |Description | Example| Type
|
|
33
|
+
| :------------ | :------------ | :------------ | :------------ | :------------ |
|
|
34
|
+
|placementId | required | Yieldmo placement ID | '1234567890' | string
|
|
35
|
+
|adUnitPath | required | Google Ad Manager ad unit path | '/6355419/ad_unit_name_used_in_gam' | string
|
|
36
|
+
|
|
37
|
+
### How to get ad unit path
|
|
38
|
+
|
|
39
|
+
Ad unit path follows the format /network-code/[parent-ad-unit-code/.../]ad-unit-code, where:
|
|
40
|
+
|
|
41
|
+
- network-code is a unique identifier for the Ad Manager network the ad unit belongs to
|
|
42
|
+
- parent-ad-unit-code are the codes of all parent ad units (only applies to non-top level ad units)
|
|
43
|
+
- ad-unit-code is the code for the ad unit to be displayed
|
|
44
|
+
|
|
45
|
+
Note that all ad unit codes included in the ad unit path must adhere to the [formatting rules](https://support.google.com/admanager/answer/1628457#ad-unit-codes) specified by Ad Manager.
|
|
46
|
+
|
|
47
|
+
Another and probably the easiest way to get an ad unit path is to get it from the google ad manager ad unit document header generated tag:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
googletag.defineSlot('/1234567/ad_unit_name_used_in_gam', [1, 1], 'ad-container-id').addService(googletag.pubads());
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### How to get Yieldmo placement id
|
|
54
|
+
|
|
55
|
+
Please reach out to your Yieldmo account's person or email to support@yieldmo.com
|
|
56
|
+
|
|
57
|
+
### Google Ad Manager setup
|
|
58
|
+
|
|
59
|
+
Yieldmo Synthetic Inventory Module is designed to be used along with Google Ad Manager. GAM should be set as usual, but there are a few requirements:
|
|
60
|
+
|
|
61
|
+
- Ad unit size should be 1x1
|
|
62
|
+
- Creative should NOT be served into a SafeFrame and also should have 1x1 size
|
|
63
|
+
- Synthetic Inventory Universal Tag should be used as 3rd party creative code
|
|
64
|
+
### Synthetic Inventory Universal Tag
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
<div id="ym_%%PATTERN:ym_sim_p_id%%" class="ym"></div><script type="text/javascript">(function(e,t){if(t._ym===void 0){t._ym="";var m=e.createElement("script");m.type="text/javascript",m.async=!0,m.src="//static.yieldmo.com/ym."+Math.round(5*Math.random()/3)+".js",(e.getElementsByTagName("head")[0]||e.getElementsByTagName("body")[0]).appendChild(m)}else t._ym instanceof String||void 0===t._ym.chkPls||t._ym.chkPls()})(document,window);</script>
|
|
68
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prebid.js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Header Bidding Management Library",
|
|
5
5
|
"main": "src/prebid.js",
|
|
6
6
|
"scripts": {
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "https://github.com/prebid/Prebid.js.git"
|
|
13
13
|
},
|
|
14
|
+
"browserslist": [
|
|
15
|
+
"> 0.25%",
|
|
16
|
+
"not IE 11",
|
|
17
|
+
"not op_mini all"
|
|
18
|
+
],
|
|
14
19
|
"keywords": [
|
|
15
20
|
"advertising",
|
|
16
21
|
"auction",
|