prebid.js 5.16.0 → 5.20.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.
Files changed (182) hide show
  1. package/.devcontainer/Dockerfile +11 -0
  2. package/.devcontainer/devcontainer.json +27 -0
  3. package/.devcontainer/postCreate.sh +6 -0
  4. package/browsers.json +1 -0
  5. package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
  6. package/modules/.submodules.json +1 -0
  7. package/modules/adfBidAdapter.js +21 -16
  8. package/modules/adgenerationBidAdapter.js +28 -4
  9. package/modules/adkernelBidAdapter.js +3 -1
  10. package/modules/admixerBidAdapter.js +11 -0
  11. package/modules/adnuntiusBidAdapter.js +1 -0
  12. package/modules/adtelligentBidAdapter.js +2 -1
  13. package/modules/airgridRtdProvider.js +1 -1
  14. package/modules/akamaiDapRtdProvider.js +474 -0
  15. package/modules/akamaiDapRtdProvider.md +47 -0
  16. package/modules/aolBidAdapter.js +2 -1
  17. package/modules/appnexusBidAdapter.js +5 -3
  18. package/modules/atsAnalyticsAdapter.js +89 -63
  19. package/modules/atsAnalyticsAdapter.md +1 -0
  20. package/modules/betweenBidAdapter.js +20 -3
  21. package/modules/bliinkBidAdapter.js +58 -32
  22. package/modules/bliinkBidAdapter.md +29 -6
  23. package/modules/browsiRtdProvider.js +106 -18
  24. package/modules/cleanioRtdProvider.js +192 -0
  25. package/modules/cleanioRtdProvider.md +59 -0
  26. package/modules/codefuelBidAdapter.js +183 -0
  27. package/modules/codefuelBidAdapter.md +111 -0
  28. package/modules/connectIdSystem.js +104 -0
  29. package/modules/connectIdSystem.md +33 -0
  30. package/modules/cwireBidAdapter.js +272 -0
  31. package/modules/cwireBidAdapter.md +43 -0
  32. package/modules/deepintentBidAdapter.js +106 -9
  33. package/modules/deepintentBidAdapter.md +36 -1
  34. package/modules/deltaprojectsBidAdapter.js +252 -0
  35. package/modules/deltaprojectsBidAdapter.md +32 -0
  36. package/modules/dgkeywordRtdProvider.js +0 -1
  37. package/modules/engageyaBidAdapter.js +157 -0
  38. package/modules/glimpseBidAdapter.js +160 -48
  39. package/modules/glimpseBidAdapter.md +11 -74
  40. package/modules/gridBidAdapter.js +1 -0
  41. package/modules/gridNMBidAdapter.js +7 -6
  42. package/modules/gumgumBidAdapter.js +16 -2
  43. package/modules/iasRtdProvider.js +83 -67
  44. package/modules/inskinBidAdapter.js +7 -3
  45. package/modules/ixBidAdapter.js +8 -1
  46. package/modules/jixieBidAdapter.js +8 -2
  47. package/modules/justpremiumBidAdapter.js +6 -1
  48. package/modules/kargoBidAdapter.js +14 -7
  49. package/modules/kargoBidAdapter.md +20 -0
  50. package/modules/limelightDigitalBidAdapter.js +22 -2
  51. package/modules/livewrappedAnalyticsAdapter.js +53 -3
  52. package/modules/mediakeysBidAdapter.js +405 -14
  53. package/modules/mediakeysBidAdapter.md +108 -0
  54. package/modules/multibid/index.js +3 -3
  55. package/modules/mytargetBidAdapter.js +112 -0
  56. package/modules/nativoBidAdapter.js +48 -29
  57. package/modules/nativoBidAdapter.md +0 -1
  58. package/modules/nextMillenniumBidAdapter.js +12 -3
  59. package/modules/nextrollBidAdapter.js +375 -0
  60. package/modules/nobidBidAdapter.js +2 -1
  61. package/modules/oguryBidAdapter.js +36 -7
  62. package/modules/openxBidAdapter.js +34 -22
  63. package/modules/operaadsBidAdapter.js +21 -1
  64. package/modules/otmBidAdapter.js +146 -0
  65. package/modules/otmBidAdapter.md +27 -26
  66. package/modules/outbrainBidAdapter.js +5 -0
  67. package/modules/pixfutureBidAdapter.js +24 -4
  68. package/modules/pixfutureBidAdapter.md +127 -0
  69. package/modules/playwireBidAdapter.md +61 -0
  70. package/modules/prebidServerBidAdapter/index.js +1 -1
  71. package/modules/proxistoreBidAdapter.js +4 -6
  72. package/modules/publinkIdSystem.js +17 -7
  73. package/modules/publinkIdSystem.md +7 -2
  74. package/modules/pubmaticBidAdapter.js +22 -6
  75. package/modules/pubmaticBidAdapter.md +1 -1
  76. package/modules/relaidoBidAdapter.js +8 -2
  77. package/modules/rtdModule/index.js +2 -2
  78. package/modules/sharethroughBidAdapter.js +12 -19
  79. package/modules/slimcutBidAdapter.js +121 -0
  80. package/modules/sonobiBidAdapter.js +7 -0
  81. package/modules/sortableBidAdapter.js +1 -0
  82. package/modules/spotxBidAdapter.js +15 -1
  83. package/modules/sspBCBidAdapter.js +207 -12
  84. package/modules/sspBCBidAdapter.md +1 -1
  85. package/modules/talkadsBidAdapter.js +129 -0
  86. package/modules/talkadsBidAdapter.md +60 -0
  87. package/modules/tappxBidAdapter.js +6 -5
  88. package/modules/teadsBidAdapter.js +3 -0
  89. package/modules/tripleliftBidAdapter.js +22 -5
  90. package/modules/trustxBidAdapter.js +17 -11
  91. package/modules/undertoneBidAdapter.js +9 -5
  92. package/modules/undertoneBidAdapter.md +5 -1
  93. package/modules/unicornBidAdapter.js +3 -3
  94. package/modules/userId/eids.js +18 -0
  95. package/modules/userId/eids.md +7 -0
  96. package/modules/userId/userId.md +12 -0
  97. package/modules/ventesBidAdapter.js +370 -0
  98. package/modules/ventesBidAdapter.md +94 -0
  99. package/modules/videobyteBidAdapter.js +13 -6
  100. package/modules/videobyteBidAdapter.md +49 -0
  101. package/modules/vidoomyBidAdapter.js +20 -12
  102. package/modules/visxBidAdapter.js +15 -22
  103. package/modules/yahoosspBidAdapter.js +637 -0
  104. package/modules/yahoosspBidAdapter.md +795 -0
  105. package/modules/yieldlabBidAdapter.js +48 -3
  106. package/modules/yieldlabBidAdapter.md +16 -1
  107. package/modules/yieldmoBidAdapter.js +20 -6
  108. package/modules/yieldmoSyntheticInventoryModule.js +46 -0
  109. package/modules/yieldmoSyntheticInventoryModule.md +68 -0
  110. package/package.json +1 -1
  111. package/src/adapterManager.js +5 -0
  112. package/src/adapters/bidderFactory.js +4 -3
  113. package/src/auction.js +11 -11
  114. package/src/constants.json +1 -0
  115. package/src/secureCreatives.js +6 -7
  116. package/src/targeting.js +11 -9
  117. package/test/.eslintrc.js +2 -1
  118. package/test/spec/modules/adfBidAdapter_spec.js +83 -29
  119. package/test/spec/modules/adgenerationBidAdapter_spec.js +121 -50
  120. package/test/spec/modules/adnuntiusBidAdapter_spec.js +68 -0
  121. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  122. package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
  123. package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
  124. package/test/spec/modules/atsAnalyticsAdapter_spec.js +77 -9
  125. package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
  126. package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
  127. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  128. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  129. package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
  130. package/test/spec/modules/connectIdSystem_spec.js +189 -0
  131. package/test/spec/modules/cwireBidAdapter_spec.js +246 -0
  132. package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
  133. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  134. package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
  135. package/test/spec/modules/glimpseBidAdapter_spec.js +302 -204
  136. package/test/spec/modules/gridNMBidAdapter_spec.js +40 -1
  137. package/test/spec/modules/gumgumBidAdapter_spec.js +23 -6
  138. package/test/spec/modules/iasRtdProvider_spec.js +71 -6
  139. package/test/spec/modules/ixBidAdapter_spec.js +13 -3
  140. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  141. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  142. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
  143. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +67 -12
  144. package/test/spec/modules/mediakeysBidAdapter_spec.js +406 -51
  145. package/test/spec/modules/multibid_spec.js +31 -31
  146. package/test/spec/modules/mytargetBidAdapter_spec.js +199 -0
  147. package/test/spec/modules/nativoBidAdapter_spec.js +50 -3
  148. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
  149. package/test/spec/modules/nextrollBidAdapter_spec.js +290 -0
  150. package/test/spec/modules/nobidBidAdapter_spec.js +65 -1
  151. package/test/spec/modules/oguryBidAdapter_spec.js +125 -37
  152. package/test/spec/modules/openxBidAdapter_spec.js +85 -13
  153. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  154. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  155. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  156. package/test/spec/modules/publinkIdSystem_spec.js +34 -15
  157. package/test/spec/modules/pubmaticBidAdapter_spec.js +217 -1
  158. package/test/spec/modules/relaidoBidAdapter_spec.js +21 -20
  159. package/test/spec/modules/sharethroughBidAdapter_spec.js +156 -136
  160. package/test/spec/modules/slimcutBidAdapter_spec.js +200 -0
  161. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  162. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  163. package/test/spec/modules/spotxBidAdapter_spec.js +36 -0
  164. package/test/spec/modules/sspBCBidAdapter_spec.js +210 -62
  165. package/test/spec/modules/talkadsBidAdapter_spec.js +231 -0
  166. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  167. package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
  168. package/test/spec/modules/trustxBidAdapter_spec.js +38 -5
  169. package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
  170. package/test/spec/modules/unicornBidAdapter_spec.js +4 -4
  171. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  172. package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
  173. package/test/spec/modules/visxBidAdapter_spec.js +48 -4
  174. package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
  175. package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
  176. package/test/spec/modules/yieldmoBidAdapter_spec.js +30 -9
  177. package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
  178. package/test/spec/unit/core/adapterManager_spec.js +32 -0
  179. package/test/spec/unit/core/bidderFactory_spec.js +61 -1
  180. package/test/spec/unit/pbjs_api_spec.js +37 -2
  181. package/test/spec/unit/secureCreatives_spec.js +54 -25
  182. package/modules/turktelekomBidAdapter.md +0 -49
@@ -3,6 +3,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'
3
3
  import find from 'core-js-pure/features/array/find.js'
4
4
  import { VIDEO, BANNER } from '../src/mediaTypes.js'
5
5
  import { Renderer } from '../src/Renderer.js'
6
+ import { config } from '../src/config.js';
6
7
 
7
8
  const ENDPOINT = 'https://ad.yieldlab.net'
8
9
  const BIDDER_CODE = 'yieldlab'
@@ -52,6 +53,11 @@ export const spec = {
52
53
  if (bid.schain && isPlainObject(bid.schain) && Array.isArray(bid.schain.nodes)) {
53
54
  query.schain = createSchainString(bid.schain)
54
55
  }
56
+
57
+ const iabContent = getContentObject(bid)
58
+ if (iabContent) {
59
+ query.iab_content = createIabContentString(iabContent)
60
+ }
55
61
  })
56
62
 
57
63
  if (bidderRequest) {
@@ -105,6 +111,7 @@ export const spec = {
105
111
  const gdprApplies = reqParams.gdpr ? '&gdpr=' + reqParams.gdpr : ''
106
112
  const gdprConsent = reqParams.consent ? '&consent=' + reqParams.consent : ''
107
113
  const pvId = matchedBid.pvid !== undefined ? '&pvid=' + matchedBid.pvid : ''
114
+ const iabContent = reqParams.iab_content ? '&iab_content=' + reqParams.iab_content : ''
108
115
 
109
116
  const bidResponse = {
110
117
  requestId: bidRequest.bidId,
@@ -117,7 +124,7 @@ export const spec = {
117
124
  netRevenue: false,
118
125
  ttl: BID_RESPONSE_TTL_SEC,
119
126
  referrer: '',
120
- ad: `<script src="${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}"></script>`,
127
+ ad: `<script src="${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}${iabContent}"></script>`,
121
128
  meta: {
122
129
  advertiserDomains: (matchedBid.advertiser) ? matchedBid.advertiser : 'n/a'
123
130
  }
@@ -130,7 +137,7 @@ export const spec = {
130
137
  bidResponse.height = playersize[1]
131
138
  }
132
139
  bidResponse.mediaType = VIDEO
133
- bidResponse.vastUrl = `${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}`
140
+ bidResponse.vastUrl = `${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}${iabContent}`
134
141
  if (isOutstream(bidRequest)) {
135
142
  const renderer = Renderer.install({
136
143
  id: bidRequest.bidId,
@@ -211,7 +218,7 @@ function createQueryString (obj) {
211
218
  for (var p in obj) {
212
219
  if (obj.hasOwnProperty(p)) {
213
220
  let val = obj[p]
214
- if (p !== 'schain') {
221
+ if (p !== 'schain' && p !== 'iab_content') {
215
222
  str.push(encodeURIComponent(p) + '=' + encodeURIComponent(val))
216
223
  } else {
217
224
  str.push(p + '=' + val)
@@ -253,6 +260,44 @@ function createSchainString (schain) {
253
260
  return `${ver},${complete}${nodesString}`
254
261
  }
255
262
 
263
+ /**
264
+ * Get content object from bid request
265
+ * First get content from bidder params;
266
+ * If not provided in bidder params, get from first party data under 'ortb2.site.content' or 'ortb2.app.content'
267
+ * @param {Object} bid
268
+ * @returns {Object}
269
+ */
270
+ function getContentObject(bid) {
271
+ if (bid.params.iabContent && isPlainObject(bid.params.iabContent)) {
272
+ return bid.params.iabContent
273
+ }
274
+
275
+ const globalContent = config.getConfig('ortb2.site') ? config.getConfig('ortb2.site.content')
276
+ : config.getConfig('ortb2.app.content')
277
+ if (globalContent && isPlainObject(globalContent)) {
278
+ return globalContent
279
+ }
280
+ return undefined
281
+ }
282
+
283
+ /**
284
+ * Creates a string for iab_content object
285
+ * @param {Object} iabContent
286
+ * @returns {String}
287
+ */
288
+ function createIabContentString(iabContent) {
289
+ const arrKeys = ['keywords', 'cat']
290
+ let str = []
291
+ for (let key in iabContent) {
292
+ if (iabContent.hasOwnProperty(key)) {
293
+ const value = (arrKeys.indexOf(key) !== -1 && Array.isArray(iabContent[key]))
294
+ ? iabContent[key].map(node => encodeURIComponent(node)).join('|') : encodeURIComponent(iabContent[key])
295
+ str.push(''.concat(key, ':', value))
296
+ }
297
+ }
298
+ return encodeURIComponent(str.join(','))
299
+ }
300
+
256
301
  /**
257
302
  * Encodes URI Component with exlamation mark included. Needed for schain object.
258
303
  * @param {String} str
@@ -25,7 +25,22 @@ Module that connects to Yieldlab's demand sources
25
25
  key1: "value1",
26
26
  key2: "value2"
27
27
  },
28
- extId: "abc"
28
+ extId: "abc",
29
+ iabContent: {
30
+ id: "some_id",
31
+ episode: "1",
32
+ title: "some title",
33
+ series: "some series",
34
+ season: "s1",
35
+ artist: "John Doe",
36
+ genre: "some genre",
37
+ isrc: "CC-XXX-YY-NNNNN",
38
+ url: "http://foo_url.de",
39
+ cat: ["IAB1-1", "IAB1-2", "IAB2-10"],
40
+ context: "7",
41
+ keywords: ["k1", "k2"],
42
+ live: "0"
43
+ }
29
44
  }
30
45
  }]
31
46
  }, {
@@ -1,9 +1,10 @@
1
- import { getWindowTop, deepAccess, parseQueryStringParameters, isArrayOfNums, isArray, parseUrl, isEmpty, deepSetValue, isStr, isNumber, isInteger, isBoolean, logError } from '../src/utils.js';
1
+ import { isNumber, isStr, isInteger, isBoolean, isArray, isEmpty, isArrayOfNums, getWindowTop, parseQueryStringParameters, parseUrl, deepSetValue, deepAccess, logError } from '../src/utils.js';
2
2
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
4
  import { Renderer } from '../src/Renderer.js';
5
5
  import includes from 'core-js-pure/features/array/includes';
6
6
  import find from 'core-js-pure/features/array/find.js';
7
+ import { createEidsArray } from './userId/eids.js';
7
8
 
8
9
  const BIDDER_CODE = 'yieldmo';
9
10
  const CURRENCY = 'USD';
@@ -46,8 +47,8 @@ export const spec = {
46
47
  buildRequests: function (bidRequests, bidderRequest) {
47
48
  const bannerBidRequests = bidRequests.filter(request => hasBannerMediaType(request));
48
49
  const videoBidRequests = bidRequests.filter(request => hasVideoMediaType(request));
49
-
50
50
  let serverRequests = [];
51
+ const eids = getEids(bidRequests[0]) || [];
51
52
  if (bannerBidRequests.length > 0) {
52
53
  let serverRequest = {
53
54
  pbav: '$prebid.version$',
@@ -99,6 +100,9 @@ export const spec = {
99
100
  });
100
101
  serverRequest.p = '[' + serverRequest.p.toString() + ']';
101
102
 
103
+ if (eids.length) {
104
+ serverRequest.eids = JSON.stringify(eids);
105
+ };
102
106
  // check if url exceeded max length
103
107
  const url = `${BANNER_SERVER_ENDPOINT}?${parseQueryStringParameters(serverRequest)}`;
104
108
  let extraCharacters = url.length - MAX_BANNER_REQUEST_URL_LENGTH;
@@ -121,6 +125,9 @@ export const spec = {
121
125
 
122
126
  if (videoBidRequests.length > 0) {
123
127
  const serverRequest = openRtbRequest(videoBidRequests, bidderRequest);
128
+ if (eids.length) {
129
+ serverRequest.user = { eids };
130
+ };
124
131
  serverRequests.push({
125
132
  method: 'POST',
126
133
  url: VIDEO_SERVER_ENDPOINT,
@@ -447,14 +454,10 @@ function openRtbSite(bidRequest, bidderRequest) {
447
454
  * @return Object OpenRTB's 'device' object
448
455
  */
449
456
  function openRtbDevice(bidRequest) {
450
- const ip = deepAccess(bidRequest, 'params.device.ip');
451
457
  const deviceObj = {
452
458
  ua: navigator.userAgent,
453
459
  language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage),
454
460
  };
455
- if (ip) {
456
- deviceObj.ip = ip;
457
- }
458
461
  return deviceObj;
459
462
  }
460
463
 
@@ -595,3 +598,14 @@ function shortcutProperty(extraCharacters, target, propertyName) {
595
598
 
596
599
  return charactersLeft;
597
600
  }
601
+
602
+ /**
603
+ * Creates and returnes eids arr using createEidsArray from './userId/eids.js' module;
604
+ * @param {Object} openRtbRequest OpenRTB's request as a cource of userId.
605
+ * @return array of eids objects
606
+ */
607
+ function getEids(bidRequest) {
608
+ if (deepAccess(bidRequest, 'userId')) {
609
+ return createEidsArray(bidRequest.userId) || [];
610
+ }
611
+ };
@@ -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": "5.16.0",
3
+ "version": "5.20.0",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.js",
6
6
  "scripts": {
@@ -621,4 +621,9 @@ adapterManager.callBidViewableBidder = function(bidder, bid) {
621
621
  tryCallBidderMethod(bidder, 'onBidViewable', bid);
622
622
  };
623
623
 
624
+ adapterManager.callBidderError = function(bidder, error, bidderRequest) {
625
+ const param = { error, bidderRequest };
626
+ tryCallBidderMethod(bidder, 'onBidderError', param);
627
+ };
628
+
624
629
  export default adapterManager;
@@ -335,10 +335,11 @@ export function newBidder(spec) {
335
335
 
336
336
  // If the server responds with an error, there's not much we can do. Log it, and make sure to
337
337
  // call onResponse() so that we're one step closer to calling done().
338
- function onFailure(err) {
338
+ function onFailure(errorMessage, error) {
339
339
  onTimelyResponse(spec.code);
340
-
341
- logError(`Server call for ${spec.code} failed: ${err}. Continuing without bids.`);
340
+ adapterManager.callBidderError(spec.code, error, bidderRequest)
341
+ events.emit(CONSTANTS.EVENTS.BIDDER_ERROR, { error, bidderRequest });
342
+ logError(`Server call for ${spec.code} failed: ${errorMessage} ${error.status}. Continuing without bids.`);
342
343
  onResponse();
343
344
  }
344
345
  }
package/src/auction.js CHANGED
@@ -613,7 +613,8 @@ export const getPriceGranularity = (mediaType, bidReq) => {
613
613
  * @returns {function}
614
614
  */
615
615
  export const getPriceByGranularity = (granularity) => {
616
- return (bid) => {
616
+ return (bid, bidReq) => {
617
+ granularity = granularity || getPriceGranularity(bid.mediaType, bidReq);
617
618
  if (granularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) {
618
619
  return bid.pbAg;
619
620
  } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) {
@@ -646,14 +647,14 @@ export const getAdvertiserDomain = () => {
646
647
  * @param {BidRequest} bidReq
647
648
  * @returns {*}
648
649
  */
649
- export function getStandardBidderSettings(mediaType, bidderCode, bidReq) {
650
+ export function getStandardBidderSettings(mediaType, bidderCode) {
650
651
  // factory for key value objs
651
652
  function createKeyVal(key, value) {
652
653
  return {
653
654
  key,
654
655
  val: (typeof value === 'function')
655
- ? function (bidResponse) {
656
- return value(bidResponse);
656
+ ? function (bidResponse, bidReq) {
657
+ return value(bidResponse, bidReq);
657
658
  }
658
659
  : function (bidResponse) {
659
660
  return getValue(bidResponse, value);
@@ -661,7 +662,6 @@ export function getStandardBidderSettings(mediaType, bidderCode, bidReq) {
661
662
  };
662
663
  }
663
664
  const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS;
664
- const granularity = getPriceGranularity(mediaType, bidReq);
665
665
 
666
666
  let bidderSettings = $$PREBID_GLOBAL$$.bidderSettings;
667
667
  if (!bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD]) {
@@ -671,7 +671,7 @@ export function getStandardBidderSettings(mediaType, bidderCode, bidReq) {
671
671
  bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = [
672
672
  createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'),
673
673
  createKeyVal(TARGETING_KEYS.AD_ID, 'adId'),
674
- createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity(granularity)),
674
+ createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity()),
675
675
  createKeyVal(TARGETING_KEYS.SIZE, 'size'),
676
676
  createKeyVal(TARGETING_KEYS.DEAL, 'dealId'),
677
677
  createKeyVal(TARGETING_KEYS.SOURCE, 'source'),
@@ -716,12 +716,12 @@ export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) {
716
716
  // 1) set the keys from "standard" setting or from prebid defaults
717
717
  if (bidderSettings) {
718
718
  // initialize default if not set
719
- const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode, bidReq);
720
- setKeys(keyValues, standardSettings, custBidObj);
719
+ const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode);
720
+ setKeys(keyValues, standardSettings, custBidObj, bidReq);
721
721
 
722
722
  // 2) set keys from specific bidder setting override if they exist
723
723
  if (bidderCode && bidderSettings[bidderCode] && bidderSettings[bidderCode][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) {
724
- setKeys(keyValues, bidderSettings[bidderCode], custBidObj);
724
+ setKeys(keyValues, bidderSettings[bidderCode], custBidObj, bidReq);
725
725
  custBidObj.sendStandardTargeting = bidderSettings[bidderCode].sendStandardTargeting;
726
726
  }
727
727
  }
@@ -734,7 +734,7 @@ export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) {
734
734
  return keyValues;
735
735
  }
736
736
 
737
- function setKeys(keyValues, bidderSettings, custBidObj) {
737
+ function setKeys(keyValues, bidderSettings, custBidObj, bidReq) {
738
738
  var targeting = bidderSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING];
739
739
  custBidObj.size = custBidObj.getSize();
740
740
 
@@ -748,7 +748,7 @@ function setKeys(keyValues, bidderSettings, custBidObj) {
748
748
 
749
749
  if (isFn(value)) {
750
750
  try {
751
- value = value(custBidObj);
751
+ value = value(custBidObj, bidReq);
752
752
  } catch (e) {
753
753
  logError('bidmanager', 'ERROR', e);
754
754
  }
@@ -32,6 +32,7 @@
32
32
  "NO_BID": "noBid",
33
33
  "BID_WON": "bidWon",
34
34
  "BIDDER_DONE": "bidderDone",
35
+ "BIDDER_ERROR": "bidderError",
35
36
  "SET_TARGETING": "setTargeting",
36
37
  "BEFORE_REQUEST_BIDS": "beforeRequestBids",
37
38
  "BEFORE_BIDDER_HTTP": "beforeBidderHttp",
@@ -60,7 +60,6 @@ export function receiveMessage(ev) {
60
60
  if (data.action === 'assetRequest') {
61
61
  const message = getAssetMessage(data, adObject);
62
62
  ev.source.postMessage(JSON.stringify(message), ev.origin);
63
- return;
64
63
  } else if (data.action === 'allAssetRequest') {
65
64
  const message = getAllAssetsMessage(data, adObject);
66
65
  ev.source.postMessage(JSON.stringify(message), ev.origin);
@@ -68,13 +67,13 @@ export function receiveMessage(ev) {
68
67
  adObject.height = data.height;
69
68
  adObject.width = data.width;
70
69
  resizeRemoteCreative(adObject);
71
- }
72
-
73
- const trackerType = fireNativeTrackers(data, adObject);
74
- if (trackerType === 'click') { return; }
70
+ } else {
71
+ const trackerType = fireNativeTrackers(data, adObject);
72
+ if (trackerType === 'click') { return; }
75
73
 
76
- auctionManager.addWinningBid(adObject);
77
- events.emit(BID_WON, adObject);
74
+ auctionManager.addWinningBid(adObject);
75
+ events.emit(BID_WON, adObject);
76
+ }
78
77
  }
79
78
  }
80
79
  }
package/src/targeting.js CHANGED
@@ -123,17 +123,19 @@ export function newTargeting(auctionManager) {
123
123
  if (isGptPubadsDefined()) {
124
124
  const adUnitCodes = getAdUnitCodes(adUnitCode);
125
125
  const adUnits = auctionManager.getAdUnits().filter(adUnit => includes(adUnitCodes, adUnit.code));
126
+ let unsetKeys = pbTargetingKeys.reduce((reducer, key) => {
127
+ reducer[key] = null;
128
+ return reducer;
129
+ }, {});
126
130
  window.googletag.pubads().getSlots().forEach(slot => {
127
131
  let customSlotMatchingFunc = isFn(customSlotMatching) && customSlotMatching(slot);
128
- pbTargetingKeys.forEach(function(key) {
129
- // reset only registered adunits
130
- adUnits.forEach(function(unit) {
131
- if (unit.code === slot.getAdUnitPath() ||
132
- unit.code === slot.getSlotElementId() ||
133
- (isFn(customSlotMatchingFunc) && customSlotMatchingFunc(unit.code))) {
134
- slot.setTargeting(key, null);
135
- }
136
- });
132
+ // reset only registered adunits
133
+ adUnits.forEach(unit => {
134
+ if (unit.code === slot.getAdUnitPath() ||
135
+ unit.code === slot.getSlotElementId() ||
136
+ (isFn(customSlotMatchingFunc) && customSlotMatchingFunc(unit.code))) {
137
+ slot.updateTargetingFromMap(unsetKeys);
138
+ }
137
139
  });
138
140
  });
139
141
  }
package/test/.eslintrc.js CHANGED
@@ -8,7 +8,8 @@ module.exports = {
8
8
  '$$PREBID_GLOBAL$$': false
9
9
  },
10
10
  parserOptions: {
11
- sourceType: 'module'
11
+ sourceType: 'module',
12
+ ecmaVersion: 2018
12
13
  },
13
14
  rules: {
14
15
  'comma-dangle': 'off',