prebid.js 7.34.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 (169) hide show
  1. package/.devcontainer/devcontainer.json +2 -1
  2. package/.github/workflows/issue_tracker.yml +1 -1
  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/adrelevantisBidAdapter.js +1 -1
  9. package/dist/adtrgtmeBidAdapter.js +1 -1
  10. package/dist/adxcgBidAdapter.js +1 -1
  11. package/dist/adyoulikeBidAdapter.js +1 -1
  12. package/dist/ajaBidAdapter.js +1 -1
  13. package/dist/amxBidAdapter.js +1 -1
  14. package/dist/amxIdSystem.js +1 -1
  15. package/dist/appierAnalyticsAdapter.js +1 -1
  16. package/dist/appnexusBidAdapter.js +1 -1
  17. package/dist/asoBidAdapter.js +1 -1
  18. package/dist/axonixBidAdapter.js +1 -1
  19. package/dist/bidglassBidAdapter.js +1 -1
  20. package/dist/big-richmediaBidAdapter.js +1 -1
  21. package/dist/bridgewellBidAdapter.js +1 -1
  22. package/dist/brightMountainMediaBidAdapter.js +1 -1
  23. package/dist/carodaBidAdapter.js +1 -1
  24. package/dist/chtnwBidAdapter.js +1 -1
  25. package/dist/concertBidAdapter.js +1 -1
  26. package/dist/connectadBidAdapter.js +1 -1
  27. package/dist/consentManagement.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/cwireBidAdapter.js +1 -1
  33. package/dist/dspxBidAdapter.js +1 -1
  34. package/dist/eplanningBidAdapter.js +1 -1
  35. package/dist/feedadBidAdapter.js +1 -1
  36. package/dist/finativeBidAdapter.js +1 -1
  37. package/dist/glimpseBidAdapter.js +1 -1
  38. package/dist/gmosspBidAdapter.js +1 -1
  39. package/dist/goldbachBidAdapter.js +1 -1
  40. package/dist/gridBidAdapter.js +1 -1
  41. package/dist/gridNMBidAdapter.js +1 -1
  42. package/dist/gumgumBidAdapter.js +1 -1
  43. package/dist/h12mediaBidAdapter.js +1 -1
  44. package/dist/hadronIdSystem.js +1 -1
  45. package/dist/id5IdSystem.js +1 -1
  46. package/dist/improvedigitalBidAdapter.js +1 -1
  47. package/dist/inmarBidAdapter.js +1 -1
  48. package/dist/insticatorBidAdapter.js +1 -1
  49. package/dist/ixBidAdapter.js +1 -1
  50. package/dist/justpremiumBidAdapter.js +1 -1
  51. package/dist/konduitAnalyticsAdapter.js +1 -1
  52. package/dist/kueezBidAdapter.js +1 -1
  53. package/dist/kueezRtbBidAdapter.js +1 -1
  54. package/dist/lassoBidAdapter.js +1 -1
  55. package/dist/lifestreetBidAdapter.js +1 -1
  56. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  57. package/dist/logicadBidAdapter.js +1 -1
  58. package/dist/loglyliftBidAdapter.js +1 -1
  59. package/dist/magniteAnalyticsAdapter.js +1 -1
  60. package/dist/malltvAnalyticsAdapter.js +1 -1
  61. package/dist/marsmediaBidAdapter.js +1 -1
  62. package/dist/mediafuseBidAdapter.js +1 -1
  63. package/dist/mediasquareBidAdapter.js +1 -1
  64. package/dist/mgidBidAdapter.js +1 -1
  65. package/dist/minutemediaBidAdapter.js +1 -1
  66. package/dist/nexx360BidAdapter.js +1 -1
  67. package/dist/not-for-prod/prebid.js +127 -137
  68. package/dist/oguryBidAdapter.js +1 -1
  69. package/dist/onetagBidAdapter.js +1 -1
  70. package/dist/ooloAnalyticsAdapter.js +1 -1
  71. package/dist/outbrainBidAdapter.js +1 -1
  72. package/dist/parrableIdSystem.js +1 -1
  73. package/dist/permutiveRtdProvider.js +1 -1
  74. package/dist/pixfutureBidAdapter.js +1 -1
  75. package/dist/prebid-core.js +1 -1
  76. package/dist/priceFloors.js +1 -1
  77. package/dist/publinkIdSystem.js +1 -1
  78. package/dist/pubmaticBidAdapter.js +1 -1
  79. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  80. package/dist/pulsepointBidAdapter.js +1 -1
  81. package/dist/pxyzBidAdapter.js +1 -1
  82. package/dist/quantcastBidAdapter.js +1 -1
  83. package/dist/readpeakBidAdapter.js +1 -1
  84. package/dist/relaidoBidAdapter.js +1 -1
  85. package/dist/rhythmoneBidAdapter.js +1 -1
  86. package/dist/riseBidAdapter.js +1 -1
  87. package/dist/rubiconAnalyticsAdapter.js +1 -1
  88. package/dist/rubiconBidAdapter.js +1 -1
  89. package/dist/seedingAllianceBidAdapter.js +1 -1
  90. package/dist/seedtagBidAdapter.js +1 -1
  91. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  92. package/dist/sharethroughBidAdapter.js +1 -1
  93. package/dist/shinezBidAdapter.js +1 -1
  94. package/dist/smaatoBidAdapter.js +1 -1
  95. package/dist/smartadserverBidAdapter.js +1 -1
  96. package/dist/smartxBidAdapter.js +1 -1
  97. package/dist/smartytechBidAdapter.js +1 -1
  98. package/dist/smilewantedBidAdapter.js +1 -1
  99. package/dist/sonobiBidAdapter.js +1 -1
  100. package/dist/sovrnAnalyticsAdapter.js +1 -1
  101. package/dist/sovrnBidAdapter.js +1 -1
  102. package/dist/sspBCBidAdapter.js +1 -1
  103. package/dist/sublimeBidAdapter.js +1 -1
  104. package/dist/synacormediaBidAdapter.js +1 -1
  105. package/dist/taboolaBidAdapter.js +1 -1
  106. package/dist/targetVideoBidAdapter.js +1 -1
  107. package/dist/teadsBidAdapter.js +1 -1
  108. package/dist/trionBidAdapter.js +1 -1
  109. package/dist/tripleliftBidAdapter.js +1 -1
  110. package/dist/ttdBidAdapter.js +1 -1
  111. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  112. package/dist/uid2IdSystem.js +1 -1
  113. package/dist/underdogmediaBidAdapter.js +1 -1
  114. package/dist/undertoneBidAdapter.js +1 -1
  115. package/dist/vidazooBidAdapter.js +1 -1
  116. package/dist/videobyteBidAdapter.js +1 -1
  117. package/dist/visxBidAdapter.js +1 -1
  118. package/dist/vuukleBidAdapter.js +1 -1
  119. package/dist/widespaceBidAdapter.js +1 -1
  120. package/dist/winrBidAdapter.js +1 -1
  121. package/dist/yahoosspBidAdapter.js +1 -1
  122. package/dist/yieldmoBidAdapter.js +1 -1
  123. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  124. package/dist/zeta_global_sspBidAdapter.js +1 -1
  125. package/dist/zeusPrimeRtdProvider.js +4 -14
  126. package/integrationExamples/gpt/hello_world.html +0 -0
  127. package/modules/adyoulikeBidAdapter.js +2 -0
  128. package/modules/consentManagement.js +33 -5
  129. package/modules/cwireBidAdapter.js +169 -242
  130. package/modules/cwireBidAdapter.md +15 -14
  131. package/modules/hadronIdSystem.js +37 -32
  132. package/modules/nexx360BidAdapter.js +1 -2
  133. package/modules/onetagBidAdapter.js +12 -1
  134. package/modules/outbrainBidAdapter.js +103 -6
  135. package/modules/permutiveRtdProvider.js +17 -12
  136. package/modules/priceFloors.js +7 -8
  137. package/modules/pulsepointBidAdapter.js +2 -0
  138. package/modules/smartadserverBidAdapter.js +39 -28
  139. package/modules/smartyadsBidAdapter.md +9 -0
  140. package/modules/smartytechBidAdapter.js +67 -10
  141. package/modules/smartytechBidAdapter.md +44 -33
  142. package/modules/sonobiBidAdapter.js +17 -10
  143. package/modules/taboolaBidAdapter.js +2 -1
  144. package/modules/vidazooBidAdapter.js +56 -22
  145. package/modules/zeta_global_sspBidAdapter.js +15 -0
  146. package/modules/zeusPrimeRtdProvider.js +3 -323
  147. package/modules/zeusPrimeRtdProvider.md +3 -0
  148. package/package.json +1 -1
  149. package/src/auction.js +2 -11
  150. package/src/prebid.js +8 -0
  151. package/src/utils/cpm.js +17 -0
  152. package/test/spec/modules/adyoulikeBidAdapter_spec.js +3 -0
  153. package/test/spec/modules/consentManagement_spec.js +49 -1
  154. package/test/spec/modules/cwireBidAdapter_spec.js +249 -335
  155. package/test/spec/modules/hadronIdSystem_spec.js +4 -6
  156. package/test/spec/modules/nexx360BidAdapter_spec.js +0 -4
  157. package/test/spec/modules/onetagBidAdapter_spec.js +43 -0
  158. package/test/spec/modules/outbrainBidAdapter_spec.js +182 -18
  159. package/test/spec/modules/pulsepointBidAdapter_spec.js +11 -1
  160. package/test/spec/modules/smartadserverBidAdapter_spec.js +116 -5
  161. package/test/spec/modules/smartytechBidAdapter_spec.js +172 -14
  162. package/test/spec/modules/sonobiBidAdapter_spec.js +2 -1
  163. package/test/spec/modules/taboolaBidAdapter_spec.js +12 -3
  164. package/test/spec/modules/userId_spec.js +19 -14
  165. package/test/spec/modules/vidazooBidAdapter_spec.js +61 -22
  166. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +8 -0
  167. package/test/spec/unit/pbjs_api_spec.js +14 -0
  168. package/test/spec/unit/utils/cpm_spec.js +64 -0
  169. package/test/spec/modules/zeusPrimeRtdProvider_spec.js +0 -410
@@ -1,307 +1,234 @@
1
1
  import {registerBidder} from '../src/adapters/bidderFactory.js';
2
2
  import {getStorageManager} from '../src/storageManager.js';
3
- import {BANNER, VIDEO} from '../src/mediaTypes.js';
4
- import {OUTSTREAM} from '../src/video.js';
5
- import {
6
- deepAccess,
7
- generateUUID,
8
- getBidIdParameter,
9
- getParameterByName,
10
- getValue,
11
- isArray,
12
- isNumber,
13
- isStr,
14
- logError,
15
- logWarn,
16
- parseSizesInput,
17
- } from '../src/utils.js';
18
- import {Renderer} from '../src/Renderer.js';
19
- import {find} from '../src/polyfill.js';
3
+ import {BANNER} from '../src/mediaTypes.js';
4
+ import {generateUUID, getParameterByName, isNumber, logError, logInfo} from '../src/utils.js';
20
5
 
21
6
  // ------------------------------------
22
7
  const BIDDER_CODE = 'cwire';
23
- export const ENDPOINT_URL = 'https://embed.cwi.re/delivery/prebid';
24
- export const RENDERER_URL = 'https://cdn.cwi.re/prebid/renderer/LATEST/renderer.min.js';
25
- // ------------------------------------
26
- export const CW_PAGE_VIEW_ID = generateUUID();
27
- const LS_CWID_KEY = 'cw_cwid';
28
- const CW_GROUPS_QUERY = 'cwgroups';
29
- const CW_CREATIVE_QUERY = 'cwcreative';
8
+ const CWID_KEY = 'cw_cwid';
30
9
 
31
- const storage = getStorageManager({bidderCode: BIDDER_CODE});
10
+ export const BID_ENDPOINT = 'https://prebid.cwi.re/v1/bid';
11
+ export const EVENT_ENDPOINT = 'https://prebid.cwi.re/v1/event';
32
12
 
33
13
  /**
34
- * ------------------------------------
35
- * ------------------------------------
36
- * @param bid
37
- * @returns {Array<string>}
14
+ * Allows limiting ad impressions per site render. Unique per prebid instance ID.
38
15
  */
39
- export function getSlotSizes(bid) {
40
- return parseSizesInput(getAllMediaSizes(bid));
41
- }
16
+ export const pageViewId = generateUUID();
17
+
18
+ export const storage = getStorageManager({bidderCode: BIDDER_CODE});
42
19
 
43
20
  /**
44
- * ------------------------------------
45
- * ------------------------------------
21
+ * Retrieve dimensions and CSS max height/width from a given slot and attach the properties to the bidRequest.
46
22
  * @param bid
47
- * @returns {*[]}
23
+ * @returns {*&{cwExt: {dimensions: {width: number, height: number}, style: {maxWidth: number, maxHeight: number}}}}
48
24
  */
49
- export function getAllMediaSizes(bid) {
50
- let playerSizes = deepAccess(bid, 'mediaTypes.video.playerSize');
51
- let videoSizes = deepAccess(bid, 'mediaTypes.video.sizes');
52
- let bannerSizes = deepAccess(bid, 'mediaTypes.banner.sizes');
53
-
54
- const sizes = [];
55
-
56
- if (isArray(playerSizes)) {
57
- playerSizes.forEach((s) => {
58
- sizes.push(s);
59
- })
60
- }
61
-
62
- if (isArray(videoSizes)) {
63
- videoSizes.forEach((s) => {
64
- sizes.push(s);
65
- })
25
+ function slotDimensions(bid) {
26
+ let adUnitCode = bid.adUnitCode;
27
+ let slotEl = document.getElementById(adUnitCode);
28
+
29
+ if (slotEl) {
30
+ logInfo(`Slot element found: ${adUnitCode}`)
31
+ const slotW = slotEl.offsetWidth
32
+ const slotH = slotEl.offsetHeight
33
+ const cssMaxW = slotEl.style?.maxWidth;
34
+ const cssMaxH = slotEl.style?.maxHeight;
35
+ logInfo(`Slot dimensions (w/h): ${slotW} / ${slotH}`)
36
+ logInfo(`Slot Styles (maxW/maxH): ${cssMaxW} / ${cssMaxH}`)
37
+
38
+ bid = {
39
+ ...bid,
40
+ cwExt: {
41
+ dimensions: {
42
+ width: slotW,
43
+ height: slotH,
44
+ },
45
+ style: {
46
+ ...(cssMaxW) && {
47
+ maxWidth: cssMaxW
48
+ },
49
+ ...(cssMaxH) && {
50
+ maxHeight: cssMaxH
51
+ }
52
+ }
53
+ }
54
+ }
66
55
  }
56
+ return bid
57
+ }
67
58
 
68
- if (isArray(bannerSizes)) {
69
- bannerSizes.forEach((s) => {
70
- sizes.push(s);
71
- })
59
+ /**
60
+ * Extracts feature flags from a comma-separated url parameter `cwfeatures`.
61
+ *
62
+ * @returns *[]
63
+ */
64
+ function getFeatureFlags() {
65
+ let ffParam = getParameterByName('cwfeatures')
66
+ if (ffParam) {
67
+ return ffParam.split(',')
72
68
  }
73
- return sizes;
69
+ return []
74
70
  }
75
71
 
76
- const getQueryVariable = (variable) => {
77
- let value = getParameterByName(variable);
78
- if (value === '') {
79
- value = null;
72
+ function getRefGroups() {
73
+ const groups = getParameterByName('cwgroups')
74
+ if (groups) {
75
+ return groups.split(',')
80
76
  }
81
- return value;
82
- };
77
+ return []
78
+ }
83
79
 
84
80
  /**
85
- * ------------------------------------
86
- * ------------------------------------
87
- * @param validBidRequests
88
- * @returns {*[]}
81
+ * Reads the CWID from local storage.
89
82
  */
90
- export const mapSlotsData = function(validBidRequests) {
91
- const slots = [];
92
- validBidRequests.forEach(bid => {
93
- const bidObj = {};
94
- // get testing / debug params
95
- let cwcreative = getValue(bid.params, 'cwcreative');
96
- let refgroups = getValue(bid.params, 'refgroups');
97
- let cwapikey = getValue(bid.params, 'cwapikey');
83
+ function getCwid() {
84
+ return storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(CWID_KEY) : null;
85
+ }
98
86
 
99
- // get the pacement and page ids
100
- let placementId = getValue(bid.params, 'placementId');
101
- let pageId = getValue(bid.params, 'pageId');
102
- // get the rest of the auction/bid/transaction info
103
- bidObj.auctionId = getBidIdParameter('auctionId', bid);
104
- bidObj.adUnitCode = getBidIdParameter('adUnitCode', bid);
105
- bidObj.bidId = getBidIdParameter('bidId', bid);
106
- bidObj.bidderRequestId = getBidIdParameter('bidderRequestId', bid);
107
- bidObj.placementId = placementId;
108
- bidObj.pageId = pageId;
109
- bidObj.mediaTypes = getBidIdParameter('mediaTypes', bid);
110
- bidObj.transactionId = getBidIdParameter('transactionId', bid);
111
- bidObj.sizes = getSlotSizes(bid);
112
- bidObj.cwcreative = cwcreative;
113
- bidObj.refgroups = refgroups;
114
- bidObj.cwapikey = cwapikey;
115
- slots.push(bidObj);
116
- });
87
+ function hasCwid() {
88
+ return storage.localStorageIsEnabled() && storage.getDataFromLocalStorage(CWID_KEY);
89
+ }
117
90
 
118
- return slots;
119
- };
91
+ /**
92
+ * Store the CWID to local storage.
93
+ */
94
+ function updateCwid(cwid) {
95
+ if (storage.localStorageIsEnabled()) {
96
+ storage.setDataInLocalStorage(CWID_KEY, cwid)
97
+ } else {
98
+ logInfo(`Could not set CWID ${cwid} in localstorage`);
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Extract and collect cwire specific extensions.
104
+ */
105
+ function getCwExtension() {
106
+ const cwId = getCwid();
107
+ const cwCreative = getParameterByName('cwcreative')
108
+ const cwGroups = getRefGroups()
109
+ const cwFeatures = getFeatureFlags();
110
+ // Enable debug flag by passing ?cwdebug=true as url parameter.
111
+ // Note: pbjs_debug=true enables it on prebid level
112
+ // More info: https://docs.prebid.org/troubleshooting/troubleshooting-guide.html#turn-on-prebidjs-debug-messages
113
+ const debug = getParameterByName('cwdebug');
114
+
115
+ return {
116
+ ...(cwId) && {
117
+ cwid: cwId
118
+ },
119
+ ...(cwGroups.length > 0) && {
120
+ refgroups: cwGroups
121
+ },
122
+ ...(cwFeatures.length > 0) && {
123
+ featureFlags: cwFeatures
124
+ },
125
+ ...(cwCreative) && {
126
+ cwcreative: cwCreative
127
+ },
128
+ ...(debug) && {
129
+ debug: true
130
+ }
131
+ };
132
+ }
120
133
 
121
134
  export const spec = {
122
135
  code: BIDDER_CODE,
123
- supportedMediaTypes: [BANNER, VIDEO],
136
+ supportedMediaTypes: [BANNER],
137
+
124
138
  /**
125
- * Determines whether or not the given bid request is valid.
139
+ * Determines whether the given bid request is valid.
126
140
  *
127
141
  * @param {BidRequest} bid The bid params to validate.
128
142
  * @return boolean True if this is a valid bid, and false otherwise.
129
143
  */
130
- isBidRequestValid: function(bid) {
131
- bid.params = bid.params || {};
132
-
133
- if (bid.params.cwcreative && !isStr(bid.params.cwcreative)) {
134
- logError('cwcreative must be of type string!');
135
- return false;
136
- }
137
-
138
- if (!bid.params.placementId || !isNumber(bid.params.placementId)) {
139
- logError('placementId not provided or invalid');
144
+ isBidRequestValid: function (bid) {
145
+ if (!bid.params?.placementId || !isNumber(bid.params.placementId)) {
146
+ logError('placementId not provided or not a number');
140
147
  return false;
141
148
  }
142
149
 
143
- if (!bid.params.pageId || !isNumber(bid.params.pageId)) {
144
- logError('pageId not provided');
150
+ if (!bid.params?.pageId || !isNumber(bid.params.pageId)) {
151
+ logError('pageId not provided or not a number');
145
152
  return false;
146
153
  }
147
-
148
154
  return true;
149
155
  },
150
156
 
151
157
  /**
152
- * ------------------------------------
153
- * itterate trough slots array and try
154
- * to extract first occurence of a given
155
- * key, if not found - return null
156
- * ------------------------------------
157
- */
158
- getFirstValueOrNull: function(slots, key) {
159
- const found = slots.find((item) => {
160
- return (typeof item[key] !== 'undefined');
161
- });
162
-
163
- return (found) ? found[key] : null;
164
- },
165
-
166
- /**
167
- * ------------------------------------
168
- * Make a server request from the
169
- * list of BidRequests.
170
- * ------------------------------------
171
- * @param {validBidRequests[]} - an array of bids
158
+ * Make a server request from the list of BidRequests.
159
+ *
160
+ * @param {validBidRequests[]} validBidRequests An array of bids.
172
161
  * @return ServerRequest Info describing the request to the server.
173
162
  */
174
- buildRequests: function(validBidRequests, bidderRequest) {
175
- let slots = [];
176
- let referer;
177
- try {
178
- referer = bidderRequest?.refererInfo?.page;
179
- slots = mapSlotsData(validBidRequests);
180
- } catch (e) {
181
- logWarn(e);
182
- }
163
+ buildRequests: function (validBidRequests, bidderRequest) {
164
+ // There are more fields on the refererInfo object
165
+ let referrer = bidderRequest?.refererInfo?.page
183
166
 
184
- let refgroups = [];
185
-
186
- const cwCreative = getQueryVariable(CW_CREATIVE_QUERY) || null;
187
- const cwCreativeIdFromConfig = this.getFirstValueOrNull(slots, 'cwcreative');
188
- const refGroupsFromConfig = this.getFirstValueOrNull(slots, 'refgroups');
189
- const cwApiKeyFromConfig = this.getFirstValueOrNull(slots, 'cwapikey');
190
- const rgQuery = getQueryVariable(CW_GROUPS_QUERY);
191
-
192
- if (refGroupsFromConfig !== null) {
193
- refgroups = refGroupsFromConfig.split(',');
194
- }
195
-
196
- if (rgQuery !== null) {
197
- // override if query param is present
198
- refgroups = [];
199
- refgroups = rgQuery.split(',');
200
- }
201
-
202
- const localStorageCWID = storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(LS_CWID_KEY) : null;
167
+ // process bid requests
168
+ let processed = validBidRequests
169
+ .map(bid => slotDimensions(bid))
170
+ // Flattens the pageId and placement Id for backwards compatibility.
171
+ .map((bid) => ({...bid, pageId: bid.params?.pageId, placementId: bid.params?.placementId}));
203
172
 
173
+ const extensions = getCwExtension();
204
174
  const payload = {
205
- cwid: localStorageCWID,
206
- refgroups,
207
- cwcreative: cwCreative || cwCreativeIdFromConfig,
208
- slots: slots,
209
- cwapikey: cwApiKeyFromConfig,
210
- httpRef: referer || '',
211
- pageViewId: CW_PAGE_VIEW_ID,
175
+ slots: processed,
176
+ httpRef: referrer,
177
+ // TODO: Verify whether the auctionId and the usage of pageViewId make sense.
178
+ pageViewId: pageViewId,
179
+ sdk: {
180
+ version: '$prebid.version$'
181
+ },
182
+ ...extensions
212
183
  };
213
-
184
+ const payloadString = JSON.stringify(payload);
214
185
  return {
215
186
  method: 'POST',
216
- url: ENDPOINT_URL,
217
- data: payload
187
+ url: BID_ENDPOINT,
188
+ data: payloadString,
218
189
  };
219
190
  },
220
-
221
191
  /**
222
192
  * Unpack the response from the server into a list of bids.
223
193
  *
224
194
  * @param {ServerResponse} serverResponse A successful response from the server.
225
195
  * @return {Bid[]} An array of bids which were nested inside the server.
226
196
  */
227
- interpretResponse: function(serverResponse, bidRequest) {
228
- const bidResponses = [];
229
-
230
- try {
231
- if (typeof bidRequest.data === 'string') {
232
- bidRequest.data = JSON.parse(bidRequest.data);
197
+ interpretResponse: function (serverResponse, bidRequest) {
198
+ if (!hasCwid()) {
199
+ const cwid = serverResponse.body?.cwid
200
+ if (cwid) {
201
+ updateCwid(cwid);
233
202
  }
234
- const serverBody = serverResponse.body;
235
- serverBody.bids.forEach((br) => {
236
- const bidReq = find(bidRequest.data.slots, bid => bid.bidId === br.requestId);
237
-
238
- let mediaType = BANNER;
239
-
240
- const bidResponse = {
241
- requestId: br.requestId,
242
- cpm: br.cpm,
243
- bidderCode: BIDDER_CODE,
244
- width: br.dimensions[0],
245
- height: br.dimensions[1],
246
- creativeId: br.creativeId,
247
- currency: br.currency,
248
- netRevenue: br.netRevenue,
249
- ttl: br.ttl,
250
- meta: {
251
- advertiserDomains: br.adomains ? br.advertiserDomains : [],
252
- },
253
-
254
- };
255
-
256
- // ------------------------------------
257
- // IF BANNER
258
- // ------------------------------------
259
-
260
- if (deepAccess(bidReq, 'mediaTypes.banner')) {
261
- bidResponse.ad = br.html;
262
- }
263
- // ------------------------------------
264
- // IF VIDEO
265
- // ------------------------------------
266
- if (deepAccess(bidReq, 'mediaTypes.video')) {
267
- mediaType = VIDEO;
268
- bidResponse.vastXml = br.vastXml;
269
- bidResponse.videoScript = br.html;
270
- const mediaTypeContext = deepAccess(bidReq, 'mediaTypes.video.context');
271
- if (mediaTypeContext === OUTSTREAM) {
272
- const r = Renderer.install({
273
- id: bidResponse.requestId,
274
- adUnitCode: bidReq.adUnitCode,
275
- url: RENDERER_URL,
276
- loaded: false,
277
- config: {
278
- ...deepAccess(bidReq, 'mediaTypes.video'),
279
- ...deepAccess(br, 'outstream', {})
280
- }
281
- });
203
+ }
282
204
 
283
- // set renderer
284
- try {
285
- bidResponse.renderer = r;
286
- bidResponse.renderer.setRender(function(bid) {
287
- if (window.CWIRE && window.CWIRE.outstream) {
288
- window.CWIRE.outstream.renderAd(bid);
289
- }
290
- });
291
- } catch (err) {
292
- logWarn('Prebid Error calling setRender on newRenderer', err);
293
- }
294
- }
295
- }
205
+ // Rename `html` response property to `ad` as used by prebid.
206
+ const bids = serverResponse.body?.bids.map(({html, ...rest}) => ({...rest, ad: html}));
207
+ return bids || [];
208
+ },
296
209
 
297
- bidResponse.mediaType = mediaType;
298
- bidResponses.push(bidResponse);
299
- });
300
- } catch (e) {
301
- logWarn(e);
210
+ onBidWon: function (bid) {
211
+ logInfo(`Bid won.`)
212
+ const event = {
213
+ type: 'BID_WON',
214
+ payload: {
215
+ bid: bid
216
+ }
302
217
  }
218
+ navigator.sendBeacon(EVENT_ENDPOINT, JSON.stringify(event))
219
+ },
303
220
 
304
- return bidResponses;
221
+ onBidderError: function (error, bidderRequest) {
222
+ logInfo(`Bidder error: ${error}`)
223
+ const event = {
224
+ type: 'BID_ERROR',
225
+ payload: {
226
+ error: error,
227
+ bidderRequest: bidderRequest
228
+ }
229
+ }
230
+ navigator.sendBeacon(EVENT_ENDPOINT, JSON.stringify(event))
305
231
  },
232
+
306
233
  };
307
234
  registerBidder(spec);
@@ -1,25 +1,27 @@
1
1
  # Overview
2
2
 
3
- Module Name: C-WIRE Bid Adapter
4
- Module Type: Adagio Adapter
5
- Maintainer: publishers@cwire.ch
3
+ ```
4
+ Module Name: C-WIRE Bid Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: devs@cwire.ch
7
+ ```
6
8
 
7
9
  ## Description
8
10
 
9
- Connects to C-WIRE demand source to fetch bids.
11
+ Prebid.js Adapter for C-Wire.
10
12
 
11
13
  ## Configuration
12
14
 
13
-
14
15
  Below, the list of C-WIRE params and where they can be set.
15
16
 
16
- | Param name | Global config | AdUnit config | Type | Required |
17
- | ---------- | ------------- | ------------- |--------| ---------|
18
- | pageId | | x | number | YES |
19
- | placementId | | x | number | YES |
20
- | refgroups | | x | string | NO |
21
- | cwcreative | | x | string | NO |
22
- | cwapikey | | x | string | NO |
17
+ | Param name | URL parameter | AdUnit config | Type | Required |
18
+ |-------------|:-------------:|:-------------:|:--------:|:-------------:|
19
+ | pageId | | x | number | YES |
20
+ | placementId | | x | number | YES |
21
+ | cwgroups | x | | string | NO |
22
+ | cwcreative | x | | string | NO |
23
+ | cwdebug | x | | boolean | NO |
24
+ | cwfeatures | x | | string | NO |
23
25
 
24
26
 
25
27
  ### adUnit configuration
@@ -32,7 +34,7 @@ var adUnits = [
32
34
  bidder: 'cwire',
33
35
  mediaTypes: {
34
36
  banner: {
35
- sizes: [[1, 1]],
37
+ sizes: [[400, 600]],
36
38
  }
37
39
  },
38
40
  params: {
@@ -40,7 +42,6 @@ var adUnits = [
40
42
  placementId: 2211521, // required - number
41
43
  cwcreative: '42', // optional - id of creative to force
42
44
  refgroups: 'test-user', // optional - name of group or coma separated list of groups to force
43
- cwapikey: 'api_key_xyz', // optional - api key for integration testing
44
45
  }
45
46
  }]
46
47
  }
@@ -8,8 +8,9 @@
8
8
  import {ajax} from '../src/ajax.js';
9
9
  import {getStorageManager} from '../src/storageManager.js';
10
10
  import {submodule} from '../src/hook.js';
11
- import { isFn, isStr, isPlainObject, logError } from '../src/utils.js';
11
+ import {isFn, isStr, isPlainObject, logError, logInfo} from '../src/utils.js';
12
12
 
13
+ const HADRONID_LOCAL_NAME = 'auHadronId';
13
14
  const MODULE_NAME = 'hadronId';
14
15
  const AU_GVLID = 561;
15
16
  const DEFAULT_HADRON_URL_ENDPOINT = 'https://id.hadron.ad.gt/api/v1/pbhid';
@@ -18,8 +19,9 @@ export const storage = getStorageManager({gvlid: AU_GVLID, moduleName: 'hadron'}
18
19
 
19
20
  /**
20
21
  * Param or default.
21
- * @param {String} param
22
+ * @param {String|function} param
22
23
  * @param {String} defaultVal
24
+ * @param arg
23
25
  */
24
26
  function paramOrDefault(param, defaultVal, arg) {
25
27
  if (isFn(param)) {
@@ -53,11 +55,11 @@ export const hadronIdSubmodule = {
53
55
  * @returns {Object}
54
56
  */
55
57
  decode(value) {
56
- let hadronId = storage.getDataFromLocalStorage('auHadronId');
58
+ const hadronId = storage.getDataFromLocalStorage(HADRONID_LOCAL_NAME);
57
59
  if (isStr(hadronId)) {
58
60
  return {hadronId: hadronId};
59
61
  }
60
- return (value && typeof value['hadronId'] === 'string') ? { 'hadronId': value['hadronId'] } : undefined;
62
+ return (value && typeof value['hadronId'] === 'string') ? {'hadronId': value['hadronId']} : undefined;
61
63
  },
62
64
  /**
63
65
  * performs action to obtain id and return a value in the callback's response argument
@@ -70,37 +72,40 @@ export const hadronIdSubmodule = {
70
72
  config.params = {};
71
73
  }
72
74
  const partnerId = config.params.partnerId | 0;
73
-
74
- const url = urlAddParams(
75
- paramOrDefault(config.params.url, DEFAULT_HADRON_URL_ENDPOINT, config.params.urlArg),
76
- `partner_id=${partnerId}&_it=prebid`
77
- );
78
-
75
+ let hadronId = storage.getDataFromLocalStorage(HADRONID_LOCAL_NAME);
76
+ if (isStr(hadronId)) {
77
+ return {id: {hadronId}};
78
+ }
79
79
  const resp = function (callback) {
80
- let hadronId = storage.getDataFromLocalStorage('auHadronId');
81
- if (isStr(hadronId)) {
82
- const responseObj = {hadronId: hadronId};
83
- callback(responseObj);
84
- } else {
85
- const callbacks = {
86
- success: response => {
87
- let responseObj;
88
- if (response) {
89
- try {
90
- responseObj = JSON.parse(response);
91
- } catch (error) {
92
- logError(error);
93
- }
80
+ let responseObj = {};
81
+ const callbacks = {
82
+ success: response => {
83
+ if (response) {
84
+ try {
85
+ responseObj = JSON.parse(response);
86
+ } catch (error) {
87
+ logError(error);
94
88
  }
95
- callback(responseObj);
96
- },
97
- error: error => {
98
- logError(`${MODULE_NAME}: ID fetch encountered an error`, error);
99
- callback();
89
+ logInfo(`Response from backend is ${responseObj}`);
90
+ hadronId = responseObj['hadronId'];
91
+ storage.setDataInLocalStorage(HADRONID_LOCAL_NAME, hadronId);
92
+ responseObj = {id: {hadronId}};
100
93
  }
101
- };
102
- ajax(url, callbacks, undefined, {method: 'GET'});
103
- }
94
+ callback(responseObj);
95
+ },
96
+ error: error => {
97
+ logError(`${MODULE_NAME}: ID fetch encountered an error`, error);
98
+ callback();
99
+ }
100
+ };
101
+ logInfo('HadronId not found in storage, calling backend...');
102
+ const url = urlAddParams(
103
+ // config.params.url and config.params.urlArg are not documented
104
+ // since their use is for debugging purposes only
105
+ paramOrDefault(config.params.url, DEFAULT_HADRON_URL_ENDPOINT, config.params.urlArg),
106
+ `partner_id=${partnerId}&_it=prebid`
107
+ );
108
+ ajax(url, callbacks, undefined, {method: 'GET'});
104
109
  };
105
110
  return {callback: resp};
106
111
  }
@@ -258,14 +258,13 @@ function interpretResponse(response, req) {
258
258
  currency: respBody.cur || 'USD',
259
259
  netRevenue: true,
260
260
  ttl: 120,
261
- bidderCode: allowAlternateBidderCodes ? `n360-${bid.ssp}` : 'nexx360',
262
261
  mediaType: bid.type === 'banner' ? 'banner' : 'video',
263
262
  meta: {
264
263
  advertiserDomains: bid.adomain,
265
264
  demandSource: ssp,
266
265
  },
267
266
  };
268
- // if (bid.dealid) response.dealid = bid.dealid;
267
+ if (allowAlternateBidderCodes) response.bidderCode = `n360-${bid.ssp}`;
269
268
 
270
269
  if (response.mediaType === 'banner') {
271
270
  response.adUrl = bid.adUrl;