prebid.js 7.33.0 → 7.35.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 (219) hide show
  1. package/.devcontainer/devcontainer.json +2 -1
  2. package/.github/workflows/issue_tracker.yml +27 -16
  3. package/dist/33acrossBidAdapter.js +1 -1
  4. package/dist/33acrossIdSystem.js +1 -1
  5. package/dist/adagioBidAdapter.js +1 -1
  6. package/dist/adbookpspBidAdapter.js +1 -1
  7. package/dist/adgenerationBidAdapter.js +1 -1
  8. package/dist/admaticBidAdapter.js +1 -1
  9. package/dist/admixerBidAdapter.js +1 -1
  10. package/dist/adnuntiusBidAdapter.js +1 -1
  11. package/dist/adrelevantisBidAdapter.js +1 -1
  12. package/dist/adtrgtmeBidAdapter.js +1 -1
  13. package/dist/adxcgBidAdapter.js +1 -1
  14. package/dist/adyoulikeBidAdapter.js +1 -1
  15. package/dist/ajaBidAdapter.js +1 -1
  16. package/dist/amxBidAdapter.js +1 -1
  17. package/dist/amxIdSystem.js +1 -1
  18. package/dist/appierAnalyticsAdapter.js +1 -1
  19. package/dist/appnexusBidAdapter.js +1 -1
  20. package/dist/arcspanRtdProvider.js +1 -0
  21. package/dist/asoBidAdapter.js +1 -1
  22. package/dist/axonixBidAdapter.js +1 -1
  23. package/dist/bidglassBidAdapter.js +1 -1
  24. package/dist/big-richmediaBidAdapter.js +1 -1
  25. package/dist/bliinkBidAdapter.js +1 -1
  26. package/dist/bridgewellBidAdapter.js +1 -1
  27. package/dist/brightMountainMediaBidAdapter.js +1 -1
  28. package/dist/carodaBidAdapter.js +1 -1
  29. package/dist/chtnwBidAdapter.js +1 -1
  30. package/dist/concertBidAdapter.js +1 -1
  31. package/dist/connectadBidAdapter.js +1 -1
  32. package/dist/consentManagement.js +1 -1
  33. package/dist/consumableBidAdapter.js +1 -1
  34. package/dist/conversantBidAdapter.js +1 -1
  35. package/dist/craftBidAdapter.js +1 -1
  36. package/dist/criteoBidAdapter.js +1 -1
  37. package/dist/cwireBidAdapter.js +1 -1
  38. package/dist/dspxBidAdapter.js +1 -1
  39. package/dist/emx_digitalBidAdapter.js +1 -1
  40. package/dist/eplanningBidAdapter.js +1 -1
  41. package/dist/feedadBidAdapter.js +1 -1
  42. package/dist/finativeBidAdapter.js +1 -1
  43. package/dist/glimpseBidAdapter.js +1 -1
  44. package/dist/gmosspBidAdapter.js +1 -1
  45. package/dist/goldbachBidAdapter.js +1 -1
  46. package/dist/gridBidAdapter.js +1 -1
  47. package/dist/gridNMBidAdapter.js +1 -1
  48. package/dist/gumgumBidAdapter.js +1 -1
  49. package/dist/h12mediaBidAdapter.js +1 -1
  50. package/dist/hadronIdSystem.js +1 -1
  51. package/dist/holidBidAdapter.js +1 -1
  52. package/dist/id5IdSystem.js +1 -1
  53. package/dist/improvedigitalBidAdapter.js +1 -1
  54. package/dist/inmarBidAdapter.js +1 -1
  55. package/dist/insticatorBidAdapter.js +1 -1
  56. package/dist/ixBidAdapter.js +1 -1
  57. package/dist/justpremiumBidAdapter.js +1 -1
  58. package/dist/kargoBidAdapter.js +1 -1
  59. package/dist/konduitAnalyticsAdapter.js +1 -1
  60. package/dist/kueezBidAdapter.js +1 -1
  61. package/dist/kueezRtbBidAdapter.js +1 -1
  62. package/dist/lassoBidAdapter.js +1 -1
  63. package/dist/lifestreetBidAdapter.js +1 -1
  64. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  65. package/dist/logicadBidAdapter.js +1 -1
  66. package/dist/loglyliftBidAdapter.js +1 -1
  67. package/dist/lotamePanoramaIdSystem.js +1 -1
  68. package/dist/magniteAnalyticsAdapter.js +1 -1
  69. package/dist/malltvAnalyticsAdapter.js +1 -1
  70. package/dist/marsmediaBidAdapter.js +1 -1
  71. package/dist/mediafuseBidAdapter.js +1 -1
  72. package/dist/mediasquareBidAdapter.js +1 -1
  73. package/dist/mgidBidAdapter.js +1 -1
  74. package/dist/minutemediaBidAdapter.js +1 -1
  75. package/dist/nextMillenniumBidAdapter.js +1 -1
  76. package/dist/nexx360BidAdapter.js +1 -1
  77. package/dist/not-for-prod/prebid.js +140 -149
  78. package/dist/oguryBidAdapter.js +1 -1
  79. package/dist/onetagBidAdapter.js +1 -1
  80. package/dist/ooloAnalyticsAdapter.js +1 -1
  81. package/dist/openxBidAdapter.js +1 -1
  82. package/dist/ortbConverter.js +1 -1
  83. package/dist/outbrainBidAdapter.js +1 -1
  84. package/dist/parrableIdSystem.js +1 -1
  85. package/dist/permutiveRtdProvider.js +1 -1
  86. package/dist/pixfutureBidAdapter.js +1 -1
  87. package/dist/prebid-core.js +1 -1
  88. package/dist/prebidServerBidAdapter.js +1 -1
  89. package/dist/priceFloors.js +1 -1
  90. package/dist/publinkIdSystem.js +1 -1
  91. package/dist/pubmaticBidAdapter.js +1 -1
  92. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  93. package/dist/pulsepointBidAdapter.js +1 -1
  94. package/dist/pxyzBidAdapter.js +1 -1
  95. package/dist/quantcastBidAdapter.js +1 -1
  96. package/dist/readpeakBidAdapter.js +1 -1
  97. package/dist/relaidoBidAdapter.js +1 -1
  98. package/dist/rhythmoneBidAdapter.js +1 -1
  99. package/dist/riseBidAdapter.js +1 -1
  100. package/dist/rubiconAnalyticsAdapter.js +1 -1
  101. package/dist/rubiconBidAdapter.js +1 -1
  102. package/dist/seedingAllianceBidAdapter.js +1 -1
  103. package/dist/seedtagBidAdapter.js +1 -1
  104. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  105. package/dist/sharethroughBidAdapter.js +1 -1
  106. package/dist/shinezBidAdapter.js +1 -1
  107. package/dist/smaatoBidAdapter.js +1 -1
  108. package/dist/smartadserverBidAdapter.js +1 -1
  109. package/dist/smartxBidAdapter.js +1 -1
  110. package/dist/smartytechBidAdapter.js +1 -1
  111. package/dist/smilewantedBidAdapter.js +1 -1
  112. package/dist/sonobiBidAdapter.js +1 -1
  113. package/dist/sovrnAnalyticsAdapter.js +1 -1
  114. package/dist/sovrnBidAdapter.js +1 -1
  115. package/dist/sspBCBidAdapter.js +1 -1
  116. package/dist/sublimeBidAdapter.js +1 -1
  117. package/dist/synacormediaBidAdapter.js +1 -1
  118. package/dist/taboolaBidAdapter.js +1 -1
  119. package/dist/targetVideoBidAdapter.js +1 -1
  120. package/dist/teadsBidAdapter.js +1 -1
  121. package/dist/trionBidAdapter.js +1 -1
  122. package/dist/tripleliftBidAdapter.js +1 -1
  123. package/dist/ttdBidAdapter.js +1 -1
  124. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  125. package/dist/uid2IdSystem.js +1 -1
  126. package/dist/underdogmediaBidAdapter.js +1 -1
  127. package/dist/undertoneBidAdapter.js +1 -1
  128. package/dist/vidazooBidAdapter.js +1 -1
  129. package/dist/videobyteBidAdapter.js +1 -1
  130. package/dist/visxBidAdapter.js +1 -1
  131. package/dist/vuukleBidAdapter.js +1 -1
  132. package/dist/widespaceBidAdapter.js +1 -1
  133. package/dist/winrBidAdapter.js +1 -1
  134. package/dist/yahoosspBidAdapter.js +1 -1
  135. package/dist/yieldmoBidAdapter.js +1 -1
  136. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  137. package/dist/zeta_global_sspBidAdapter.js +1 -1
  138. package/dist/zeusPrimeRtdProvider.js +4 -14
  139. package/integrationExamples/gpt/hello_world.html +0 -0
  140. package/libraries/ortbConverter/processors/default.js +19 -1
  141. package/modules/.submodules.json +1 -0
  142. package/modules/admaticBidAdapter.js +2 -1
  143. package/modules/admixerBidAdapter.js +26 -4
  144. package/modules/adnuntiusBidAdapter.js +36 -38
  145. package/modules/adyoulikeBidAdapter.js +2 -0
  146. package/modules/arcspanRtdProvider.js +73 -0
  147. package/modules/arcspanRtdProvider.md +11 -0
  148. package/modules/bliinkBidAdapter.js +1 -1
  149. package/modules/consentManagement.js +33 -5
  150. package/modules/consumableBidAdapter.js +20 -2
  151. package/modules/criteoBidAdapter.js +1 -1
  152. package/modules/cwireBidAdapter.js +169 -242
  153. package/modules/cwireBidAdapter.md +15 -14
  154. package/modules/emx_digitalBidAdapter.js +9 -2
  155. package/modules/hadronIdSystem.js +37 -32
  156. package/modules/holidBidAdapter.js +9 -4
  157. package/modules/kargoBidAdapter.js +5 -1
  158. package/modules/lotamePanoramaIdSystem.js +9 -1
  159. package/modules/nextMillenniumBidAdapter.js +19 -9
  160. package/modules/nexx360BidAdapter.js +1 -2
  161. package/modules/onetagBidAdapter.js +12 -1
  162. package/modules/openxBidAdapter.js +5 -0
  163. package/modules/outbrainBidAdapter.js +103 -6
  164. package/modules/permutiveRtdProvider.js +17 -12
  165. package/modules/prebidServerBidAdapter/index.js +14 -1
  166. package/modules/prebidServerBidAdapter/ortbConverter.js +1 -1
  167. package/modules/priceFloors.js +7 -8
  168. package/modules/pulsepointBidAdapter.js +2 -0
  169. package/modules/seedingAllianceBidAdapter.js +129 -116
  170. package/modules/smartadserverBidAdapter.js +39 -28
  171. package/modules/smartyadsBidAdapter.md +9 -0
  172. package/modules/smartytechBidAdapter.js +67 -10
  173. package/modules/smartytechBidAdapter.md +44 -33
  174. package/modules/sonobiBidAdapter.js +17 -10
  175. package/modules/taboolaBidAdapter.js +2 -1
  176. package/modules/tripleliftBidAdapter.js +4 -0
  177. package/modules/vidazooBidAdapter.js +56 -22
  178. package/modules/zeta_global_sspBidAdapter.js +15 -0
  179. package/modules/zeusPrimeRtdProvider.js +3 -323
  180. package/modules/zeusPrimeRtdProvider.md +3 -0
  181. package/package.json +1 -1
  182. package/src/adloader.js +2 -1
  183. package/src/auction.js +2 -11
  184. package/src/prebid.js +8 -0
  185. package/src/utils/cpm.js +17 -0
  186. package/test/spec/modules/admixerBidAdapter_spec.js +140 -60
  187. package/test/spec/modules/adnuntiusBidAdapter_spec.js +120 -120
  188. package/test/spec/modules/adyoulikeBidAdapter_spec.js +3 -0
  189. package/test/spec/modules/arcspanRtdProvider_spec.js +187 -0
  190. package/test/spec/modules/bliinkBidAdapter_spec.js +7 -7
  191. package/test/spec/modules/consentManagement_spec.js +49 -1
  192. package/test/spec/modules/consumableBidAdapter_spec.js +46 -0
  193. package/test/spec/modules/cwireBidAdapter_spec.js +249 -335
  194. package/test/spec/modules/emx_digitalBidAdapter_spec.js +30 -1
  195. package/test/spec/modules/hadronIdSystem_spec.js +4 -6
  196. package/test/spec/modules/holidBidAdapter_spec.js +29 -0
  197. package/test/spec/modules/kargoBidAdapter_spec.js +32 -0
  198. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +16 -10
  199. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +14 -2
  200. package/test/spec/modules/nexx360BidAdapter_spec.js +0 -4
  201. package/test/spec/modules/onetagBidAdapter_spec.js +43 -0
  202. package/test/spec/modules/openxBidAdapter_spec.js +41 -0
  203. package/test/spec/modules/openxOrtbBidAdapter_spec.js +41 -0
  204. package/test/spec/modules/outbrainBidAdapter_spec.js +182 -18
  205. package/test/spec/modules/prebidServerBidAdapter_spec.js +138 -0
  206. package/test/spec/modules/pulsepointBidAdapter_spec.js +11 -1
  207. package/test/spec/modules/seedingAllianceAdapter_spec.js +66 -23
  208. package/test/spec/modules/smartadserverBidAdapter_spec.js +116 -5
  209. package/test/spec/modules/smartytechBidAdapter_spec.js +172 -14
  210. package/test/spec/modules/sonobiBidAdapter_spec.js +2 -1
  211. package/test/spec/modules/taboolaBidAdapter_spec.js +12 -3
  212. package/test/spec/modules/tripleliftBidAdapter_spec.js +13 -0
  213. package/test/spec/modules/userId_spec.js +19 -14
  214. package/test/spec/modules/vidazooBidAdapter_spec.js +61 -22
  215. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +8 -0
  216. package/test/spec/ortbConverter/default_processors_spec.js +23 -0
  217. package/test/spec/unit/pbjs_api_spec.js +14 -0
  218. package/test/spec/unit/utils/cpm_spec.js +64 -0
  219. package/test/spec/modules/zeusPrimeRtdProvider_spec.js +0 -410
@@ -2,120 +2,111 @@
2
2
  'use strict';
3
3
 
4
4
  import { registerBidder } from '../src/adapters/bidderFactory.js';
5
- import { NATIVE } from '../src/mediaTypes.js';
6
- import { _map, deepSetValue, isEmpty, deepAccess } from '../src/utils.js';
5
+ import { NATIVE, BANNER } from '../src/mediaTypes.js';
6
+ import { _map, isArray, isEmpty, deepSetValue, replaceAuctionPrice } from '../src/utils.js';
7
7
  import { config } from '../src/config.js';
8
8
  import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
9
9
 
10
- const BIDDER_CODE = 'seedingAlliance';
11
10
  const GVL_ID = 371;
11
+ const BIDDER_CODE = 'seedingAlliance';
12
12
  const DEFAULT_CUR = 'EUR';
13
13
  const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=pb';
14
14
 
15
- const NATIVE_ASSET_IDS = {0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon'};
15
+ const NATIVE_ASSET_IDS = { 0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon' };
16
16
 
17
17
  const NATIVE_PARAMS = {
18
- title: {
19
- id: 0,
20
- name: 'title'
21
- },
22
-
23
- body: {
24
- id: 1,
25
- name: 'data',
26
- type: 2
27
- },
28
-
29
- sponsoredBy: {
30
- id: 2,
31
- name: 'data',
32
- type: 1
33
- },
34
-
35
- image: {
36
- id: 3,
37
- type: 3,
38
- name: 'img'
39
- },
40
-
41
- cta: {
42
- id: 4,
43
- type: 12,
44
- name: 'data'
45
- },
46
-
47
- icon: {
48
- id: 5,
49
- type: 1,
50
- name: 'img'
51
- }
18
+ title: { id: 0, name: 'title' },
19
+ body: { id: 1, name: 'data', type: 2 },
20
+ sponsoredBy: { id: 2, name: 'data', type: 1 },
21
+ image: { id: 3, type: 3, name: 'img' },
22
+ cta: { id: 4, type: 12, name: 'data' },
23
+ icon: { id: 5, type: 1, name: 'img' }
52
24
  };
53
25
 
54
26
  export const spec = {
55
27
  code: BIDDER_CODE,
56
-
57
28
  gvlid: GVL_ID,
29
+ supportedMediaTypes: [NATIVE, BANNER],
58
30
 
59
- supportedMediaTypes: [NATIVE],
60
-
61
- isBidRequestValid: function(bid) {
31
+ isBidRequestValid: function (bid) {
62
32
  return !!bid.params.adUnitId;
63
33
  },
64
34
 
65
- buildRequests: (validBidRequests, bidderRequest) => {
35
+ buildRequests: (validBidRequests = [], bidderRequest) => {
66
36
  // convert Native ORTB definition to old-style prebid native definition
67
37
  validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
68
38
 
69
- const pt = setOnAny(validBidRequests, 'params.pt') || setOnAny(validBidRequests, 'params.priceType') || 'net';
70
- const tid = bidderRequest.auctionId;
71
- const cur = [config.getConfig('currency.adServerCurrency') || DEFAULT_CUR];
72
39
  let url = bidderRequest.refererInfo.page;
73
40
 
74
- const imp = validBidRequests.map((bid, id) => {
75
- const assets = _map(bid.nativeParams, (bidParams, key) => {
76
- const props = NATIVE_PARAMS[key];
77
-
78
- const asset = {
79
- required: bidParams.required & 1
80
- };
41
+ const imps = validBidRequests.map((bidRequest, id) => {
42
+ const imp = {
43
+ id: String(id + 1),
44
+ tagid: bidRequest.params.adUnitId
45
+ };
81
46
 
82
- if (props) {
83
- asset.id = props.id;
47
+ /**
48
+ * Native Ad
49
+ */
50
+ if (bidRequest.nativeParams) {
51
+ const assets = _map(bidRequest.nativeParams, (nativeAsset, key) => {
52
+ const props = NATIVE_PARAMS[key];
53
+
54
+ if (props) {
55
+ let wmin, hmin, w, h;
56
+ let aRatios = nativeAsset.aspect_ratios;
57
+
58
+ if (aRatios && aRatios[0]) {
59
+ aRatios = aRatios[0];
60
+ wmin = aRatios.min_width || 0;
61
+ hmin = aRatios.ratio_height * wmin / aRatios.ratio_width | 0;
62
+ }
84
63
 
85
- let w, h;
64
+ if (nativeAsset.sizes) {
65
+ const sizes = flatten(nativeAsset.sizes);
66
+ w = parseInt(sizes[0], 10);
67
+ h = parseInt(sizes[1], 10);
68
+ }
86
69
 
87
- if (bidParams.sizes) {
88
- w = bidParams.sizes[0];
89
- h = bidParams.sizes[1];
70
+ const asset = {
71
+ id: props.id,
72
+ required: nativeAsset.required & 1
73
+ };
74
+
75
+ asset[props.name] = {
76
+ len: nativeAsset.len,
77
+ type: props.type,
78
+ wmin,
79
+ hmin,
80
+ w,
81
+ h
82
+ };
83
+
84
+ return asset;
85
+ } else {
86
+ // TODO Filter impressions with required assets we don't support
90
87
  }
88
+ }).filter(Boolean);
91
89
 
92
- asset[props.name] = {
93
- len: bidParams.len,
94
- type: props.type,
95
- w,
96
- h
97
- };
90
+ imp.native = {
91
+ request: {
92
+ assets
93
+ }
94
+ };
95
+ } else {
96
+ let sizes = transformSizes(bidRequest.sizes);
98
97
 
99
- return asset;
98
+ imp.banner = {
99
+ format: sizes,
100
+ w: sizes[0] ? sizes[0].w : 0,
101
+ h: sizes[0] ? sizes[0].h : 0
100
102
  }
101
- })
102
- .filter(Boolean);
103
+ }
103
104
 
104
- if (bid.params.url) {
105
- url = bid.params.url;
105
+ if (bidRequest.params.url) {
106
+ url = bidRequest.params.url;
106
107
  }
107
108
 
108
- return {
109
- id: String(id + 1),
110
- tagid: bid.params.adUnitId,
111
- tid: tid,
112
- pt: pt,
113
- native: {
114
- request: {
115
- assets
116
- }
117
- }
118
- };
109
+ return imp;
119
110
  });
120
111
 
121
112
  const request = {
@@ -123,12 +114,9 @@ export const spec = {
123
114
  site: {
124
115
  page: url
125
116
  },
126
- device: {
127
- ua: navigator.userAgent
128
- },
129
- cur,
130
- imp,
131
- user: {},
117
+ cur: [config.getConfig('currency.adServerCurrency') || DEFAULT_CUR],
118
+ imp: imps,
119
+ tmax: bidderRequest.timeout,
132
120
  regs: {
133
121
  ext: {
134
122
  gdpr: 0,
@@ -137,23 +125,22 @@ export const spec = {
137
125
  }
138
126
  };
139
127
 
140
- if (bidderRequest && bidderRequest.gdprConsent) {
128
+ if (bidderRequest.gdprConsent) {
129
+ request.user = {};
130
+
141
131
  deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString);
142
132
  deepSetValue(request, 'regs.ext.gdpr', (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean' && bidderRequest.gdprConsent.gdprApplies) ? 1 : 0);
143
133
  }
144
134
 
145
135
  return {
146
136
  method: 'POST',
147
- url: ENDPOINT_URL,
137
+ url: config.getConfig('seedingAlliance.endpoint') || ENDPOINT_URL,
148
138
  data: JSON.stringify(request),
149
- options: {
150
- contentType: 'application/json'
151
- },
152
- bids: validBidRequests
139
+ bidRequests: validBidRequests
153
140
  };
154
141
  },
155
142
 
156
- interpretResponse: function(serverResponse, { bids }) {
143
+ interpretResponse: function (serverResponse, { bidRequests }) {
157
144
  if (isEmpty(serverResponse.body)) {
158
145
  return [];
159
146
  }
@@ -165,35 +152,72 @@ export const spec = {
165
152
  return result;
166
153
  }, []) : [];
167
154
 
168
- return bids
169
- .map((bid, id) => {
155
+ return bidRequests
156
+ .map((bidRequest, id) => {
170
157
  const bidResponse = bidResponses[id];
171
158
 
159
+ const type = bidRequest.nativeParams ? NATIVE : BANNER;
160
+
172
161
  if (bidResponse) {
173
- return {
174
- requestId: bid.bidId,
162
+ const bidObject = {
163
+ requestId: bidRequest.bidId, // TODO get this value from response?
175
164
  cpm: bidResponse.price,
176
165
  creativeId: bidResponse.crid,
177
- ttl: 1000,
178
- netRevenue: (!bid.netRevenue || bid.netRevenue === 'net'),
166
+ ttl: 600,
167
+ netRevenue: true,
179
168
  currency: cur,
180
- mediaType: NATIVE,
169
+ mediaType: type,
181
170
  bidderCode: BIDDER_CODE,
182
- native: parseNative(bidResponse),
183
171
  meta: {
184
172
  advertiserDomains: bidResponse.adomain && bidResponse.adomain.length > 0 ? bidResponse.adomain : []
185
173
  }
186
174
  };
175
+
176
+ if (type === NATIVE) {
177
+ bidObject.native = parseNative(bidResponse);
178
+ bidObject.mediaType = NATIVE;
179
+ }
180
+
181
+ if (type === BANNER) {
182
+ bidObject.ad = replaceAuctionPrice(bidResponse.adm, bidResponse.price);
183
+ bidObject.width = bidResponse.w;
184
+ bidObject.height = bidResponse.h;
185
+ bidObject.mediaType = BANNER;
186
+ }
187
+
188
+ return bidObject;
187
189
  }
188
190
  })
189
191
  .filter(Boolean);
190
192
  }
191
193
  };
192
194
 
193
- registerBidder(spec);
195
+ function transformSizes(requestSizes) {
196
+ if (!isArray(requestSizes)) {
197
+ return [];
198
+ }
199
+
200
+ if (requestSizes.length === 2 && !isArray(requestSizes[0])) {
201
+ return [{
202
+ w: parseInt(requestSizes[0], 10),
203
+ h: parseInt(requestSizes[1], 10)
204
+ }];
205
+ } else if (isArray(requestSizes[0])) {
206
+ return requestSizes.map(item => ({
207
+ w: parseInt(item[0], 10),
208
+ h: parseInt(item[1], 10)
209
+ }));
210
+ }
211
+
212
+ return [];
213
+ }
214
+
215
+ function flatten(arr) {
216
+ return [].concat(...arr);
217
+ }
194
218
 
195
219
  function parseNative(bid) {
196
- const {assets, link, imptrackers} = bid.adm.native;
220
+ const { assets, link, imptrackers } = bid.adm.native;
197
221
 
198
222
  let clickUrl = link.url.replace(/\$\{AUCTION_PRICE\}/g, bid.price);
199
223
 
@@ -228,15 +252,4 @@ function parseNative(bid) {
228
252
  return result;
229
253
  }
230
254
 
231
- function setOnAny(collection, key) {
232
- for (let i = 0, result; i < collection.length; i++) {
233
- result = deepAccess(collection[i], key);
234
- if (result) {
235
- return result;
236
- }
237
- }
238
- }
239
-
240
- function flatten(arr) {
241
- return [].concat(...arr);
242
- }
255
+ registerBidder(spec);
@@ -13,6 +13,7 @@ export const spec = {
13
13
  gvlid: GVL_ID,
14
14
  aliases: ['smart'], // short code
15
15
  supportedMediaTypes: [BANNER, VIDEO],
16
+
16
17
  /**
17
18
  * Determines whether or not the given bid request is valid.
18
19
  *
@@ -131,7 +132,6 @@ export const spec = {
131
132
  */
132
133
  buildRequests: function (validBidRequests, bidderRequest) {
133
134
  // use bidderRequest.bids[] to get bidder-dependent request info
134
-
135
135
  const adServerCurrency = config.getConfig('currency.adServerCurrency');
136
136
  const sellerDefinedAudience = deepAccess(bidderRequest, 'ortb2.user.data', config.getAnyConfig('ortb2.user.data'));
137
137
  const sellerDefinedContext = deepAccess(bidderRequest, 'ortb2.site.content.data', config.getAnyConfig('ortb2.site.content.data'));
@@ -144,7 +144,6 @@ export const spec = {
144
144
  pageid: bid.params.pageId,
145
145
  formatid: bid.params.formatId,
146
146
  currencyCode: adServerCurrency,
147
- bidfloor: bid.params.bidfloor || spec.getBidFloor(bid, adServerCurrency),
148
147
  targeting: bid.params.target && bid.params.target !== '' ? bid.params.target : undefined,
149
148
  buid: bid.params.buId && bid.params.buId !== '' ? bid.params.buId : undefined,
150
149
  appname: bid.params.appName && bid.params.appName !== '' ? bid.params.appName : undefined,
@@ -161,10 +160,21 @@ export const spec = {
161
160
  sdc: sellerDefinedContext
162
161
  };
163
162
 
164
- if (bidderRequest && bidderRequest.gdprConsent) {
165
- payload.addtl_consent = bidderRequest.gdprConsent.addtlConsent;
166
- payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
167
- payload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side
163
+ if (bidderRequest) {
164
+ if (bidderRequest.gdprConsent) {
165
+ payload.addtl_consent = bidderRequest.gdprConsent.addtlConsent;
166
+ payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
167
+ payload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side
168
+ }
169
+
170
+ if (bidderRequest.gppConsent) {
171
+ payload.gpp = bidderRequest.gppConsent.gppString;
172
+ payload.gpp_sid = bidderRequest.gppConsent.applicableSections;
173
+ }
174
+
175
+ if (bidderRequest.uspConsent) {
176
+ payload.us_privacy = bidderRequest.uspConsent;
177
+ }
168
178
  }
169
179
 
170
180
  if (bid && bid.userId) {
@@ -175,24 +185,28 @@ export const spec = {
175
185
  payload.us_privacy = bidderRequest.uspConsent;
176
186
  }
177
187
 
178
- const videoMediaType = deepAccess(bid, 'mediaTypes.video');
179
188
  const bannerMediaType = deepAccess(bid, 'mediaTypes.banner');
180
- const isAdUnitContainingVideo = videoMediaType && (videoMediaType.context === 'instream' || videoMediaType.context === 'outstream');
181
- if (!isAdUnitContainingVideo && bannerMediaType) {
182
- payload.sizes = spec.adaptBannerSizes(bannerMediaType.sizes);
183
- bidRequests.push(spec.createServerRequest(payload, bid.params.domain));
184
- } else if (isAdUnitContainingVideo && !bannerMediaType) {
185
- spec.fillPayloadForVideoBidRequest(payload, videoMediaType, bid.params.video);
186
- bidRequests.push(spec.createServerRequest(payload, bid.params.domain));
187
- } else if (isAdUnitContainingVideo && bannerMediaType) {
188
- // If there are video and banner media types in the ad unit, we clone the payload
189
- // to create a specific one for video.
190
- let videoPayload = deepClone(payload);
189
+ const videoMediaType = deepAccess(bid, 'mediaTypes.video');
190
+ const isSupportedVideoContext = videoMediaType && (videoMediaType.context === 'instream' || videoMediaType.context === 'outstream');
191
+
192
+ if (bannerMediaType || isSupportedVideoContext) {
193
+ let type;
194
+ if (bannerMediaType) {
195
+ type = BANNER;
196
+ payload.sizes = spec.adaptBannerSizes(bannerMediaType.sizes);
191
197
 
192
- spec.fillPayloadForVideoBidRequest(videoPayload, videoMediaType, bid.params.video);
193
- bidRequests.push(spec.createServerRequest(videoPayload, bid.params.domain));
198
+ if (isSupportedVideoContext) {
199
+ let videoPayload = deepClone(payload);
200
+ spec.fillPayloadForVideoBidRequest(videoPayload, videoMediaType, bid.params.video);
201
+ videoPayload.bidfloor = bid.params.bidfloor || spec.getBidFloor(bid, adServerCurrency, VIDEO);
202
+ bidRequests.push(spec.createServerRequest(videoPayload, bid.params.domain));
203
+ }
204
+ } else {
205
+ type = VIDEO;
206
+ spec.fillPayloadForVideoBidRequest(payload, videoMediaType, bid.params.video);
207
+ }
194
208
 
195
- payload.sizes = spec.adaptBannerSizes(bannerMediaType.sizes);
209
+ payload.bidfloor = bid.params.bidfloor || spec.getBidFloor(bid, adServerCurrency, type);
196
210
  bidRequests.push(spec.createServerRequest(payload, bid.params.domain));
197
211
  } else {
198
212
  bidRequests.push({});
@@ -253,24 +267,21 @@ export const spec = {
253
267
  *
254
268
  * @param {object} bid Bid request object
255
269
  * @param {string} currency Ad server currency
270
+ * @param {string} mediaType Bid media type
256
271
  * @return {number} Floor price
257
272
  */
258
- getBidFloor: function (bid, currency) {
273
+ getBidFloor: function (bid, currency, mediaType) {
259
274
  if (!isFn(bid.getFloor)) {
260
275
  return DEFAULT_FLOOR;
261
276
  }
262
277
 
263
278
  const floor = bid.getFloor({
264
279
  currency: currency || 'USD',
265
- mediaType: '*',
280
+ mediaType,
266
281
  size: '*'
267
282
  });
268
283
 
269
- if (isPlainObject(floor) && !isNaN(floor.floor)) {
270
- return floor.floor;
271
- }
272
-
273
- return DEFAULT_FLOOR;
284
+ return isPlainObject(floor) && !isNaN(floor.floor) ? floor.floor : DEFAULT_FLOOR;
274
285
  },
275
286
 
276
287
  /**
@@ -10,6 +10,15 @@ Maintainer: supply@smartyads.com
10
10
 
11
11
  Module that connects to SmartyAds' demand sources
12
12
 
13
+ # Parameters
14
+
15
+ | Name | Scope | Description | Example |
16
+ | :------------ | :------- | :------------------------ | :------------------- |
17
+ | `sourceid` | required (for prebid.js) | placement ID | "0" |
18
+ | `host` | required (for prebid-server) | const value, set to "prebid" | "prebid" |
19
+ | `accountid` | required (for prebid-server) | partner ID | "1901" |
20
+ | `traffic` | optional (for prebid.js) | Configures the mediaType that should be used. Values can be banner, native or video | "banner" |
21
+
13
22
  # Test Parameters
14
23
  ```
15
24
  var adUnits = [
@@ -1,29 +1,77 @@
1
+ import {buildUrl, deepAccess} from '../src/utils.js'
2
+ import { BANNER, VIDEO } from '../src/mediaTypes.js';
1
3
  import {registerBidder} from '../src/adapters/bidderFactory.js';
2
- import {buildUrl} from '../src/utils.js'
3
4
 
4
5
  const BIDDER_CODE = 'smartytech';
5
6
  export const ENDPOINT_PROTOCOL = 'https';
6
7
  export const ENDPOINT_DOMAIN = 'server.smartytech.io';
7
- export const ENDPOINT_PATH = '/hb/bidder';
8
+ export const ENDPOINT_PATH = '/hb/v2/bidder';
8
9
 
9
10
  export const spec = {
11
+ supportedMediaTypes: [ BANNER, VIDEO ],
10
12
  code: BIDDER_CODE,
11
13
 
12
14
  isBidRequestValid: function (bidRequest) {
13
- return !!parseInt(bidRequest.params.endpointId);
15
+ return (
16
+ !!parseInt(bidRequest.params.endpointId) &&
17
+ spec._validateBanner(bidRequest) &&
18
+ spec._validateVideo(bidRequest)
19
+ );
20
+ },
21
+
22
+ _validateBanner: function(bidRequest) {
23
+ const bannerAdUnit = deepAccess(bidRequest, 'mediaTypes.banner');
24
+
25
+ if (bannerAdUnit === undefined) {
26
+ return true;
27
+ }
28
+
29
+ if (!Array.isArray(bannerAdUnit.sizes)) {
30
+ return false;
31
+ }
32
+
33
+ return true;
34
+ },
35
+
36
+ _validateVideo: function(bidRequest) {
37
+ const videoAdUnit = deepAccess(bidRequest, 'mediaTypes.video');
38
+
39
+ if (videoAdUnit === undefined) {
40
+ return true;
41
+ }
42
+
43
+ if (!Array.isArray(videoAdUnit.playerSize)) {
44
+ return false;
45
+ }
46
+
47
+ if (!videoAdUnit.context) {
48
+ return false;
49
+ }
50
+
51
+ return true;
14
52
  },
15
53
 
16
54
  buildRequests: function (validBidRequests, bidderRequest) {
17
55
  const referer = bidderRequest?.refererInfo?.page || window.location.href;
18
56
 
19
57
  const bidRequests = validBidRequests.map((validBidRequest) => {
20
- return {
58
+ let video = deepAccess(validBidRequest, 'mediaTypes.video', false);
59
+ let banner = deepAccess(validBidRequest, 'mediaTypes.banner', false);
60
+
61
+ let oneRequest = {
21
62
  endpointId: validBidRequest.params.endpointId,
22
63
  adUnitCode: validBidRequest.adUnitCode,
23
- sizes: validBidRequest.sizes,
24
- bidId: validBidRequest.bidId,
25
- referer: referer
64
+ referer: referer,
65
+ bidId: validBidRequest.bidId
26
66
  };
67
+
68
+ if (video) {
69
+ oneRequest.video = video;
70
+ } else if (banner) {
71
+ oneRequest.banner = banner;
72
+ }
73
+
74
+ return oneRequest
27
75
  });
28
76
 
29
77
  let adPartnerRequestUrl = buildUrl({
@@ -55,12 +103,14 @@ export const spec = {
55
103
  bid: validBids.find(b => b.adUnitCode === key),
56
104
  response: responseBody[key]
57
105
  }
58
- }).map(item => spec.adResponse(item.bid.bidId, item.response));
106
+ }).map(item => spec._adResponse(item.bid, item.response));
59
107
  },
60
108
 
61
- adResponse: function (requestId, response) {
109
+ _adResponse: function (request, response) {
62
110
  const bidObject = {
63
- requestId,
111
+ requestId: request.bidId,
112
+ adUnitCode: request.adUnitCode,
113
+ bidderCode: BIDDER_CODE,
64
114
  ad: response.ad,
65
115
  cpm: response.cpm,
66
116
  width: response.width,
@@ -69,7 +119,14 @@ export const spec = {
69
119
  creativeId: response.creativeId,
70
120
  netRevenue: true,
71
121
  currency: response.currency,
122
+ mediaType: BANNER
72
123
  }
124
+
125
+ if (response.mediaType === VIDEO) {
126
+ bidObject.vastXml = response.ad;
127
+ bidObject.mediaType = VIDEO;
128
+ }
129
+
73
130
  return bidObject;
74
131
  },
75
132
 
@@ -1,44 +1,55 @@
1
1
  # Overview
2
2
 
3
- Module Name: SmartyTech Bidder Adapter
4
-
5
- Module Type: Bidder Adapter
6
-
3
+ ```
4
+ Module Name: SmartyTech Bid Adapter
5
+ Module Type: Bidder Adapter
7
6
  Maintainer: info@adpartner.pro
7
+ ```
8
8
 
9
9
  # Description
10
10
 
11
- You can use this adapter to get a bid from smartytech.io.
11
+ Connects to SmartyTech's exchange for bids.
12
12
 
13
- About us : https://smartytech.io
13
+ SmartyTech bid adapter supports Banner and Video
14
14
 
15
- # Test Parameters
15
+ # Sample Ad Unit: For Publishers
16
+ ## Sample Banner Ad Unit
17
+ ```
18
+ var adUnits = [{
19
+ code: '/123123123/prebidjs-banner',
20
+ mediaTypes: {
21
+ banner: {
22
+ sizes: [
23
+ [300, 301],
24
+ [300, 250]
25
+ ]
26
+ }
27
+ },
28
+ bids: [{
29
+ bidder: 'smartytech',
30
+ params: {
31
+ endpointId: 12
32
+ }
33
+ }]
34
+ }];
35
+ ```
16
36
 
17
- ```javascript
18
- var adUnits = [
19
- {
20
- code: 'div-smartytech-example',
21
- sizes: [[300, 250]],
22
- bids: [
23
- {
24
- bidder: "smartytech",
25
- params: {
26
- endpointId: 14
27
- }
28
- }
29
- ]
37
+ ## Sample Video Ad Unit
38
+ ```
39
+ var videoAdUnit = {
40
+ code: '/123123123/video-vast-banner',
41
+ mediaTypes: {
42
+ video: {
43
+ context: 'instream',
44
+ playerSize: [640, 480],
45
+ mimes: ['video/mp4'],
46
+ }
30
47
  },
31
- {
32
- code: 'div-smartytech-example-2',
33
- sizes: [[300, 250]],
34
- bids: [
35
- {
36
- bidder: "smartytech",
37
- params: {
38
- endpointId: 14
39
- }
40
- }
41
- ]
42
- }
43
- ];
48
+ bids: [{
49
+ bidder: 'smartytech',
50
+ params: {
51
+ endpointId: 12
52
+ }
53
+ }]
54
+ };
44
55
  ```