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
@@ -1,69 +1,181 @@
1
- import { registerBidder } from '../src/adapters/bidderFactory.js';
2
- import { BANNER } from '../src/mediaTypes.js';
1
+ import { BANNER } from '../src/mediaTypes.js'
2
+ import { getStorageManager } from '../src/storageManager.js'
3
+ import { isArray } from '../src/utils.js'
4
+ import { registerBidder } from '../src/adapters/bidderFactory.js'
3
5
 
4
- const BIDDER_CODE = 'glimpse';
6
+ const storageManager = getStorageManager()
5
7
 
6
- function transformEachBidResponse(glimpseBid) {
7
- const bid = glimpseBid;
8
- bid.meta = { advertiserDomains: [] };
9
-
10
- if (glimpseBid.adomain) {
11
- bid.meta.advertiserDomains = glimpseBid.adomain;
12
- }
13
-
14
- return bid;
8
+ const BIDDER_CODE = 'glimpse'
9
+ const ENDPOINT = 'https://api.glimpsevault.io/ads/serving/public/v1/prebid'
10
+ const LOCAL_STORAGE_KEY = {
11
+ glimpse: {
12
+ jwt: 'gp_vault_jwt',
13
+ },
15
14
  }
16
15
 
17
16
  export const spec = {
18
17
  code: BIDDER_CODE,
19
- url: 'https://api.glimpseprotocol.io/cloud/v1/vault/prebid',
20
18
  supportedMediaTypes: [BANNER],
21
19
 
20
+ /**
21
+ * Determines whether or not the given bid request is valid
22
+ * @param bid {BidRequest} The bid to validate
23
+ * @return {boolean}
24
+ */
22
25
  isBidRequestValid: (bid) => {
23
- try {
24
- const { placementId } = bid.params;
25
- return typeof placementId === 'string' && placementId.length > 0;
26
- } catch (error) {
27
- return false;
28
- }
26
+ return (
27
+ hasValue(bid) &&
28
+ hasValue(bid.params) &&
29
+ hasStringValue(bid.params.placementId)
30
+ )
29
31
  },
30
32
 
33
+ /**
34
+ * Builds http request for Glimpse bids
35
+ * @param validBidRequests {BidRequest[]}
36
+ * @param bidderRequest {BidderRequest}
37
+ * @returns {ServerRequest}
38
+ */
31
39
  buildRequests: (validBidRequests, bidderRequest) => {
32
- const { url, code: bidderCode } = spec;
33
-
34
- const bids = validBidRequests.map((request) => {
35
- delete request.mediaTypes;
36
- return request;
37
- });
40
+ const networkId = window.networkId || -1
41
+ const bids = validBidRequests.map(processBidRequest)
42
+ const referer = getReferer(bidderRequest)
43
+ const gdprConsent = getGdprConsentChoice(bidderRequest)
44
+ const jwt = getVaultJwt()
38
45
 
39
- const sdk = {
40
- source: 'pbjs',
41
- version: '$prebid.version$',
42
- };
43
-
44
- const payload = {
45
- ...bidderRequest,
46
- bidderCode,
47
- bids,
48
- sdk,
49
- };
46
+ const data = {
47
+ auth: jwt,
48
+ data: {
49
+ bidderCode: spec.code,
50
+ networkId,
51
+ bids,
52
+ referer,
53
+ gdprConsent,
54
+ }
55
+ }
50
56
 
51
57
  return {
52
58
  method: 'POST',
53
- url,
54
- data: JSON.stringify(payload),
55
- };
59
+ url: ENDPOINT,
60
+ data: JSON.stringify(data),
61
+ options: {},
62
+ }
56
63
  },
57
64
 
58
- interpretResponse: (serverResponse, _) => {
59
- let bids = [];
60
- try {
61
- const { body } = serverResponse;
62
- bids = body.map(transformEachBidResponse);
63
- } catch (error) {}
65
+ /**
66
+ * Parse response from Glimpse server
67
+ * @param bidResponse {ServerResponse}
68
+ * @param bidRequest {BidRequest}
69
+ * @returns {Bid[]}
70
+ */
71
+ interpretResponse: (bidResponse, bidRequest) => {
72
+ const isValidResponse = isValidBidResponse(bidResponse)
73
+
74
+ if (isValidResponse) {
75
+ const {auth, data} = bidResponse.body
76
+ setVaultJwt(auth)
77
+ return data.bids
78
+ }
64
79
 
65
- return bids;
80
+ return []
66
81
  },
67
- };
82
+ }
83
+
84
+ function processBidRequest(bidRequest) {
85
+ const sizes = normalizeSizes(bidRequest.sizes)
86
+ const keywords = bidRequest.params.keywords || []
87
+
88
+ return {
89
+ bidId: bidRequest.bidId,
90
+ placementId: bidRequest.params.placementId,
91
+ unitCode: bidRequest.adUnitCode,
92
+ sizes,
93
+ keywords,
94
+ }
95
+ }
96
+
97
+ function normalizeSizes(sizes) {
98
+ const isSingleSize =
99
+ isArray(sizes) &&
100
+ sizes.length === 2 &&
101
+ !isArray(sizes[0]) &&
102
+ !isArray(sizes[1])
103
+
104
+ if (isSingleSize) {
105
+ return [sizes]
106
+ }
107
+
108
+ return sizes
109
+ }
110
+
111
+ function getReferer(bidderRequest) {
112
+ const hasReferer =
113
+ hasValue(bidderRequest) &&
114
+ hasValue(bidderRequest.refererInfo) &&
115
+ hasStringValue(bidderRequest.refererInfo.referer)
116
+
117
+ if (hasReferer) {
118
+ return bidderRequest.refererInfo.referer
119
+ }
120
+
121
+ return ''
122
+ }
123
+
124
+ function getGdprConsentChoice(bidderRequest) {
125
+ const hasGdprConsent =
126
+ hasValue(bidderRequest) &&
127
+ hasValue(bidderRequest.gdprConsent)
128
+
129
+ if (hasGdprConsent) {
130
+ return bidderRequest.gdprConsent
131
+ }
132
+
133
+ return {
134
+ consentString: '',
135
+ vendorData: {},
136
+ gdprApplies: false,
137
+ }
138
+ }
139
+
140
+ function setVaultJwt(auth) {
141
+ storageManager.setDataInLocalStorage(LOCAL_STORAGE_KEY.glimpse.jwt, auth)
142
+ }
143
+
144
+ function getVaultJwt() {
145
+ return storageManager.getDataFromLocalStorage(LOCAL_STORAGE_KEY.glimpse.jwt) || ''
146
+ }
147
+
148
+ function isValidBidResponse(bidResponse) {
149
+ return (
150
+ hasValue(bidResponse) &&
151
+ hasValue(bidResponse.body) &&
152
+ hasValue(bidResponse.body.data) &&
153
+ hasArrayValue(bidResponse.body.data.bids) &&
154
+ hasStringValue(bidResponse.body.auth)
155
+ )
156
+ }
157
+
158
+ function hasValue(value) {
159
+ return (
160
+ value !== undefined &&
161
+ value !== null
162
+ )
163
+ }
164
+
165
+ function hasStringValue(value) {
166
+ return (
167
+ hasValue(value) &&
168
+ typeof value === 'string' &&
169
+ value.length > 0
170
+ )
171
+ }
172
+
173
+ function hasArrayValue(value) {
174
+ return (
175
+ hasValue(value) &&
176
+ isArray(value) &&
177
+ value.length > 0
178
+ )
179
+ }
68
180
 
69
- registerBidder(spec);
181
+ registerBidder(spec)
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  Module Name: Glimpse Protocol Bid Adapter
5
5
  Module Type: Bidder Adapter
6
- Maintainer: hello@glimpseprotocol.io
6
+ Maintainer: publisher@glimpseprotocol.io
7
7
  ```
8
8
 
9
9
  # Description
@@ -11,12 +11,12 @@ Maintainer: hello@glimpseprotocol.io
11
11
  This module connects publishers to Glimpse Protocol's demand sources via Prebid.js. Our innovative marketplace protects
12
12
  consumer privacy while allowing precise targeting. It is compliant with GDPR, DPA and CCPA.
13
13
 
14
- This adapter supports Banner.
14
+ The Glimpse Adapter supports banner formats.
15
15
 
16
16
  # Test Parameters
17
17
 
18
18
  ```javascript
19
- var adUnits = [
19
+ const adUnits = [
20
20
  {
21
21
  code: 'banner-div-a',
22
22
  mediaTypes: {
@@ -24,78 +24,15 @@ var adUnits = [
24
24
  sizes: [[300, 250]],
25
25
  },
26
26
  },
27
- bids: [
28
- {
29
- bidder: 'glimpse',
30
- params: {
31
- placementId: 'glimpse-demo-300x250',
27
+ bids: [{
28
+ bidder: 'glimpse',
29
+ params: {
30
+ placementId: 'e53a7f564f8f44cc913b',
31
+ keywords: {
32
+ country: 'uk',
32
33
  },
33
34
  },
34
- ],
35
+ }],
35
36
  },
36
- {
37
- code: 'banner-div-b',
38
- mediaTypes: {
39
- banner: {
40
- sizes: [[320, 50]],
41
- },
42
- },
43
- bids: [
44
- {
45
- bidder: 'glimpse',
46
- params: {
47
- placementId: 'glimpse-demo-320x50',
48
- },
49
- },
50
- ],
51
- },
52
- {
53
- code: 'banner-div-c',
54
- mediaTypes: {
55
- banner: {
56
- sizes: [[970, 250]],
57
- },
58
- },
59
- bids: [
60
- {
61
- bidder: 'glimpse',
62
- params: {
63
- placementId: 'glimpse-demo-970x250',
64
- },
65
- },
66
- ],
67
- },
68
- {
69
- code: 'banner-div-d',
70
- mediaTypes: {
71
- banner: {
72
- sizes: [[728, 90]],
73
- },
74
- },
75
- bids: [
76
- {
77
- bidder: 'glimpse',
78
- params: {
79
- placementId: 'glimpse-demo-728x90',
80
- },
81
- },
82
- ],
83
- },
84
- {
85
- code: 'banner-div-e',
86
- mediaTypes: {
87
- banner: {
88
- sizes: [[300, 600]],
89
- },
90
- },
91
- bids: [
92
- {
93
- bidder: 'glimpse',
94
- params: {
95
- placementId: 'glimpse-demo-300x600',
96
- },
97
- },
98
- ],
99
- },
100
- ];
37
+ ]
101
38
  ```
@@ -29,6 +29,7 @@ let hasSynced = false;
29
29
 
30
30
  export const spec = {
31
31
  code: BIDDER_CODE,
32
+ aliases: ['playwire'],
32
33
  supportedMediaTypes: [ BANNER, VIDEO ],
33
34
  /**
34
35
  * Determines whether or not the given bid request is valid.
@@ -231,7 +231,7 @@ export const spec = {
231
231
  if (!errorMessage && serverResponse.seatbid) {
232
232
  const serverBid = _getBidFromResponse(serverResponse.seatbid[0]);
233
233
  if (serverBid) {
234
- if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
234
+ if (!serverBid.adm && !serverBid.nurl) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
235
235
  else if (!serverBid.price) errorMessage = LOG_ERROR_MESS.noPrice + JSON.stringify(serverBid);
236
236
  else if (serverBid.content_type !== 'video') errorMessage = LOG_ERROR_MESS.wrongContentType + serverBid.content_type;
237
237
  if (!errorMessage) {
@@ -246,17 +246,18 @@ export const spec = {
246
246
  netRevenue: true,
247
247
  ttl: TIME_TO_LIVE,
248
248
  dealId: serverBid.dealid,
249
- vastXml: serverBid.adm,
250
249
  mediaType: VIDEO,
251
250
  meta: {
252
251
  advertiserDomains: serverBid.adomain ? serverBid.adomain : []
253
- },
254
- adResponse: {
255
- content: serverBid.adm
256
252
  }
257
253
  };
258
254
 
259
- if (serverBid.nurl) {
255
+ if (serverBid.adm) {
256
+ bidResponse.vastXml = serverBid.adm;
257
+ bidResponse.adResponse = {
258
+ content: bidResponse.vastXml
259
+ };
260
+ } else if (serverBid.nurl) {
260
261
  bidResponse.vastUrl = serverBid.nurl;
261
262
  }
262
263
 
@@ -1,5 +1,6 @@
1
- import { logError, logWarn, parseSizesInput, _each, deepAccess } from '../src/utils.js';
2
1
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
2
+ import { _each, deepAccess, logError, logWarn, parseSizesInput } from '../src/utils.js';
3
+
3
4
  import { config } from '../src/config.js'
4
5
  import { getStorageManager } from '../src/storageManager.js';
5
6
  import includes from 'core-js-pure/features/array/includes';
@@ -293,6 +294,14 @@ function buildRequests(validBidRequests, bidderRequest) {
293
294
  let data = {};
294
295
  let gpid = '';
295
296
 
297
+ const date = new Date();
298
+ const lt = date && date.getTime();
299
+ const to = date && date.getTimezoneOffset();
300
+ if (to) {
301
+ lt && (data.lt = lt);
302
+ data.to = to;
303
+ }
304
+
296
305
  // ADTS-134 Retrieve ID envelopes
297
306
  for (const eid in eids) data[eid] = eids[eid];
298
307
 
@@ -488,7 +497,12 @@ function interpretResponse(serverResponse, bidRequest) {
488
497
  } else if (product === 5 && includes(sizes, '1x1')) {
489
498
  sizes = ['1x1'];
490
499
  } else if (product === 2 && includes(sizes, '1x1')) {
491
- sizes = responseWidth && responseHeight ? [`${responseWidth}x${responseHeight}`] : parseSizesInput(bidRequest.sizes)
500
+ const requestSizesThatMatchResponse = (bidRequest.sizes && bidRequest.sizes.reduce((result, current) => {
501
+ const [ width, height ] = current;
502
+ if (responseWidth === width || responseHeight === height) result.push(current.join('x'));
503
+ return result
504
+ }, [])) || [];
505
+ sizes = requestSizesThatMatchResponse.length ? requestSizesThatMatchResponse : parseSizesInput(bidRequest.sizes)
492
506
  }
493
507
 
494
508
  let [width, height] = sizes[0].split('x');
@@ -1,13 +1,18 @@
1
- import { isArray, getAdUnitSizes, getKeys, logError } from '../src/utils.js';
2
1
  import { submodule } from '../src/hook.js';
2
+ import * as utils from '../src/utils.js';
3
+ import { ajax } from '../src/ajax.js';
3
4
  import { getGlobal } from '../src/prebidGlobal.js';
4
- import { ajaxBuilder } from '../src/ajax.js';
5
5
 
6
6
  /** @type {string} */
7
7
  const MODULE_NAME = 'realTimeData';
8
8
  const SUBMODULE_NAME = 'ias';
9
-
10
- let bidResponses = {};
9
+ const IAS_HOST = 'https://pixel.adsafeprotected.com/services/pub';
10
+ export let iasTargeting = {};
11
+ const BRAND_SAFETY_OBJECT_FIELD_NAME = 'brandSafety';
12
+ const FRAUD_FIELD_NAME = 'fr';
13
+ const SLOTS_OBJECT_FIELD_NAME = 'slots';
14
+ const CUSTOM_FIELD_NAME = 'custom';
15
+ const IAS_KW = 'ias-kw';
11
16
 
12
17
  /**
13
18
  * Module init
@@ -16,12 +21,17 @@ let bidResponses = {};
16
21
  * @return {boolean}
17
22
  */
18
23
  export function init(config, userConsent) {
24
+ const params = config.params;
25
+ if (!params || !params.pubId) {
26
+ utils.logError('missing pubId param for IAS provider');
27
+ return false;
28
+ }
19
29
  return true;
20
30
  }
21
31
 
22
32
  function stringifySlotSizes(sizes) {
23
33
  let result = '';
24
- if (isArray(sizes)) {
34
+ if (utils.isArray(sizes)) {
25
35
  result = sizes.reduce((acc, size) => {
26
36
  acc.push(size.join('.'));
27
37
  return acc;
@@ -31,13 +41,14 @@ function stringifySlotSizes(sizes) {
31
41
  return result;
32
42
  }
33
43
 
34
- function stringifySlot(bidRequest, adUnitPath) {
35
- const sizes = getAdUnitSizes(bidRequest);
44
+ function stringifySlot(bidRequest) {
45
+ const sizes = utils.getAdUnitSizes(bidRequest);
36
46
  const id = bidRequest.code;
37
47
  const ss = stringifySlotSizes(sizes);
38
- const p = bidRequest.code;
48
+ const adSlot = utils.getGptSlotInfoForAdUnitCode(bidRequest.code);
49
+ const p = utils.isEmpty(adSlot) ? bidRequest.code : adSlot.gptSlot;
39
50
  const slot = { id, ss, p };
40
- const keyValues = getKeys(slot).map(function (key) {
51
+ const keyValues = utils.getKeys(slot).map(function (key) {
41
52
  return [key, slot[key]].join(':');
42
53
  });
43
54
  return '{' + keyValues.join(',') + '}';
@@ -51,35 +62,29 @@ function stringifyScreenSize() {
51
62
  return [(window.screen && window.screen.width) || -1, (window.screen && window.screen.height) || -1].join('.');
52
63
  }
53
64
 
54
- function getPageLevelKeywords(response) {
65
+ function formatTargetingData(adUnit) {
55
66
  let result = {};
56
- if (response.brandSafety) {
57
- shallowMerge(result, response.brandSafety);
67
+ if (iasTargeting[BRAND_SAFETY_OBJECT_FIELD_NAME]) {
68
+ utils.mergeDeep(result, iasTargeting[BRAND_SAFETY_OBJECT_FIELD_NAME]);
69
+ }
70
+ if (iasTargeting[FRAUD_FIELD_NAME]) {
71
+ result[FRAUD_FIELD_NAME] = iasTargeting[FRAUD_FIELD_NAME];
72
+ }
73
+ if (iasTargeting[CUSTOM_FIELD_NAME] && IAS_KW in iasTargeting[CUSTOM_FIELD_NAME]) {
74
+ result[IAS_KW] = iasTargeting[CUSTOM_FIELD_NAME][IAS_KW];
75
+ }
76
+ if (iasTargeting[SLOTS_OBJECT_FIELD_NAME] && adUnit in iasTargeting[SLOTS_OBJECT_FIELD_NAME]) {
77
+ utils.mergeDeep(result, iasTargeting[SLOTS_OBJECT_FIELD_NAME][adUnit]);
58
78
  }
59
- result.fr = response.fr;
60
- result.custom = response.custom;
61
79
  return result;
62
80
  }
63
81
 
64
- function shallowMerge(dest, src) {
65
- getKeys(src).reduce((dest, srcKey) => {
66
- dest[srcKey] = src[srcKey];
67
- return dest;
68
- }, dest);
69
- }
70
-
71
- function getBidRequestData(reqBidsConfigObj, callback, config) {
72
- const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits;
73
- let isFinish = false;
74
-
75
- const IAS_HOST = 'https://pixel.adsafeprotected.com/services/pub';
76
- const { pubId, adUnitPath } = config.params;
77
- const anId = pubId;
82
+ function constructQueryString(anId, adUnits) {
78
83
  let queries = [];
79
84
  queries.push(['anId', anId]);
80
85
 
81
86
  queries = queries.concat(adUnits.reduce(function (acc, request) {
82
- acc.push(['slot', stringifySlot(request, adUnitPath)]);
87
+ acc.push(['slot', stringifySlot(request)]);
83
88
  return acc;
84
89
  }, []));
85
90
 
@@ -87,58 +92,69 @@ function getBidRequestData(reqBidsConfigObj, callback, config) {
87
92
  queries.push(['sr', stringifyScreenSize()]);
88
93
  queries.push(['url', encodeURIComponent(window.location.href)]);
89
94
 
90
- const queryString = encodeURI(queries.map(qs => qs.join('=')).join('&'));
91
-
92
- const ajax = ajaxBuilder();
93
-
94
- ajax(`${IAS_HOST}?${queryString}`, {
95
- success: function (response, request) {
96
- if (!isFinish) {
97
- if (request.status === 200) {
98
- const iasResponse = JSON.parse(response);
99
- const commonBidResponse = {};
100
- shallowMerge(commonBidResponse, getPageLevelKeywords(iasResponse));
101
- commonBidResponse.slots = iasResponse.slots;
102
- bidResponses = commonBidResponse;
103
- adUnits.forEach(adUnit => {
104
- adUnit.bids.forEach(bid => {
105
- const rtd = bid.rtd || {};
106
- const iasRtd = {};
107
- iasRtd[SUBMODULE_NAME] = Object.assign({}, rtd[SUBMODULE_NAME], bidResponses);
108
- bid.rtd = Object.assign({}, rtd, iasRtd);
109
- });
110
- });
111
- }
112
- isFinish = true;
113
- }
114
- callback();
115
- },
116
- error: function () {
117
- logError('failed to retrieve targeting information');
118
- callback();
119
- }
120
- });
95
+ return encodeURI(queries.map(qs => qs.join('=')).join('&'));
96
+ }
97
+
98
+ function parseResponse(result) {
99
+ let iasResponse = {};
100
+ try {
101
+ iasResponse = JSON.parse(result);
102
+ } catch (err) {
103
+ utils.logError('error', err);
104
+ }
105
+ iasTargeting = iasResponse;
121
106
  }
122
107
 
123
108
  function getTargetingData(adUnits, config, userConsent) {
124
109
  const targeting = {};
125
- Object.keys(bidResponses).forEach(key => bidResponses[key] === undefined ? delete bidResponses[key] : {});
126
110
  try {
127
- adUnits.forEach(function(adUnit) {
128
- targeting[adUnit] = bidResponses;
129
- });
111
+ if (!utils.isEmpty(iasTargeting)) {
112
+ adUnits.forEach(function (adUnit) {
113
+ targeting[adUnit] = formatTargetingData(adUnit);
114
+ });
115
+ }
130
116
  } catch (err) {
131
- logError('error', err);
117
+ utils.logError('error', err);
132
118
  }
119
+ utils.logInfo('IAS targeting', targeting);
133
120
  return targeting;
134
121
  }
135
122
 
123
+ export function getApiCallback() {
124
+ return {
125
+ success: function (response, req) {
126
+ if (req.status === 200) {
127
+ try {
128
+ parseResponse(response);
129
+ } catch (e) {
130
+ utils.logError('Unable to parse IAS response.', e);
131
+ }
132
+ }
133
+ },
134
+ error: function () {
135
+ utils.logError('failed to retrieve IAS data');
136
+ }
137
+ }
138
+ }
139
+
140
+ function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) {
141
+ const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits;
142
+ const { pubId } = config.params;
143
+ const queryString = constructQueryString(pubId, adUnits);
144
+ ajax(
145
+ `${IAS_HOST}?${queryString}`,
146
+ getApiCallback(),
147
+ undefined,
148
+ { method: 'GET' }
149
+ );
150
+ }
151
+
136
152
  /** @type {RtdSubmodule} */
137
153
  export const iasSubModule = {
138
154
  name: SUBMODULE_NAME,
139
155
  init: init,
140
- getBidRequestData: getBidRequestData,
141
- getTargetingData: getTargetingData
156
+ getTargetingData: getTargetingData,
157
+ getBidRequestData: getBidRequestData
142
158
  };
143
159
 
144
160
  submodule(MODULE_NAME, iasSubModule);
@@ -55,7 +55,11 @@ export const spec = {
55
55
  parallel: true
56
56
  }, validBidRequests[0].params);
57
57
 
58
- if (data.publisherId) {
58
+ if (validBidRequests[0].schain) {
59
+ data.rtb = {
60
+ schain: validBidRequests[0].schain
61
+ };
62
+ } else if (data.publisherId) {
59
63
  data.rtb = {
60
64
  schain: {
61
65
  ext: {
@@ -63,10 +67,10 @@ export const spec = {
63
67
  }
64
68
  }
65
69
  };
66
-
67
- delete data.publisherId;
68
70
  }
69
71
 
72
+ delete data.publisherId;
73
+
70
74
  data.keywords = data.keywords || [];
71
75
  const restrictions = [];
72
76
 
@@ -490,6 +490,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
490
490
  r.ext.ixdiag.msd = 0;
491
491
  r.ext.ixdiag.msi = 0;
492
492
  r.imp = [];
493
+ r.at = 1;
493
494
 
494
495
  // getting ixdiags for adunits of the video, outstream & multi format (MF) style
495
496
  let ixdiag = buildIXDiag(validBidRequests);
@@ -645,7 +646,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
645
646
  }
646
647
 
647
648
  if (impressionObjects.length && BANNER in impressionObjects[0]) {
648
- const { id, banner: { topframe } } = impressionObjects[0];
649
+ const { id, banner: { topframe }, ext } = impressionObjects[0];
649
650
  const _bannerImpression = {
650
651
  id,
651
652
  banner: {
@@ -654,6 +655,12 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
654
655
  },
655
656
  }
656
657
 
658
+ if (ext.dfp_ad_unit_code) {
659
+ _bannerImpression.ext = {
660
+ dfp_ad_unit_code: ext.dfp_ad_unit_code
661
+ }
662
+ }
663
+
657
664
  if ('bidfloor' in impressionObjects[0]) {
658
665
  _bannerImpression.bidfloor = impressionObjects[0].bidfloor;
659
666
  }