prebid.js 7.6.0 → 7.7.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 (159) hide show
  1. package/dist/1plusXRtdProvider.js +1 -0
  2. package/dist/33acrossBidAdapter.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/adoceanBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/ajaBidAdapter.js +1 -1
  10. package/dist/amxBidAdapter.js +1 -1
  11. package/dist/amxIdSystem.js +1 -1
  12. package/dist/appierAnalyticsAdapter.js +1 -1
  13. package/dist/appnexusBidAdapter.js +1 -1
  14. package/dist/asoBidAdapter.js +1 -1
  15. package/dist/axonixBidAdapter.js +1 -1
  16. package/dist/bidglassBidAdapter.js +1 -1
  17. package/dist/big-richmediaBidAdapter.js +1 -1
  18. package/dist/bliinkBidAdapter.js +1 -1
  19. package/dist/bridgewellBidAdapter.js +1 -1
  20. package/dist/brightMountainMediaBidAdapter.js +1 -1
  21. package/dist/concertBidAdapter.js +1 -1
  22. package/dist/connectadBidAdapter.js +1 -1
  23. package/dist/consumableBidAdapter.js +1 -1
  24. package/dist/conversantBidAdapter.js +1 -1
  25. package/dist/craftBidAdapter.js +1 -1
  26. package/dist/criteoBidAdapter.js +1 -1
  27. package/dist/currency.js +1 -1
  28. package/dist/dspxBidAdapter.js +1 -1
  29. package/dist/eplanningBidAdapter.js +1 -1
  30. package/dist/finativeBidAdapter.js +1 -1
  31. package/dist/glimpseBidAdapter.js +1 -1
  32. package/dist/gmosspBidAdapter.js +1 -1
  33. package/dist/goldbachBidAdapter.js +1 -1
  34. package/dist/gridBidAdapter.js +1 -1
  35. package/dist/gridNMBidAdapter.js +1 -1
  36. package/dist/gumgumBidAdapter.js +1 -1
  37. package/dist/h12mediaBidAdapter.js +1 -1
  38. package/dist/id5IdSystem.js +1 -1
  39. package/dist/impactifyBidAdapter.js +1 -1
  40. package/dist/improvedigitalBidAdapter.js +1 -1
  41. package/dist/inmarBidAdapter.js +1 -1
  42. package/dist/insticatorBidAdapter.js +1 -1
  43. package/dist/ixBidAdapter.js +1 -1
  44. package/dist/jixieBidAdapter.js +1 -1
  45. package/dist/justpremiumBidAdapter.js +1 -1
  46. package/dist/konduitAnalyticsAdapter.js +1 -1
  47. package/dist/kueezBidAdapter.js +1 -1
  48. package/dist/lassoBidAdapter.js +1 -1
  49. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  50. package/dist/logicadBidAdapter.js +1 -1
  51. package/dist/loglyliftBidAdapter.js +1 -1
  52. package/dist/malltvAnalyticsAdapter.js +1 -1
  53. package/dist/marsmediaBidAdapter.js +1 -1
  54. package/dist/mediafuseBidAdapter.js +1 -1
  55. package/dist/mediasquareBidAdapter.js +1 -1
  56. package/dist/mgidBidAdapter.js +1 -1
  57. package/dist/minutemediaBidAdapter.js +1 -1
  58. package/dist/naveggIdSystem.js +1 -1
  59. package/dist/not-for-prod/prebid.js +112 -111
  60. package/dist/oguryBidAdapter.js +1 -1
  61. package/dist/onetagBidAdapter.js +1 -1
  62. package/dist/ooloAnalyticsAdapter.js +1 -1
  63. package/dist/outbrainBidAdapter.js +1 -1
  64. package/dist/parrableIdSystem.js +1 -1
  65. package/dist/pixfutureBidAdapter.js +1 -1
  66. package/dist/prebid-core.js +1 -1
  67. package/dist/prebidServerBidAdapter.js +1 -1
  68. package/dist/publinkIdSystem.js +1 -1
  69. package/dist/pubmaticBidAdapter.js +1 -1
  70. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  71. package/dist/pxyzBidAdapter.js +1 -1
  72. package/dist/quantcastBidAdapter.js +1 -1
  73. package/dist/readpeakBidAdapter.js +1 -1
  74. package/dist/relaidoBidAdapter.js +1 -1
  75. package/dist/rhythmoneBidAdapter.js +1 -1
  76. package/dist/riseBidAdapter.js +1 -1
  77. package/dist/rubiconAnalyticsAdapter.js +1 -1
  78. package/dist/rubiconBidAdapter.js +1 -1
  79. package/dist/seedingAllianceBidAdapter.js +1 -1
  80. package/dist/seedtagBidAdapter.js +1 -1
  81. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  82. package/dist/sharethroughBidAdapter.js +1 -1
  83. package/dist/shinezBidAdapter.js +1 -1
  84. package/dist/smaatoBidAdapter.js +1 -1
  85. package/dist/smartadserverBidAdapter.js +1 -1
  86. package/dist/smartxBidAdapter.js +1 -1
  87. package/dist/smilewantedBidAdapter.js +1 -1
  88. package/dist/sonobiBidAdapter.js +1 -1
  89. package/dist/sovrnAnalyticsAdapter.js +1 -1
  90. package/dist/sovrnBidAdapter.js +1 -1
  91. package/dist/sspBCBidAdapter.js +1 -1
  92. package/dist/sublimeBidAdapter.js +1 -1
  93. package/dist/synacormediaBidAdapter.js +1 -1
  94. package/dist/targetVideoBidAdapter.js +1 -1
  95. package/dist/teadsBidAdapter.js +1 -1
  96. package/dist/trionBidAdapter.js +1 -1
  97. package/dist/tripleliftBidAdapter.js +1 -1
  98. package/dist/ttdBidAdapter.js +1 -1
  99. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  100. package/dist/underdogmediaBidAdapter.js +1 -1
  101. package/dist/undertoneBidAdapter.js +1 -1
  102. package/dist/userId.js +1 -1
  103. package/dist/vidazooBidAdapter.js +1 -1
  104. package/dist/videobyteBidAdapter.js +1 -1
  105. package/dist/visxBidAdapter.js +1 -1
  106. package/dist/vuukleBidAdapter.js +1 -1
  107. package/dist/widespaceBidAdapter.js +1 -1
  108. package/dist/winrBidAdapter.js +1 -1
  109. package/dist/yahoosspBidAdapter.js +1 -1
  110. package/dist/yieldmoBidAdapter.js +1 -1
  111. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  112. package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
  113. package/modules/.submodules.json +2 -1
  114. package/modules/1plusXRtdProvider.js +251 -0
  115. package/modules/1plusXRtdProvider.md +65 -0
  116. package/modules/adoceanBidAdapter.js +10 -3
  117. package/modules/big-richmediaBidAdapter.js +3 -3
  118. package/modules/bliinkBidAdapter.js +120 -193
  119. package/modules/bliinkBidAdapter.md +2 -5
  120. package/modules/consumableBidAdapter.js +9 -0
  121. package/modules/currency.js +2 -2
  122. package/modules/impactifyBidAdapter.js +6 -2
  123. package/modules/ixBidAdapter.js +61 -14
  124. package/modules/ixBidAdapter.md +2 -5
  125. package/modules/jixieBidAdapter.js +10 -10
  126. package/modules/naveggIdSystem.js +1 -12
  127. package/modules/nextMillenniumBidAdapter.md +1 -1
  128. package/modules/onetagBidAdapter.js +44 -7
  129. package/modules/prebidServerBidAdapter/index.js +7 -0
  130. package/modules/rubiconBidAdapter.js +5 -0
  131. package/modules/seedingAllianceBidAdapter.js +3 -0
  132. package/modules/targetVideoBidAdapter.js +18 -0
  133. package/modules/userId/index.js +39 -21
  134. package/package.json +1 -1
  135. package/src/auction.js +6 -5
  136. package/src/consentHandler.js +11 -11
  137. package/src/debugging.js +5 -3
  138. package/src/hook.js +2 -2
  139. package/src/utils/promise.js +96 -21
  140. package/src/utils.js +3 -2
  141. package/test/helpers/consentData.js +2 -1
  142. package/test/spec/auctionmanager_spec.js +1 -6
  143. package/test/spec/debugging_spec.js +2 -2
  144. package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
  145. package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
  146. package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
  147. package/test/spec/modules/consumableBidAdapter_spec.js +47 -1
  148. package/test/spec/modules/idxIdSystem_spec.js +1 -1
  149. package/test/spec/modules/ixBidAdapter_spec.js +77 -2
  150. package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
  151. package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
  152. package/test/spec/modules/parrableIdSystem_spec.js +2 -1
  153. package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
  154. package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
  155. package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
  156. package/test/spec/modules/userId_spec.js +15 -2
  157. package/test/spec/unit/pbjs_api_spec.js +1 -5
  158. package/test/spec/unit/utils/promise_spec.js +283 -38
  159. package/test/helpers/syncPromise.js +0 -71
@@ -1,10 +1,12 @@
1
1
  // eslint-disable-next-line prebid/validate-imports
2
2
  // eslint-disable-next-line prebid/validate-imports
3
- import {registerBidder} from '../src/adapters/bidderFactory.js'
3
+ import { registerBidder } from '../src/adapters/bidderFactory.js'
4
+ import { config } from '../src/config.js'
5
+ import {_each, deepAccess, deepSetValue} from '../src/utils.js'
4
6
  export const BIDDER_CODE = 'bliink'
5
- export const BLIINK_ENDPOINT_ENGINE = 'https://engine.bliink.io/delivery'
6
- export const BLIINK_ENDPOINT_ENGINE_VAST = 'https://engine.bliink.io/vast'
7
- export const BLIINK_ENDPOINT_COOKIE_SYNC = 'https://cookiesync.api.bliink.io'
7
+ export const BLIINK_ENDPOINT_ENGINE = 'https://engine.bliink.io/prebid'
8
+
9
+ export const BLIINK_ENDPOINT_COOKIE_SYNC_IFRAME = 'https://tag.bliink.io/usersync.html'
8
10
  export const META_KEYWORDS = 'keywords'
9
11
  export const META_DESCRIPTION = 'description'
10
12
 
@@ -14,6 +16,13 @@ const BANNER = 'banner'
14
16
  const supportedMediaTypes = [BANNER, VIDEO]
15
17
  const aliasBidderCode = ['bk']
16
18
 
19
+ /**
20
+ * @description get coppa value from config
21
+ */
22
+ function getCoppa() {
23
+ return config.getConfig('coppa') === true ? 1 : 0;
24
+ }
25
+
17
26
  export function getMetaList(name) {
18
27
  if (!name || name.length === 0) return []
19
28
 
@@ -52,7 +61,7 @@ export function getOneMetaValue(query) {
52
61
  return metaEl.content
53
62
  }
54
63
 
55
- return null
64
+ return null;
56
65
  }
57
66
 
58
67
  export function getMetaValue(name) {
@@ -75,79 +84,51 @@ export function getKeywords() {
75
84
  ]
76
85
 
77
86
  if (keywords && keywords.length > 0) {
78
- return keywords
79
- .filter((value) => value)
80
- .map((value) => value.trim())
87
+ return keywords.filter((value) => value).map((value) => value.trim());
81
88
  }
82
89
  }
83
90
 
84
- return []
85
- }
86
-
87
- export const parseXML = (content) => {
88
- if (typeof content !== 'string' || content.length === 0) return null
89
-
90
- const parser = new DOMParser()
91
- let xml;
92
-
93
- try {
94
- xml = parser.parseFromString(content, 'text/xml')
95
- } catch (e) {}
96
-
97
- if (xml &&
98
- xml.getElementsByTagName('VAST')[0] &&
99
- xml.getElementsByTagName('VAST')[0].tagName === 'VAST') {
100
- return xml
101
- }
102
-
103
- return null
91
+ return [];
104
92
  }
105
93
 
106
94
  /**
107
95
  * @param bidRequest
108
- * @param bliinkCreative
109
- * @return {{cpm, netRevenue: boolean, requestId, width: (*|number), currency, ttl: number, creativeId, height: (*|number)} & {mediaType: string, vastXml}}
96
+ * @return {({cpm, netRevenue: boolean, requestId, width: number, currency, ttl: number, creativeId, height: number}&{mediaType: string, vastXml})|null}
110
97
  */
111
- export const buildBid = (bidRequest, bliinkCreative) => {
112
- if (!bidRequest && !bliinkCreative) return null
113
-
114
- const body = {
115
- requestId: bidRequest.bidId,
116
- currency: bliinkCreative.currency,
117
- cpm: bliinkCreative.price,
118
- creativeId: bliinkCreative.creativeId,
119
- width: (bidRequest.sizes && bidRequest.sizes[0][0]) || 1,
120
- height: (bidRequest.sizes && bidRequest.sizes[0][1]) || 1,
121
- netRevenue: false,
122
- ttl: 3600,
123
- }
124
-
125
- // eslint-disable-next-line no-mixed-operators
126
- if ((bliinkCreative) && bidRequest &&
127
- // eslint-disable-next-line no-mixed-operators
128
- !bidRequest.bidId ||
129
- !bidRequest.sizes ||
130
- !bidRequest.params ||
131
- !(bidRequest.params.placement)
132
- ) return null
133
-
134
- delete bidRequest['bids']
98
+ export const buildBid = (bidResponse) => {
99
+ const mediaType = deepAccess(bidResponse, 'creative.media_type')
100
+ if (!mediaType) return null;
135
101
 
136
- switch (bliinkCreative.media_type) {
102
+ let bid;
103
+ switch (mediaType) {
137
104
  case VIDEO:
138
- return Object.assign(body, {
139
- mediaType: VIDEO,
140
- vastXml: bliinkCreative.content,
141
- })
105
+ const vastXml = deepAccess(bidResponse, 'creative.video.content');
106
+ bid = {
107
+ vastXml,
108
+ mediaType: 'video',
109
+ vastUrl: 'data:text/xml;charset=utf-8;base64,' + btoa(vastXml.replace(/\\"/g, '"'))
110
+ };
111
+ break;
142
112
  case BANNER:
143
- return Object.assign(body, {
144
- mediaType: BANNER,
145
- ad: (bliinkCreative && bliinkCreative.content && bliinkCreative.content.creative && bliinkCreative.content.creative.adm) || '',
146
- })
147
- default:
113
+ bid = {
114
+ ad: deepAccess(bidResponse, 'creative.banner.adm'),
115
+ mediaType: 'banner',
116
+ };
148
117
  break;
118
+ default:
119
+ return null;
149
120
  }
150
- }
121
+ return Object.assign(bid, {
122
+ cpm: bidResponse.price,
123
+ currency: bidResponse.currency || 'EUR',
124
+ creativeId: deepAccess(bidResponse, 'extras.deal_id'),
125
+ requestId: deepAccess(bidResponse, 'extras.transaction_id'),
126
+ width: deepAccess(bidResponse, `creative.${bid.mediaType}.width`) || 1,
127
+ height: deepAccess(bidResponse, `creative.${bid.mediaType}.height`) || 1,
128
+ ttl: 3600,
129
+ netRevenue: true,
130
+ });
131
+ };
151
132
 
152
133
  /**
153
134
  * @description Verify the the AdUnits.bids, respond with true (valid) or false (invalid).
@@ -156,61 +137,58 @@ export const buildBid = (bidRequest, bliinkCreative) => {
156
137
  * @return boolean
157
138
  */
158
139
  export const isBidRequestValid = (bid) => {
159
- return !(!bid || !bid.params || !bid.params.placement || !bid.params.tagId)
160
- }
140
+ return !!deepAccess(bid, 'params.tagId');
141
+ };
161
142
 
162
143
  /**
163
144
  * @description Takes an array of valid bid requests, all of which are guaranteed to have passed the isBidRequestValid() test.
164
145
  *
165
- * @param _[]
146
+ * @param validBidRequests
166
147
  * @param bidderRequest
167
- * @return {{ method: string, url: string } | null}
148
+ * @returns {null|{method: string, data: {gdprConsent: string, keywords: string, pageTitle: string, pageDescription: (*|string), pageUrl, gdpr: boolean, tags: *}, url: string}}
168
149
  */
169
- export const buildRequests = (_, bidderRequest) => {
170
- if (!bidderRequest) return null
150
+ export const buildRequests = (validBidRequests, bidderRequest) => {
151
+ if (!validBidRequests || !bidderRequest || !bidderRequest.bids) return null
171
152
 
172
- let data = {
173
- pageUrl: bidderRequest.refererInfo.page,
153
+ const tags = bidderRequest.bids.map((bid) => {
154
+ return {
155
+ sizes: bid.sizes.map((size) => ({ w: size[0], h: size[1] })),
156
+ id: bid.params.tagId,
157
+ transactionId: bid.bidId,
158
+ mediaTypes: Object.keys(bid.mediaTypes),
159
+ imageUrl: deepAccess(bid, 'params.imageUrl', ''),
160
+ };
161
+ });
162
+
163
+ let request = {
164
+ tags,
165
+ pageTitle: document.title,
166
+ pageUrl: deepAccess(bidderRequest, 'refererInfo.page'),
174
167
  pageDescription: getMetaValue(META_DESCRIPTION),
175
168
  keywords: getKeywords().join(','),
176
- gdpr: false,
177
- gdpr_consent: '',
178
- pageTitle: document.title,
169
+ };
170
+ const schain = deepAccess(validBidRequests[0], 'schain')
171
+ if (schain) {
172
+ request.schain = schain
179
173
  }
180
-
181
- const endPoint = bidderRequest.bids[0].params.placement === VIDEO ? BLIINK_ENDPOINT_ENGINE_VAST : BLIINK_ENDPOINT_ENGINE
182
-
183
- const params = {
184
- bidderRequestId: bidderRequest.bidderRequestId,
185
- bidderCode: bidderRequest.bidderCode,
186
- bids: bidderRequest.bids,
187
- // TODO: please do not send internal data structures over the network
188
- refererInfo: bidderRequest.refererInfo.legacy,
174
+ const gdprConsent = deepAccess(bidderRequest, 'gdprConsent');
175
+ if (!!gdprConsent && gdprConsent.gdprApplies) {
176
+ request.gdpr = true
177
+ deepSetValue(request, 'gdprConsent', gdprConsent.consentString);
189
178
  }
190
-
191
- if (bidderRequest.gdprConsent) {
192
- data = Object.assign(data, {
193
- gdpr: bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies,
194
- gdpr_consent: bidderRequest.gdprConsent.consentString
195
- })
179
+ if (config.getConfig('coppa')) {
180
+ request.coppa = 1
196
181
  }
197
-
198
- if (bidderRequest.bids && bidderRequest.bids.length > 0 && bidderRequest.bids[0].sizes && bidderRequest.bids[0].sizes[0]) {
199
- data = Object.assign(data, {
200
- width: bidderRequest.bids[0].sizes[0][0],
201
- height: bidderRequest.bids[0].sizes[0][1]
202
- })
203
-
204
- return {
205
- method: 'GET',
206
- url: `${endPoint}/${bidderRequest.bids[0].params.tagId}`,
207
- data: data,
208
- params: params,
209
- }
182
+ if (bidderRequest.uspConsent) {
183
+ deepSetValue(request, 'uspConsent', bidderRequest.uspConsent);
210
184
  }
211
185
 
212
- return null
213
- }
186
+ return {
187
+ method: 'POST',
188
+ url: BLIINK_ENDPOINT_ENGINE,
189
+ data: request,
190
+ };
191
+ };
214
192
 
215
193
  /**
216
194
  * @description Parse the response (from buildRequests) and generate one or more bid objects.
@@ -219,51 +197,15 @@ export const buildRequests = (_, bidderRequest) => {
219
197
  * @param request
220
198
  * @return
221
199
  */
222
- const interpretResponse = (serverResponse, request) => {
223
- if ((serverResponse && serverResponse.mode === 'no-ad')) {
224
- return []
225
- }
226
-
227
- const body = serverResponse.body
228
- const serverBody = request.params
229
-
230
- const xml = parseXML(body)
231
-
232
- let creative;
233
-
234
- switch (serverBody.bids[0].params.placement) {
235
- case xml && VIDEO:
236
- const price = xml.getElementsByTagName('Price') && xml.getElementsByTagName('Price')[0]
237
- const currency = xml.getElementsByTagName('Currency') && xml.getElementsByTagName('Currency')[0]
238
- const creativeId = xml.getElementsByTagName('CreativeId') && xml.getElementsByTagName('CreativeId')[0]
239
-
240
- creative = {
241
- content: body,
242
- price: (price && price.textContent) || 0,
243
- currency: (currency && currency.textContent) || 'EUR',
244
- creativeId: creativeId || 0,
245
- media_type: 'video',
246
- }
247
-
248
- return buildBid(serverBody.bids[0], creative)
249
- case BANNER:
250
- if (body) {
251
- creative = {
252
- content: body,
253
- price: body.price,
254
- currency: body.currency,
255
- creativeId: 0,
256
- media_type: 'banner',
257
- }
258
-
259
- return buildBid(serverBody.bids[0], creative)
260
- }
261
-
262
- break
263
- default:
264
- break
265
- }
266
- }
200
+ const interpretResponse = (serverResponse) => {
201
+ const bodyResponse = deepAccess(serverResponse, 'body.bids')
202
+ if (!serverResponse.body || !bodyResponse) return []
203
+ const bidResponses = [];
204
+ _each(bodyResponse, function (response) {
205
+ return bidResponses.push(buildBid(response));
206
+ });
207
+ return bidResponses.filter(bid => !!bid)
208
+ };
267
209
 
268
210
  /**
269
211
  * @description If the publisher allows user-sync activity, the platform will call this function and the adapter may register pixels and/or iframe user syncs. For more information, see Registering User Syncs below
@@ -272,54 +214,39 @@ const interpretResponse = (serverResponse, request) => {
272
214
  * @param gdprConsent
273
215
  * @return {[{type: string, url: string}]|*[]}
274
216
  */
275
- const getUserSyncs = (syncOptions, serverResponses, gdprConsent) => {
276
- let syncs = []
277
-
217
+ const getUserSyncs = (syncOptions, serverResponses, gdprConsent, uspConsent) => {
218
+ let syncs = [];
278
219
  if (syncOptions.pixelEnabled && serverResponses.length > 0) {
220
+ let gdprParams = ''
221
+ let uspConsentStr = ''
222
+ let apiVersion
223
+ let gdpr = false
279
224
  if (gdprConsent) {
280
- const gdprParams = `consentString=${gdprConsent.consentString}`
281
- const smartCallbackURL = encodeURIComponent(`${BLIINK_ENDPOINT_COOKIE_SYNC}/cookiesync?partner=smart&uid=[sas_uid]`)
282
- const azerionCallbackURL = encodeURIComponent(`${BLIINK_ENDPOINT_COOKIE_SYNC}/cookiesync?partner=azerion&uid={PUB_USER_ID}`)
283
- const appnexusCallbackURL = encodeURIComponent(`${BLIINK_ENDPOINT_COOKIE_SYNC}/cookiesync?partner=azerion&uid=$UID`)
284
- return [
285
- {
286
- type: 'script',
287
- url: 'https://prg.smartadserver.com/ac?out=js&nwid=3392&siteid=305791&pgname=rg&fmtid=81127&tgt=[sas_target]&visit=m&tmstp=[timestamp]&clcturl=[countgo]'
288
- },
289
- {
290
- type: 'image',
291
- url: `https://sync.smartadserver.com/getuid?nwid=3392&${gdprParams}&url=${smartCallbackURL}`,
292
- },
293
- {
294
- type: 'image',
295
- url: `https://ad.360yield.com/server_match?partner_id=1531&${gdprParams}&r=${azerionCallbackURL}`,
296
- },
297
- {
298
- type: 'image',
299
- url: `https://ads.stickyadstv.com/auto-user-sync?${gdprParams}`,
300
- },
301
- {
302
- type: 'image',
303
- url: `https://cookiesync.api.bliink.io/getuid?url=https%3A%2F%2Fvisitor.omnitagjs.com%2Fvisitor%2Fsync%3Fuid%3D1625272249969090bb9d544bd6d8d645%26name%3DBLIINK%26visitor%3D%24UID%26external%3Dtrue&${gdprParams}`,
304
- },
305
- {
306
- type: 'image',
307
- url: `https://cookiesync.api.bliink.io/getuid?url=https://pixel.advertising.com/ups/58444/sync?&gdpr=1&gdpr_consent=${gdprConsent.consentString}&redir=true&uid=$UID`,
308
- },
309
- {
310
- type: 'image',
311
- url: `https://ups.analytics.yahoo.com/ups/58499/occ?gdpr=1&gdpr_consent=${gdprConsent.consentString}`,
312
- },
225
+ gdprParams = `&gdprConsent=${gdprConsent.consentString}`;
226
+ apiVersion = `&apiVersion=${gdprConsent.apiVersion}`
227
+ gdpr = Number(
228
+ gdprConsent.gdprApplies)
229
+ }
230
+ if (uspConsent) {
231
+ uspConsentStr = `&uspConsent=${uspConsent}`;
232
+ }
233
+ let sync;
234
+ if (syncOptions.iframeEnabled) {
235
+ sync = [
313
236
  {
314
- type: 'image',
315
- url: `https://secure.adnxs.com/getuid?${appnexusCallbackURL}`,
237
+ type: 'iframe',
238
+ url: `${BLIINK_ENDPOINT_COOKIE_SYNC_IFRAME}?gdpr=${gdpr}&coppa=${getCoppa()}${uspConsentStr}${gdprParams}${apiVersion}`,
316
239
  },
317
- ]
240
+ ];
241
+ } else {
242
+ sync = deepAccess(serverResponses[0], 'body.userSyncs');
318
243
  }
244
+
245
+ return sync;
319
246
  }
320
247
 
321
248
  return syncs;
322
- }
249
+ };
323
250
 
324
251
  /**
325
252
  * @type {{interpretResponse: interpretResponse, code: string, aliases: string[], getUserSyncs: getUserSyncs, buildRequests: buildRequests, onTimeout: onTimeout, onSetTargeting: onSetTargeting, isBidRequestValid: isBidRequestValid, onBidWon: onBidWon}}
@@ -332,6 +259,6 @@ export const spec = {
332
259
  buildRequests,
333
260
  interpretResponse,
334
261
  getUserSyncs,
335
- }
262
+ };
336
263
 
337
- registerBidder(spec)
264
+ registerBidder(spec);
@@ -3,10 +3,10 @@
3
3
  ```
4
4
  Module Name: BLIINK Bidder Adapter
5
5
  Module Type: Bidder Adapter
6
- Maintainer: samuel@bliink.io | jonathan@bliink.io
6
+ Maintainer: samuel@bliink.io | ibrahima@bliink.io
7
7
  gdpr_supported: true
8
8
  tcf2_supported: true
9
- media_types: banner, native, video
9
+ media_types: banner, video
10
10
  ```
11
11
 
12
12
  # Description
@@ -30,7 +30,6 @@ const adUnits = [
30
30
  {
31
31
  bidder: 'bliink',
32
32
  params: {
33
- placement: 'banner',
34
33
  tagId: '41'
35
34
  }
36
35
  }
@@ -58,7 +57,6 @@ const adUnits = [
58
57
  bidder: 'bliink',
59
58
  params: {
60
59
  tagId: '41',
61
- placement: 'video',
62
60
  }
63
61
  }
64
62
  ]
@@ -85,7 +83,6 @@ const adUnits = [
85
83
  bidder: 'bliink',
86
84
  params: {
87
85
  tagId: '41',
88
- placement: 'video',
89
86
  }
90
87
  }
91
88
  ]
@@ -1,4 +1,5 @@
1
1
  import { logWarn, createTrackPixelHtml, deepAccess, isArray, deepSetValue } from '../src/utils.js';
2
+ import {config} from '../src/config.js';
2
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
4
 
4
5
  const BIDDER_CODE = 'consumable';
@@ -66,6 +67,14 @@ export const spec = {
66
67
  data.ccpa = bidderRequest.uspConsent;
67
68
  }
68
69
 
70
+ if (bidderRequest && bidderRequest.schain) {
71
+ data.schain = bidderRequest.schain;
72
+ }
73
+
74
+ if (config.getConfig('coppa')) {
75
+ data.coppa = true;
76
+ }
77
+
69
78
  validBidRequests.map(bid => {
70
79
  const sizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes || [];
71
80
  const placement = Object.assign({
@@ -5,7 +5,7 @@ import CONSTANTS from '../src/constants.json';
5
5
  import { ajax } from '../src/ajax.js';
6
6
  import { config } from '../src/config.js';
7
7
  import { getHook } from '../src/hook.js';
8
- import {promiseControls} from '../src/utils/promise.js';
8
+ import {defer} from '../src/utils/promise.js';
9
9
 
10
10
  const DEFAULT_CURRENCY_RATE_URL = 'https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json?date=$$TODAY$$';
11
11
  const CURRENCY_RATE_PRECISION = 4;
@@ -24,7 +24,7 @@ var defaultRates;
24
24
  export const ready = (() => {
25
25
  let ctl;
26
26
  function reset() {
27
- ctl = promiseControls();
27
+ ctl = defer();
28
28
  }
29
29
  reset();
30
30
  return {done: () => ctl.resolve(), reset, promise: () => ctl.promise}
@@ -37,9 +37,13 @@ const createOpenRtbRequest = (validBidRequests, bidderRequest) => {
37
37
  source: {tid: bidderRequest.auctionId}
38
38
  };
39
39
 
40
+ // Get the url parameters
41
+ const queryString = window.location.search;
42
+ const urlParams = new URLSearchParams(queryString);
43
+ const checkPrebid = urlParams.get('_checkPrebid');
40
44
  // Force impactify debugging parameter
41
- if (window.localStorage.getItem('_im_db_bidder') != null) {
42
- request.test = Number(window.localStorage.getItem('_im_db_bidder'));
45
+ if (checkPrebid != null) {
46
+ request.test = Number(checkPrebid);
43
47
  }
44
48
 
45
49
  // Set Schain in request
@@ -244,6 +244,8 @@ function bidToVideoImp(bid) {
244
244
  }
245
245
 
246
246
  imp.video = videoParamRef ? deepClone(bid.params.video) : {};
247
+ // populate imp level transactionId
248
+ imp.ext.tid = deepAccess(bid, 'ortb2Imp.ext.tid');
247
249
 
248
250
  // copy all video properties to imp object
249
251
  for (const adUnitProperty in videoAdUnitRef) {
@@ -355,6 +357,9 @@ function bidToNativeImp(bid) {
355
357
  ver: '1.2'
356
358
  };
357
359
 
360
+ // populate imp level transactionId
361
+ imp.ext.tid = deepAccess(bid, 'ortb2Imp.ext.tid');
362
+
358
363
  _applyFloor(bid, imp, NATIVE);
359
364
 
360
365
  return imp;
@@ -1048,9 +1053,14 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
1048
1053
  currentImpressionSize = encodeURIComponent(JSON.stringify({ impressionObjects })).length;
1049
1054
  }
1050
1055
 
1051
- const gpid = impressions[transactionIds[adUnitIndex]].gpid;
1056
+ let gpid = impressions[transactionIds[adUnitIndex]].gpid;
1052
1057
  const dfpAdUnitCode = impressions[transactionIds[adUnitIndex]].dfp_ad_unit_code;
1053
- const tid = impressions[transactionIds[adUnitIndex]].tid
1058
+ const tid = impressions[transactionIds[adUnitIndex]].tid;
1059
+ const divId = impressions[transactionIds[adUnitIndex]].divId;
1060
+
1061
+ if (!gpid && dfpAdUnitCode && divId) {
1062
+ gpid = `${dfpAdUnitCode}#${divId}`
1063
+ }
1054
1064
  if (impressionObjects.length && BANNER in impressionObjects[0]) {
1055
1065
  const { id, banner: { topframe } } = impressionObjects[0];
1056
1066
  const _bannerImpression = {
@@ -1126,6 +1136,21 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
1126
1136
  }
1127
1137
  }
1128
1138
 
1139
+ // add identifiers info to ixDiag
1140
+ const pbaAdSlot = impressions[transactionIds[adUnitIndex]].pbadslot
1141
+ const tagId = impressions[transactionIds[adUnitIndex]].tagId
1142
+ const adUnitCode = impressions[transactionIds[adUnitIndex]].adUnitCode
1143
+ if (pbaAdSlot || tagId || adUnitCode || divId) {
1144
+ const clonedRObject = deepClone(r);
1145
+ const requestSize = `${baseUrl}${parseQueryStringParameters({ ...payload, r: JSON.stringify(clonedRObject) })}`.length;
1146
+ if (requestSize < MAX_REQUEST_SIZE) {
1147
+ r.ext.ixdiag.pbadslot = pbaAdSlot;
1148
+ r.ext.ixdiag.tagid = tagId;
1149
+ r.ext.ixdiag.adunitcode = adUnitCode;
1150
+ r.ext.ixdiag.divId = divId;
1151
+ }
1152
+ }
1153
+
1129
1154
  const isLastAdUnit = adUnitIndex === transactionIds.length - 1;
1130
1155
 
1131
1156
  if (wasAdUnitImpressionsTrimmed || isLastAdUnit) {
@@ -1258,7 +1283,15 @@ function createNativeImps(validBidRequest, nativeImps) {
1258
1283
  nativeImps[validBidRequest.transactionId] = {};
1259
1284
  nativeImps[validBidRequest.transactionId].ixImps = [];
1260
1285
  nativeImps[validBidRequest.transactionId].ixImps.push(imp);
1261
- nativeImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid')
1286
+ nativeImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid');
1287
+ nativeImps[validBidRequest.transactionId].dfp_ad_unit_code = deepAccess(validBidRequest, 'ortb2Imp.ext.data.adserver.adslot');
1288
+ nativeImps[validBidRequest.transactionId].pbadslot = deepAccess(validBidRequest, 'ortb2Imp.ext.data.pbadslot');
1289
+ nativeImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId');
1290
+
1291
+ const adUnitCode = validBidRequest.adUnitCode;
1292
+ const divId = document.getElementById(adUnitCode) ? adUnitCode : getGptSlotInfoForAdUnitCode(adUnitCode).divId;
1293
+ nativeImps[validBidRequest.transactionId].adUnitCode = adUnitCode;
1294
+ nativeImps[validBidRequest.transactionId].divId = divId;
1262
1295
  }
1263
1296
  }
1264
1297
 
@@ -1274,7 +1307,14 @@ function createVideoImps(validBidRequest, videoImps) {
1274
1307
  videoImps[validBidRequest.transactionId].ixImps = [];
1275
1308
  videoImps[validBidRequest.transactionId].ixImps.push(imp);
1276
1309
  videoImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid');
1277
- videoImps[validBidRequest.transactionId].tid = deepAccess(validBidRequest, 'ortb2Imp.ext.tid');
1310
+ videoImps[validBidRequest.transactionId].dfp_ad_unit_code = deepAccess(validBidRequest, 'ortb2Imp.ext.data.adserver.adslot');
1311
+ videoImps[validBidRequest.transactionId].pbadslot = deepAccess(validBidRequest, 'ortb2Imp.ext.data.pbadslot');
1312
+ videoImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId');
1313
+
1314
+ const adUnitCode = validBidRequest.adUnitCode;
1315
+ const divId = document.getElementById(adUnitCode) ? adUnitCode : getGptSlotInfoForAdUnitCode(adUnitCode).divId;
1316
+ videoImps[validBidRequest.transactionId].adUnitCode = adUnitCode;
1317
+ videoImps[validBidRequest.transactionId].divId = divId;
1278
1318
  }
1279
1319
  }
1280
1320
 
@@ -1302,6 +1342,13 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
1302
1342
  bannerImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid');
1303
1343
  bannerImps[validBidRequest.transactionId].dfp_ad_unit_code = deepAccess(validBidRequest, 'ortb2Imp.ext.data.adserver.adslot');
1304
1344
  bannerImps[validBidRequest.transactionId].tid = deepAccess(validBidRequest, 'ortb2Imp.ext.tid');
1345
+ bannerImps[validBidRequest.transactionId].pbadslot = deepAccess(validBidRequest, 'ortb2Imp.ext.data.pbadslot');
1346
+ bannerImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId');
1347
+
1348
+ const adUnitCode = validBidRequest.adUnitCode;
1349
+ const divId = document.getElementById(adUnitCode) ? adUnitCode : getGptSlotInfoForAdUnitCode(adUnitCode).divId;
1350
+ bannerImps[validBidRequest.transactionId].adUnitCode = adUnitCode;
1351
+ bannerImps[validBidRequest.transactionId].divId = divId;
1305
1352
 
1306
1353
  // Create IX imps from params.size
1307
1354
  if (bannerSizeDefined) {
@@ -1610,7 +1657,17 @@ export const spec = {
1610
1657
  }
1611
1658
 
1612
1659
  if (mediaTypeVideoRef && paramsVideoRef) {
1660
+ const videoImp = bidToVideoImp(bid).video;
1613
1661
  const errorList = checkVideoParams(mediaTypeVideoRef, paramsVideoRef);
1662
+ if (deepAccess(bid, 'mediaTypes.video.context') === OUTSTREAM && isIndexRendererPreferred(bid) && videoImp) {
1663
+ const outstreamPlayerSize = [deepAccess(videoImp, 'w'), deepAccess(videoImp, 'h')];
1664
+ const isValidSize = outstreamPlayerSize[0] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[0] && outstreamPlayerSize[1] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[1];
1665
+ if (!isValidSize) {
1666
+ logError(`IX Bid Adapter: ${outstreamPlayerSize} is an invalid size for IX outstream renderer`);
1667
+ return false;
1668
+ }
1669
+ }
1670
+
1614
1671
  if (errorList.length) {
1615
1672
  errorList.forEach((err) => {
1616
1673
  logError(err, { bidder: BIDDER_CODE, code: ERROR_CODES.PROPERTY_NOT_INCLUDED });
@@ -1619,16 +1676,6 @@ export const spec = {
1619
1676
  }
1620
1677
  }
1621
1678
 
1622
- const videoImp = bidToVideoImp(bid).video;
1623
- if (deepAccess(bid, 'mediaTypes.video.context') === OUTSTREAM && isIndexRendererPreferred(bid) && videoImp) {
1624
- const outstreamPlayerSize = [deepAccess(videoImp, 'w'), deepAccess(videoImp, 'h')];
1625
- const isValidSize = outstreamPlayerSize[0] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[0] && outstreamPlayerSize[1] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[1];
1626
- if (!isValidSize) {
1627
- logError(`IX Bid Adapter: ${outstreamPlayerSize} is an invalid size for IX outstream renderer`);
1628
- return false;
1629
- }
1630
- }
1631
-
1632
1679
  return nativeMediaTypeValid(mediaTypeNativeRef);
1633
1680
  },
1634
1681
 
@@ -502,11 +502,8 @@ to `'ix'` across all ad units that bids are being requested for does not exceed
502
502
 
503
503
  ### Time-To-Live (TTL)
504
504
 
505
- Banner bids from IX have a TTL of 300 seconds while video bids have a TTL of 1 hour, after which time they become
506
- invalid.
507
-
508
- If an invalid bid wins, and its associated ad is rendered, it will not count
509
- towards total impressions on IX's side.
505
+ Banner bids from Index have a TTL of 600 seconds while video bids have a TTL of three hours, after which time they become invalid.
506
+ **Note:** Index supports the `bid.exp` attribute in the bid response which allows our adapter to specify the maximum number of seconds allowed between the auction and billing notice. In the absence of the `bid.exp` attribute, the TTL provided above applies.
510
507
 
511
508
  FAQs
512
509
  ====