prebid.js 8.5.0 → 8.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adqueryBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adsinteractiveBidAdapter.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/alkimiBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/appierAnalyticsAdapter.js +1 -1
  17. package/dist/appnexusBidAdapter.js +1 -1
  18. package/dist/asoBidAdapter.js +1 -1
  19. package/dist/automatadAnalyticsAdapter.js +1 -0
  20. package/dist/axonixBidAdapter.js +1 -1
  21. package/dist/bidglassBidAdapter.js +1 -1
  22. package/dist/big-richmediaBidAdapter.js +1 -1
  23. package/dist/bridBidAdapter.js +1 -1
  24. package/dist/bridgewellBidAdapter.js +1 -1
  25. package/dist/brightMountainMediaBidAdapter.js +1 -1
  26. package/dist/carodaBidAdapter.js +1 -1
  27. package/dist/chtnwBidAdapter.js +1 -1
  28. package/dist/concertBidAdapter.js +1 -1
  29. package/dist/connatixBidAdapter.js +1 -0
  30. package/dist/connectadBidAdapter.js +1 -1
  31. package/dist/consumableBidAdapter.js +1 -1
  32. package/dist/conversantAnalyticsAdapter.js +1 -1
  33. package/dist/conversantBidAdapter.js +1 -1
  34. package/dist/craftBidAdapter.js +1 -1
  35. package/dist/criteoBidAdapter.js +1 -1
  36. package/dist/cwireBidAdapter.js +1 -1
  37. package/dist/dependencies.json +6 -0
  38. package/dist/dspxBidAdapter.js +1 -1
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/euidIdSystem.js +1 -1
  41. package/dist/feedadBidAdapter.js +1 -1
  42. package/dist/finativeBidAdapter.js +1 -1
  43. package/dist/freepassBidAdapter.js +1 -1
  44. package/dist/freewheel-sspBidAdapter.js +1 -1
  45. package/dist/gmosspBidAdapter.js +1 -1
  46. package/dist/goldbachBidAdapter.js +1 -1
  47. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  48. package/dist/greenbidsRtdProvider.js +1 -1
  49. package/dist/gridBidAdapter.js +1 -1
  50. package/dist/growthCodeAnalyticsAdapter.js +1 -1
  51. package/dist/gumgumBidAdapter.js +1 -1
  52. package/dist/h12mediaBidAdapter.js +1 -1
  53. package/dist/hypelabBidAdapter.js +1 -1
  54. package/dist/id5IdSystem.js +1 -1
  55. package/dist/imdsBidAdapter.js +1 -1
  56. package/dist/improvedigitalBidAdapter.js +1 -1
  57. package/dist/insticatorBidAdapter.js +1 -1
  58. package/dist/ixBidAdapter.js +1 -1
  59. package/dist/justpremiumBidAdapter.js +1 -1
  60. package/dist/kargoBidAdapter.js +1 -1
  61. package/dist/konduitAnalyticsAdapter.js +1 -1
  62. package/dist/kueezBidAdapter.js +1 -1
  63. package/dist/kueezRtbBidAdapter.js +1 -1
  64. package/dist/kulturemediaBidAdapter.js +1 -1
  65. package/dist/lassoBidAdapter.js +1 -1
  66. package/dist/lifestreetBidAdapter.js +1 -1
  67. package/dist/logicadBidAdapter.js +1 -1
  68. package/dist/loglyliftBidAdapter.js +1 -1
  69. package/dist/magniteAnalyticsAdapter.js +1 -1
  70. package/dist/malltvAnalyticsAdapter.js +1 -1
  71. package/dist/marsmediaBidAdapter.js +1 -1
  72. package/dist/mediafuseBidAdapter.js +1 -1
  73. package/dist/medianetBidAdapter.js +1 -1
  74. package/dist/mediasquareBidAdapter.js +1 -1
  75. package/dist/mgidBidAdapter.js +1 -1
  76. package/dist/minutemediaBidAdapter.js +1 -1
  77. package/dist/minutemediaplusBidAdapter.js +1 -1
  78. package/dist/mspa.js +1 -1
  79. package/dist/newspassidBidAdapter.js +1 -1
  80. package/dist/nexx360BidAdapter.js +1 -1
  81. package/dist/not-for-prod/prebid.js +140 -136
  82. package/dist/oguryBidAdapter.js +1 -1
  83. package/dist/onetagBidAdapter.js +1 -1
  84. package/dist/ooloAnalyticsAdapter.js +1 -1
  85. package/dist/optidigitalBidAdapter.js +1 -1
  86. package/dist/outbrainBidAdapter.js +1 -1
  87. package/dist/parrableIdSystem.js +1 -1
  88. package/dist/pixfutureBidAdapter.js +1 -1
  89. package/dist/prebid-core.js +1 -1
  90. package/dist/pubCircleBidAdapter.js +1 -0
  91. package/dist/publinkIdSystem.js +1 -1
  92. package/dist/pubmaticBidAdapter.js +1 -1
  93. package/dist/pubwiseAnalyticsAdapter.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/relevadRtdProvider.js +1 -1
  99. package/dist/retailspotBidAdapter.js +1 -1
  100. package/dist/rhythmoneBidAdapter.js +1 -1
  101. package/dist/riseBidAdapter.js +1 -1
  102. package/dist/rubiconBidAdapter.js +1 -1
  103. package/dist/seedingAllianceBidAdapter.js +1 -1
  104. package/dist/seedtagBidAdapter.js +1 -1
  105. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  106. package/dist/sharethroughBidAdapter.js +1 -1
  107. package/dist/shinezBidAdapter.js +1 -1
  108. package/dist/smaatoBidAdapter.js +1 -1
  109. package/dist/smartadserverBidAdapter.js +1 -1
  110. package/dist/smartxBidAdapter.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/ssmasBidAdapter.js +1 -1
  116. package/dist/sspBCBidAdapter.js +1 -1
  117. package/dist/stvBidAdapter.js +1 -1
  118. package/dist/sublimeBidAdapter.js +1 -1
  119. package/dist/tappxBidAdapter.js +1 -1
  120. package/dist/targetVideoBidAdapter.js +1 -1
  121. package/dist/teadsBidAdapter.js +1 -1
  122. package/dist/topicsFpdModule.js +1 -1
  123. package/dist/trionBidAdapter.js +1 -1
  124. package/dist/tripleliftBidAdapter.js +1 -1
  125. package/dist/ttdBidAdapter.js +1 -1
  126. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  127. package/dist/uid2IdSystem.js +1 -1
  128. package/dist/underdogmediaBidAdapter.js +1 -1
  129. package/dist/undertoneBidAdapter.js +1 -1
  130. package/dist/viantOrtbBidAdapter.js +1 -0
  131. package/dist/vidazooBidAdapter.js +1 -1
  132. package/dist/videobyteBidAdapter.js +1 -1
  133. package/dist/videojsVideoProvider.js +1 -1
  134. package/dist/visxBidAdapter.js +1 -1
  135. package/dist/vuukleBidAdapter.js +1 -1
  136. package/dist/widespaceBidAdapter.js +1 -1
  137. package/dist/winrBidAdapter.js +1 -1
  138. package/dist/yahoosspBidAdapter.js +1 -1
  139. package/dist/yieldmoBidAdapter.js +1 -1
  140. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  141. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +1 -1
  142. package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +1 -1
  143. package/integrationExamples/videoModule/jwplayer/bidsBackHandlerOverride.html +137 -0
  144. package/integrationExamples/videoModule/jwplayer/eventListeners.html +1 -1
  145. package/integrationExamples/videoModule/jwplayer/eventsUI.html +1 -1
  146. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +1 -1
  147. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +1 -1
  148. package/integrationExamples/videoModule/jwplayer/playlist.html +1 -1
  149. package/integrationExamples/videoModule/videojs/bidsBackHandlerOverride.html +164 -0
  150. package/libraries/mspa/activityControls.js +51 -32
  151. package/modules/adagioBidAdapter.js +15 -1
  152. package/modules/adgenerationBidAdapter.js +5 -4
  153. package/modules/adsinteractiveBidAdapter.js +4 -2
  154. package/modules/alkimiBidAdapter.js +19 -7
  155. package/modules/appnexusBidAdapter.js +1 -1
  156. package/modules/automatadAnalyticsAdapter.js +325 -0
  157. package/modules/automatadAnalyticsAdapter.md +23 -0
  158. package/modules/connatixBidAdapter.js +185 -0
  159. package/modules/connatixBidAdapter.md +37 -0
  160. package/modules/criteoBidAdapter.js +18 -0
  161. package/modules/cwireBidAdapter.js +19 -0
  162. package/modules/freepassBidAdapter.js +20 -1
  163. package/modules/freepassBidAdapter.md +4 -1
  164. package/modules/gridBidAdapter.js +1 -8
  165. package/modules/growthCodeAnalyticsAdapter.js +7 -2
  166. package/modules/medianetBidAdapter.js +7 -4
  167. package/modules/mediasquareBidAdapter.js +3 -0
  168. package/modules/newspassid.md +76 -0
  169. package/modules/newspassidBidAdapter.js +44 -18
  170. package/modules/optidigitalBidAdapter.js +25 -16
  171. package/modules/pubCircleBidAdapter.js +231 -0
  172. package/modules/pubCircleBidAdapter.md +79 -0
  173. package/modules/relevadRtdProvider.js +6 -7
  174. package/modules/ssmasBidAdapter.js +2 -2
  175. package/modules/tappxBidAdapter.js +27 -15
  176. package/modules/tappxBidAdapter.md +17 -0
  177. package/modules/topicsFpdModule.js +21 -48
  178. package/modules/undertoneBidAdapter.md +1 -1
  179. package/modules/userId/eids.md +7 -0
  180. package/modules/viantOrtbBidAdapter.js +113 -0
  181. package/modules/viantOrtbBidAdapter.md +54 -0
  182. package/modules/vidazooBidAdapter.js +9 -2
  183. package/modules/videojsVideoProvider.js +9 -2
  184. package/package.json +1 -1
  185. package/test/spec/libraries/mspa/activityControls_spec.js +145 -212
  186. package/test/spec/modules/adagioBidAdapter_spec.js +89 -0
  187. package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
  188. package/test/spec/modules/alkimiBidAdapter_spec.js +3 -9
  189. package/test/spec/modules/appnexusBidAdapter_spec.js +12 -1
  190. package/test/spec/modules/automatadAnalyticsAdapter_spec.js +533 -0
  191. package/test/spec/modules/connatixBidAdapter_spec.js +366 -0
  192. package/test/spec/modules/criteoBidAdapter_spec.js +52 -3
  193. package/test/spec/modules/cwireBidAdapter_spec.js +47 -0
  194. package/test/spec/modules/freepassBidAdapter_spec.js +44 -0
  195. package/test/spec/modules/gridBidAdapter_spec.js +68 -0
  196. package/test/spec/modules/medianetBidAdapter_spec.js +18 -18
  197. package/test/spec/modules/mediasquareBidAdapter_spec.js +5 -0
  198. package/test/spec/modules/newspassidBidAdapter_spec.js +6 -0
  199. package/test/spec/modules/optidigitalBidAdapter_spec.js +9 -2
  200. package/test/spec/modules/pubCircleBidAdapter_spec.js +399 -0
  201. package/test/spec/modules/tappxBidAdapter_spec.js +19 -0
  202. package/test/spec/modules/topicsFpdModule_spec.js +343 -365
  203. package/test/spec/modules/viantOrtbBidAdapter_spec.js +432 -0
@@ -7,6 +7,7 @@ const GVL_ID = 915;
7
7
  const ENDPOINT_URL = 'https://pbs.optidigital.com/bidder';
8
8
  const USER_SYNC_URL_IFRAME = 'https://scripts.opti-digital.com/js/presync.html?endpoint=optidigital';
9
9
  let CUR = 'USD';
10
+ let isSynced = false;
10
11
 
11
12
  export const spec = {
12
13
  code: BIDDER_CODE,
@@ -46,8 +47,6 @@ export const spec = {
46
47
  referrer: (bidderRequest.refererInfo && bidderRequest.refererInfo.page) ? bidderRequest.refererInfo.page : '',
47
48
  hb_version: '$prebid.version$',
48
49
  deviceWidth: document.documentElement.clientWidth,
49
- // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781
50
- auctionId: deepAccess(validBidRequests[0], 'auctionId'),
51
50
  bidderRequestId: deepAccess(validBidRequests[0], 'bidderRequestId'),
52
51
  publisherId: deepAccess(validBidRequests[0], 'params.publisherId'),
53
52
  imp: validBidRequests.map(bidRequest => buildImp(bidRequest, ortb2)),
@@ -56,6 +55,10 @@ export const spec = {
56
55
  bapp: deepAccess(validBidRequests[0], 'params.bapp') || []
57
56
  }
58
57
 
58
+ if (validBidRequests[0].auctionId) {
59
+ payload.auctionId = validBidRequests[0].auctionId;
60
+ }
61
+
59
62
  if (validBidRequests[0].params.pageTemplate && validBidRequests[0].params.pageTemplate !== '') {
60
63
  payload.pageTemplate = validBidRequests[0].params.pageTemplate;
61
64
  }
@@ -136,21 +139,23 @@ export const spec = {
136
139
  */
137
140
  getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
138
141
  let syncurl = '';
142
+ if (!isSynced) {
143
+ // Attaching GDPR Consent Params in UserSync url
144
+ if (gdprConsent) {
145
+ syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0);
146
+ syncurl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '');
147
+ }
148
+ if (uspConsent && uspConsent.consentString) {
149
+ syncurl += `&ccpa_consent=${uspConsent.consentString}`;
150
+ }
139
151
 
140
- // Attaching GDPR Consent Params in UserSync url
141
- if (gdprConsent) {
142
- syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0);
143
- syncurl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '');
144
- }
145
- if (uspConsent && uspConsent.consentString) {
146
- syncurl += `&ccpa_consent=${uspConsent.consentString}`;
147
- }
148
-
149
- if (syncOptions.iframeEnabled) {
150
- return [{
151
- type: 'iframe',
152
- url: USER_SYNC_URL_IFRAME + syncurl
153
- }];
152
+ if (syncOptions.iframeEnabled) {
153
+ isSynced = true;
154
+ return [{
155
+ type: 'iframe',
156
+ url: USER_SYNC_URL_IFRAME + syncurl
157
+ }];
158
+ }
154
159
  }
155
160
  },
156
161
  };
@@ -218,4 +223,8 @@ function _getFloor (bid, sizes, currency) {
218
223
  return floor !== null ? floor : bid.params.floor;
219
224
  }
220
225
 
226
+ export function resetSync() {
227
+ isSynced = false;
228
+ }
229
+
221
230
  registerBidder(spec);
@@ -0,0 +1,231 @@
1
+ import { isFn, deepAccess, logMessage, logError } from '../src/utils.js';
2
+ import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
3
+
4
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
5
+ import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
6
+ import { config } from '../src/config.js';
7
+
8
+ const BIDDER_CODE = 'pubcircle';
9
+ const AD_URL = 'https://ml.pubcircle.ai/pbjs';
10
+ const SYNC_URL = 'https://cs.pubcircle.ai';
11
+
12
+ function isBidResponseValid(bid) {
13
+ if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) {
14
+ return false;
15
+ }
16
+
17
+ switch (bid.mediaType) {
18
+ case BANNER:
19
+ return Boolean(bid.width && bid.height && bid.ad);
20
+ case VIDEO:
21
+ return Boolean(bid.vastUrl || bid.vastXml);
22
+ case NATIVE:
23
+ return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length);
24
+ default:
25
+ return false;
26
+ }
27
+ }
28
+
29
+ function getPlacementReqData(bid) {
30
+ const { params, bidId, mediaTypes } = bid;
31
+ const schain = bid.schain || {};
32
+ const { placementId } = params;
33
+ const bidfloor = getBidFloor(bid);
34
+
35
+ const placement = {
36
+ bidId,
37
+ schain,
38
+ bidfloor
39
+ };
40
+
41
+ placement.placementId = placementId;
42
+ placement.type = 'publisher';
43
+
44
+ if (bid.userId) {
45
+ getUserId(placement.eids, bid.userId.uid2 && bid.userId.uid2.id, 'uidapi.com');
46
+ getUserId(placement.eids, bid.userId.lotamePanoramaId, 'lotame.com');
47
+ getUserId(placement.eids, bid.userId.idx, 'idx.lat');
48
+ getUserId(placement.eids, bid.userId.idl_env, 'liveramp.com');
49
+ }
50
+
51
+ if (mediaTypes && mediaTypes[BANNER]) {
52
+ placement.adFormat = BANNER;
53
+ placement.sizes = mediaTypes[BANNER].sizes;
54
+ } else if (mediaTypes && mediaTypes[VIDEO]) {
55
+ placement.adFormat = VIDEO;
56
+ placement.playerSize = mediaTypes[VIDEO].playerSize;
57
+ placement.minduration = mediaTypes[VIDEO].minduration;
58
+ placement.maxduration = mediaTypes[VIDEO].maxduration;
59
+ placement.mimes = mediaTypes[VIDEO].mimes;
60
+ placement.protocols = mediaTypes[VIDEO].protocols;
61
+ placement.startdelay = mediaTypes[VIDEO].startdelay;
62
+ placement.placement = mediaTypes[VIDEO].placement;
63
+ placement.skip = mediaTypes[VIDEO].skip;
64
+ placement.skipafter = mediaTypes[VIDEO].skipafter;
65
+ placement.minbitrate = mediaTypes[VIDEO].minbitrate;
66
+ placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
67
+ placement.delivery = mediaTypes[VIDEO].delivery;
68
+ placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
69
+ placement.api = mediaTypes[VIDEO].api;
70
+ placement.linearity = mediaTypes[VIDEO].linearity;
71
+ } else if (mediaTypes && mediaTypes[NATIVE]) {
72
+ placement.native = mediaTypes[NATIVE];
73
+ placement.adFormat = NATIVE;
74
+ }
75
+
76
+ return placement;
77
+ }
78
+
79
+ function getBidFloor(bid) {
80
+ if (!isFn(bid.getFloor)) {
81
+ return deepAccess(bid, 'params.bidfloor', 0);
82
+ }
83
+
84
+ try {
85
+ const bidFloor = bid.getFloor({
86
+ currency: 'USD',
87
+ mediaType: '*',
88
+ size: '*',
89
+ });
90
+ return bidFloor.floor;
91
+ } catch (err) {
92
+ logError(err);
93
+ return 0;
94
+ }
95
+ }
96
+
97
+ function getUserId(eids, id, source, uidExt) {
98
+ if (id) {
99
+ var uid = { id };
100
+ if (uidExt) {
101
+ uid.ext = uidExt;
102
+ }
103
+ eids.push({
104
+ source,
105
+ uids: [ uid ]
106
+ });
107
+ }
108
+ }
109
+
110
+ export const spec = {
111
+ code: BIDDER_CODE,
112
+ supportedMediaTypes: [BANNER, VIDEO, NATIVE],
113
+
114
+ isBidRequestValid: (bid = {}) => {
115
+ const { params, bidId, mediaTypes } = bid;
116
+ let valid = Boolean(bidId && params && params.placementId);
117
+
118
+ if (mediaTypes && mediaTypes[BANNER]) {
119
+ valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
120
+ } else if (mediaTypes && mediaTypes[VIDEO]) {
121
+ valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize);
122
+ } else if (mediaTypes && mediaTypes[NATIVE]) {
123
+ valid = valid && Boolean(mediaTypes[NATIVE]);
124
+ } else {
125
+ valid = false;
126
+ }
127
+ return valid;
128
+ },
129
+
130
+ buildRequests: (validBidRequests = [], bidderRequest = {}) => {
131
+ // convert Native ORTB definition to old-style prebid native definition
132
+ validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
133
+
134
+ let deviceWidth = 0;
135
+ let deviceHeight = 0;
136
+
137
+ let winLocation;
138
+ try {
139
+ const winTop = window.top;
140
+ deviceWidth = winTop.screen.width;
141
+ deviceHeight = winTop.screen.height;
142
+ winLocation = winTop.location;
143
+ } catch (e) {
144
+ logMessage(e);
145
+ winLocation = window.location;
146
+ }
147
+
148
+ const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page;
149
+ let refferLocation;
150
+ try {
151
+ refferLocation = refferUrl && new URL(refferUrl);
152
+ } catch (e) {
153
+ logMessage(e);
154
+ }
155
+ // TODO: does the fallback make sense here?
156
+ let location = refferLocation || winLocation;
157
+ const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : '';
158
+ const host = location.host;
159
+ const page = location.pathname;
160
+ const secure = location.protocol === 'https:' ? 1 : 0;
161
+ const placements = [];
162
+ const request = {
163
+ deviceWidth,
164
+ deviceHeight,
165
+ language,
166
+ secure,
167
+ host,
168
+ page,
169
+ placements,
170
+ coppa: config.getConfig('coppa') === true ? 1 : 0,
171
+ ccpa: bidderRequest.uspConsent || undefined,
172
+ gdpr: bidderRequest.gdprConsent || undefined,
173
+ tmax: bidderRequest.timeout
174
+ };
175
+
176
+ const len = validBidRequests.length;
177
+ for (let i = 0; i < len; i++) {
178
+ const bid = validBidRequests[i];
179
+ placements.push(getPlacementReqData(bid));
180
+ }
181
+
182
+ return {
183
+ method: 'POST',
184
+ url: AD_URL,
185
+ data: request
186
+ };
187
+ },
188
+
189
+ interpretResponse: (serverResponse) => {
190
+ let response = [];
191
+ for (let i = 0; i < serverResponse.body.length; i++) {
192
+ let resItem = serverResponse.body[i];
193
+ if (isBidResponseValid(resItem)) {
194
+ const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
195
+ resItem.meta = { ...resItem.meta, advertiserDomains };
196
+
197
+ response.push(resItem);
198
+ }
199
+ }
200
+ return response;
201
+ },
202
+
203
+ getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
204
+ let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
205
+ let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`;
206
+ if (gdprConsent && gdprConsent.consentString) {
207
+ if (typeof gdprConsent.gdprApplies === 'boolean') {
208
+ syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
209
+ } else {
210
+ syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
211
+ }
212
+ }
213
+ if (uspConsent && uspConsent.consentString) {
214
+ syncUrl += `&ccpa_consent=${uspConsent.consentString}`;
215
+ }
216
+
217
+ const coppa = config.getConfig('coppa') ? 1 : 0;
218
+ syncUrl += `&coppa=${coppa}`;
219
+
220
+ return [{
221
+ type: syncType,
222
+ url: syncUrl
223
+ }];
224
+ },
225
+
226
+ onBidViewable: function (bid) {
227
+ // to do : we need to implement js tag to fire pixel with viewability counter
228
+ }
229
+ };
230
+
231
+ registerBidder(spec);
@@ -0,0 +1,79 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: PubCirlce Bidder Adapter
5
+ Module Type: PubCirlce Bidder Adapter
6
+ Maintainer: system@smartyads.com
7
+ ```
8
+
9
+ # Description
10
+
11
+ Connects to PubCirlce exchange for bids.
12
+ PubCirlce bid adapter supports Banner, Video (instream and outstream) and Native.
13
+
14
+ # Test Parameters
15
+ ```
16
+ var adUnits = [
17
+ // Will return static test banner
18
+ {
19
+ code: 'addunit1',
20
+ mediaTypes: {
21
+ banner: {
22
+ sizes: [ [300, 250], [320, 50] ],
23
+ }
24
+ },
25
+ bids: [
26
+ {
27
+ bidder: 'pubcircle',
28
+ params: {
29
+ placementId: 'testBanner',
30
+ }
31
+ }
32
+ ]
33
+ },
34
+ {
35
+ code: 'addunit2',
36
+ mediaTypes: {
37
+ video: {
38
+ playerSize: [ [640, 480] ],
39
+ context: 'instream',
40
+ minduration: 5,
41
+ maxduration: 60,
42
+ }
43
+ },
44
+ bids: [
45
+ {
46
+ bidder: 'pubcircle',
47
+ params: {
48
+ placementId: 'testVideo',
49
+ }
50
+ }
51
+ ]
52
+ },
53
+ {
54
+ code: 'addunit3',
55
+ mediaTypes: {
56
+ native: {
57
+ title: {
58
+ required: true
59
+ },
60
+ body: {
61
+ required: true
62
+ },
63
+ icon: {
64
+ required: true,
65
+ size: [64, 64]
66
+ }
67
+ }
68
+ },
69
+ bids: [
70
+ {
71
+ bidder: 'pubcircle',
72
+ params: {
73
+ placementId: 'testNative',
74
+ }
75
+ }
76
+ ]
77
+ }
78
+ ];
79
+ ```
@@ -110,6 +110,7 @@ function composeOrtb2Data(rtdData, prefix) {
110
110
  !isEmpty(categories.cat) && deepSetValue(addOrtb2, prefix + '.cat', categories.cat);
111
111
  !isEmpty(categories.pagecat) && deepSetValue(addOrtb2, prefix + '.pagecat', categories.pagecat);
112
112
  !isEmpty(categories.sectioncat) && deepSetValue(addOrtb2, prefix + '.sectioncat', categories.sectioncat);
113
+ !isEmpty(categories.sectioncat) && deepSetValue(addOrtb2, prefix + '.ext.data.relevad_rtd', categories.sectioncat);
113
114
  !isEmpty(categories.cattax) && deepSetValue(addOrtb2, prefix + '.cattax', categories.cattax);
114
115
 
115
116
  if (!isEmpty(content) && !isEmpty(content.segs) && content.segtax) {
@@ -134,7 +135,8 @@ function setBidderSiteAndContent(bidderOrtbFragment, bidder, rtdData) {
134
135
  try {
135
136
  let addOrtb2 = composeOrtb2Data(rtdData, 'site');
136
137
  !isEmpty(rtdData.segments) && deepSetValue(addOrtb2, 'user.ext.data.relevad_rtd', rtdData.segments);
137
- !isEmpty(rtdData.categories?.sectioncat) && deepSetValue(addOrtb2, 'site.ext.data.relevad_rtd', rtdData.categories.sectioncat);
138
+ !isEmpty(rtdData.segments) && deepSetValue(addOrtb2, 'user.ext.data.segments', rtdData.segments);
139
+ !isEmpty(rtdData.categories) && deepSetValue(addOrtb2, 'user.ext.data.contextual_categories', rtdData.categories.pagecat);
138
140
  if (isEmpty(addOrtb2)) {
139
141
  return;
140
142
  }
@@ -180,7 +182,7 @@ function getFiltered(data, minscore) {
180
182
  const cats = filterByScore(data.cats, minscore);
181
183
  const pcats = filterByScore(data.pcats, minscore) || cats;
182
184
  const scats = filterByScore(data.scats, minscore) || pcats;
183
- const cattax = data.cattax ? data.cattax : CATTAX_IAB;
185
+ const cattax = (data.cattax || data.cattax === undefined) ? data.cattax : CATTAX_IAB;
184
186
  relevadData.categories = {cat: cats, pagecat: pcats, sectioncat: scats, cattax: cattax};
185
187
 
186
188
  const contsegs = filterByScore(data.contsegs, minscore);
@@ -268,15 +270,12 @@ export function addRtdData(reqBids, data, moduleConfig) {
268
270
  }
269
271
  if (wb && !isEmpty(relevadList)) {
270
272
  setBidderSiteAndContent(reqBids.ortb2Fragments?.bidder, bid.bidder, relevadData);
273
+ setBidderSiteAndContent(bid, 'ortb2', relevadData);
271
274
  deepSetValue(bid, 'params.keywords.relevad_rtd', relevadList);
272
- deepSetValue(bid, 'params.target', [].concat(bid.params?.target ? [bid.params.target] : []).concat(relevadList.map(entry => { return 'relevad_rtd=' + entry; })).join(';'));
275
+ !(bid.params?.target || '').includes('relevad_rtd=') && deepSetValue(bid, 'params.target', [].concat(bid.params?.target ? [bid.params.target] : []).concat(relevadList.map(entry => { return 'relevad_rtd=' + entry; })).join(';'));
273
276
  let firstPartyData = {};
274
277
  firstPartyData[bid.bidder] = { firstPartyData: { relevad_rtd: relevadList } };
275
278
  config.setConfig(firstPartyData);
276
- !isEmpty(relevadData.segments) && deepSetValue(bid, 'ortb2.user.ext.data.segments', relevadData.segments);
277
- !isEmpty(relevadData.categories) && deepSetValue(bid, 'ortb2.user.ext.data.contextual_categories', relevadData.categories.pagecat);
278
- !isEmpty(relevadData.categories) && deepSetValue(bid, 'ortb2.site.ext.data.relevad_rtd', relevadData.categories.pagecat);
279
- !isEmpty(relevadData.segments) && deepSetValue(bid, 'ortb2.user.ext.data.relevad_rtd', relevadData.segments);
280
279
  }
281
280
  }
282
281
  } catch (e) {
@@ -6,8 +6,8 @@ import {config} from '../src/config.js';
6
6
 
7
7
  export const SSMAS_CODE = 'ssmas';
8
8
  const SSMAS_SERVER = 'ads.ssmas.com';
9
- export const SSMAS_ENDPOINT = `http://${SSMAS_SERVER}/ortb`;
10
- const SYNC_URL = `http://sync.ssmas.com/user_sync`;
9
+ export const SSMAS_ENDPOINT = `https://${SSMAS_SERVER}/ortb`;
10
+ const SYNC_URL = `https://sync.ssmas.com/user_sync`;
11
11
  export const SSMAS_REQUEST_METHOD = 'POST';
12
12
  const GDPR_VENDOR_ID = 1183;
13
13
 
@@ -12,7 +12,7 @@ const BIDDER_CODE = 'tappx';
12
12
  const GVLID_CODE = 628;
13
13
  const TTL = 360;
14
14
  const CUR = 'USD';
15
- const TAPPX_BIDDER_VERSION = '0.1.2';
15
+ const TAPPX_BIDDER_VERSION = '0.1.3';
16
16
  const TYPE_CNN = 'prebidjs';
17
17
  const LOG_PREFIX = '[TAPPX]: ';
18
18
  const VIDEO_SUPPORT = ['instream', 'outstream'];
@@ -146,22 +146,22 @@ function validBasic(bid) {
146
146
  return false;
147
147
  }
148
148
 
149
- if (bid.params.tappxkey == null) {
149
+ if (!bid.params.tappxkey) {
150
150
  logWarn(LOG_PREFIX, 'Please review the mandatory Tappxkey parameter.');
151
151
  return false;
152
152
  }
153
153
 
154
- if (bid.params.host == null) {
154
+ if (!bid.params.host) {
155
155
  logWarn(LOG_PREFIX, 'Please review the mandatory Host parameter.');
156
156
  return false;
157
157
  }
158
158
 
159
- let classicEndpoint = true
159
+ let classicEndpoint = true;
160
160
  if ((new RegExp(`^(vz.*|zz.*)\\.*$`, 'i')).test(bid.params.host)) {
161
- classicEndpoint = false
161
+ classicEndpoint = false;
162
162
  }
163
163
 
164
- if (classicEndpoint && bid.params.endpoint == null) {
164
+ if (classicEndpoint && !bid.params.endpoint) {
165
165
  logWarn(LOG_PREFIX, 'Please review the mandatory endpoint Tappx parameters.');
166
166
  return false;
167
167
  }
@@ -191,7 +191,7 @@ function validMediaType(bid) {
191
191
  */
192
192
  function interpretBid(serverBid, request) {
193
193
  let bidReturned = {
194
- requestId: request.bids.bidId,
194
+ requestId: request.bids?.bidId,
195
195
  cpm: serverBid.price,
196
196
  currency: serverBid.cur ? serverBid.cur : CUR,
197
197
  width: serverBid.w,
@@ -206,7 +206,7 @@ function interpretBid(serverBid, request) {
206
206
  if (typeof serverBid.nurl != 'undefined') { bidReturned.nurl = serverBid.nurl }
207
207
  if (typeof serverBid.burl != 'undefined') { bidReturned.burl = serverBid.burl }
208
208
 
209
- if (typeof request.bids.mediaTypes !== 'undefined' && typeof request.bids.mediaTypes.video !== 'undefined') {
209
+ if (typeof request.bids?.mediaTypes !== 'undefined' && typeof request.bids?.mediaTypes.video !== 'undefined') {
210
210
  bidReturned.vastXml = serverBid.adm;
211
211
  bidReturned.vastUrl = serverBid.lurl;
212
212
  bidReturned.ad = serverBid.adm;
@@ -214,13 +214,12 @@ function interpretBid(serverBid, request) {
214
214
  bidReturned.width = serverBid.w;
215
215
  bidReturned.height = serverBid.h;
216
216
 
217
- if (request.bids.mediaTypes.video.context === 'outstream') {
218
- const url = (serverBid.ext.purl) ? serverBid.ext.purl : false;
219
- if (typeof url === 'undefined') {
217
+ if (request.bids?.mediaTypes.video.context === 'outstream') {
218
+ if (!serverBid.ext.purl) {
220
219
  logWarn(LOG_PREFIX, 'Error getting player outstream from tappx');
221
220
  return false;
222
221
  }
223
- bidReturned.renderer = createRenderer(bidReturned, request, url);
222
+ bidReturned.renderer = createRenderer(bidReturned, request, serverBid.ext.purl);
224
223
  }
225
224
  } else {
226
225
  bidReturned.ad = serverBid.adm;
@@ -228,7 +227,7 @@ function interpretBid(serverBid, request) {
228
227
  }
229
228
 
230
229
  if (typeof bidReturned.adomain !== 'undefined' || bidReturned.adomain !== null) {
231
- bidReturned.meta = { advertiserDomains: request.bids.adomain };
230
+ bidReturned.meta = { advertiserDomains: request.bids?.adomain };
232
231
  }
233
232
 
234
233
  return bidReturned;
@@ -252,6 +251,7 @@ function buildOneRequest(validBidRequests, bidderRequest) {
252
251
  const BIDEXTRA = deepAccess(validBidRequests, 'params.ext');
253
252
  const bannerMediaType = deepAccess(validBidRequests, 'mediaTypes.banner');
254
253
  const videoMediaType = deepAccess(validBidRequests, 'mediaTypes.video');
254
+ const ORTB2 = deepAccess(validBidRequests, 'ortb2');
255
255
 
256
256
  // let requests = [];
257
257
  let payload = {};
@@ -304,6 +304,8 @@ function buildOneRequest(validBidRequests, bidderRequest) {
304
304
  let h;
305
305
 
306
306
  if (bannerMediaType) {
307
+ if (!Array.isArray(bannerMediaType.sizes)) { logWarn(LOG_PREFIX, 'Banner sizes array not found.'); }
308
+
307
309
  let banner = {};
308
310
  w = bannerMediaType.sizes[0][0];
309
311
  h = bannerMediaType.sizes[0][1];
@@ -341,7 +343,9 @@ function buildOneRequest(validBidRequests, bidderRequest) {
341
343
  }
342
344
 
343
345
  if ((video.w === undefined || video.w == null || video.w <= 0) ||
344
- (video.h === undefined || video.h == null || video.h <= 0)) {
346
+ (video.h === undefined || video.h == null || video.h <= 0)) {
347
+ if (!Array.isArray(videoMediaType.playerSize)) { logWarn(LOG_PREFIX, 'Video playerSize array not found.'); }
348
+
345
349
  w = videoMediaType.playerSize[0][0];
346
350
  h = videoMediaType.playerSize[0][1];
347
351
  video.w = w;
@@ -410,6 +414,14 @@ function buildOneRequest(validBidRequests, bidderRequest) {
410
414
  let geo = {};
411
415
  geo.country = deepAccess(validBidRequests, 'params.geo.country');
412
416
  // < Device object
417
+ let configGeo = {};
418
+ configGeo.country = ORTB2?.device?.geo;
419
+
420
+ if (typeof configGeo.country !== 'undefined') {
421
+ device.geo = configGeo;
422
+ } else if (typeof geo.country !== 'undefined') {
423
+ device.geo = geo;
424
+ };
413
425
 
414
426
  // > GDPR
415
427
  let user = {};
@@ -491,7 +503,7 @@ function getLanguage() {
491
503
 
492
504
  function getOs() {
493
505
  let ua = navigator.userAgent;
494
- if (ua.indexOf('Windows') != -1) { return 'Windows'; } else if (ua.indexOf('Mac OS X') != -1) { return 'macOS'; } else if (ua.match(/Android/)) { return 'Android'; } else if (ua.match(/(iPhone|iPod|iPad)/)) { return 'iOS'; } else if (ua.indexOf('Linux') != -1) { return 'Linux'; } else { return 'Unknown'; }
506
+ if (ua.match(/Android/)) { return 'Android'; } else if (ua.match(/(iPhone|iPod|iPad)/)) { return 'iOS'; } else if (ua.indexOf('Mac OS X') != -1) { return 'macOS'; } else if (ua.indexOf('Windows') != -1) { return 'Windows'; } else if (ua.indexOf('Linux') != -1) { return 'Linux'; } else { return 'Unknown'; }
495
507
  }
496
508
 
497
509
  function getVendor() {
@@ -92,3 +92,20 @@ Ads sizes available: [300,250], [320,50], [320,480], [480,320], [728,90], [768,1
92
92
  }
93
93
  ];
94
94
  ```
95
+ ### Configuration
96
+
97
+ Use `setConfig` to configure this submodule ortb2.device.geo, this will allow geolocation
98
+ `Geo` object to bring First Party Information.
99
+
100
+ ```javascript
101
+ var TIMEOUT = 1000;
102
+ pbjs.setConfig({
103
+ ortb2:{
104
+ device:{
105
+ geo:{
106
+ country:'US'
107
+ }
108
+ }
109
+ }
110
+ });
111
+ ```