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.
- package/.eslintrc.js +8 -1
- package/integrationExamples/gpt/amp/creative.html +11 -33
- package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
- package/integrationExamples/gpt/x-domain/creative.html +63 -29
- package/modules/.submodules.json +2 -1
- package/modules/adagioBidAdapter.js +0 -8
- package/modules/adagioBidAdapter.md +1 -1
- package/modules/adbookpspBidAdapter.js +27 -10
- package/modules/adhashBidAdapter.js +3 -3
- package/modules/adkernelBidAdapter.js +2 -1
- package/modules/admanBidAdapter.js +10 -4
- package/modules/adomikAnalyticsAdapter.js +23 -11
- package/modules/adqueryIdSystem.js +103 -0
- package/modules/adqueryIdSystem.md +35 -0
- package/modules/appnexusBidAdapter.js +14 -2
- package/modules/asealBidAdapter.js +58 -0
- package/modules/asealBidAdapter.md +52 -0
- package/modules/bliinkBidAdapter.js +2 -1
- package/modules/brandmetricsRtdProvider.js +168 -0
- package/modules/brandmetricsRtdProvider.md +40 -0
- package/modules/colossussspBidAdapter.js +12 -8
- package/modules/colossussspBidAdapter.md +15 -1
- package/modules/compassBidAdapter.js +10 -3
- package/modules/consumableBidAdapter.md +1 -1
- package/modules/conversantBidAdapter.js +7 -0
- package/modules/criteoBidAdapter.js +10 -1
- package/modules/criteoIdSystem.js +29 -7
- package/modules/currency.js +26 -1
- package/modules/displayioBidAdapter.js +157 -0
- package/modules/displayioBidAdapter.md +148 -0
- package/modules/e_volutionBidAdapter.js +158 -0
- package/modules/glimpseBidAdapter.js +66 -44
- package/modules/gnetBidAdapter.js +3 -3
- package/modules/gnetBidAdapter.md +4 -4
- package/modules/gumgumBidAdapter.js +56 -42
- package/modules/idImportLibrary.js +45 -8
- package/modules/idImportLibrary.md +4 -0
- package/modules/improvedigitalBidAdapter.js +29 -2
- package/modules/interactiveOffersBidAdapter.js +9 -6
- package/modules/jwplayerRtdProvider.js +71 -6
- package/modules/jwplayerRtdProvider.md +27 -11
- package/modules/kargoBidAdapter.js +2 -2
- package/modules/lunamediahbBidAdapter.js +32 -4
- package/modules/nextMillenniumBidAdapter.js +3 -1
- package/modules/oguryBidAdapter.js +14 -14
- package/modules/onetagBidAdapter.js +4 -2
- package/modules/pilotxBidAdapter.js +147 -0
- package/modules/pilotxBidAdapter.md +50 -0
- package/modules/priceFloors.js +2 -1
- package/modules/proxistoreBidAdapter.js +0 -2
- package/modules/pubmaticAnalyticsAdapter.js +16 -0
- package/modules/richaudienceBidAdapter.js +10 -4
- package/modules/riseBidAdapter.js +18 -7
- package/modules/rtbhouseBidAdapter.js +14 -4
- package/modules/rtdModule/index.js +14 -15
- package/modules/rubiconAnalyticsAdapter.js +8 -2
- package/modules/seedingAllianceBidAdapter.js +3 -3
- package/modules/sharethroughBidAdapter.js +12 -17
- package/modules/showheroes-bsBidAdapter.js +13 -2
- package/modules/sortableAnalyticsAdapter.js +5 -4
- package/modules/sovrnBidAdapter.js +93 -18
- package/modules/sovrnBidAdapter.md +80 -2
- package/modules/synacormediaBidAdapter.js +31 -10
- package/modules/tappxBidAdapter.js +8 -5
- package/modules/teadsBidAdapter.js +1 -2
- package/modules/undertoneBidAdapter.js +17 -1
- package/modules/userId/eids.js +7 -1
- package/modules/userId/userId.md +8 -0
- package/modules/viewability.js +177 -0
- package/modules/viewability.md +87 -0
- package/modules/weboramaRtdProvider.js +264 -34
- package/modules/weboramaRtdProvider.md +110 -40
- package/modules/welectBidAdapter.js +106 -0
- package/modules/yahoosspBidAdapter.js +2 -0
- package/package.json +2 -1
- package/src/adRendering.js +38 -0
- package/src/adloader.js +2 -1
- package/src/auction.js +103 -73
- package/src/bidderSettings.js +69 -0
- package/src/hook.js +5 -1
- package/src/prebid.js +19 -21
- package/src/secureCreatives.js +131 -47
- package/src/targeting.js +3 -2
- package/src/utils.js +13 -10
- package/test/helpers/syncPromise.js +71 -0
- package/test/spec/auctionmanager_spec.js +179 -15
- package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
- package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
- package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
- package/test/spec/modules/admanBidAdapter_spec.js +2 -2
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
- package/test/spec/modules/asealBidAdapter_spec.js +144 -0
- package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
- package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
- package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
- package/test/spec/modules/compassBidAdapter_spec.js +1 -0
- package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
- package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
- package/test/spec/modules/criteoIdSystem_spec.js +6 -3
- package/test/spec/modules/currency_spec.js +21 -6
- package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
- package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
- package/test/spec/modules/eids_spec.js +15 -0
- package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
- package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
- package/test/spec/modules/gumgumBidAdapter_spec.js +46 -0
- package/test/spec/modules/idImportLibrary_spec.js +197 -10
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +61 -0
- package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
- package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
- package/test/spec/modules/loglyliftBidAdapter_spec.js +1 -1
- package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +69 -3
- package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
- package/test/spec/modules/realTimeDataModule_spec.js +67 -5
- package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
- package/test/spec/modules/riseBidAdapter_spec.js +31 -5
- package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
- package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +61 -1
- package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
- package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
- package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
- package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
- package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
- package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
- package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
- package/test/spec/modules/userId_spec.js +68 -19
- package/test/spec/modules/viewability_spec.js +280 -0
- package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
- package/test/spec/modules/welectBidAdapter_spec.js +211 -0
- package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
- package/test/spec/unit/core/bidderSettings_spec.js +123 -0
- package/test/spec/unit/pbjs_api_spec.js +21 -8
- 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
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
218
|
-
|
|
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
|
|
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 = (
|
|
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
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
```
|