prebid.js 9.40.0 → 9.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/dist/33acrossAnalyticsAdapter.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/BTBidAdapter.js +1 -1
  5. package/dist/adagioAnalyticsAdapter.js +1 -1
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adagioUtils.js +1 -1
  8. package/dist/addefendBidAdapter.js +1 -1
  9. package/dist/adgenerationBidAdapter.js +1 -1
  10. package/dist/adlooxRtdProvider.js +1 -1
  11. package/dist/adqueryBidAdapter.js +1 -1
  12. package/dist/adrelevantisBidAdapter.js +1 -1
  13. package/dist/adstirBidAdapter.js +1 -1
  14. package/dist/adtrgtmeBidAdapter.js +1 -1
  15. package/dist/adxcgAnalyticsAdapter.js +1 -1
  16. package/dist/adxcgBidAdapter.js +1 -1
  17. package/dist/adyoulikeBidAdapter.js +1 -1
  18. package/dist/agmaAnalyticsAdapter.js +1 -1
  19. package/dist/ajaBidAdapter.js +1 -1
  20. package/dist/amxBidAdapter.js +1 -1
  21. package/dist/amxIdSystem.js +1 -1
  22. package/dist/aniviewBidAdapter.js +1 -1
  23. package/dist/appierAnalyticsAdapter.js +1 -1
  24. package/dist/appnexusBidAdapter.js +1 -1
  25. package/dist/asoBidAdapter.js +1 -1
  26. package/dist/axonixBidAdapter.js +1 -1
  27. package/dist/beopBidAdapter.js +1 -1
  28. package/dist/bidglassBidAdapter.js +1 -1
  29. package/dist/big-richmediaBidAdapter.js +1 -1
  30. package/dist/bitmediaBidAdapter.js +1 -1
  31. package/dist/braveUtils.js +1 -1
  32. package/dist/bridBidAdapter.js +1 -1
  33. package/dist/bridgeuppBidAdapter.js +1 -1
  34. package/dist/bridgewellBidAdapter.js +1 -1
  35. package/dist/brightMountainMediaBidAdapter.js +1 -1
  36. package/dist/carodaBidAdapter.js +1 -1
  37. package/dist/chtnwBidAdapter.js +1 -1
  38. package/dist/chunk-core.js +1 -1
  39. package/dist/concertBidAdapter.js +1 -1
  40. package/dist/connectadBidAdapter.js +1 -1
  41. package/dist/consumableBidAdapter.js +1 -1
  42. package/dist/contxtfulBidAdapter.js +1 -1
  43. package/dist/conversantAnalyticsAdapter.js +1 -1
  44. package/dist/conversantBidAdapter.js +1 -1
  45. package/dist/craftBidAdapter.js +1 -1
  46. package/dist/criteoBidAdapter.js +1 -1
  47. package/dist/cwireBidAdapter.js +1 -1
  48. package/dist/dailymotionBidAdapter.js +1 -1
  49. package/dist/dependencies.json +4 -0
  50. package/dist/dspxBidAdapter.js +1 -1
  51. package/dist/dxkultureBidAdapter.js +1 -1
  52. package/dist/eplanningBidAdapter.js +1 -1
  53. package/dist/epomDspBidAdapter.js +1 -0
  54. package/dist/equativBidAdapter.js +1 -1
  55. package/dist/eskimiBidAdapter.js +1 -1
  56. package/dist/euidIdSystem.js +1 -1
  57. package/dist/exadsBidAdapter.js +1 -1
  58. package/dist/excoBidAdapter.js +1 -1
  59. package/dist/feedadBidAdapter.js +1 -1
  60. package/dist/finativeBidAdapter.js +1 -1
  61. package/dist/freewheel-sspBidAdapter.js +1 -1
  62. package/dist/gmosspBidAdapter.js +1 -1
  63. package/dist/goldbachBidAdapter.js +1 -1
  64. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  65. package/dist/greenbidsBidAdapter.js +1 -1
  66. package/dist/greenbidsRtdProvider.js +1 -1
  67. package/dist/gridBidAdapter.js +1 -1
  68. package/dist/gumgumBidAdapter.js +1 -1
  69. package/dist/h12mediaBidAdapter.js +1 -1
  70. package/dist/hypelabBidAdapter.js +1 -1
  71. package/dist/id5AnalyticsAdapter.js +1 -1
  72. package/dist/id5IdSystem.js +1 -1
  73. package/dist/imdsBidAdapter.js +1 -1
  74. package/dist/improvedigitalBidAdapter.js +1 -1
  75. package/dist/inmobiBidAdapter.js +1 -1
  76. package/dist/insticatorBidAdapter.js +1 -1
  77. package/dist/intentIqAnalyticsAdapter.js +1 -1
  78. package/dist/ixBidAdapter.js +1 -1
  79. package/dist/jixieBidAdapter.js +1 -1
  80. package/dist/justpremiumBidAdapter.js +1 -1
  81. package/dist/kargoBidAdapter.js +1 -1
  82. package/dist/kimberliteBidAdapter.js +1 -1
  83. package/dist/konduitAnalyticsAdapter.js +1 -1
  84. package/dist/kueezBidAdapter.js +1 -1
  85. package/dist/lassoBidAdapter.js +1 -1
  86. package/dist/lifestreetBidAdapter.js +1 -1
  87. package/dist/liveIntentId.js +1 -1
  88. package/dist/logicadBidAdapter.js +1 -1
  89. package/dist/loglyliftBidAdapter.js +1 -1
  90. package/dist/luceadBidAdapter.js +1 -1
  91. package/dist/mabidderBidAdapter.js +1 -1
  92. package/dist/madsenseBidAdapter.js +1 -1
  93. package/dist/magniteAnalyticsAdapter.js +1 -1
  94. package/dist/malltvAnalyticsAdapter.js +1 -1
  95. package/dist/marsmediaBidAdapter.js +1 -1
  96. package/dist/mediafuseBidAdapter.js +1 -1
  97. package/dist/medianetBidAdapter.js +1 -1
  98. package/dist/medianetUtils.js +1 -1
  99. package/dist/mediasquareBidAdapter.js +1 -1
  100. package/dist/mgidBidAdapter.js +1 -1
  101. package/dist/missenaBidAdapter.js +1 -1
  102. package/dist/nextMillenniumBidAdapter.js +1 -1
  103. package/dist/nexx360BidAdapter.js +1 -1
  104. package/dist/nobidAnalyticsAdapter.js +1 -1
  105. package/dist/nobidBidAdapter.js +1 -1
  106. package/dist/nodalsAiRtdProvider.js +1 -1
  107. package/dist/not-for-prod/prebid.js +170 -168
  108. package/dist/oguryBidAdapter.js +1 -1
  109. package/dist/onetagBidAdapter.js +1 -1
  110. package/dist/ooloAnalyticsAdapter.js +1 -1
  111. package/dist/openxBidAdapter.js +1 -1
  112. package/dist/optidigitalBidAdapter.js +1 -1
  113. package/dist/orbidderBidAdapter.js +1 -1
  114. package/dist/outbrainBidAdapter.js +1 -1
  115. package/dist/pixfutureBidAdapter.js +1 -1
  116. package/dist/publinkIdSystem.js +1 -1
  117. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  118. package/dist/pubmaticBidAdapter.js +1 -1
  119. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  120. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  121. package/dist/pxyzBidAdapter.js +1 -1
  122. package/dist/quantcastBidAdapter.js +1 -1
  123. package/dist/raveltechRtdProvider.js +1 -0
  124. package/dist/readpeakBidAdapter.js +1 -1
  125. package/dist/relaidoBidAdapter.js +1 -1
  126. package/dist/retailspotBidAdapter.js +1 -1
  127. package/dist/rhythmoneBidAdapter.js +1 -1
  128. package/dist/riseUtils.js +1 -1
  129. package/dist/rubiconBidAdapter.js +1 -1
  130. package/dist/seedingAllianceBidAdapter.js +1 -1
  131. package/dist/seedtagBidAdapter.js +1 -1
  132. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  133. package/dist/sharethroughBidAdapter.js +1 -1
  134. package/dist/showheroes-bsBidAdapter.js +1 -1
  135. package/dist/smaatoBidAdapter.js +1 -1
  136. package/dist/smartadserverBidAdapter.js +1 -1
  137. package/dist/smartxBidAdapter.js +1 -1
  138. package/dist/smilewantedBidAdapter.js +1 -1
  139. package/dist/snigelBidAdapter.js +1 -1
  140. package/dist/sonobiBidAdapter.js +1 -1
  141. package/dist/sovrnBidAdapter.js +1 -1
  142. package/dist/sparteoBidAdapter.js +1 -1
  143. package/dist/sspBCBidAdapter.js +1 -1
  144. package/dist/stvBidAdapter.js +1 -1
  145. package/dist/sublimeBidAdapter.js +1 -1
  146. package/dist/taboolaBidAdapter.js +1 -1
  147. package/dist/tappxBidAdapter.js +1 -1
  148. package/dist/targetVideoBidAdapter.js +1 -1
  149. package/dist/teadsBidAdapter.js +1 -1
  150. package/dist/terceptAnalyticsAdapter.js +1 -1
  151. package/dist/themoneytizerBidAdapter.js +1 -1
  152. package/dist/trionBidAdapter.js +1 -1
  153. package/dist/tripleliftBidAdapter.js +1 -1
  154. package/dist/ttdBidAdapter.js +1 -1
  155. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  156. package/dist/uid2IdSystem.js +1 -1
  157. package/dist/underdogmediaBidAdapter.js +1 -1
  158. package/dist/undertoneBidAdapter.js +1 -1
  159. package/dist/unrulyBidAdapter.js +1 -1
  160. package/dist/vidazooUtils.js +1 -1
  161. package/dist/videobyteBidAdapter.js +1 -1
  162. package/dist/visxBidAdapter.js +1 -1
  163. package/dist/vuukleBidAdapter.js +1 -1
  164. package/dist/widespaceBidAdapter.js +1 -1
  165. package/dist/winrBidAdapter.js +1 -1
  166. package/dist/yahooAdsBidAdapter.js +1 -1
  167. package/dist/yandexBidAdapter.js +1 -1
  168. package/dist/yieldmoBidAdapter.js +1 -1
  169. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  170. package/dist/yieldoneBidAdapter.js +1 -1
  171. package/gulpfile.js +2 -1
  172. package/integrationExamples/gpt/raveltechRtdProvider_example.html +379 -0
  173. package/libraries/braveUtils/index.js +1 -1
  174. package/libraries/riseUtils/index.js +1 -1
  175. package/modules/epomDspBidAdapter.js +177 -0
  176. package/modules/epomDspBidAdapter.md +170 -0
  177. package/modules/equativBidAdapter.js +14 -3
  178. package/modules/goldbachBidAdapter.js +160 -300
  179. package/modules/raveltechRtdProvider.js +131 -0
  180. package/modules/raveltechRtdProvider.md +61 -0
  181. package/modules/seedtagBidAdapter.js +1 -0
  182. package/modules/yandexBidAdapter.js +4 -0
  183. package/modules/yieldoneBidAdapter.js +6 -0
  184. package/package.json +2 -2
  185. package/test/spec/modules/epomDspBidAdapter_spec.js +73 -0
  186. package/test/spec/modules/equativBidAdapter_spec.js +19 -1
  187. package/test/spec/modules/goldbachBidAdapter_spec.js +227 -499
  188. package/test/spec/modules/raveltechRtdProvider_spec.js +108 -0
  189. package/test/spec/modules/seedtagBidAdapter_spec.js +56 -2
  190. package/test/spec/modules/yandexBidAdapter_spec.js +6 -0
  191. package/test/spec/modules/yieldoneBidAdapter_spec.js +40 -0
@@ -1,24 +1,30 @@
1
1
  import { ajax } from '../src/ajax.js';
2
2
  import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
3
+ import { deepAccess, generateUUID } from '../src/utils.js';
3
4
  import { registerBidder } from '../src/adapters/bidderFactory.js';
5
+ import { ortbConverter } from '../libraries/ortbConverter/converter.js';
4
6
  import { Renderer } from '../src/Renderer.js';
5
- import { deepAccess } from '../src/utils.js';
7
+ import { hasPurpose1Consent } from '../src/utils/gdpr.js';
8
+ import { getStorageManager } from '../src/storageManager.js';
6
9
 
7
10
  /* General config */
8
11
  const IS_LOCAL_MODE = false;
9
12
  const BIDDER_CODE = 'goldbach';
13
+ const BIDDER_UID_KEY = 'goldbach_uid';
10
14
  const GVLID = 580;
11
- const URL = 'https://goldlayer-api.prod.gbads.net/bid/pbjs';
12
- const URL_LOCAL = 'http://localhost:3000/bid/pbjs';
13
- const LOGGING_PERCENTAGE_REGULAR = 0.0001;
15
+ const URL = 'https://goldlayer-api.prod.gbads.net/openrtb/2.5/auction';
16
+ const URL_LOCAL = 'http://localhost:3000/openrtb/2.5/auction';
17
+ const URL_LOGGING = 'https://l.da-services.ch/pb';
18
+ const URL_COOKIESYNC = 'https://goldlayer-api.prod.gbads.net/cookiesync';
19
+ const METHOD = 'POST';
20
+ const DEFAULT_CURRENCY = 'USD';
21
+ const LOGGING_PERCENTAGE_REGULAR = 0.001;
14
22
  const LOGGING_PERCENTAGE_ERROR = 0.001;
15
- const LOGGING_URL = 'https://l.da-services.ch/pb';
23
+ const COOKIE_EXP = 1000 * 60 * 60 * 24 * 365;
16
24
 
17
25
  /* Renderer settings */
18
26
  const RENDERER_OPTIONS = {
19
27
  OUTSTREAM_GP: {
20
- MIN_HEIGHT: 300,
21
- MIN_WIDTH: 300,
22
28
  URL: 'https://goldplayer.prod.gbads.net/scripts/goldplayer.js'
23
29
  }
24
30
  };
@@ -32,220 +38,69 @@ const EVENTS = {
32
38
  ERROR: 'error'
33
39
  };
34
40
 
35
- /* Targeting mapping */
36
- const TARGETING_KEYS = {
37
- // request level
38
- GEO_LAT: 'lat',
39
- GEO_LON: 'long',
40
- GEO_ZIP: 'zip',
41
- CONNECTION_TYPE: 'connection',
42
- // slot level
43
- VIDEO_DURATION: 'duration',
44
- };
41
+ /* Goldbach storage */
42
+ export const storage = getStorageManager({ bidderCode: BIDDER_CODE });
45
43
 
46
- /* Native mapping */
47
- export const OPENRTB = {
48
- NATIVE: {
49
- IMAGE_TYPE: {
50
- ICON: 1,
51
- MAIN: 3,
52
- },
53
- ASSET_ID: {
54
- TITLE: 1,
55
- IMAGE: 2,
56
- ICON: 3,
57
- BODY: 4,
58
- CTA: 5,
59
- SPONSORED: 6,
60
- }
44
+ const setUid = (uid) => {
45
+ if (storage.localStorageIsEnabled()) {
46
+ storage.setDataInLocalStorage(BIDDER_UID_KEY, uid);
47
+ } else if (storage.cookiesAreEnabled()) {
48
+ const cookieExpiration = new Date(Date.now() + COOKIE_EXP).toISOString();
49
+ storage.setCookie(BIDDER_UID_KEY, uid, cookieExpiration, 'None');
61
50
  }
62
51
  };
63
52
 
64
- /* Mapping */
65
- const convertToCustomTargeting = (bidderRequest) => {
66
- const customTargeting = {};
67
-
68
- // geo - lat/long
69
- if (bidderRequest?.ortb2?.device?.geo) {
70
- if (bidderRequest?.ortb2?.device?.geo?.lon) {
71
- customTargeting[TARGETING_KEYS.GEO_LON] = bidderRequest.ortb2.device.geo.lon;
72
- }
73
- if (bidderRequest?.ortb2?.device?.geo?.lat) {
74
- customTargeting[TARGETING_KEYS.GEO_LAT] = bidderRequest.ortb2.device.geo.lat;
75
- }
76
- }
77
-
78
- // connection
79
- if (bidderRequest?.ortb2?.device?.connectiontype) {
80
- switch (bidderRequest.ortb2.device.connectiontype) {
81
- case 1:
82
- customTargeting[TARGETING_KEYS.CONNECTION_TYPE] = 'ethernet';
83
- break;
84
- case 2:
85
- customTargeting[TARGETING_KEYS.CONNECTION_TYPE] = 'wifi';
86
- break;
87
- case 4:
88
- customTargeting[TARGETING_KEYS.CONNECTION_TYPE] = '2G';
89
- break;
90
- case 5:
91
- customTargeting[TARGETING_KEYS.CONNECTION_TYPE] = '3G';
92
- break;
93
- case 6:
94
- customTargeting[TARGETING_KEYS.CONNECTION_TYPE] = '4G';
95
- break;
96
- case 0:
97
- case 3:
98
- default:
99
- break;
100
- }
101
- }
102
-
103
- // zip
104
- if (bidderRequest?.ortb2?.device?.geo?.zip) {
105
- customTargeting[TARGETING_KEYS.GEO_ZIP] = bidderRequest.ortb2.device.geo.zip;
53
+ const getUid = () => {
54
+ if (storage.localStorageIsEnabled()) {
55
+ return storage.getDataFromLocalStorage(BIDDER_UID_KEY);
56
+ } else if (storage.cookiesAreEnabled()) {
57
+ return storage.getCookie(BIDDER_UID_KEY);
106
58
  }
59
+ return null;
60
+ };
107
61
 
108
- return customTargeting;
109
- }
110
-
111
- const convertToCustomSlotTargeting = (validBidRequest) => {
112
- const customTargeting = {};
113
-
114
- // Video duration
115
- if (validBidRequest.mediaTypes?.[VIDEO]) {
116
- if (validBidRequest.params?.video?.maxduration) {
117
- const duration = validBidRequest.params?.video?.maxduration;
118
- if (duration <= 15) customTargeting[TARGETING_KEYS.VIDEO_DURATION] = 'M';
119
- if (duration > 15 && duration <= 30) customTargeting[TARGETING_KEYS.VIDEO_DURATION] = 'XL';
120
- if (duration > 30) customTargeting[TARGETING_KEYS.VIDEO_DURATION] = 'XXL';
121
- }
122
- }
123
-
124
- return customTargeting
125
- }
126
-
127
- const convertToProprietaryData = (validBidRequests, bidderRequest) => {
128
- const requestData = {
129
- mock: false,
130
- debug: false,
131
- timestampStart: undefined,
132
- timestampEnd: undefined,
133
- config: {
134
- publisher: {
135
- id: undefined,
136
- }
137
- },
138
- gdpr: {
139
- consent: undefined,
140
- consentString: undefined,
141
- },
142
- contextInfo: {
143
- contentUrl: undefined,
144
- bidderResources: undefined,
145
- },
146
- appInfo: {
147
- id: undefined,
148
- },
149
- userInfo: {
150
- ip: undefined,
151
- ua: undefined,
152
- ifa: undefined,
153
- ppid: [],
154
- },
155
- slots: [],
156
- targetings: {},
157
- };
158
-
159
- // Set timestamps
160
- requestData.timestampStart = Date.now();
161
- requestData.timestampEnd = Date.now() + (!isNaN(bidderRequest.timeout) ? Number(bidderRequest.timeout) : 0);
162
-
163
- // Set config
164
- if (validBidRequests[0]?.params?.publisherId) {
165
- requestData.config.publisher.id = validBidRequests[0].params.publisherId;
166
- }
167
-
168
- // Set GDPR
169
- if (bidderRequest?.gdprConsent) {
170
- requestData.gdpr.consent = bidderRequest.gdprConsent.gdprApplies;
171
- requestData.gdpr.consentString = bidderRequest.gdprConsent.consentString;
172
- }
173
-
174
- // Set contextInfo
175
- requestData.contextInfo.contentUrl = bidderRequest.refererInfo?.canonicalUrl || bidderRequest.refererInfo?.topmostLocation || bidderRequest?.ortb2?.site?.page;
176
-
177
- // Set appInfo
178
- requestData.appInfo.id = bidderRequest?.ortb2?.site?.domain || bidderRequest.refererInfo?.page;
179
-
180
- // Set userInfo
181
- requestData.userInfo.ip = bidderRequest?.ortb2?.device?.ip || navigator.ip;
182
- requestData.userInfo.ua = bidderRequest?.ortb2?.device?.ua || navigator.userAgent;
183
-
184
- // Set userInfo.ppid
185
- requestData.userInfo.ppid = (validBidRequests || []).reduce((ppids, validBidRequest) => {
186
- const extractedPpids = [];
187
- (validBidRequest.userIdAsEids || []).forEach((eid) => {
188
- (eid?.uids || []).forEach(uid => {
189
- if (uid?.ext?.stype === 'ppuid') {
190
- const isExistingInExtracted = !!extractedPpids.find(id => id.source === eid.source);
191
- const isExistingInPpids = !!ppids.find(id => id.source === eid.source);
192
- if (!isExistingInExtracted && !isExistingInPpids) extractedPpids.push({source: eid.source, id: uid.id});
193
- }
194
- });
195
- })
196
- return [...ppids, ...extractedPpids];
197
- }, []);
198
-
199
- // Set userInfo.ifa
200
- if (bidderRequest.ortb2?.device?.ifa) {
201
- requestData.userInfo.ifa = bidderRequest.ortb2.device.ifa;
202
- } else {
203
- requestData.userInfo.ifa = validBidRequests.find(validBidRequest => {
204
- return !!validBidRequest.ortb2?.device?.ifa;
205
- });
206
- }
207
-
208
- // Set slots
209
- requestData.slots = validBidRequests.map((validBidRequest) => {
210
- const slot = {
211
- id: validBidRequest.params?.slotId,
212
- sizes: [
213
- ...(validBidRequest.sizes || []),
214
- ...(validBidRequest.mediaTypes?.[VIDEO]?.sizes ? validBidRequest.mediaTypes[VIDEO].sizes : [])
215
- ],
216
- targetings: {
217
- ...validBidRequest?.params?.customTargeting,
218
- ...convertToCustomSlotTargeting(validBidRequest)
219
- }
220
- };
221
- return slot;
222
- });
223
-
224
- // Set targetings
225
- requestData.targetings = convertToCustomTargeting(bidderRequest);
226
-
227
- return requestData;
228
- }
229
-
230
- const getRendererForBid = (bidRequest, creative) => {
231
- if (!bidRequest.renderer && creative.contextType === 'video_outstream') {
232
- if (!creative.vastUrl && !creative.vastXml) return undefined;
62
+ const ensureUid = (gdprConsent) => {
63
+ // Check if the user has given consent for purpose 1
64
+ if (!gdprConsent || !hasPurpose1Consent(gdprConsent)) return null;
65
+ // Check if the UID already exists
66
+ const existingUid = getUid();
67
+ if (existingUid) return existingUid;
68
+ // Generate a new UID if it doesn't exist
69
+ const uid = generateUUID();
70
+ setUid(uid);
71
+ return uid;
72
+ };
233
73
 
74
+ /* Custom extensions */
75
+ const getRendererForBid = (bidRequest, bidResponse) => {
76
+ if (!bidRequest.renderer) {
234
77
  const config = { documentResolver: (_, sourceDocument, renderDocument) => renderDocument ?? sourceDocument };
235
- const renderer = Renderer.install({id: bidRequest.bidId, url: RENDERER_OPTIONS.OUTSTREAM_GP.URL, adUnitCode: bidRequest.adUnitCode, config});
78
+ const renderer = Renderer.install({
79
+ id: bidRequest.bidId,
80
+ url: RENDERER_OPTIONS.OUTSTREAM_GP.URL,
81
+ adUnitCode: bidRequest.adUnitCode,
82
+ config
83
+ });
236
84
 
237
85
  renderer.setRender((bid, doc) => {
86
+ const videoParams = bidRequest?.mediaTypes?.video || {};
87
+ const playerSize = videoParams.playerSize;
88
+ const playbackmethod = videoParams.playbackmethod;
89
+ const isMuted = typeof playbackmethod === 'number' ? [2, 6].includes(playbackmethod) : false;
90
+ const isAutoplay = typeof playbackmethod === 'number' ? [1, 2].includes(playbackmethod) : false;
91
+
238
92
  bid.renderer.push(() => {
239
93
  if (doc.defaultView?.GoldPlayer) {
240
94
  const options = {
241
- vastUrl: creative.vastUrl,
242
- vastXML: creative.vastXml,
243
- autoplay: false,
244
- muted: false,
95
+ vastUrl: bid.vastUrl,
96
+ vastXML: bid.vastXml,
97
+ autoplay: isAutoplay,
98
+ muted: isMuted,
245
99
  controls: true,
100
+ resizeMode: 'auto',
246
101
  styling: { progressbarColor: '#000' },
247
- videoHeight: Math.min(deepAccess(doc, 'defaultView.innerWidth') / 16 * 9, RENDERER_OPTIONS.OUTSTREAM_GP.MIN_HEIGHT),
248
- videoVerticalHeight: Math.min(deepAccess(doc, 'defaultView.innerWidth') / 9 * 16, RENDERER_OPTIONS.OUTSTREAM_GP.MIN_WIDTH),
102
+ publisherProvidedWidth: playerSize?.[0],
103
+ publisherProvidedHeight: playerSize?.[1],
249
104
  };
250
105
  const GP = doc.defaultView.GoldPlayer;
251
106
  const player = new GP(options);
@@ -253,98 +108,86 @@ const getRendererForBid = (bidRequest, creative) => {
253
108
  }
254
109
  });
255
110
  });
256
-
257
111
  return renderer;
258
112
  }
259
113
  return undefined;
260
- }
114
+ };
261
115
 
262
- const getNativeAssetsForBid = (bidRequest, creative) => {
263
- if (creative.contextType === 'native' && creative.ad) {
264
- const nativeAssets = JSON.parse(creative.ad);
265
- const result = {
266
- clickUrl: encodeURI(nativeAssets?.link?.url),
267
- impressionTrackers: nativeAssets?.imptrackers,
268
- clickTrackers: nativeAssets?.clicktrackers,
269
- javascriptTrackers: nativeAssets?.jstracker && [nativeAssets.jstracker],
270
- };
271
- (nativeAssets?.assets || []).forEach(asset => {
272
- switch (asset.id) {
273
- case OPENRTB.NATIVE.ASSET_ID.TITLE:
274
- result.title = asset.title?.text;
275
- break;
276
- case OPENRTB.NATIVE.ASSET_ID.IMAGE:
277
- result.image = {
278
- url: encodeURI(asset.img?.url),
279
- width: asset.img?.w,
280
- height: asset.img?.h
281
- };
282
- break;
283
- case OPENRTB.NATIVE.ASSET_ID.ICON:
284
- result.icon = {
285
- url: encodeURI(asset.img.url),
286
- width: asset.img?.w,
287
- height: asset.img?.h
288
- };
289
- break;
290
- case OPENRTB.NATIVE.ASSET_ID.BODY:
291
- result.body = asset.data?.value;
292
- break;
293
- case OPENRTB.NATIVE.ASSET_ID.SPONSORED:
294
- result.sponsoredBy = asset.data?.value;
295
- break;
296
- case OPENRTB.NATIVE.ASSET_ID.CTA:
297
- result.cta = asset.data?.value;
298
- break;
299
- }
300
- });
301
- return result;
302
- }
303
- return undefined;
304
- }
116
+ /* Converter config, applying custom extensions */
117
+ const converter = ortbConverter({
118
+ context: { netRevenue: true, ttl: 3600 },
119
+ imp(buildImp, bidRequest, context) {
120
+ const imp = buildImp(bidRequest, context);
305
121
 
306
- const convertProprietaryResponseToBidResponses = (serverResponse, bidRequest) => {
307
- const bidRequests = bidRequest?.bidderRequest?.bids || [];
308
- const creativeGroups = serverResponse?.body?.creatives || {};
122
+ // Apply custom extensions to the imp
123
+ imp.ext = imp.ext || {};
124
+ imp.ext[BIDDER_CODE] = imp.ext[BIDDER_CODE] || {};
125
+ imp.ext[BIDDER_CODE].targetings = bidRequest?.params?.customTargeting || {};
126
+ imp.ext[BIDDER_CODE].slotId = bidRequest?.params?.slotId || bidRequest?.adUnitCode;
309
127
 
310
- return bidRequests.reduce((bidResponses, bidRequest) => {
311
- const matchingCreativeGroup = (creativeGroups[bidRequest.params?.slotId] || []).filter((creative) => {
312
- if (bidRequest.mediaTypes?.[BANNER] && creative.mediaType === BANNER) return true;
313
- if (bidRequest.mediaTypes?.[VIDEO] && creative.mediaType === VIDEO) return true;
314
- if (bidRequest.mediaTypes?.[NATIVE] && creative.mediaType === NATIVE) return true;
315
- return false;
316
- });
317
- const matchingBidResponses = matchingCreativeGroup.map((creative) => {
318
- return {
319
- requestId: bidRequest.bidId,
320
- cpm: creative.cpm,
321
- currency: creative.currency,
322
- width: creative.width,
323
- height: creative.height,
324
- creativeId: creative.creativeId,
325
- dealId: creative.dealId,
326
- netRevenue: creative.netRevenue,
327
- ttl: creative.ttl,
328
- ad: creative.ad,
329
- vastUrl: creative.vastUrl,
330
- vastXml: creative.vastXml,
331
- mediaType: creative.mediaType,
332
- meta: creative.meta,
333
- native: getNativeAssetsForBid(bidRequest, creative),
334
- renderer: getRendererForBid(bidRequest, creative),
335
- };
336
- });
337
- return [...bidResponses, ...matchingBidResponses];
338
- }, []);
339
- }
128
+ return imp;
129
+ },
130
+ request(buildRequest, imps, bidderRequest, context) {
131
+ const ortbRequest = buildRequest(imps, bidderRequest, context);
132
+ const { bidRequests = [] } = context;
133
+ const firstBidRequest = bidRequests?.[0];
134
+
135
+ // Read gdpr consent data
136
+ const gdprConsent = bidderRequest?.gdprConsent;
137
+
138
+ // Apply custom extensions to the request
139
+ if (bidRequests.length > 0) {
140
+ ortbRequest.ext = ortbRequest.ext || {};
141
+ ortbRequest.ext[BIDDER_CODE] = ortbRequest.ext[BIDDER_CODE] || {};
142
+ ortbRequest.ext[BIDDER_CODE].uid = ensureUid(gdprConsent);
143
+ ortbRequest.ext[BIDDER_CODE].publisherId = firstBidRequest?.params?.publisherId;
144
+ ortbRequest.ext[BIDDER_CODE].mockResponse = firstBidRequest?.params?.mockResponse || false;
145
+ }
146
+
147
+ // Apply gdpr consent data
148
+ if (bidderRequest?.gdprConsent) {
149
+ ortbRequest.regs = ortbRequest.regs || {};
150
+ ortbRequest.regs.ext = ortbRequest.regs.ext || {};
151
+ ortbRequest.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
152
+ ortbRequest.user = ortbRequest.user || {};
153
+ ortbRequest.user.ext = ortbRequest.user.ext || {};
154
+ ortbRequest.user.ext.consent = bidderRequest.gdprConsent.consentString;
155
+ }
156
+
157
+ return ortbRequest;
158
+ },
159
+ bidResponse(buildBidResponse, bid, context) {
160
+ // Setting context: media type
161
+ context.mediaType = deepAccess(bid, 'ext.prebid.type');
162
+ const bidResponse = buildBidResponse(bid, context);
163
+ const { bidRequest } = context;
164
+
165
+ // Setting required properties: cpm, currency
166
+ bidResponse.currency = bidResponse.currency || deepAccess(bid, 'ext.origbidcur') || DEFAULT_CURRENCY;
167
+ bidResponse.cpm = bidResponse.cpm || deepAccess(bid, 'price');
168
+
169
+ // Setting required properties: meta
170
+ bidResponse.meta = bidResponse.meta || {};
171
+ bidResponse.meta.advertiserDomains = deepAccess(bid, 'adomain');
172
+ bidResponse.meta.mediaType = deepAccess(bid, 'ext.prebid.type');
173
+ bidResponse.meta.primaryCatId = deepAccess(bid, 'ext.prebid.video.primary_category');
174
+ bidResponse.meta.secondaryCatIds = deepAccess(bid, 'ext.prebid.video.secondary_categories');
175
+
176
+ // Setting extensions: outstream video renderer
177
+ if (bidResponse.mediaType === VIDEO && bidRequest.mediaTypes.video.context === 'outstream' && (bidResponse.vastUrl || bidResponse.vastXml)) {
178
+ bidResponse.renderer = getRendererForBid(bidRequest, bidResponse);
179
+ }
180
+ return bidResponse;
181
+ }
182
+ });
340
183
 
341
184
  /* Logging */
342
185
  const sendLog = (data, percentage = 0.0001) => {
343
186
  if (Math.random() > percentage) return;
344
187
  const encodedData = `data=${window.btoa(JSON.stringify({...data, source: 'goldbach_pbjs', projectedAmount: (1 / percentage)}))}`;
345
- ajax(LOGGING_URL, null, encodedData, {
188
+ ajax(URL_LOGGING, null, encodedData, {
346
189
  withCredentials: false,
347
- method: 'POST',
190
+ method: METHOD,
348
191
  crossOrigin: true,
349
192
  contentType: 'application/x-www-form-urlencoded',
350
193
  });
@@ -355,24 +198,38 @@ export const spec = {
355
198
  gvlid: GVLID,
356
199
  supportedMediaTypes: [BANNER, VIDEO, NATIVE],
357
200
  isBidRequestValid: function (bid) {
358
- return typeof bid.params.publisherId === 'string' && Array.isArray(bid.sizes);
201
+ return typeof bid.params?.publisherId === 'string' && bid.params?.publisherId.length > 0;
359
202
  },
360
- buildRequests: function (validBidRequests, bidderRequest) {
203
+ buildRequests: function (bidRequests, bidderRequest) {
361
204
  const url = IS_LOCAL_MODE ? URL_LOCAL : URL;
362
- const data = convertToProprietaryData(validBidRequests, bidderRequest);
363
- return [{
364
- method: 'POST',
205
+ const data = converter.toORTB({ bidRequests, bidderRequest });
206
+ return {
207
+ method: METHOD,
365
208
  url: url,
366
209
  data: data,
367
- bidderRequest: bidderRequest,
368
210
  options: {
369
211
  withCredentials: false,
370
212
  contentType: 'application/json',
371
213
  }
372
- }];
214
+ };
373
215
  },
374
- interpretResponse: function (serverResponse, request) {
375
- return convertProprietaryResponseToBidResponses(serverResponse, request);
216
+ interpretResponse: function (ortbResponse, request) {
217
+ const bids = converter.fromORTB({response: ortbResponse.body, request: request.data}).bids;
218
+ return bids
219
+ },
220
+ getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
221
+ const syncs = []
222
+ const uid = ensureUid(gdprConsent);
223
+ if (hasPurpose1Consent(gdprConsent)) {
224
+ let type = (syncOptions.pixelEnabled) ? 'image' : null ?? (syncOptions.iframeEnabled) ? 'iframe' : null
225
+ if (type) {
226
+ syncs.push({
227
+ type: type,
228
+ url: `https://ib.adnxs.com/getuid?${URL_COOKIESYNC}?uid=${uid}&xandrId=$UID`
229
+ })
230
+ }
231
+ }
232
+ return syncs
376
233
  },
377
234
  onTimeout: function(timeoutData) {
378
235
  const payload = {
@@ -384,8 +241,9 @@ export const spec = {
384
241
  onBidWon: function(bid) {
385
242
  const payload = {
386
243
  event: EVENTS.BID_WON,
244
+ publisherId: bid.params?.[0]?.publisherId,
245
+ creativeId: bid.creativeId,
387
246
  adUnitCode: bid.adUnitCode,
388
- adId: bid.adId,
389
247
  mediaType: bid.mediaType,
390
248
  size: bid.size,
391
249
  };
@@ -393,9 +251,10 @@ export const spec = {
393
251
  },
394
252
  onSetTargeting: function(bid) {
395
253
  const payload = {
396
- event: EVENTS.TARGETING,
254
+ event: EVENTS.BID_WON,
255
+ publisherId: bid.params?.[0]?.publisherId,
256
+ creativeId: bid.creativeId,
397
257
  adUnitCode: bid.adUnitCode,
398
- adId: bid.adId,
399
258
  mediaType: bid.mediaType,
400
259
  size: bid.size,
401
260
  };
@@ -410,9 +269,10 @@ export const spec = {
410
269
  },
411
270
  onAdRenderSucceeded: function(bid) {
412
271
  const payload = {
413
- event: EVENTS.RENDER,
272
+ event: EVENTS.BID_WON,
273
+ publisherId: bid.params?.[0]?.publisherId,
274
+ creativeId: bid.creativeId,
414
275
  adUnitCode: bid.adUnitCode,
415
- adId: bid.adId,
416
276
  mediaType: bid.mediaType,
417
277
  size: bid.size,
418
278
  };
@@ -0,0 +1,131 @@
1
+ import {submodule, getHook} from '../src/hook.js';
2
+ import adapterManager from '../src/adapterManager.js';
3
+ import {logInfo, deepClone, isArray, isStr, isPlainObject, logError} from '../src/utils.js';
4
+
5
+ // Constants
6
+ const MODULE_NAME = 'raveltech';
7
+ const RAVEL_ENDPOINT = 'https://pb1.rvlproxy.net/bid/bid';
8
+
9
+ const getAdapterNameForAlias = (aliasName) => adapterManager.aliasRegistry[aliasName] || aliasName;
10
+
11
+ const getAnonymizedEids = (eids) => {
12
+ const ZKAD = window.ZKAD || { anonymizeID(v, p) { return undefined; } };
13
+ logInfo('ZKAD.ready=', ZKAD.ready);
14
+ if (!eids) { return eids; }
15
+
16
+ eids.forEach(eid => {
17
+ if (!eid || !eid.uids || eid.uids.length === 0) { return eid }
18
+ logInfo('eid.source=', eid.source);
19
+ eid.uids = eid.uids.flatMap(uid => {
20
+ if (!uid || !uid.id) { return []; }
21
+ const id = ZKAD.anonymizeID(uid.id, eid.source);
22
+ if (!id) {
23
+ logError('Error while anonymizing uid :', eid, uid);
24
+ return [];
25
+ }
26
+ logInfo('Anonymized as byte array of length=', id.length);
27
+ return [ {
28
+ ...uid,
29
+ id
30
+ } ];
31
+ })
32
+ })
33
+
34
+ return eids;
35
+ };
36
+
37
+ const addRavelDataToRequest = (request, adapterName) => {
38
+ if (isStr(request.data)) {
39
+ try {
40
+ const data = JSON.parse(request.data);
41
+ data.ravel = { pbjsAdapter: adapterName };
42
+ request.data = JSON.stringify(data);
43
+ } catch (_e) {}
44
+ } else if (!request.data) {
45
+ request.data = { ravel: { pbjsAdapter: adapterName } };
46
+ } else if (isPlainObject(request.data)) {
47
+ request.data.ravel = { pbjsAdapter: adapterName };
48
+ }
49
+ };
50
+
51
+ const wrapBuildRequests = (aliasName, preserveOriginalBid, buildRequests) => {
52
+ const adapterName = getAdapterNameForAlias(aliasName)
53
+
54
+ return (validBidRequests, ...rest) => {
55
+ if (!window.ZKAD || !window.ZKAD.ready) {
56
+ return buildRequests(validBidRequests, ...rest);
57
+ }
58
+ let requests = preserveOriginalBid ? buildRequests(validBidRequests, ...rest) : [];
59
+ if (!isArray(requests)) {
60
+ requests = [ requests ];
61
+ }
62
+
63
+ try {
64
+ const ravelBidRequests = deepClone(validBidRequests);
65
+
66
+ // Anonymize eids for ravel proxified requests
67
+ const anonymizedEids = getAnonymizedEids(ravelBidRequests[0]?.userIdAsEids);
68
+
69
+ ravelBidRequests.forEach(bidRequest => {
70
+ // Replace original eids with anonymized eids
71
+ bidRequest.userIdAsEids = anonymizedEids;
72
+ });
73
+
74
+ let ravelRequests = buildRequests(ravelBidRequests, ...rest);
75
+ if (!isArray(ravelRequests) && ravelRequests) {
76
+ ravelRequests = [ ravelRequests ];
77
+ }
78
+ if (ravelRequests) {
79
+ ravelRequests.forEach(request => {
80
+ // Proxyfy request
81
+ request.url = RAVEL_ENDPOINT;
82
+ request.method = 'POST';
83
+ addRavelDataToRequest(request, adapterName);
84
+ })
85
+ }
86
+
87
+ return [ ...requests ?? [], ...ravelRequests ?? [] ];
88
+ } catch (e) {
89
+ logError('Error while generating ravel requests :', e);
90
+ return requests;
91
+ }
92
+ }
93
+ };
94
+
95
+ const getBidderRequestsHook = (config) => {
96
+ const allowedBidders = config.params.bidders || [];
97
+ const preserveOriginalBid = config.params.preserveOriginalBid ?? false;
98
+ const wrappedBidders = [];
99
+
100
+ return (next, spec, ...rest) => {
101
+ if (allowedBidders.includes(spec.code) && !wrappedBidders.includes(spec.code)) {
102
+ spec.buildRequests = wrapBuildRequests(spec.code, preserveOriginalBid, spec.buildRequests);
103
+
104
+ wrappedBidders.push(spec.code);
105
+ }
106
+ next(spec, ...rest);
107
+ }
108
+ };
109
+
110
+ /**
111
+ * Init
112
+ * @param {Object} config Module configuration
113
+ * @param {boolean} _userConsent
114
+ * @returns true
115
+ */
116
+ const init = (config, _userConsent) => {
117
+ const allowedBidders = config.params.bidders || [];
118
+ const preserveOriginalBid = config.params.preserveOriginalBid ?? false;
119
+
120
+ getHook('processBidderRequests').before(getBidderRequestsHook(config));
121
+ logInfo(`Raveltech RTD ready - ${preserveOriginalBid ? 'will' : `won't`} duplicate bid requests - Allowed bidders : `, allowedBidders);
122
+ return true;
123
+ };
124
+
125
+ export const raveltechSubmodule = {
126
+ name: MODULE_NAME,
127
+ init
128
+ };
129
+
130
+ // Register raveltechSubmodule as submodule of realTimeData
131
+ submodule('realTimeData', raveltechSubmodule);