prebid.js 7.40.0 → 7.41.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 (167) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/aduptechBidAdapter.js +1 -1
  9. package/dist/adxcgBidAdapter.js +1 -1
  10. package/dist/adyoulikeBidAdapter.js +1 -1
  11. package/dist/ajaBidAdapter.js +1 -1
  12. package/dist/amxBidAdapter.js +1 -1
  13. package/dist/amxIdSystem.js +1 -1
  14. package/dist/appierAnalyticsAdapter.js +1 -1
  15. package/dist/appnexusBidAdapter.js +1 -1
  16. package/dist/asoBidAdapter.js +1 -1
  17. package/dist/axonixBidAdapter.js +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bridgewellBidAdapter.js +1 -1
  21. package/dist/brightMountainMediaBidAdapter.js +1 -1
  22. package/dist/browsiBidAdapter.js +1 -0
  23. package/dist/carodaBidAdapter.js +1 -1
  24. package/dist/chtnwBidAdapter.js +1 -1
  25. package/dist/cleanmedianetBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantAnalyticsAdapter.js +1 -1
  30. package/dist/conversantBidAdapter.js +1 -1
  31. package/dist/craftBidAdapter.js +1 -1
  32. package/dist/criteoBidAdapter.js +1 -1
  33. package/dist/cwireBidAdapter.js +1 -1
  34. package/dist/dfpAdServerVideo.js +1 -1
  35. package/dist/dspxBidAdapter.js +1 -1
  36. package/dist/eplanningBidAdapter.js +1 -1
  37. package/dist/feedadBidAdapter.js +1 -1
  38. package/dist/finativeBidAdapter.js +1 -1
  39. package/dist/freewheel-sspBidAdapter.js +1 -1
  40. package/dist/glimpseBidAdapter.js +1 -1
  41. package/dist/gmosspBidAdapter.js +1 -1
  42. package/dist/goldbachBidAdapter.js +1 -1
  43. package/dist/gridBidAdapter.js +1 -1
  44. package/dist/gridNMBidAdapter.js +1 -1
  45. package/dist/gumgumBidAdapter.js +1 -1
  46. package/dist/h12mediaBidAdapter.js +1 -1
  47. package/dist/id5IdSystem.js +1 -1
  48. package/dist/improvedigitalBidAdapter.js +1 -1
  49. package/dist/inmarBidAdapter.js +1 -1
  50. package/dist/insticatorBidAdapter.js +1 -1
  51. package/dist/ixBidAdapter.js +1 -1
  52. package/dist/justpremiumBidAdapter.js +1 -1
  53. package/dist/kargoBidAdapter.js +1 -1
  54. package/dist/konduitAnalyticsAdapter.js +1 -1
  55. package/dist/kueezBidAdapter.js +1 -1
  56. package/dist/kueezRtbBidAdapter.js +1 -1
  57. package/dist/lassoBidAdapter.js +1 -1
  58. package/dist/lifestreetBidAdapter.js +1 -1
  59. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  60. package/dist/logicadBidAdapter.js +1 -1
  61. package/dist/loglyliftBidAdapter.js +1 -1
  62. package/dist/magniteAnalyticsAdapter.js +1 -1
  63. package/dist/malltvAnalyticsAdapter.js +1 -1
  64. package/dist/marsmediaBidAdapter.js +1 -1
  65. package/dist/mediafuseBidAdapter.js +1 -1
  66. package/dist/mediasquareBidAdapter.js +1 -1
  67. package/dist/mgidBidAdapter.js +1 -1
  68. package/dist/minutemediaBidAdapter.js +1 -1
  69. package/dist/minutemediaplusBidAdapter.js +1 -1
  70. package/dist/missenaBidAdapter.js +1 -1
  71. package/dist/nexx360BidAdapter.js +1 -1
  72. package/dist/nobidBidAdapter.js +1 -1
  73. package/dist/not-for-prod/prebid.js +130 -129
  74. package/dist/oguryBidAdapter.js +1 -1
  75. package/dist/onetagBidAdapter.js +1 -1
  76. package/dist/ooloAnalyticsAdapter.js +1 -1
  77. package/dist/optidigitalBidAdapter.js +1 -1
  78. package/dist/outbrainBidAdapter.js +1 -1
  79. package/dist/parrableIdSystem.js +1 -1
  80. package/dist/permutiveRtdProvider.js +1 -1
  81. package/dist/pixfutureBidAdapter.js +1 -1
  82. package/dist/prebid-core.js +1 -1
  83. package/dist/publinkIdSystem.js +1 -1
  84. package/dist/pubmaticBidAdapter.js +1 -1
  85. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  86. package/dist/pubwiseBidAdapter.js +1 -1
  87. package/dist/pxyzBidAdapter.js +1 -1
  88. package/dist/quantcastBidAdapter.js +1 -1
  89. package/dist/readpeakBidAdapter.js +1 -1
  90. package/dist/relaidoBidAdapter.js +1 -1
  91. package/dist/rhythmoneBidAdapter.js +1 -1
  92. package/dist/riseBidAdapter.js +1 -1
  93. package/dist/rubiconAnalyticsAdapter.js +1 -1
  94. package/dist/rubiconBidAdapter.js +1 -1
  95. package/dist/seedingAllianceBidAdapter.js +1 -1
  96. package/dist/seedtagBidAdapter.js +1 -1
  97. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  98. package/dist/sharethroughBidAdapter.js +1 -1
  99. package/dist/shinezBidAdapter.js +1 -1
  100. package/dist/smaatoBidAdapter.js +1 -1
  101. package/dist/smartadserverBidAdapter.js +1 -1
  102. package/dist/smartxBidAdapter.js +1 -1
  103. package/dist/smilewantedBidAdapter.js +1 -1
  104. package/dist/sonobiBidAdapter.js +1 -1
  105. package/dist/sovrnAnalyticsAdapter.js +1 -1
  106. package/dist/sovrnBidAdapter.js +1 -1
  107. package/dist/sspBCBidAdapter.js +1 -1
  108. package/dist/stvBidAdapter.js +1 -0
  109. package/dist/sublimeBidAdapter.js +1 -1
  110. package/dist/synacormediaBidAdapter.js +1 -1
  111. package/dist/targetVideoBidAdapter.js +1 -1
  112. package/dist/teadsBidAdapter.js +1 -1
  113. package/dist/trionBidAdapter.js +1 -1
  114. package/dist/tripleliftBidAdapter.js +1 -1
  115. package/dist/ttdBidAdapter.js +1 -1
  116. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  117. package/dist/uid2IdSystem.js +1 -1
  118. package/dist/underdogmediaBidAdapter.js +1 -1
  119. package/dist/undertoneBidAdapter.js +1 -1
  120. package/dist/vidazooBidAdapter.js +1 -1
  121. package/dist/videobyteBidAdapter.js +1 -1
  122. package/dist/visxBidAdapter.js +1 -1
  123. package/dist/vuukleBidAdapter.js +1 -1
  124. package/dist/widespaceBidAdapter.js +1 -1
  125. package/dist/winrBidAdapter.js +1 -1
  126. package/dist/yahoosspBidAdapter.js +1 -1
  127. package/dist/yandexBidAdapter.js +1 -1
  128. package/dist/yieldmoBidAdapter.js +1 -1
  129. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  130. package/integrationExamples/gpt/x-domain/creative.html +1 -1
  131. package/modules/aduptechBidAdapter.js +43 -37
  132. package/modules/browsiBidAdapter.js +171 -0
  133. package/modules/browsiBidAdapter.md +38 -0
  134. package/modules/cleanmedianetBidAdapter.js +191 -126
  135. package/modules/cleanmedianetBidAdapter.md +64 -18
  136. package/modules/conversantBidAdapter.js +4 -0
  137. package/modules/dfpAdServerVideo.js +8 -8
  138. package/modules/freewheel-sspBidAdapter.js +9 -0
  139. package/modules/gridBidAdapter.js +12 -1
  140. package/modules/ixBidAdapter.js +1 -1
  141. package/modules/missenaBidAdapter.js +2 -1
  142. package/modules/neuwoRtdProvider.js +1 -1
  143. package/modules/nobidBidAdapter.js +13 -2
  144. package/modules/nobidBidAdapter.md +2 -2
  145. package/modules/permutiveRtdProvider.js +8 -2
  146. package/modules/pubwiseBidAdapter.js +265 -33
  147. package/modules/stvBidAdapter.js +330 -0
  148. package/modules/stvBidAdapter.md +62 -0
  149. package/modules/yandexBidAdapter.js +259 -71
  150. package/modules/yandexBidAdapter.md +52 -15
  151. package/package.json +1 -1
  152. package/src/videoCache.js +4 -4
  153. package/test/spec/modules/browsiBidAdapter_spec.js +209 -0
  154. package/test/spec/modules/cleanmedianetBidAdapter_spec.js +462 -407
  155. package/test/spec/modules/conversantBidAdapter_spec.js +8 -0
  156. package/test/spec/modules/dfpAdServerVideo_spec.js +36 -4
  157. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  158. package/test/spec/modules/gridBidAdapter_spec.js +24 -0
  159. package/test/spec/modules/ixBidAdapter_spec.js +4 -4
  160. package/test/spec/modules/nobidBidAdapter_spec.js +32 -0
  161. package/test/spec/modules/permutiveRtdProvider_spec.js +61 -4
  162. package/test/spec/modules/pubwiseBidAdapter_spec.js +313 -3
  163. package/test/spec/modules/stvBidAdapter_spec.js +402 -0
  164. package/test/spec/modules/yandexBidAdapter_spec.js +315 -45
  165. package/test/spec/videoCache_spec.js +23 -0
  166. package/dist/flocIdSystem.js +0 -1
  167. package/modules/flocIdSystem.js +0 -0
@@ -1,13 +1,34 @@
1
- import {deepAccess, getDNT, inIframe, isArray, isNumber, logError, logWarn} from '../src/utils.js';
1
+ import {
2
+ deepAccess,
3
+ deepSetValue,
4
+ getDNT,
5
+ inIframe,
6
+ isArray,
7
+ isFn,
8
+ isNumber,
9
+ isPlainObject,
10
+ isStr,
11
+ logError,
12
+ logWarn
13
+ } from '../src/utils.js';
2
14
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
15
  import {Renderer} from '../src/Renderer.js';
4
16
  import {BANNER, VIDEO} from '../src/mediaTypes.js';
5
17
  import {includes} from '../src/polyfill.js';
6
18
 
19
+ const ENDPOINTS = {
20
+ 'cleanmedianet': 'https://bidder.cleanmediaads.com'
21
+ };
22
+
23
+ const DEFAULT_TTL = 360;
24
+
7
25
  export const helper = {
8
- getTopWindowDomain: function (url) {
9
- const domainStart = url.indexOf('://') + '://'.length;
10
- return url.substring(domainStart, url.indexOf('/', domainStart) < 0 ? url.length : url.indexOf('/', domainStart));
26
+ getTopFrame: function () {
27
+ try {
28
+ return window.top === window ? 1 : 0;
29
+ } catch (e) {
30
+ }
31
+ return 0;
11
32
  },
12
33
  startsWith: function (str, search) {
13
34
  return str.substr(0, search.length) === search;
@@ -23,53 +44,50 @@ export const helper = {
23
44
  }
24
45
  }
25
46
  return BANNER;
47
+ },
48
+ getBidFloor(bid) {
49
+ if (!isFn(bid.getFloor)) {
50
+ return bid.params.bidfloor ? bid.params.bidfloor : null;
51
+ }
52
+
53
+ let bidFloor = bid.getFloor({
54
+ mediaType: '*',
55
+ size: '*',
56
+ currency: 'USD'
57
+ });
58
+
59
+ if (isPlainObject(bidFloor) && !isNaN(bidFloor.floor) && bidFloor.currency === 'USD') {
60
+ return bidFloor.floor;
61
+ }
62
+
63
+ return null;
26
64
  }
27
65
  };
28
66
 
29
67
  export const spec = {
30
68
  code: 'cleanmedianet',
31
69
  aliases: [],
32
- supportedMediaTypes: [BANNER, VIDEO],
70
+ supportedMediaTypes: ['banner', 'video'],
33
71
 
34
72
  isBidRequestValid: function (bid) {
35
- return (
36
- !!bid.params.supplyPartnerId &&
37
- typeof bid.params.supplyPartnerId === 'string' &&
38
- (typeof bid.params.bidfloor === 'undefined' ||
39
- typeof bid.params.bidfloor === 'number') &&
40
- (typeof bid.params['adpos'] === 'undefined' ||
41
- typeof bid.params['adpos'] === 'number') &&
42
- (typeof bid.params['protocols'] === 'undefined' ||
43
- Array.isArray(bid.params['protocols'])) &&
44
- (typeof bid.params.instl === 'undefined' ||
45
- bid.params.instl === 0 ||
46
- bid.params.instl === 1)
47
- );
73
+ return !!bid.params.supplyPartnerId && isStr(bid.params.supplyPartnerId) &&
74
+ (!bid.params['rtbEndpoint'] || isStr(bid.params['rtbEndpoint'])) &&
75
+ (!bid.params.bidfloor || isNumber(bid.params.bidfloor)) &&
76
+ (!bid.params['adpos'] || isNumber(bid.params['adpos'])) &&
77
+ (!bid.params['protocols'] || Array.isArray(bid.params['protocols'])) &&
78
+ (!bid.params.instl || bid.params.instl === 0 || bid.params.instl === 1);
48
79
  },
49
80
 
50
81
  buildRequests: function (validBidRequests, bidderRequest) {
51
82
  return validBidRequests.map(bidRequest => {
52
- const {
53
- adUnitCode,
54
- auctionId,
55
- mediaTypes,
56
- params,
57
- sizes,
58
- transactionId
59
- } = bidRequest;
60
- const baseEndpoint = 'https://bidder.cleanmediaads.com';
61
- const rtbEndpoint =
62
- `${baseEndpoint}/r/${
63
- params.supplyPartnerId
64
- }/bidr?rformat=open_rtb&reqformat=rtb_json&bidder=prebid` +
65
- (params.query ? '&' + params.query : '');
66
- let url = bidderRequest.refererInfo.page;
67
-
83
+ const {adUnitCode, auctionId, mediaTypes, params, sizes, transactionId} = bidRequest;
84
+ const baseEndpoint = (params['rtbEndpoint'] || ENDPOINTS['cleanmedianet']).replace(/^http:/, 'https:');
85
+ const rtbEndpoint = `${baseEndpoint}/r/${params.supplyPartnerId}/bidr?rformat=open_rtb&reqformat=rtb_json&bidder=prebid` + (params.query ? '&' + params.query : '');
68
86
  const rtbBidRequest = {
69
87
  id: auctionId,
70
88
  site: {
71
89
  domain: bidderRequest.refererInfo.domain,
72
- page: url,
90
+ page: bidderRequest.refererInfo.page,
73
91
  ref: bidderRequest.refererInfo.ref
74
92
  },
75
93
  device: {
@@ -81,44 +99,35 @@ export const spec = {
81
99
  },
82
100
  imp: [],
83
101
  ext: {},
84
- user: {
85
- ext: {}
86
- }
102
+ user: {ext: {}},
103
+ source: {ext: {}},
104
+ regs: {ext: {}}
87
105
  };
88
106
 
89
- if (
90
- bidderRequest.gdprConsent &&
91
- bidderRequest.gdprConsent.consentString &&
92
- bidderRequest.gdprConsent.gdprApplies
93
- ) {
94
- rtbBidRequest.ext.gdpr_consent = {
95
- consent_string: bidderRequest.gdprConsent.consentString,
96
- consent_required: bidderRequest.gdprConsent.gdprApplies
97
- };
98
- rtbBidRequest.regs = {
99
- ext: {
100
- gdpr: bidderRequest.gdprConsent.gdprApplies === true ? 1 : 0
101
- }
102
- };
103
- rtbBidRequest.user = {
104
- ext: {
105
- consent: bidderRequest.gdprConsent.consentString
106
- }
107
- };
107
+ const gdprConsent = getGdprConsent(bidderRequest);
108
+ rtbBidRequest.ext.gdpr_consent = gdprConsent;
109
+ deepSetValue(rtbBidRequest, 'regs.ext.gdpr', gdprConsent.consent_required === true ? 1 : 0);
110
+ deepSetValue(rtbBidRequest, 'user.ext.consent', gdprConsent.consent_string);
111
+
112
+ if (validBidRequests[0].schain) {
113
+ deepSetValue(rtbBidRequest, 'source.ext.schain', validBidRequests[0].schain);
114
+ }
115
+
116
+ if (bidderRequest && bidderRequest.uspConsent) {
117
+ deepSetValue(rtbBidRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent);
108
118
  }
109
119
 
110
120
  const imp = {
111
121
  id: transactionId,
112
- instl: deepAccess(bidRequest.ortb2Imp, 'instl') === 1 || params.instl === 1 ? 1 : 0,
122
+ instl: deepAccess(bidderRequest.ortb2Imp, 'instl') === 1 || params.instl === 1 ? 1 : 0,
113
123
  tagid: adUnitCode,
114
- bidfloor: 0,
124
+ bidfloor: helper.getBidFloor(bidRequest) || 0,
115
125
  bidfloorcur: 'USD',
116
126
  secure: 1
117
127
  };
118
128
 
119
129
  const hasFavoredMediaType =
120
- params.favoredMediaType &&
121
- includes(this.supportedMediaTypes, params.favoredMediaType);
130
+ params.favoredMediaType && includes(this.supportedMediaTypes, params.favoredMediaType);
122
131
 
123
132
  if (!mediaTypes || mediaTypes.banner) {
124
133
  if (!hasFavoredMediaType || params.favoredMediaType === BANNER) {
@@ -126,7 +135,7 @@ export const spec = {
126
135
  banner: {
127
136
  w: sizes.length ? sizes[0][0] : 300,
128
137
  h: sizes.length ? sizes[0][1] : 250,
129
- pos: params.pos || 0,
138
+ pos: deepAccess(bidderRequest, 'mediaTypes.banner.pos') || params.pos || 0,
130
139
  topframe: inIframe() ? 0 : 1
131
140
  }
132
141
  });
@@ -136,15 +145,25 @@ export const spec = {
136
145
 
137
146
  if (mediaTypes && mediaTypes.video) {
138
147
  if (!hasFavoredMediaType || params.favoredMediaType === VIDEO) {
139
- let videoImp = {
148
+ const playerSize = mediaTypes.video.playerSize || sizes;
149
+ const videoImp = Object.assign({}, imp, {
140
150
  video: {
141
- protocols: params.protocols || [1, 2, 3, 4, 5, 6],
142
- pos: params.pos || 0,
143
- ext: {context: mediaTypes.video.context}
151
+ protocols: bidRequest.mediaTypes.video.protocols || params.protocols || [1, 2, 3, 4, 5, 6],
152
+ pos: deepAccess(bidRequest, 'mediaTypes.video.pos') || params.pos || 0,
153
+ ext: {
154
+ context: mediaTypes.video.context
155
+ },
156
+ mimes: bidRequest.mediaTypes.video.mimes,
157
+ maxduration: bidRequest.mediaTypes.video.maxduration,
158
+ api: bidRequest.mediaTypes.video.api,
159
+ skip: bidRequest.mediaTypes.video.skip || bidRequest.params.video.skip,
160
+ placement: bidRequest.mediaTypes.video.placement || bidRequest.params.video.placement,
161
+ minduration: bidRequest.mediaTypes.video.minduration || bidRequest.params.video.minduration,
162
+ playbackmethod: bidRequest.mediaTypes.video.playbackmethod || bidRequest.params.video.playbackmethod,
163
+ startdelay: bidRequest.mediaTypes.video.startdelay || bidRequest.params.video.startdelay
144
164
  }
145
- };
165
+ });
146
166
 
147
- let playerSize = mediaTypes.video.playerSize || sizes;
148
167
  if (isArray(playerSize[0])) {
149
168
  videoImp.video.w = playerSize[0][0];
150
169
  videoImp.video.h = playerSize[0][1];
@@ -156,11 +175,20 @@ export const spec = {
156
175
  videoImp.video.h = 250;
157
176
  }
158
177
 
159
- videoImp = Object.assign({}, imp, videoImp);
160
178
  rtbBidRequest.imp.push(videoImp);
161
179
  }
162
180
  }
163
181
 
182
+ let eids = [];
183
+ if (bidRequest && bidRequest.userId) {
184
+ addExternalUserId(eids, deepAccess(bidRequest, `userId.id5id.uid`), 'id5-sync.com', 'ID5ID');
185
+ addExternalUserId(eids, deepAccess(bidRequest, `userId.tdid`), 'adserver.org', 'TDID');
186
+ addExternalUserId(eids, deepAccess(bidRequest, `userId.idl_env`), 'liveramp.com', 'idl');
187
+ }
188
+ if (eids.length > 0) {
189
+ rtbBidRequest.user.ext.eids = eids;
190
+ }
191
+
164
192
  if (rtbBidRequest.imp.length === 0) {
165
193
  return;
166
194
  }
@@ -181,10 +209,7 @@ export const spec = {
181
209
  return [];
182
210
  }
183
211
 
184
- const bids = response.seatbid.reduce(
185
- (acc, seatBid) => acc.concat(seatBid.bid),
186
- []
187
- );
212
+ const bids = response.seatbid.reduce((acc, seatBid) => acc.concat(seatBid.bid), []);
188
213
  let outBids = [];
189
214
 
190
215
  bids.forEach(bid => {
@@ -193,75 +218,81 @@ export const spec = {
193
218
  cpm: bid.price,
194
219
  width: bid.w,
195
220
  height: bid.h,
196
- ttl: 360,
221
+ ttl: DEFAULT_TTL,
197
222
  creativeId: bid.crid || bid.adid,
198
223
  netRevenue: true,
199
224
  currency: bid.cur || response.cur,
200
- mediaType: helper.getMediaType(bid)
225
+ mediaType: helper.getMediaType(bid),
201
226
  };
202
227
 
203
- if (
204
- deepAccess(
205
- bidRequest.bidRequest,
206
- 'mediaTypes.' + outBid.mediaType
207
- )
208
- ) {
228
+ if (bid.adomain && bid.adomain.length) {
229
+ outBid.meta = {
230
+ advertiserDomains: bid.adomain
231
+ }
232
+ }
233
+
234
+ if (deepAccess(bidRequest.bidRequest, 'mediaTypes.' + outBid.mediaType)) {
209
235
  if (outBid.mediaType === BANNER) {
210
236
  outBids.push(Object.assign({}, outBid, {ad: bid.adm}));
211
237
  } else if (outBid.mediaType === VIDEO) {
212
- const context = deepAccess(
213
- bidRequest.bidRequest,
214
- 'mediaTypes.video.context'
215
- );
216
- outBids.push(
217
- Object.assign({}, outBid, {
218
- vastUrl: bid.ext.vast_url,
219
- vastXml: bid.adm,
220
- renderer:
221
- context === 'outstream'
222
- ? newRenderer(bidRequest.bidRequest, bid)
223
- : undefined
224
- })
225
- );
238
+ const context = deepAccess(bidRequest.bidRequest, 'mediaTypes.video.context');
239
+ outBids.push(Object.assign({}, outBid, {
240
+ vastUrl: bid.ext.vast_url,
241
+ vastXml: bid.adm,
242
+ renderer: context === 'outstream' ? newRenderer(bidRequest.bidRequest, bid) : undefined
243
+ }));
226
244
  }
227
245
  }
228
246
  });
229
247
  return outBids;
230
248
  },
231
249
 
232
- getUserSyncs: function (syncOptions, serverResponses, gdprConsent) {
250
+ getUserSyncs: function (syncOptions, serverResponses, gdprConsent, uspConsent) {
233
251
  const syncs = [];
234
- const gdprApplies =
235
- gdprConsent && typeof gdprConsent.gdprApplies === 'boolean'
236
- ? gdprConsent.gdprApplies
237
- : false;
238
- const suffix = gdprApplies
239
- ? 'gc=' + encodeURIComponent(gdprConsent.consentString)
240
- : 'gc=missing';
252
+ let gdprApplies = false;
253
+ let consentString = '';
254
+ let uspConsentString = '';
255
+
256
+ if (gdprConsent && (typeof gdprConsent.gdprApplies === 'boolean')) {
257
+ gdprApplies = gdprConsent.gdprApplies;
258
+ }
259
+ let gdpr = gdprApplies ? 1 : 0;
260
+
261
+ if (gdprApplies && gdprConsent.consentString) {
262
+ consentString = encodeURIComponent(gdprConsent.consentString);
263
+ }
264
+
265
+ if (uspConsent) {
266
+ uspConsentString = encodeURIComponent(uspConsent);
267
+ }
268
+
269
+ const macroValues = {
270
+ gdpr: gdpr,
271
+ consent: consentString,
272
+ uspConsent: uspConsentString
273
+ };
274
+
241
275
  serverResponses.forEach(resp => {
242
276
  if (resp.body) {
243
277
  const bidResponse = resp.body;
244
278
  if (bidResponse.ext && Array.isArray(bidResponse.ext['utrk'])) {
245
- bidResponse.ext['utrk'].forEach(pixel => {
246
- const url =
247
- pixel.url +
248
- (pixel.url.indexOf('?') > 0 ? '&' + suffix : '?' + suffix);
249
- return syncs.push({type: pixel.type, url});
250
- });
279
+ bidResponse.ext['utrk']
280
+ .forEach(pixel => {
281
+ const url = replaceMacros(pixel.url, macroValues);
282
+ syncs.push({type: pixel.type, url});
283
+ });
251
284
  }
285
+
252
286
  if (Array.isArray(bidResponse.seatbid)) {
253
287
  bidResponse.seatbid.forEach(seatBid => {
254
288
  if (Array.isArray(seatBid.bid)) {
255
289
  seatBid.bid.forEach(bid => {
256
290
  if (bid.ext && Array.isArray(bid.ext['utrk'])) {
257
- bid.ext['utrk'].forEach(pixel => {
258
- const url =
259
- pixel.url +
260
- (pixel.url.indexOf('?') > 0
261
- ? '&' + suffix
262
- : '?' + suffix);
263
- return syncs.push({type: pixel.type, url});
264
- });
291
+ bid.ext['utrk']
292
+ .forEach(pixel => {
293
+ const url = replaceMacros(pixel.url, macroValues);
294
+ syncs.push({type: pixel.type, url});
295
+ });
265
296
  }
266
297
  });
267
298
  }
@@ -269,18 +300,16 @@ export const spec = {
269
300
  }
270
301
  }
271
302
  });
303
+
272
304
  return syncs;
273
305
  }
274
306
  };
275
307
 
276
308
  function newRenderer(bidRequest, bid, rendererOptions = {}) {
277
309
  const renderer = Renderer.install({
278
- url:
279
- (bidRequest.params && bidRequest.params.rendererUrl) ||
280
- (bid.ext && bid.ext.renderer_url) ||
281
- 'https://s.wlplayer.com/video/latest/renderer.js',
310
+ url: (bidRequest.params && bidRequest.params.rendererUrl) || (bid.ext && bid.ext.renderer_url) || 'https://s.gamoshi.io/video/latest/renderer.js',
282
311
  config: rendererOptions,
283
- loaded: false
312
+ loaded: false,
284
313
  });
285
314
  try {
286
315
  renderer.setRender(renderOutstream);
@@ -300,10 +329,9 @@ function renderOutstream(bid) {
300
329
  width: bid.width,
301
330
  height: bid.height,
302
331
  events: {
303
- ALL_ADS_COMPLETED: () =>
304
- window.setTimeout(() => {
305
- window['GamoshiPlayer'].removeAd(unitId);
306
- }, 300)
332
+ ALL_ADS_COMPLETED: () => window.setTimeout(() => {
333
+ window['GamoshiPlayer'].removeAd(unitId);
334
+ }, 300)
307
335
  },
308
336
  vastUrl: bid.vastUrl,
309
337
  vastXml: bid.vastXml
@@ -311,4 +339,41 @@ function renderOutstream(bid) {
311
339
  });
312
340
  }
313
341
 
342
+ function addExternalUserId(eids, value, source, rtiPartner) {
343
+ if (isStr(value)) {
344
+ eids.push({
345
+ source,
346
+ uids: [{
347
+ id: value,
348
+ ext: {
349
+ rtiPartner
350
+ }
351
+ }]
352
+ });
353
+ }
354
+ }
355
+
356
+ function replaceMacros(url, macros) {
357
+ return url
358
+ .replace('[GDPR]', macros.gdpr)
359
+ .replace('[CONSENT]', macros.consent)
360
+ .replace('[US_PRIVACY]', macros.uspConsent);
361
+ }
362
+
363
+ function getGdprConsent(bidderRequest) {
364
+ const gdprConsent = bidderRequest.gdprConsent;
365
+
366
+ if (gdprConsent && gdprConsent.consentString && gdprConsent.gdprApplies) {
367
+ return {
368
+ consent_string: gdprConsent.consentString,
369
+ consent_required: gdprConsent.gdprApplies
370
+ };
371
+ }
372
+
373
+ return {
374
+ consent_required: false,
375
+ consent_string: '',
376
+ };
377
+ }
378
+
314
379
  registerBidder(spec);
@@ -1,45 +1,49 @@
1
1
  # Overview
2
2
 
3
3
  ```
4
- Module Name: Clean Media Net Adapter
4
+ Module Name: CleanMedia Bid Adapter
5
5
  Module Type: Bidder Adapter
6
- Maintainer: dev@cleanmedia.net
6
+ Maintainer: dev@CleanMedia.net
7
7
  ```
8
8
 
9
9
  # Description
10
10
 
11
- Connects to Clean Media Net's Programmatic advertising platform as a service.
11
+ Connects to CleanMedia's Programmatic advertising platform as a service.
12
12
 
13
- Clean Media bid adapter supports Banner & Video (Instream and Outstream).
14
- The *only* required parameter (in the `params` section) is the `supplyPartnerId` parameter.
13
+ CleanMedia bid adapter supports Banner & Outstream Video. The *only* required parameter (in the `params` section) is the `supplyPartnerId` parameter.
15
14
 
16
15
  # Test Parameters
17
16
  ```
18
17
  var adUnits = [
19
- // Banner adUnit
18
+
19
+ // Banner adUnit
20
20
  {
21
21
  code: 'banner-div',
22
22
  sizes: [[300, 250]],
23
23
  bids: [{
24
24
  bidder: 'cleanmedianet',
25
25
  params: {
26
- // ID of the supply partner you created in the Clean Media Net dashboard
26
+
27
+ // ID of the supply partner you created in the CleanMedia dashboard
27
28
  supplyPartnerId: '1253',
28
- // OPTIONAL: custom bid floor
29
+
30
+ // OPTIONAL: custom bid floor
29
31
  bidfloor: 0.01,
30
- // OPTIONAL: if you know the ad position on the page, specify it here
32
+
33
+ // OPTIONAL: if you know the ad position on the page, specify it here
31
34
  // (this corresponds to "Ad Position" in OpenRTB 2.3, section 5.4)
32
35
  //adpos: 1,
33
- // OPTIONAL: whether this is an interstitial placement (0 or 1)
36
+
37
+ // OPTIONAL: whether this is an interstitial placement (0 or 1)
34
38
  // (see "instl" property in "Imp" object in the OpenRTB 2.3, section 3.2.2)
35
39
  //instl: 0
36
40
  }
37
41
  }]
38
42
  },
39
- // Video outstream adUnit
43
+
44
+ // Video outstream adUnit
40
45
  {
41
46
  code: 'video-outstream',
42
- sizes: [[300, 250]],
43
47
  mediaTypes: {
44
48
  video: {
45
49
  context: 'outstream',
@@ -47,20 +51,62 @@ var adUnits = [
47
51
  }
48
52
  },
49
53
  bids: [ {
50
- bidder: 'cleanmedianet',
54
+ bidder: 'CleanMedia',
51
55
  params: {
52
- // ID of the supply partner you created in the dashboard
56
+
57
+ // ID of the supply partner you created in the dashboard
53
58
  supplyPartnerId: '1254',
54
- // OPTIONAL: custom bid floor
59
+
60
+ // OPTIONAL: custom bid floor
55
61
  bidfloor: 0.01,
56
- // OPTIONAL: if you know the ad position on the page, specify it here
62
+
63
+ // OPTIONAL: if you know the ad position on the page, specify it here
57
64
  // (this corresponds to "Ad Position" in OpenRTB 2.3, section 5.4)
58
65
  //adpos: 1,
59
- // OPTIONAL: whether this is an interstitial placement (0 or 1)
66
+
67
+ // OPTIONAL: whether this is an interstitial placement (0 or 1)
60
68
  // (see "instl" property in "Imp" object in the OpenRTB 2.3, section 3.2.2)
61
69
  //instl: 0
62
70
  }
63
71
  }]
64
- }
72
+ },
73
+
74
+ // Multi-Format adUnit
75
+ {
76
+ code: 'banner-div',
77
+ mediaTypes: {
78
+ video: {
79
+ context: 'outstream',
80
+ playerSize: [300, 250]
81
+ },
82
+ banner: {
83
+ sizes: [[300, 250]]
84
+ }
85
+ },
86
+ bids: [{
87
+ bidder: 'CleanMedia',
88
+ params: {
89
+
90
+ // ID of the supply partner you created in the CleanMedia dashboard
91
+ supplyPartnerId: '1253',
92
+
93
+ // OPTIONAL: custom bid floor
94
+ bidfloor: 0.01,
95
+
96
+ // OPTIONAL: if you know the ad position on the page, specify it here
97
+ // (this corresponds to "Ad Position" in OpenRTB 2.3, section 5.4)
98
+ //adpos: 1,
99
+
100
+ // OPTIONAL: whether this is an interstitial placement (0 or 1)
101
+ // (see "instl" property in "Imp" object in the OpenRTB 2.3, section 3.2.2)
102
+ //instl: 0,
103
+
104
+ // OPTIONAL: enable enforcement bids of a specific media type (video, banner)
105
+ // in this ad placement
106
+ // query: 'key1=value1&k2=value2',
107
+ // favoredMediaType: 'video',
108
+ }
109
+ }]
110
+ },
65
111
  ];
66
112
  ```
@@ -142,6 +142,10 @@ export const spec = {
142
142
  }
143
143
 
144
144
  if (bidderRequest) {
145
+ if (bidderRequest.timeout) {
146
+ deepSetValue(payload, 'tmax', bidderRequest.timeout);
147
+ }
148
+
145
149
  // Add GDPR flag and consent string
146
150
  if (bidderRequest.gdprConsent) {
147
151
  userExt.consent = bidderRequest.gdprConsent.consentString;
@@ -12,6 +12,7 @@ import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../src/adapterM
12
12
  import * as events from '../src/events.js';
13
13
  import CONSTANTS from '../src/constants.json';
14
14
  import {getPPID} from '../src/adserver.js';
15
+ import {getRefererInfo} from '../src/refererDetection.js';
15
16
 
16
17
  /**
17
18
  * @typedef {Object} DfpVideoParams
@@ -52,6 +53,10 @@ const defaultParamConstants = {
52
53
 
53
54
  export const adpodUtils = {};
54
55
 
56
+ export const dep = {
57
+ ri: getRefererInfo
58
+ }
59
+
55
60
  /**
56
61
  * Merge all the bid data and publisher-supplied options into a single URL, and then return it.
57
62
  *
@@ -259,14 +264,7 @@ function buildUrlFromAdserverUrlComponents(components, bid, options) {
259
264
  * @return {string | undefined} The encoded vast url if it exists, or undefined
260
265
  */
261
266
  function getDescriptionUrl(bid, components, prop) {
262
- if (config.getConfig('cache.url')) { return; }
263
-
264
- if (!deepAccess(components, `${prop}.description_url`)) {
265
- const vastUrl = bid && bid.vastUrl;
266
- if (vastUrl) { return encodeURIComponent(vastUrl); }
267
- } else {
268
- logError(`input cannnot contain description_url`);
269
- }
267
+ return deepAccess(components, `${prop}.description_url`) || dep.ri().page;
270
268
  }
271
269
 
272
270
  /**
@@ -293,6 +291,8 @@ function getCustParams(bid, options, urlCustParams) {
293
291
  allTargetingData,
294
292
  adserverTargeting,
295
293
  );
294
+
295
+ // TODO: WTF is this? just firing random events, guessing at the argument, hoping noone notices?
296
296
  events.emit(CONSTANTS.EVENTS.SET_TARGETING, {[adUnit.code]: prebidTargetingSet});
297
297
 
298
298
  // merge the prebid + publisher targeting sets
@@ -350,6 +350,7 @@ export const spec = {
350
350
  timestamp: timeInMillis,
351
351
  _fw_bidfloor: (bidfloor > 0) ? bidfloor : 0,
352
352
  _fw_bidfloorcur: (bidfloor > 0) ? getFloorCurrency(config) : '',
353
+ pbjs_version: '$prebid.version$',
353
354
  pKey: keyCode
354
355
  };
355
356
 
@@ -381,6 +382,14 @@ export const spec = {
381
382
  }
382
383
  }
383
384
 
385
+ if (currentBidRequest.userIdAsEids && currentBidRequest.userIdAsEids.length > 0) {
386
+ try {
387
+ requestParams._fw_prebid_3p_UID = JSON.stringify(currentBidRequest.userIdAsEids);
388
+ } catch (error) {
389
+ logWarn('PREBID - ' + BIDDER_CODE + ': Unable to stringify the userIdAsEids: ' + error);
390
+ }
391
+ }
392
+
384
393
  var vastParams = currentBidRequest.params.vastUrlParams;
385
394
  if (typeof vastParams === 'object') {
386
395
  for (var key in vastParams) {