prebid.js 6.5.0 → 6.9.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 (139) hide show
  1. package/.eslintrc.js +8 -1
  2. package/integrationExamples/gpt/amp/creative.html +11 -33
  3. package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
  4. package/integrationExamples/gpt/x-domain/creative.html +63 -29
  5. package/modules/.submodules.json +2 -1
  6. package/modules/adagioBidAdapter.js +0 -8
  7. package/modules/adagioBidAdapter.md +1 -1
  8. package/modules/adbookpspBidAdapter.js +27 -10
  9. package/modules/adhashBidAdapter.js +3 -3
  10. package/modules/adkernelBidAdapter.js +2 -1
  11. package/modules/admanBidAdapter.js +10 -4
  12. package/modules/adomikAnalyticsAdapter.js +23 -11
  13. package/modules/adqueryIdSystem.js +103 -0
  14. package/modules/adqueryIdSystem.md +35 -0
  15. package/modules/appnexusBidAdapter.js +14 -2
  16. package/modules/asealBidAdapter.js +58 -0
  17. package/modules/asealBidAdapter.md +52 -0
  18. package/modules/bliinkBidAdapter.js +2 -1
  19. package/modules/brandmetricsRtdProvider.js +168 -0
  20. package/modules/brandmetricsRtdProvider.md +40 -0
  21. package/modules/colossussspBidAdapter.js +12 -8
  22. package/modules/colossussspBidAdapter.md +15 -1
  23. package/modules/compassBidAdapter.js +10 -3
  24. package/modules/consumableBidAdapter.md +1 -1
  25. package/modules/conversantBidAdapter.js +7 -0
  26. package/modules/criteoBidAdapter.js +10 -1
  27. package/modules/criteoIdSystem.js +29 -7
  28. package/modules/currency.js +26 -1
  29. package/modules/displayioBidAdapter.js +157 -0
  30. package/modules/displayioBidAdapter.md +148 -0
  31. package/modules/e_volutionBidAdapter.js +158 -0
  32. package/modules/glimpseBidAdapter.js +66 -44
  33. package/modules/gnetBidAdapter.js +3 -3
  34. package/modules/gnetBidAdapter.md +4 -4
  35. package/modules/gumgumBidAdapter.js +56 -42
  36. package/modules/idImportLibrary.js +45 -8
  37. package/modules/idImportLibrary.md +4 -0
  38. package/modules/improvedigitalBidAdapter.js +29 -2
  39. package/modules/interactiveOffersBidAdapter.js +9 -6
  40. package/modules/jwplayerRtdProvider.js +71 -6
  41. package/modules/jwplayerRtdProvider.md +27 -11
  42. package/modules/kargoBidAdapter.js +2 -2
  43. package/modules/lunamediahbBidAdapter.js +32 -4
  44. package/modules/nextMillenniumBidAdapter.js +3 -1
  45. package/modules/oguryBidAdapter.js +14 -14
  46. package/modules/onetagBidAdapter.js +4 -2
  47. package/modules/pilotxBidAdapter.js +147 -0
  48. package/modules/pilotxBidAdapter.md +50 -0
  49. package/modules/priceFloors.js +2 -1
  50. package/modules/proxistoreBidAdapter.js +0 -2
  51. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  52. package/modules/richaudienceBidAdapter.js +10 -4
  53. package/modules/riseBidAdapter.js +18 -7
  54. package/modules/rtbhouseBidAdapter.js +14 -4
  55. package/modules/rtdModule/index.js +14 -15
  56. package/modules/rubiconAnalyticsAdapter.js +8 -2
  57. package/modules/seedingAllianceBidAdapter.js +3 -3
  58. package/modules/sharethroughBidAdapter.js +12 -17
  59. package/modules/showheroes-bsBidAdapter.js +13 -2
  60. package/modules/sortableAnalyticsAdapter.js +5 -4
  61. package/modules/sovrnBidAdapter.js +93 -18
  62. package/modules/sovrnBidAdapter.md +80 -2
  63. package/modules/synacormediaBidAdapter.js +31 -10
  64. package/modules/tappxBidAdapter.js +8 -5
  65. package/modules/teadsBidAdapter.js +1 -2
  66. package/modules/undertoneBidAdapter.js +17 -1
  67. package/modules/userId/eids.js +7 -1
  68. package/modules/userId/userId.md +8 -0
  69. package/modules/viewability.js +177 -0
  70. package/modules/viewability.md +87 -0
  71. package/modules/weboramaRtdProvider.js +264 -34
  72. package/modules/weboramaRtdProvider.md +110 -40
  73. package/modules/welectBidAdapter.js +106 -0
  74. package/modules/yahoosspBidAdapter.js +2 -0
  75. package/package.json +2 -1
  76. package/src/adRendering.js +38 -0
  77. package/src/adloader.js +2 -1
  78. package/src/auction.js +103 -73
  79. package/src/bidderSettings.js +69 -0
  80. package/src/hook.js +5 -1
  81. package/src/prebid.js +19 -21
  82. package/src/secureCreatives.js +131 -47
  83. package/src/targeting.js +3 -2
  84. package/src/utils.js +13 -10
  85. package/test/helpers/syncPromise.js +71 -0
  86. package/test/spec/auctionmanager_spec.js +179 -15
  87. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  88. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  89. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  90. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  91. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  92. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  93. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  94. package/test/spec/modules/asealBidAdapter_spec.js +144 -0
  95. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  96. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  97. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  98. package/test/spec/modules/compassBidAdapter_spec.js +1 -0
  99. package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
  100. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  101. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  102. package/test/spec/modules/currency_spec.js +21 -6
  103. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  104. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  105. package/test/spec/modules/eids_spec.js +15 -0
  106. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  107. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  108. package/test/spec/modules/gumgumBidAdapter_spec.js +46 -0
  109. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  110. package/test/spec/modules/improvedigitalBidAdapter_spec.js +61 -0
  111. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  112. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  113. package/test/spec/modules/loglyliftBidAdapter_spec.js +1 -1
  114. package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
  115. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
  116. package/test/spec/modules/oguryBidAdapter_spec.js +69 -3
  117. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  118. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  119. package/test/spec/modules/realTimeDataModule_spec.js +67 -5
  120. package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
  121. package/test/spec/modules/riseBidAdapter_spec.js +31 -5
  122. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  123. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +61 -1
  124. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  125. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  126. package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
  127. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  128. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  129. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  130. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  131. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  132. package/test/spec/modules/userId_spec.js +68 -19
  133. package/test/spec/modules/viewability_spec.js +280 -0
  134. package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
  135. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  136. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  137. package/test/spec/unit/core/bidderSettings_spec.js +123 -0
  138. package/test/spec/unit/pbjs_api_spec.js +21 -8
  139. package/test/spec/unit/secureCreatives_spec.js +143 -24
@@ -1,10 +1,11 @@
1
1
  import {registerBidder} from '../src/adapters/bidderFactory.js';
2
2
  import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
3
3
  import { isFn, deepAccess, logMessage } from '../src/utils.js';
4
+ import {config} from '../src/config.js';
4
5
 
5
6
  const BIDDER_CODE = 'adman';
6
7
  const AD_URL = 'https://pub.admanmedia.com/?c=o&m=multi';
7
- const URL_SYNC = 'https://pub.admanmedia.com/?c=o&m=sync';
8
+ const URL_SYNC = 'https://pub.admanmedia.com';
8
9
 
9
10
  function isBidResponseValid(bid) {
10
11
  if (!bid.requestId || !bid.cpm || !bid.creativeId ||
@@ -152,19 +153,24 @@ export const spec = {
152
153
  },
153
154
 
154
155
  getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
155
- let syncUrl = URL_SYNC
156
+ let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
157
+ let syncUrl = URL_SYNC + `/${syncType}?pbjs=1`;
156
158
  if (gdprConsent && gdprConsent.consentString) {
157
159
  if (typeof gdprConsent.gdprApplies === 'boolean') {
158
160
  syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
159
161
  } else {
160
- syncUrl += `&gdpr==0&gdpr_consent=${gdprConsent.consentString}`;
162
+ syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
161
163
  }
162
164
  }
163
165
  if (uspConsent && uspConsent.consentString) {
164
166
  syncUrl += `&ccpa_consent=${uspConsent.consentString}`;
165
167
  }
168
+
169
+ const coppa = config.getConfig('coppa') ? 1 : 0;
170
+ syncUrl += `&coppa=${coppa}`;
171
+
166
172
  return [{
167
- type: 'image',
173
+ type: syncType,
168
174
  url: syncUrl
169
175
  }];
170
176
  }
@@ -14,6 +14,8 @@ const bidWon = CONSTANTS.EVENTS.BID_WON;
14
14
  const bidTimeout = CONSTANTS.EVENTS.BID_TIMEOUT;
15
15
  const ua = navigator.userAgent;
16
16
 
17
+ var _sampled = true;
18
+
17
19
  let adomikAdapter = Object.assign(adapter({}),
18
20
  {
19
21
  // Track every event needed
@@ -81,6 +83,7 @@ adomikAdapter.sendTypedEvent = function() {
81
83
  uid: adomikAdapter.currentContext.uid,
82
84
  ahbaid: adomikAdapter.currentContext.id,
83
85
  hostname: window.location.hostname,
86
+ sampling: adomikAdapter.currentContext.sampling,
84
87
  eventsByPlacementCode: groupedTypedEvents.map(function(typedEventsByType) {
85
88
  let sizes = [];
86
89
  const eventKeys = ['request', 'response', 'winner'];
@@ -203,19 +206,28 @@ adomikAdapter.adapterEnableAnalytics = adomikAdapter.enableAnalytics;
203
206
 
204
207
  adomikAdapter.enableAnalytics = function (config) {
205
208
  adomikAdapter.currentContext = {};
206
-
207
209
  const initOptions = config.options;
208
- if (initOptions) {
209
- adomikAdapter.currentContext = {
210
- uid: initOptions.id,
211
- url: initOptions.url,
212
- testId: initOptions.testId,
213
- testValue: initOptions.testValue,
214
- id: '',
215
- timeouted: false,
210
+
211
+ _sampled = typeof config === 'undefined' ||
212
+ typeof config.sampling === 'undefined' ||
213
+ Math.random() < parseFloat(config.sampling);
214
+
215
+ if (_sampled) {
216
+ if (initOptions) {
217
+ adomikAdapter.currentContext = {
218
+ uid: initOptions.id,
219
+ url: initOptions.url,
220
+ testId: initOptions.testId,
221
+ testValue: initOptions.testValue,
222
+ id: '',
223
+ timeouted: false,
224
+ sampling: config.sampling
225
+ }
226
+ logInfo('Adomik Analytics enabled with config', initOptions);
227
+ adomikAdapter.adapterEnableAnalytics(config);
216
228
  }
217
- logInfo('Adomik Analytics enabled with config', initOptions);
218
- adomikAdapter.adapterEnableAnalytics(config);
229
+ } else {
230
+ logInfo('Adomik Analytics ignored for sampling', config.sampling);
219
231
  }
220
232
  };
221
233
 
@@ -0,0 +1,103 @@
1
+ /**
2
+ * This module adds Adquery QID to the User ID module
3
+ * The {@link module:modules/userId} module is required
4
+ * @module modules/adqueryIdSystem
5
+ * @requires module:modules/userId
6
+ */
7
+
8
+ import {ajax} from '../src/ajax.js';
9
+ import {getStorageManager} from '../src/storageManager.js';
10
+ import {submodule} from '../src/hook.js';
11
+ import * as utils from '../src/utils.js';
12
+
13
+ const MODULE_NAME = 'qid';
14
+ const AU_GVLID = 902;
15
+
16
+ export const storage = getStorageManager(AU_GVLID, 'qid');
17
+
18
+ /**
19
+ * Param or default.
20
+ * @param {String} param
21
+ * @param {String} defaultVal
22
+ */
23
+ function paramOrDefault(param, defaultVal, arg) {
24
+ if (utils.isFn(param)) {
25
+ return param(arg);
26
+ } else if (utils.isStr(param)) {
27
+ return param;
28
+ }
29
+ return defaultVal;
30
+ }
31
+
32
+ /** @type {Submodule} */
33
+ export const adqueryIdSubmodule = {
34
+ /**
35
+ * used to link submodule with config
36
+ * @type {string}
37
+ */
38
+ name: MODULE_NAME,
39
+
40
+ /**
41
+ * IAB TCF Vendor ID
42
+ * @type {string}
43
+ */
44
+ gvlid: AU_GVLID,
45
+
46
+ /**
47
+ * decode the stored id value for passing to bid requests
48
+ * @function
49
+ * @param {{value:string}} value
50
+ * @returns {{qid:Object}}
51
+ */
52
+ decode(value) {
53
+ let qid = storage.getDataFromLocalStorage('qid');
54
+ if (utils.isStr(qid)) {
55
+ return {qid: qid};
56
+ }
57
+ return (value && typeof value['qid'] === 'string') ? { 'qid': value['qid'] } : undefined;
58
+ },
59
+ /**
60
+ * performs action to obtain id and return a value in the callback's response argument
61
+ * @function
62
+ * @param {SubmoduleConfig} [config]
63
+ * @returns {IdResponse|undefined}
64
+ */
65
+ getId(config) {
66
+ if (!utils.isPlainObject(config.params)) {
67
+ config.params = {};
68
+ }
69
+ const url = paramOrDefault(config.params.url,
70
+ `https://bidder.adquery.io/prebid/qid`,
71
+ config.params.urlArg);
72
+
73
+ const resp = function (callback) {
74
+ let qid = storage.getDataFromLocalStorage('qid');
75
+ if (utils.isStr(qid)) {
76
+ const responseObj = {qid: qid};
77
+ callback(responseObj);
78
+ } else {
79
+ const callbacks = {
80
+ success: response => {
81
+ let responseObj;
82
+ if (response) {
83
+ try {
84
+ responseObj = JSON.parse(response);
85
+ } catch (error) {
86
+ utils.logError(error);
87
+ }
88
+ }
89
+ callback(responseObj);
90
+ },
91
+ error: error => {
92
+ utils.logError(`${MODULE_NAME}: ID fetch encountered an error`, error);
93
+ callback();
94
+ }
95
+ };
96
+ ajax(url, callbacks, undefined, {method: 'GET'});
97
+ }
98
+ };
99
+ return {callback: resp};
100
+ }
101
+ };
102
+
103
+ submodule('userId', adqueryIdSubmodule);
@@ -0,0 +1,35 @@
1
+ # Adquery QID
2
+
3
+ Adquery QID Module. For assistance setting up your module please contact us at [prebid@adquery.io](prebid@adquery.io).
4
+
5
+ ### Prebid Params
6
+
7
+ Individual params may be set for the Adquery ID Submodule. At least one identifier must be set in the params.
8
+
9
+ ```
10
+ pbjs.setConfig({
11
+ usersync: {
12
+ userIds: [{
13
+ name: 'qid',
14
+ storage: {
15
+ name: 'qid',
16
+ type: 'html5'
17
+ }
18
+ }]
19
+ }
20
+ });
21
+ ```
22
+ ## Parameter Descriptions for the `usersync` Configuration Section
23
+ The below parameters apply only to the Adquery User ID Module integration.
24
+
25
+ | Param under usersync.userIds[] | Scope | Type | Description | Example |
26
+ | --- | --- | --- | --- | --- |
27
+ | name | Required | String | ID value for the Adquery ID module - `"qid"` | `"qid"` |
28
+ | storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. | |
29
+ | storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` |
30
+ | storage.name | Required | String | The name of the html5 local storage where the user ID will be stored. | `"qid"` |
31
+ | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` |
32
+ | value | Optional | Object | Used only if the page has a separate mechanism for storing the Adquery ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"qid": "2abf9f001fcd81241b67"}` |
33
+ | params | Optional | Object | Used to store params for the id system |
34
+ | params.url | Optional | String | Set an alternate GET url for qid with this parameter |
35
+ | params.urlArg | Optional | Object | Optional url parameter for params.url |
@@ -1,4 +1,4 @@
1
- import { convertCamelToUnderscore, isArray, isNumber, isPlainObject, logError, logInfo, deepAccess, logMessage, convertTypes, isStr, getParameterByName, deepClone, chunk, logWarn, getBidRequest, createTrackPixelHtml, isEmpty, transformBidderParamKeywords, getMaxValueFromArray, fill, getMinValueFromArray, isArrayOfNums, isFn, isAllowZeroCpmBidsEnabled } from '../src/utils.js';
1
+ import { convertCamelToUnderscore, isArray, isNumber, isPlainObject, logError, logInfo, deepAccess, logMessage, convertTypes, isStr, getParameterByName, deepClone, chunk, logWarn, getBidRequest, createTrackPixelHtml, isEmpty, transformBidderParamKeywords, getMaxValueFromArray, fill, getMinValueFromArray, isArrayOfNums, isFn } from '../src/utils.js';
2
2
  import { Renderer } from '../src/Renderer.js';
3
3
  import { config } from '../src/config.js';
4
4
  import { registerBidder, getIabSubCategory } from '../src/adapters/bidderFactory.js';
@@ -8,6 +8,7 @@ import find from 'core-js-pure/features/array/find.js';
8
8
  import includes from 'core-js-pure/features/array/includes.js';
9
9
  import { OUTSTREAM, INSTREAM } from '../src/video.js';
10
10
  import { getStorageManager } from '../src/storageManager.js';
11
+ import { bidderSettings } from '../src/bidderSettings.js';
11
12
 
12
13
  const BIDDER_CODE = 'appnexus';
13
14
  const URL = 'https://ib.adnxs.com/ut/v3/prebid';
@@ -201,6 +202,17 @@ export const spec = {
201
202
  payload.app = appIdObj;
202
203
  }
203
204
 
205
+ let auctionKeywords = config.getConfig('appnexusAuctionKeywords');
206
+ if (isPlainObject(auctionKeywords)) {
207
+ let aucKeywords = transformBidderParamKeywords(auctionKeywords);
208
+
209
+ if (aucKeywords.length > 0) {
210
+ aucKeywords.forEach(deleteValues);
211
+ }
212
+
213
+ payload.keywords = aucKeywords;
214
+ }
215
+
204
216
  if (config.getConfig('adpod.brandCategoryExclusion')) {
205
217
  payload.brand_category_uniqueness = true;
206
218
  }
@@ -292,7 +304,7 @@ export const spec = {
292
304
  serverResponse.tags.forEach(serverBid => {
293
305
  const rtbBid = getRtbBid(serverBid);
294
306
  if (rtbBid) {
295
- const cpmCheck = (isAllowZeroCpmBidsEnabled(bidderRequest.bidderCode)) ? rtbBid.cpm >= 0 : rtbBid.cpm > 0;
307
+ const cpmCheck = (bidderSettings.get(bidderRequest.bidderCode, 'allowZeroCpmBids') === true) ? rtbBid.cpm >= 0 : rtbBid.cpm > 0;
296
308
  if (cpmCheck && includes(this.supportedMediaTypes, rtbBid.ad_type)) {
297
309
  const bid = newBid(serverBid, rtbBid, bidderRequest);
298
310
  bid.mediaType = parseMediaType(rtbBid);
@@ -0,0 +1,58 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ import { BANNER } from '../src/mediaTypes.js';
3
+ import { config } from '../src/config.js';
4
+
5
+ export const BIDDER_CODE = 'aseal';
6
+ const SUPPORTED_AD_TYPES = [BANNER];
7
+ export const API_ENDPOINT = 'https://tkprebid.aotter.net/prebid/adapter';
8
+ export const HEADER_AOTTER_VERSION = 'prebid_0.0.1';
9
+
10
+ export const spec = {
11
+ code: BIDDER_CODE,
12
+ aliases: ['aotter', 'trek'],
13
+ supportedMediaTypes: SUPPORTED_AD_TYPES,
14
+
15
+ isBidRequestValid: (bid) => !!bid.params.placeUid && typeof bid.params.placeUid === 'string',
16
+
17
+ buildRequests: (validBidRequests, bidderRequest) => {
18
+ if (validBidRequests.length === 0) {
19
+ return [];
20
+ }
21
+
22
+ const clientId =
23
+ config.getConfig('aseal.clientId') || '';
24
+
25
+ const data = {
26
+ bids: validBidRequests,
27
+ refererInfo: bidderRequest.refererInfo,
28
+ };
29
+
30
+ const options = {
31
+ contentType: 'application/json',
32
+ withCredentials: true,
33
+ customHeaders: {
34
+ 'x-aotter-clientid': clientId,
35
+ 'x-aotter-version': HEADER_AOTTER_VERSION,
36
+ },
37
+ };
38
+
39
+ return [{
40
+ method: 'POST',
41
+ url: API_ENDPOINT,
42
+ data,
43
+ options,
44
+ }];
45
+ },
46
+
47
+ interpretResponse: (serverResponse, bidRequest) => {
48
+ if (!Array.isArray(serverResponse.body)) {
49
+ return [];
50
+ }
51
+
52
+ const bidResponses = serverResponse.body;
53
+
54
+ return bidResponses;
55
+ },
56
+ };
57
+
58
+ registerBidder(spec);
@@ -0,0 +1,52 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Aseal Bid Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: tech-service@aotter.net
7
+ ```
8
+
9
+ # Description
10
+
11
+ Module that connects to Aseal server for bids.
12
+ Supported Ad Formats:
13
+
14
+ - Banner
15
+
16
+ # Configuration
17
+
18
+ Following configuration is required:
19
+
20
+ ```js
21
+ pbjs.setConfig({
22
+ aseal: {
23
+ clientId: "YOUR_CLIENT_ID"
24
+ }
25
+ });
26
+ ```
27
+
28
+ # Ad Unit Example
29
+
30
+ ```js
31
+ var adUnits = [
32
+ {
33
+ code: "banner-div",
34
+ mediaTypes: {
35
+ banner: {
36
+ sizes: [
37
+ [300, 250],
38
+ [300, 600]
39
+ ]
40
+ }
41
+ },
42
+ bids: [
43
+ {
44
+ bidder: "aseal",
45
+ params: {
46
+ placeUid: "f4a74f73-9a74-4a87-91c9-545c6316c23d"
47
+ }
48
+ }
49
+ ]
50
+ }
51
+ ];
52
+ ```
@@ -1,7 +1,6 @@
1
1
  // eslint-disable-next-line prebid/validate-imports
2
2
  // eslint-disable-next-line prebid/validate-imports
3
3
  import {registerBidder} from '../src/adapters/bidderFactory.js'
4
-
5
4
  export const BIDDER_CODE = 'bliink'
6
5
  export const BLIINK_ENDPOINT_ENGINE = 'https://engine.bliink.io/delivery'
7
6
  export const BLIINK_ENDPOINT_ENGINE_VAST = 'https://engine.bliink.io/vast'
@@ -174,6 +173,8 @@ export const buildRequests = (_, bidderRequest) => {
174
173
  pageUrl: bidderRequest.refererInfo.referer,
175
174
  pageDescription: getMetaValue(META_DESCRIPTION),
176
175
  keywords: getKeywords().join(','),
176
+ gdpr: false,
177
+ gdpr_consent: '',
177
178
  pageTitle: document.title,
178
179
  }
179
180
 
@@ -0,0 +1,168 @@
1
+ /**
2
+ * This module adds brandmetrics provider to the real time data module
3
+ * The {@link module:modules/realTimeData} module is required
4
+ * The module will load load the brandmetrics script and set survey- targeting to ad units of specific bidders.
5
+ * @module modules/brandmetricsRtdProvider
6
+ * @requires module:modules/realTimeData
7
+ */
8
+ import { config } from '../src/config.js'
9
+ import { submodule } from '../src/hook.js'
10
+ import { deepSetValue, mergeDeep, logError, deepAccess } from '../src/utils.js'
11
+ import {loadExternalScript} from '../src/adloader.js'
12
+ const MODULE_NAME = 'brandmetrics'
13
+ const MODULE_CODE = MODULE_NAME
14
+ const RECEIVED_EVENTS = []
15
+ const GVL_ID = 422
16
+ const TCF_PURPOSES = [1, 7]
17
+
18
+ function init (config, userConsent) {
19
+ const hasConsent = checkConsent(userConsent)
20
+
21
+ if (hasConsent) {
22
+ const moduleConfig = getMergedConfig(config)
23
+ initializeBrandmetrics(moduleConfig.params.scriptId)
24
+ }
25
+ return hasConsent
26
+ }
27
+
28
+ /**
29
+ * Checks TCF and USP consents
30
+ * @param {Object} userConsent
31
+ * @returns {boolean}
32
+ */
33
+ function checkConsent (userConsent) {
34
+ let consent = false
35
+
36
+ if (userConsent && userConsent.gdpr && userConsent.gdpr.gdprApplies) {
37
+ const gdpr = userConsent.gdpr
38
+
39
+ if (gdpr.vendorData) {
40
+ const vendor = gdpr.vendorData.vendor
41
+ const purpose = gdpr.vendorData.purpose
42
+
43
+ let vendorConsent = false
44
+ if (vendor.consents) {
45
+ vendorConsent = vendor.consents[GVL_ID]
46
+ }
47
+
48
+ if (vendor.legitimateInterests) {
49
+ vendorConsent = vendorConsent || vendor.legitimateInterests[GVL_ID]
50
+ }
51
+
52
+ const purposes = TCF_PURPOSES.map(id => {
53
+ return (purpose.consents && purpose.consents[id]) || (purpose.legitimateInterests && purpose.legitimateInterests[id])
54
+ })
55
+ const purposesValid = purposes.filter(p => p === true).length === TCF_PURPOSES.length
56
+ consent = vendorConsent && purposesValid
57
+ }
58
+ } else if (userConsent.usp) {
59
+ const usp = userConsent.usp
60
+ consent = usp[1] !== 'N' && usp[2] !== 'Y'
61
+ }
62
+
63
+ return consent
64
+ }
65
+
66
+ /**
67
+ * Add event- listeners to hook in to brandmetrics events
68
+ * @param {Object} reqBidsConfigObj
69
+ * @param {function} callback
70
+ */
71
+ function processBrandmetricsEvents (reqBidsConfigObj, moduleConfig, callback) {
72
+ const callBidTargeting = (event) => {
73
+ if (event.available && event.conf) {
74
+ const targetingConf = event.conf.displayOption || {}
75
+ if (targetingConf.type === 'pbjs') {
76
+ setBidderTargeting(reqBidsConfigObj, moduleConfig, targetingConf.targetKey || 'brandmetrics_survey', event.survey.measurementId)
77
+ }
78
+ }
79
+ callback()
80
+ }
81
+
82
+ if (RECEIVED_EVENTS.length > 0) {
83
+ callBidTargeting(RECEIVED_EVENTS[RECEIVED_EVENTS.length - 1])
84
+ } else {
85
+ window._brandmetrics = window._brandmetrics || []
86
+ window._brandmetrics.push({
87
+ cmd: '_addeventlistener',
88
+ val: {
89
+ event: 'surveyloaded',
90
+ reEmitLast: true,
91
+ handler: (ev) => {
92
+ RECEIVED_EVENTS.push(ev)
93
+ if (RECEIVED_EVENTS.length === 1) {
94
+ // Call bid targeting only for the first received event, if called subsequently, last event from the RECEIVED_EVENTS array is used
95
+ callBidTargeting(ev)
96
+ }
97
+ },
98
+ }
99
+ })
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Sets bid targeting of specific bidders
105
+ * @param {Object} reqBidsConfigObj
106
+ * @param {string} key Targeting key
107
+ * @param {string} val Targeting value
108
+ */
109
+ function setBidderTargeting (reqBidsConfigObj, moduleConfig, key, val) {
110
+ const bidders = deepAccess(moduleConfig, 'params.bidders')
111
+ if (bidders && bidders.length > 0) {
112
+ const ortb2 = {}
113
+ deepSetValue(ortb2, 'ortb2.user.ext.data.' + key, val)
114
+ config.setBidderConfig({
115
+ bidders: bidders,
116
+ config: ortb2
117
+ })
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Add the brandmetrics script to the page.
123
+ * @param {string} scriptId - The script- id provided by brandmetrics or brandmetrics partner
124
+ */
125
+ function initializeBrandmetrics(scriptId) {
126
+ if (scriptId) {
127
+ const path = 'https://cdn.brandmetrics.com/survey/script/'
128
+ const file = scriptId + '.js'
129
+ const url = path + file
130
+
131
+ loadExternalScript(url, MODULE_CODE)
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Merges a provided config with default values
137
+ * @param {Object} customConfig
138
+ * @returns
139
+ */
140
+ function getMergedConfig(customConfig) {
141
+ return mergeDeep({
142
+ waitForIt: false,
143
+ params: {
144
+ bidders: [],
145
+ scriptId: undefined,
146
+ }
147
+ }, customConfig)
148
+ }
149
+
150
+ /** @type {RtdSubmodule} */
151
+ export const brandmetricsSubmodule = {
152
+ name: MODULE_NAME,
153
+ getBidRequestData: function (reqBidsConfigObj, callback, customConfig) {
154
+ try {
155
+ const moduleConfig = getMergedConfig(customConfig)
156
+ if (moduleConfig.waitForIt) {
157
+ processBrandmetricsEvents(reqBidsConfigObj, moduleConfig, callback)
158
+ } else {
159
+ callback()
160
+ }
161
+ } catch (e) {
162
+ logError(e)
163
+ }
164
+ },
165
+ init: init
166
+ }
167
+
168
+ submodule('realTimeData', brandmetricsSubmodule)
@@ -0,0 +1,40 @@
1
+ # Brandmetrics Real-time Data Submodule
2
+ This module is intended to be used by brandmetrics (https://brandmetrics.com) partners and sets targeting keywords to bids if the browser is eligeble to see a brandmetrics survey.
3
+ The module hooks in to brandmetrics events and requires a brandmetrics script to be running. The module can optionally load and initialize brandmetrics by providing the 'scriptId'- parameter.
4
+
5
+ ## Usage
6
+ Compile the Brandmetrics RTD module into your Prebid build:
7
+ ```
8
+ gulp build --modules=rtdModule,brandmetricsRtdProvider
9
+ ```
10
+
11
+ > Note that the global RTD module, `rtdModule`, is a prerequisite of the Brandmetrics RTD module.
12
+
13
+ Enable the Brandmetrics RTD in your Prebid configuration, using the below format:
14
+
15
+ ```javascript
16
+ pbjs.setConfig({
17
+ ...,
18
+ realTimeData: {
19
+ auctionDelay: 500, // auction delay
20
+ dataProviders: [{
21
+ name: 'brandmetrics',
22
+ waitForIt: true // should be true if there's an `auctionDelay`,
23
+ params: {
24
+ scriptId: '00000000-0000-0000-0000-000000000000',
25
+ bidders: ['ozone']
26
+ }
27
+ }]
28
+ },
29
+ ...
30
+ })
31
+ ```
32
+
33
+ ## Parameters
34
+ | Name | Type | Description | Default |
35
+ | ----------------- | -------------------- | ------------------ | ------------------ |
36
+ | name | String | This should always be `brandmetrics` | - |
37
+ | waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (recommended) | `false` |
38
+ | params | Object | | - |
39
+ | params.bidders | String[] | An array of bidders which should receive targeting keys. | `[]` |
40
+ | params.scriptId | String | A script- id GUID if the brandmetrics- script should be initialized. | `undefined` |
@@ -47,7 +47,10 @@ export const spec = {
47
47
  * @return boolean True if this is a valid bid, and false otherwise.
48
48
  */
49
49
  isBidRequestValid: (bid) => {
50
- return Boolean(bid.bidId && bid.params && !isNaN(bid.params.placement_id));
50
+ const validPlacamentId = bid.params && !isNaN(bid.params.placement_id);
51
+ const validGroupId = bid.params && !isNaN(bid.params.group_id);
52
+
53
+ return Boolean(bid.bidId && (validPlacamentId || validGroupId));
51
54
  },
52
55
 
53
56
  /**
@@ -61,13 +64,13 @@ export const spec = {
61
64
  const location = winTop.location;
62
65
  let placements = [];
63
66
  let request = {
64
- 'deviceWidth': winTop.screen.width,
65
- 'deviceHeight': winTop.screen.height,
66
- 'language': (navigator && navigator.language) ? navigator.language : '',
67
- 'secure': location.protocol === 'https:' ? 1 : 0,
68
- 'host': location.host,
69
- 'page': location.pathname,
70
- 'placements': placements,
67
+ deviceWidth: winTop.screen.width,
68
+ deviceHeight: winTop.screen.height,
69
+ language: (navigator && navigator.language) ? navigator.language : '',
70
+ secure: location.protocol === 'https:' ? 1 : 0,
71
+ host: location.host,
72
+ page: location.pathname,
73
+ placements: placements,
71
74
  };
72
75
 
73
76
  if (bidderRequest) {
@@ -85,6 +88,7 @@ export const spec = {
85
88
  let traff = bid.params.traffic || BANNER
86
89
  let placement = {
87
90
  placementId: bid.params.placement_id,
91
+ groupId: bid.params.group_id,
88
92
  bidId: bid.bidId,
89
93
  sizes: bid.mediaTypes[traff].sizes,
90
94
  traffic: traff,
@@ -26,5 +26,19 @@ Module that connects to Colossus SSP demand sources
26
26
  traffic: 'banner'
27
27
  }
28
28
  }]
29
- ];
29
+ }, {
30
+ code: 'placementid_1',
31
+ mediaTypes: {
32
+ banner: {
33
+ sizes: [[300, 250], [300,600]]
34
+ }
35
+ },
36
+ bids: [{
37
+ bidder: 'colossusssp',
38
+ params: {
39
+ group_id: 0,
40
+ traffic: 'banner'
41
+ }
42
+ }]
43
+ }];
30
44
  ```