prebid.js 6.5.0 → 6.6.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/modules/.submodules.json +2 -1
- 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/bliinkBidAdapter.js +2 -1
- package/modules/compassBidAdapter.js +9 -2
- package/modules/criteoBidAdapter.js +1 -1
- package/modules/criteoIdSystem.js +29 -7
- package/modules/glimpseBidAdapter.js +66 -44
- package/modules/idImportLibrary.js +45 -8
- package/modules/idImportLibrary.md +4 -0
- package/modules/improvedigitalBidAdapter.js +24 -2
- package/modules/nextMillenniumBidAdapter.js +3 -1
- package/modules/oguryBidAdapter.js +9 -2
- package/modules/onetagBidAdapter.js +4 -2
- package/modules/proxistoreBidAdapter.js +0 -2
- package/modules/pubmaticAnalyticsAdapter.js +16 -0
- package/modules/richaudienceBidAdapter.js +3 -2
- package/modules/riseBidAdapter.js +1 -1
- package/modules/rtbhouseBidAdapter.js +14 -4
- package/modules/rtdModule/index.js +6 -5
- package/modules/showheroes-bsBidAdapter.js +13 -2
- package/modules/tappxBidAdapter.js +8 -5
- package/modules/teadsBidAdapter.js +1 -2
- package/modules/userId/eids.js +7 -1
- package/modules/userId/userId.md +8 -0
- package/modules/welectBidAdapter.js +106 -0
- package/package.json +1 -1
- package/src/hook.js +5 -1
- package/src/prebid.js +18 -4
- 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/bliinkBidAdapter_spec.js +2 -0
- package/test/spec/modules/compassBidAdapter_spec.js +1 -0
- package/test/spec/modules/criteoIdSystem_spec.js +6 -3
- package/test/spec/modules/eids_spec.js +15 -0
- package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
- package/test/spec/modules/idImportLibrary_spec.js +197 -10
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +42 -0
- package/test/spec/modules/loglyliftBidAdapter_spec.js +1 -1
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +10 -2
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
- package/test/spec/modules/realTimeDataModule_spec.js +16 -3
- package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
- package/test/spec/modules/riseBidAdapter_spec.js +1 -1
- package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
- package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
- package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
- package/test/spec/modules/userId_spec.js +68 -19
- package/test/spec/modules/welectBidAdapter_spec.js +211 -0
- package/test/spec/unit/pbjs_api_spec.js +3 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deepSetValue, logError, _each, getBidRequest, isNumber, isArray, deepAccess, isFn, isPlainObject, logWarn, getBidIdParameter, getUniqueIdentifierStr, isEmpty, isInteger } from '../src/utils.js';
|
|
1
|
+
import { deepSetValue, logError, _each, getBidRequest, isNumber, isArray, deepAccess, isFn, isPlainObject, logWarn, getBidIdParameter, getUniqueIdentifierStr, isEmpty, isInteger, isStr } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import { config } from '../src/config.js';
|
|
4
4
|
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
|
|
@@ -11,7 +11,7 @@ const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js
|
|
|
11
11
|
const VIDEO_TARGETING = ['skip', 'skipmin', 'skipafter'];
|
|
12
12
|
|
|
13
13
|
export const spec = {
|
|
14
|
-
version: '7.
|
|
14
|
+
version: '7.6.0',
|
|
15
15
|
code: BIDDER_CODE,
|
|
16
16
|
gvlid: 253,
|
|
17
17
|
aliases: ['id'],
|
|
@@ -73,6 +73,22 @@ export const spec = {
|
|
|
73
73
|
requestParameters.referrer = bidderRequest.refererInfo.referer;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
// Adding first party data
|
|
77
|
+
const site = config.getConfig('ortb2.site');
|
|
78
|
+
if (site) {
|
|
79
|
+
const pageCategory = site.pagecat || site.cat;
|
|
80
|
+
if (pageCategory && isArray(pageCategory)) {
|
|
81
|
+
requestParameters.pagecat = pageCategory.filter((category) => {
|
|
82
|
+
return category && isStr(category)
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const genre = deepAccess(site, 'content.genre');
|
|
86
|
+
if (genre && isStr(genre)) {
|
|
87
|
+
requestParameters.genre = genre;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// End of adding first party data
|
|
91
|
+
|
|
76
92
|
requestParameters.schain = bidRequests[0].schain;
|
|
77
93
|
|
|
78
94
|
if (bidRequests[0].userId) {
|
|
@@ -621,6 +637,12 @@ export function ImproveDigitalAdServerJSClient(endPoint) {
|
|
|
621
637
|
if (requestParameters.schain) {
|
|
622
638
|
impressionBidRequestObject.schain = requestParameters.schain;
|
|
623
639
|
}
|
|
640
|
+
if (requestParameters.pagecat) {
|
|
641
|
+
impressionBidRequestObject.pagecat = requestParameters.pagecat;
|
|
642
|
+
}
|
|
643
|
+
if (requestParameters.genre) {
|
|
644
|
+
impressionBidRequestObject.genre = requestParameters.genre;
|
|
645
|
+
}
|
|
624
646
|
if (requestParameters.user) {
|
|
625
647
|
impressionBidRequestObject.user = requestParameters.user;
|
|
626
648
|
}
|
|
@@ -25,12 +25,14 @@ export const spec = {
|
|
|
25
25
|
window.nmmRefreshCounts[bid.adUnitCode] = window.nmmRefreshCounts[bid.adUnitCode] || 0;
|
|
26
26
|
const postBody = {
|
|
27
27
|
'id': bid.auctionId,
|
|
28
|
-
'refresh_count': window.nmmRefreshCounts[bid.adUnitCode]++,
|
|
29
28
|
'ext': {
|
|
30
29
|
'prebid': {
|
|
31
30
|
'storedrequest': {
|
|
32
31
|
'id': getBidIdParameter('placement_id', bid.params)
|
|
33
32
|
}
|
|
33
|
+
},
|
|
34
|
+
'nextMillennium': {
|
|
35
|
+
'refresh_count': window.nmmRefreshCounts[bid.adUnitCode]++,
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
}
|
|
@@ -10,6 +10,7 @@ const DEFAULT_TIMEOUT = 1000;
|
|
|
10
10
|
const BID_HOST = 'https://mweb-hb.presage.io/api/header-bidding-request';
|
|
11
11
|
const TIMEOUT_MONITORING_HOST = 'https://ms-ads-monitoring-events.presage.io';
|
|
12
12
|
const MS_COOKIE_SYNC_DOMAIN = 'https://ms-cookie-sync.presage.io';
|
|
13
|
+
const ADAPTER_VERSION = '1.2.7';
|
|
13
14
|
|
|
14
15
|
function isBidRequestValid(bid) {
|
|
15
16
|
const adUnitSizes = getAdUnitSizes(bid);
|
|
@@ -55,7 +56,11 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
55
56
|
consent: ''
|
|
56
57
|
}
|
|
57
58
|
},
|
|
58
|
-
imp: []
|
|
59
|
+
imp: [],
|
|
60
|
+
ext: {
|
|
61
|
+
adapterversion: ADAPTER_VERSION,
|
|
62
|
+
prebidversion: '$prebid.version$'
|
|
63
|
+
}
|
|
59
64
|
};
|
|
60
65
|
|
|
61
66
|
if (bidderRequest.hasOwnProperty('gdprConsent') &&
|
|
@@ -123,7 +128,9 @@ function interpretResponse(openRtbBidResponse) {
|
|
|
123
128
|
meta: {
|
|
124
129
|
advertiserDomains: bid.adomain
|
|
125
130
|
},
|
|
126
|
-
nurl: bid.nurl
|
|
131
|
+
nurl: bid.nurl,
|
|
132
|
+
adapterVersion: ADAPTER_VERSION,
|
|
133
|
+
prebidVersion: '$prebid.version$'
|
|
127
134
|
};
|
|
128
135
|
|
|
129
136
|
bidResponse.ad = bid.adm;
|
|
@@ -347,11 +347,13 @@ function getSizes(sizes) {
|
|
|
347
347
|
function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
348
348
|
let syncs = [];
|
|
349
349
|
let params = '';
|
|
350
|
-
if (gdprConsent
|
|
351
|
-
params += '&gdpr_consent=' + gdprConsent.consentString;
|
|
350
|
+
if (gdprConsent) {
|
|
352
351
|
if (typeof gdprConsent.gdprApplies === 'boolean') {
|
|
353
352
|
params += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0);
|
|
354
353
|
}
|
|
354
|
+
if (typeof gdprConsent.consentString === 'string') {
|
|
355
|
+
params += '&gdpr_consent=' + gdprConsent.consentString;
|
|
356
|
+
}
|
|
355
357
|
}
|
|
356
358
|
if (uspConsent && typeof uspConsent === 'string') {
|
|
357
359
|
params += '&us_privacy=' + uspConsent;
|
|
@@ -172,8 +172,6 @@ function interpretResponse(serverResponse, bidRequest) {
|
|
|
172
172
|
|
|
173
173
|
function _assignFloor(bid) {
|
|
174
174
|
if (!isFn(bid.getFloor)) {
|
|
175
|
-
// eslint-disable-next-line no-console
|
|
176
|
-
console.log(bid.params.bidFloor);
|
|
177
175
|
return bid.params.bidFloor ? bid.params.bidFloor : null;
|
|
178
176
|
}
|
|
179
177
|
const floor = bid.getFloor({
|
|
@@ -200,6 +200,21 @@ function getAdapterNameForAlias(aliasName) {
|
|
|
200
200
|
return adapterManager.aliasRegistry[aliasName] || aliasName;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
function getAdDomain(bidResponse) {
|
|
204
|
+
if (bidResponse.meta && bidResponse.meta.advertiserDomains) {
|
|
205
|
+
let adomain = bidResponse.meta.advertiserDomains[0]
|
|
206
|
+
if (adomain) {
|
|
207
|
+
try {
|
|
208
|
+
let hostname = (new URL(adomain));
|
|
209
|
+
return hostname.hostname.replace('www.', '');
|
|
210
|
+
} catch (e) {
|
|
211
|
+
logWarn(LOG_PRE_FIX + 'Adomain URL (Not a proper URL):', adomain);
|
|
212
|
+
return adomain.replace('www.', '');
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
203
218
|
function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
|
|
204
219
|
highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null;
|
|
205
220
|
return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) {
|
|
@@ -218,6 +233,7 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
|
|
|
218
233
|
'dc': bid.bidResponse ? (bid.bidResponse.dealChannel || EMPTY_STRING) : EMPTY_STRING,
|
|
219
234
|
'l1': bid.bidResponse ? bid.clientLatencyTimeMs : 0,
|
|
220
235
|
'l2': 0,
|
|
236
|
+
'adv': bid.bidResponse ? getAdDomain(bid.bidResponse) || undefined : undefined,
|
|
221
237
|
'ss': (s2sBidders.indexOf(bid.bidder) > -1) ? 1 : 0,
|
|
222
238
|
't': (bid.status == ERROR && bid.error.code == TIMEOUT_ERROR) ? 1 : 0,
|
|
223
239
|
'wb': (highestBid && highestBid.requestId === bid.bidId ? 1 : 0),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {isEmpty, deepAccess, isStr} from '../src/utils.js';
|
|
2
2
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import {config} from '../src/config.js';
|
|
4
4
|
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
@@ -52,7 +52,8 @@ export const spec = {
|
|
|
52
52
|
videoData: raiGetVideoInfo(bid),
|
|
53
53
|
scr_rsl: raiGetResolution(),
|
|
54
54
|
cpuc: (typeof window.navigator != 'undefined' ? window.navigator.hardwareConcurrency : null),
|
|
55
|
-
kws: (!isEmpty(bid.params.keywords) ? bid.params.keywords : null)
|
|
55
|
+
kws: (!isEmpty(bid.params.keywords) ? bid.params.keywords : null),
|
|
56
|
+
schain: bid.schain
|
|
56
57
|
};
|
|
57
58
|
|
|
58
59
|
REFERER = (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null)
|
|
@@ -159,7 +159,7 @@ function getSupplyChain(schainObject) {
|
|
|
159
159
|
scStr += '!';
|
|
160
160
|
scStr += `${getEncodedValIfNotEmpty(node.asi)},`;
|
|
161
161
|
scStr += `${getEncodedValIfNotEmpty(node.sid)},`;
|
|
162
|
-
scStr += `${
|
|
162
|
+
scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`;
|
|
163
163
|
scStr += `${getEncodedValIfNotEmpty(node.rid)},`;
|
|
164
164
|
scStr += `${getEncodedValIfNotEmpty(node.name)},`;
|
|
165
165
|
scStr += `${getEncodedValIfNotEmpty(node.domain)}`;
|
|
@@ -165,16 +165,26 @@ function mapBanner(slot) {
|
|
|
165
165
|
* @returns {object} Site by OpenRTB 2.5 §3.2.13
|
|
166
166
|
*/
|
|
167
167
|
function mapSite(slot, bidderRequest) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
let pubId = 'unknown';
|
|
169
|
+
let channel = null;
|
|
170
|
+
if (slot && slot.length > 0) {
|
|
171
|
+
pubId = slot[0].params.publisherId;
|
|
172
|
+
channel = slot[0].params.channel &&
|
|
173
|
+
slot[0].params.channel
|
|
174
|
+
.toString()
|
|
175
|
+
.slice(0, 50);
|
|
176
|
+
}
|
|
177
|
+
let siteData = {
|
|
172
178
|
publisher: {
|
|
173
179
|
id: pubId.toString(),
|
|
174
180
|
},
|
|
175
181
|
page: bidderRequest.refererInfo.referer,
|
|
176
182
|
name: getOrigin()
|
|
183
|
+
};
|
|
184
|
+
if (channel) {
|
|
185
|
+
siteData.channel = channel;
|
|
177
186
|
}
|
|
187
|
+
return siteData;
|
|
178
188
|
}
|
|
179
189
|
|
|
180
190
|
/**
|
|
@@ -197,12 +197,13 @@ const setEventsListeners = (function () {
|
|
|
197
197
|
return function setEventsListeners() {
|
|
198
198
|
if (!registered) {
|
|
199
199
|
Object.entries({
|
|
200
|
-
[CONSTANTS.EVENTS.AUCTION_INIT]: 'onAuctionInitEvent',
|
|
201
|
-
[CONSTANTS.EVENTS.AUCTION_END]: 'onAuctionEndEvent',
|
|
202
|
-
[CONSTANTS.EVENTS.BID_RESPONSE]: 'onBidResponseEvent',
|
|
203
|
-
[CONSTANTS.EVENTS.BID_REQUESTED]: 'onBidRequestEvent'
|
|
204
|
-
}).forEach(([ev, handler]) => {
|
|
200
|
+
[CONSTANTS.EVENTS.AUCTION_INIT]: ['onAuctionInitEvent'],
|
|
201
|
+
[CONSTANTS.EVENTS.AUCTION_END]: ['onAuctionEndEvent', getAdUnitTargeting],
|
|
202
|
+
[CONSTANTS.EVENTS.BID_RESPONSE]: ['onBidResponseEvent'],
|
|
203
|
+
[CONSTANTS.EVENTS.BID_REQUESTED]: ['onBidRequestEvent']
|
|
204
|
+
}).forEach(([ev, [handler, preprocess]]) => {
|
|
205
205
|
events.on(ev, (args) => {
|
|
206
|
+
preprocess && preprocess(args);
|
|
206
207
|
subModules.forEach(sm => {
|
|
207
208
|
try {
|
|
208
209
|
sm[handler] && sm[handler](args, sm.config, _userConsent)
|
|
@@ -61,15 +61,24 @@ export const spec = {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
const consentData = bidderRequest.gdprConsent || {};
|
|
65
|
+
|
|
66
|
+
const gdprConsent = {
|
|
67
|
+
apiVersion: consentData.apiVersion || 2,
|
|
68
|
+
gdprApplies: consentData.gdprApplies || 0,
|
|
69
|
+
consentString: consentData.consentString || '',
|
|
70
|
+
}
|
|
71
|
+
|
|
64
72
|
return {
|
|
65
73
|
type: streamType,
|
|
74
|
+
adUnitCode: bid.adUnitCode,
|
|
66
75
|
bidId: bid.bidId,
|
|
67
76
|
mediaType: type,
|
|
68
77
|
context: context,
|
|
69
78
|
playerId: getBidIdParameter('playerId', bid.params),
|
|
70
79
|
auctionId: bidderRequest.auctionId,
|
|
71
80
|
bidderCode: BIDDER_CODE,
|
|
72
|
-
gdprConsent:
|
|
81
|
+
gdprConsent: gdprConsent,
|
|
73
82
|
start: +new Date(),
|
|
74
83
|
timeout: 3000,
|
|
75
84
|
size: {
|
|
@@ -159,6 +168,7 @@ function createBids(bidRes, reqData) {
|
|
|
159
168
|
let bidUnit = {};
|
|
160
169
|
bidUnit.cpm = bid.cpm;
|
|
161
170
|
bidUnit.requestId = bid.bidId;
|
|
171
|
+
bidUnit.adUnitCode = reqBid.adUnitCode;
|
|
162
172
|
bidUnit.currency = bid.currency;
|
|
163
173
|
bidUnit.mediaType = bid.mediaType || VIDEO;
|
|
164
174
|
bidUnit.ttl = TTL;
|
|
@@ -183,7 +193,8 @@ function createBids(bidRes, reqData) {
|
|
|
183
193
|
} else if (bid.context === 'outstream') {
|
|
184
194
|
const renderer = Renderer.install({
|
|
185
195
|
id: bid.bidId,
|
|
186
|
-
url: '
|
|
196
|
+
url: 'https://static.showheroes.com/renderer.js',
|
|
197
|
+
adUnitCode: reqBid.adUnitCode,
|
|
187
198
|
config: {
|
|
188
199
|
playerId: reqBid.playerId,
|
|
189
200
|
width: bid.size.width,
|
|
@@ -53,7 +53,14 @@ export const spec = {
|
|
|
53
53
|
* @return boolean True if this is a valid bid, and false otherwise.
|
|
54
54
|
*/
|
|
55
55
|
isBidRequestValid: function(bid) {
|
|
56
|
-
|
|
56
|
+
// bid.params.host
|
|
57
|
+
if ((new RegExp(`^(vz.*|zz.*)\\.*$`, 'i')).test(bid.params.host)) { // New endpoint
|
|
58
|
+
if ((new RegExp(`^(zz.*)\\.*$`, 'i')).test(bid.params.host)) return validBasic(bid)
|
|
59
|
+
else return validBasic(bid) && validMediaType(bid)
|
|
60
|
+
} else { // This is backward compatible feature. It will be remove in the future
|
|
61
|
+
if ((new RegExp(`^(ZZ.*)\\.*$`, 'i')).test(bid.params.endpoint)) return validBasic(bid)
|
|
62
|
+
else return validBasic(bid) && validMediaType(bid)
|
|
63
|
+
}
|
|
57
64
|
},
|
|
58
65
|
|
|
59
66
|
/**
|
|
@@ -169,10 +176,6 @@ function validMediaType(bid) {
|
|
|
169
176
|
logWarn(LOG_PREFIX, 'Please review the mandatory Tappx parameters for Video. Video context not supported.');
|
|
170
177
|
return false;
|
|
171
178
|
}
|
|
172
|
-
if (typeof video.mimes == 'undefined') {
|
|
173
|
-
logWarn(LOG_PREFIX, 'Please review the mandatory Tappx parameters for Video. Mimes param is mandatory.');
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
return true;
|
|
@@ -190,8 +190,7 @@ function buildRequestObject(bid) {
|
|
|
190
190
|
const reqObj = {};
|
|
191
191
|
let placementId = getValue(bid.params, 'placementId');
|
|
192
192
|
let pageId = getValue(bid.params, 'pageId');
|
|
193
|
-
const
|
|
194
|
-
const gpid = deepAccess(impressionData, 'pbadslot') || deepAccess(impressionData, 'adserver.adslot');
|
|
193
|
+
const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid');
|
|
195
194
|
|
|
196
195
|
reqObj.sizes = getSizes(bid);
|
|
197
196
|
reqObj.bidId = getBidIdParameter('bidId', bid);
|
package/modules/userId/eids.js
CHANGED
|
@@ -257,7 +257,13 @@ const USER_IDS_CONFIG = {
|
|
|
257
257
|
'connectId': {
|
|
258
258
|
source: 'yahoo.com',
|
|
259
259
|
atype: 3
|
|
260
|
-
}
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
// Adquery ID
|
|
263
|
+
'qid': {
|
|
264
|
+
source: 'adquery.io',
|
|
265
|
+
atype: 1
|
|
266
|
+
},
|
|
261
267
|
};
|
|
262
268
|
|
|
263
269
|
// this function will create an eid object for the given UserId sub-module
|
package/modules/userId/userId.md
CHANGED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { deepAccess } from '../src/utils.js';
|
|
2
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
|
+
|
|
4
|
+
const BIDDER_CODE = 'welect';
|
|
5
|
+
const DEFAULT_DOMAIN = 'www.welect.de';
|
|
6
|
+
|
|
7
|
+
export const spec = {
|
|
8
|
+
code: BIDDER_CODE,
|
|
9
|
+
aliases: ['wlt'],
|
|
10
|
+
gvlid: 282,
|
|
11
|
+
supportedMediaTypes: ['video'],
|
|
12
|
+
|
|
13
|
+
// short code
|
|
14
|
+
/**
|
|
15
|
+
* Determines whether or not the given bid request is valid.
|
|
16
|
+
*
|
|
17
|
+
* @param {BidRequest} bid The bid params to validate.
|
|
18
|
+
* @return boolean True if this is a valid bid, and false otherwise.
|
|
19
|
+
*/
|
|
20
|
+
isBidRequestValid: function (bid) {
|
|
21
|
+
return (
|
|
22
|
+
deepAccess(bid, 'mediaTypes.video.context') === 'instream' &&
|
|
23
|
+
!!bid.params.placementId
|
|
24
|
+
);
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Make a server request from the list of BidRequests.
|
|
28
|
+
*
|
|
29
|
+
* @param {validBidRequests[]} - an array of bids
|
|
30
|
+
* @return ServerRequest Info describing the request to the server.
|
|
31
|
+
*/
|
|
32
|
+
buildRequests: function (validBidRequests) {
|
|
33
|
+
return validBidRequests.map((bidRequest) => {
|
|
34
|
+
let rawSizes =
|
|
35
|
+
deepAccess(bidRequest, 'mediaTypes.video.playerSize') ||
|
|
36
|
+
bidRequest.sizes;
|
|
37
|
+
let size = rawSizes[0];
|
|
38
|
+
|
|
39
|
+
let domain = bidRequest.params.domain || DEFAULT_DOMAIN;
|
|
40
|
+
|
|
41
|
+
let url = `https://${domain}/api/v2/preflight/${bidRequest.params.placementId}`;
|
|
42
|
+
|
|
43
|
+
let gdprConsent = null;
|
|
44
|
+
|
|
45
|
+
if (bidRequest && bidRequest.gdprConsent) {
|
|
46
|
+
gdprConsent = {
|
|
47
|
+
gdpr_consent: {
|
|
48
|
+
gdprApplies: bidRequest.gdprConsent.gdprApplies,
|
|
49
|
+
tcString: bidRequest.gdprConsent.gdprConsent,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const data = {
|
|
55
|
+
width: size[0],
|
|
56
|
+
height: size[1],
|
|
57
|
+
bid_id: bidRequest.bidId,
|
|
58
|
+
...gdprConsent,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
url: url,
|
|
64
|
+
data: data,
|
|
65
|
+
options: {
|
|
66
|
+
contentType: 'application/json',
|
|
67
|
+
withCredentials: false,
|
|
68
|
+
crossOrigin: true,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
/**
|
|
74
|
+
* Unpack the response from the server into a list of bids.
|
|
75
|
+
*
|
|
76
|
+
* @param {ServerResponse} serverResponse A successful response from the server.
|
|
77
|
+
* @return {Bid[]} An array of bids which were nested inside the server.
|
|
78
|
+
*/
|
|
79
|
+
interpretResponse: function (serverResponse, bidRequest) {
|
|
80
|
+
const responseBody = serverResponse.body;
|
|
81
|
+
|
|
82
|
+
if (typeof responseBody !== 'object' || responseBody.available !== true) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const bidResponses = [];
|
|
87
|
+
const bidResponse = {
|
|
88
|
+
requestId: responseBody.bidResponse.requestId,
|
|
89
|
+
cpm: responseBody.bidResponse.cpm,
|
|
90
|
+
width: responseBody.bidResponse.width,
|
|
91
|
+
height: responseBody.bidResponse.height,
|
|
92
|
+
creativeId: responseBody.bidResponse.creativeId,
|
|
93
|
+
currency: responseBody.bidResponse.currency,
|
|
94
|
+
netRevenue: responseBody.bidResponse.netRevenue,
|
|
95
|
+
ttl: responseBody.bidResponse.ttl,
|
|
96
|
+
ad: responseBody.bidResponse.ad,
|
|
97
|
+
vastUrl: responseBody.bidResponse.vastUrl,
|
|
98
|
+
meta: {
|
|
99
|
+
advertiserDomains: responseBody.bidResponse.meta.advertiserDomains
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
bidResponses.push(bidResponse);
|
|
103
|
+
return bidResponses;
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
registerBidder(spec);
|
package/package.json
CHANGED
package/src/hook.js
CHANGED
|
@@ -13,14 +13,18 @@ export function setupBeforeHookFnOnce(baseFn, hookFn, priority = 15) {
|
|
|
13
13
|
baseFn.before(hookFn, priority);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
const submoduleInstallMap = {};
|
|
16
17
|
|
|
17
|
-
export function module(name, install) {
|
|
18
|
+
export function module(name, install, {postInstallAllowed = false} = {}) {
|
|
18
19
|
hook('async', function (submodules) {
|
|
19
20
|
submodules.forEach(args => install(...args));
|
|
21
|
+
if (postInstallAllowed) submoduleInstallMap[name] = install;
|
|
20
22
|
}, name)([]); // will be queued until hook.ready() called in pbjs.processQueue();
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export function submodule(name, ...args) {
|
|
26
|
+
const install = submoduleInstallMap[name];
|
|
27
|
+
if (install) return install(...args);
|
|
24
28
|
getHook(name).before((next, modules) => {
|
|
25
29
|
modules.push(args);
|
|
26
30
|
next(modules);
|
package/src/prebid.js
CHANGED
|
@@ -402,10 +402,23 @@ function emitAdRenderSucceeded({ doc, bid, id }) {
|
|
|
402
402
|
events.emit(AD_RENDER_SUCCEEDED, data);
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
/**
|
|
406
|
+
* This function will check for presence of given node in given parent. If not present - will inject it.
|
|
407
|
+
* @param {Node} node node, whose existance is in question
|
|
408
|
+
* @param {Document} doc document element do look in
|
|
409
|
+
* @param {string} tagName tag name to look in
|
|
410
|
+
*/
|
|
411
|
+
function reinjectNodeIfRemoved(node, doc, tagName) {
|
|
412
|
+
const injectionNode = doc.querySelector(tagName);
|
|
413
|
+
if (!node.parentNode || node.parentNode !== injectionNode) {
|
|
414
|
+
insertElement(node, doc, tagName);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
405
418
|
/**
|
|
406
419
|
* This function will render the ad (based on params) in the given iframe document passed through.
|
|
407
420
|
* Note that doc SHOULD NOT be the parent document page as we can't doc.write() asynchronously
|
|
408
|
-
* @param {
|
|
421
|
+
* @param {Document} doc document
|
|
409
422
|
* @param {string} id bid id to locate the ad
|
|
410
423
|
* @alias module:pbjs.renderAd
|
|
411
424
|
*/
|
|
@@ -449,10 +462,11 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
|
|
|
449
462
|
const {height, width, ad, mediaType, adUrl, renderer} = bid;
|
|
450
463
|
|
|
451
464
|
const creativeComment = document.createComment(`Creative ${bid.creativeId} served by ${bid.bidder} Prebid.js Header Bidding`);
|
|
465
|
+
insertElement(creativeComment, doc, 'html');
|
|
452
466
|
|
|
453
467
|
if (isRendererRequired(renderer)) {
|
|
454
468
|
executeRenderer(renderer, bid);
|
|
455
|
-
|
|
469
|
+
reinjectNodeIfRemoved(creativeComment, doc, 'html');
|
|
456
470
|
emitAdRenderSucceeded({ doc, bid, id });
|
|
457
471
|
} else if ((doc === document && !inIframe()) || mediaType === 'video') {
|
|
458
472
|
const message = `Error trying to write ad. Ad render call ad id ${id} was prevented from writing to the main document.`;
|
|
@@ -471,7 +485,7 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
|
|
|
471
485
|
doc.write(ad);
|
|
472
486
|
doc.close();
|
|
473
487
|
setRenderSize(doc, width, height);
|
|
474
|
-
|
|
488
|
+
reinjectNodeIfRemoved(creativeComment, doc, 'html');
|
|
475
489
|
callBurl(bid);
|
|
476
490
|
emitAdRenderSucceeded({ doc, bid, id });
|
|
477
491
|
} else if (adUrl) {
|
|
@@ -484,7 +498,7 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
|
|
|
484
498
|
|
|
485
499
|
insertElement(iframe, doc, 'body');
|
|
486
500
|
setRenderSize(doc, width, height);
|
|
487
|
-
|
|
501
|
+
reinjectNodeIfRemoved(creativeComment, doc, 'html');
|
|
488
502
|
callBurl(bid);
|
|
489
503
|
emitAdRenderSucceeded({ doc, bid, id });
|
|
490
504
|
} else {
|
|
@@ -175,13 +175,13 @@ describe('AdmanAdapter', function () {
|
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
describe('getUserSyncs', function () {
|
|
178
|
-
let userSync = spec.getUserSyncs();
|
|
178
|
+
let userSync = spec.getUserSyncs({});
|
|
179
179
|
it('Returns valid URL and type', function () {
|
|
180
180
|
expect(userSync).to.be.an('array').with.lengthOf(1);
|
|
181
181
|
expect(userSync[0].type).to.exist;
|
|
182
182
|
expect(userSync[0].url).to.exist;
|
|
183
183
|
expect(userSync[0].type).to.be.equal('image');
|
|
184
|
-
expect(userSync[0].url).to.be.equal('https://pub.admanmedia.com
|
|
184
|
+
expect(userSync[0].url).to.be.equal('https://pub.admanmedia.com/image?pbjs=1&coppa=0');
|
|
185
185
|
});
|
|
186
186
|
});
|
|
187
187
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import adomikAnalytics from 'modules/adomikAnalyticsAdapter.js';
|
|
2
|
-
import {expect} from 'chai';
|
|
2
|
+
import { expect } from 'chai';
|
|
3
3
|
|
|
4
4
|
let events = require('src/events');
|
|
5
5
|
let adapterManager = require('src/adapterManager').default;
|
|
@@ -73,6 +73,7 @@ describe('Adomik Prebid Analytic', function () {
|
|
|
73
73
|
expect(adomikAnalytics.currentContext).to.deep.equal({
|
|
74
74
|
uid: '123456',
|
|
75
75
|
url: 'testurl',
|
|
76
|
+
sampling: undefined,
|
|
76
77
|
testId: '12345',
|
|
77
78
|
testValue: '1000',
|
|
78
79
|
id: '',
|
|
@@ -85,6 +86,7 @@ describe('Adomik Prebid Analytic', function () {
|
|
|
85
86
|
expect(adomikAnalytics.currentContext).to.deep.equal({
|
|
86
87
|
uid: '123456',
|
|
87
88
|
url: 'testurl',
|
|
89
|
+
sampling: undefined,
|
|
88
90
|
testId: '12345',
|
|
89
91
|
testValue: '1000',
|
|
90
92
|
id: 'test-test-test',
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { adqueryIdSubmodule, storage } from 'modules/adqueryIdSystem.js';
|
|
2
|
+
import { server } from 'test/mocks/xhr.js';
|
|
3
|
+
import {amxIdSubmodule} from '../../../modules/amxIdSystem';
|
|
4
|
+
import * as utils from '../../../src/utils';
|
|
5
|
+
|
|
6
|
+
const config = {
|
|
7
|
+
storage: {
|
|
8
|
+
type: 'html5',
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe('AdqueryIdSystem', function () {
|
|
13
|
+
describe('qid submodule', () => {
|
|
14
|
+
it('should expose a "name" property containing qid', () => {
|
|
15
|
+
expect(adqueryIdSubmodule.name).to.equal('qid');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should expose a "gvlid" property containing the GVL ID 902', () => {
|
|
19
|
+
expect(adqueryIdSubmodule.gvlid).to.equal(902);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('getId', function() {
|
|
24
|
+
let getDataFromLocalStorageStub;
|
|
25
|
+
|
|
26
|
+
beforeEach(function() {
|
|
27
|
+
getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
afterEach(function () {
|
|
31
|
+
getDataFromLocalStorageStub.restore();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('gets a adqueryId', function() {
|
|
35
|
+
const config = {
|
|
36
|
+
params: {}
|
|
37
|
+
};
|
|
38
|
+
const callbackSpy = sinon.spy();
|
|
39
|
+
const callback = adqueryIdSubmodule.getId(config).callback;
|
|
40
|
+
callback(callbackSpy);
|
|
41
|
+
const request = server.requests[0];
|
|
42
|
+
expect(request.url).to.eq(`https://bidder.adquery.io/prebid/qid`);
|
|
43
|
+
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ qid: 'qid' }));
|
|
44
|
+
expect(callbackSpy.lastCall.lastArg).to.deep.equal({qid: 'qid'});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('gets a cached adqueryId', function() {
|
|
48
|
+
const config = {
|
|
49
|
+
params: {}
|
|
50
|
+
};
|
|
51
|
+
getDataFromLocalStorageStub.withArgs('qid').returns('qid');
|
|
52
|
+
|
|
53
|
+
const callbackSpy = sinon.spy();
|
|
54
|
+
const callback = adqueryIdSubmodule.getId(config).callback;
|
|
55
|
+
callback(callbackSpy);
|
|
56
|
+
expect(callbackSpy.lastCall.lastArg).to.deep.equal({qid: 'qid'});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('allows configurable id url', function() {
|
|
60
|
+
const config = {
|
|
61
|
+
params: {
|
|
62
|
+
url: 'https://bidder.adquery.io'
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const callbackSpy = sinon.spy();
|
|
66
|
+
const callback = adqueryIdSubmodule.getId(config).callback;
|
|
67
|
+
callback(callbackSpy);
|
|
68
|
+
const request = server.requests[0];
|
|
69
|
+
expect(request.url).to.eq('https://bidder.adquery.io');
|
|
70
|
+
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ qid: 'testqid' }));
|
|
71
|
+
expect(callbackSpy.lastCall.lastArg).to.deep.equal({qid: 'testqid'});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|