prebid.js 6.0.0 → 6.1.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 (61) hide show
  1. package/.babelrc.js +1 -7
  2. package/gulpfile.js +1 -0
  3. package/modules/adheseBidAdapter.js +7 -2
  4. package/modules/adkernelBidAdapter.js +1 -0
  5. package/modules/adlivetechBidAdapter.md +61 -0
  6. package/modules/adomikAnalyticsAdapter.js +10 -4
  7. package/modules/appnexusBidAdapter.js +4 -0
  8. package/modules/codefuelBidAdapter.js +1 -3
  9. package/modules/codefuelBidAdapter.md +3 -3
  10. package/modules/datablocksBidAdapter.js +3 -3
  11. package/modules/deepintentBidAdapter.js +1 -1
  12. package/modules/engageyaBidAdapter.js +68 -54
  13. package/modules/glimpseBidAdapter.js +31 -16
  14. package/modules/gptPreAuction.js +11 -5
  15. package/modules/gridBidAdapter.js +1 -1
  16. package/modules/id5IdSystem.md +6 -6
  17. package/modules/imRtdProvider.js +31 -0
  18. package/modules/ixBidAdapter.js +166 -21
  19. package/modules/merkleIdSystem.js +5 -0
  20. package/modules/nativoBidAdapter.js +27 -1
  21. package/modules/oguryBidAdapter.js +2 -1
  22. package/modules/openxBidAdapter.js +6 -1
  23. package/modules/prebidServerBidAdapter/index.js +3 -3
  24. package/modules/pubmaticBidAdapter.js +2 -0
  25. package/modules/saambaaBidAdapter.js +420 -0
  26. package/modules/saambaaBidAdapter.md +65 -68
  27. package/modules/seedtagBidAdapter.js +6 -0
  28. package/modules/smaatoBidAdapter.js +6 -1
  29. package/modules/sspBCBidAdapter.js +34 -3
  30. package/modules/trustxBidAdapter.js +10 -1
  31. package/modules/vidoomyBidAdapter.js +51 -100
  32. package/modules/visxBidAdapter.js +1 -1
  33. package/modules/yieldlabBidAdapter.js +41 -10
  34. package/modules/yieldlabBidAdapter.md +91 -48
  35. package/package.json +6 -1
  36. package/src/adapterManager.js +14 -8
  37. package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
  38. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  39. package/test/spec/modules/appnexusBidAdapter_spec.js +14 -0
  40. package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
  41. package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
  42. package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
  43. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  44. package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
  45. package/test/spec/modules/gptPreAuction_spec.js +58 -4
  46. package/test/spec/modules/imRtdProvider_spec.js +25 -0
  47. package/test/spec/modules/ixBidAdapter_spec.js +285 -2
  48. package/test/spec/modules/konduitWrapper_spec.js +0 -1
  49. package/test/spec/modules/merkleIdSystem_spec.js +18 -0
  50. package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
  51. package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
  52. package/test/spec/modules/openxBidAdapter_spec.js +5 -0
  53. package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
  54. package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
  55. package/test/spec/modules/smaatoBidAdapter_spec.js +30 -0
  56. package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
  57. package/test/spec/modules/trustxBidAdapter_spec.js +42 -0
  58. package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
  59. package/test/spec/modules/visxBidAdapter_spec.js +1 -1
  60. package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
  61. package/test/spec/unit/core/adapterManager_spec.js +24 -6
package/.babelrc.js CHANGED
@@ -14,13 +14,7 @@ module.exports = {
14
14
  [
15
15
  useLocal('@babel/preset-env'),
16
16
  {
17
- "targets": {
18
- "browsers": [
19
- ">0.25%",
20
- "not ie 11",
21
- "not op_mini all"
22
- ]
23
- }
17
+ "useBuiltIns": "entry"
24
18
  }
25
19
  ]
26
20
  ],
package/gulpfile.js CHANGED
@@ -76,6 +76,7 @@ function lint(done) {
76
76
  'modules/**/*.js',
77
77
  'test/**/*.js',
78
78
  'plugins/**/*.js',
79
+ '!plugins/**/node_modules/**',
79
80
  './*.js'
80
81
  ], { base: './' })
81
82
  .pipe(gulpif(argv.nolintfix, eslint(), eslint({ fix: true })))
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
5
+ import { config } from '../src/config.js';
5
6
 
6
7
  const BIDDER_CODE = 'adhese';
7
8
  const GVLID = 553;
@@ -20,11 +21,15 @@ export const spec = {
20
21
  if (validBidRequests.length === 0) {
21
22
  return null;
22
23
  }
24
+
23
25
  const { gdprConsent, refererInfo } = bidderRequest;
24
26
 
27
+ const adheseConfig = config.getConfig('adhese');
25
28
  const gdprParams = (gdprConsent && gdprConsent.consentString) ? { xt: [gdprConsent.consentString] } : {};
26
29
  const refererParams = (refererInfo && refererInfo.referer) ? { xf: [base64urlEncode(refererInfo.referer)] } : {};
27
- const commonParams = { ...gdprParams, ...refererParams };
30
+ const globalCustomParams = (adheseConfig && adheseConfig.globalTargets) ? cleanTargets(adheseConfig.globalTargets) : {};
31
+ const commonParams = { ...globalCustomParams, ...gdprParams, ...refererParams };
32
+ const vastContentAsUrl = !(adheseConfig && adheseConfig.vastContentAsUrl == false);
28
33
 
29
34
  const slots = validBidRequests.map(bid => ({
30
35
  slotname: bidToSlotName(bid),
@@ -34,7 +39,7 @@ export const spec = {
34
39
  const payload = {
35
40
  slots: slots,
36
41
  parameters: commonParams,
37
- vastContentAsUrl: true,
42
+ vastContentAsUrl: vastContentAsUrl,
38
43
  user: {
39
44
  ext: {
40
45
  eids: getEids(validBidRequests),
@@ -75,6 +75,7 @@ export const spec = {
75
75
  {code: 'denakop'},
76
76
  {code: 'rtbanalytica'},
77
77
  {code: 'unibots'},
78
+ {code: 'catapultx'},
78
79
  {code: 'ergadx'},
79
80
  {code: 'turktelekom'}
80
81
  ],
@@ -0,0 +1,61 @@
1
+ # Overview
2
+
3
+ Module Name: Adlivetech Bidder Adapter
4
+ Module Type: Bidder Adapter
5
+ Maintainer: grid-tech@themediagrid.com
6
+
7
+ # Description
8
+
9
+ Module that connects to Grid demand source to fetch bids.
10
+ The adapter is GDPR compliant and supports banner and video (instream and outstream).
11
+
12
+ # Test Parameters
13
+ ```
14
+ var adUnits = [
15
+ {
16
+ code: 'test-div',
17
+ sizes: [[300, 250]],
18
+ bids: [
19
+ {
20
+ bidder: "adlivetech",
21
+ params: {
22
+ uid: '1',
23
+ bidFloor: 0.5
24
+ }
25
+ }
26
+ ]
27
+ },{
28
+ code: 'test-div',
29
+ sizes: [[728, 90]],
30
+ bids: [
31
+ {
32
+ bidder: "adlivetech",
33
+ params: {
34
+ uid: 2,
35
+ keywords: {
36
+ brandsafety: ['disaster'],
37
+ topic: ['stress', 'fear']
38
+ }
39
+ }
40
+ }
41
+ ]
42
+ },
43
+ {
44
+ code: 'test-div',
45
+ sizes: [[728, 90]],
46
+ mediaTypes: { video: {
47
+ context: 'instream',
48
+ playerSize: [728, 90],
49
+ mimes: ['video/mp4']
50
+ },
51
+ bids: [
52
+ {
53
+ bidder: "adlivetech",
54
+ params: {
55
+ uid: 11
56
+ }
57
+ }
58
+ ]
59
+ }
60
+ ];
61
+ ```
@@ -12,6 +12,7 @@ const bidRequested = CONSTANTS.EVENTS.BID_REQUESTED;
12
12
  const bidResponse = CONSTANTS.EVENTS.BID_RESPONSE;
13
13
  const bidWon = CONSTANTS.EVENTS.BID_WON;
14
14
  const bidTimeout = CONSTANTS.EVENTS.BID_TIMEOUT;
15
+ const ua = navigator.userAgent;
15
16
 
16
17
  let adomikAdapter = Object.assign(adapter({}),
17
18
  {
@@ -47,7 +48,7 @@ let adomikAdapter = Object.assign(adapter({}),
47
48
  type: 'request',
48
49
  event: {
49
50
  bidder: bid.bidder.toUpperCase(),
50
- placementCode: bid.placementCode
51
+ placementCode: bid.adUnitCode
51
52
  }
52
53
  });
53
54
  });
@@ -67,6 +68,10 @@ adomikAdapter.initializeBucketEvents = function() {
67
68
  adomikAdapter.bucketEvents = [];
68
69
  }
69
70
 
71
+ adomikAdapter.maxPartLength = function () {
72
+ return (ua.includes(' MSIE ')) ? 1600 : 60000;
73
+ };
74
+
70
75
  adomikAdapter.sendTypedEvent = function() {
71
76
  const groupedTypedEvents = adomikAdapter.buildTypedEvents();
72
77
 
@@ -108,9 +113,10 @@ adomikAdapter.sendTypedEvent = function() {
108
113
  // Encode object in base64
109
114
  const encodedBuf = window.btoa(stringBulkEvents);
110
115
 
111
- // Create final url and split it in 1600 characters max (+endpoint length)
116
+ // Create final url and split it (+endpoint length)
112
117
  const encodedUri = encodeURIComponent(encodedBuf);
113
- const splittedUrl = encodedUri.match(/.{1,1600}/g);
118
+ const maxLength = adomikAdapter.maxPartLength();
119
+ const splittedUrl = encodedUri.match(new RegExp(`.{1,${maxLength}}`, 'g'));
114
120
 
115
121
  splittedUrl.forEach((split, i) => {
116
122
  const partUrl = `${split}&id=${adomikAdapter.currentContext.id}&part=${i}&on=${splittedUrl.length - 1}`;
@@ -121,7 +127,7 @@ adomikAdapter.sendTypedEvent = function() {
121
127
 
122
128
  adomikAdapter.sendWonEvent = function (wonEvent) {
123
129
  const stringWonEvent = JSON.stringify(wonEvent)
124
- logInfo('Won event sent to adomik prebid analytic ' + wonEvent);
130
+ logInfo('Won event sent to adomik prebid analytic ' + stringWonEvent);
125
131
 
126
132
  // Encode object in base64
127
133
  const encodedBuf = window.btoa(stringWonEvent);
@@ -598,6 +598,10 @@ function newBid(serverBid, rtbBid, bidderRequest) {
598
598
  bid.meta = Object.assign({}, bid.meta, { advertiserId: rtbBid.advertiser_id });
599
599
  }
600
600
 
601
+ if (rtbBid.brand_id) {
602
+ bid.meta = Object.assign({}, bid.meta, { brandId: rtbBid.brand_id });
603
+ }
604
+
601
605
  if (rtbBid.rtb.video) {
602
606
  // shared video properties used for all 3 contexts
603
607
  Object.assign(bid, {
@@ -1,5 +1,4 @@
1
1
  import { deepAccess, isArray } from '../src/utils.js';
2
- import { config } from '../src/config.js';
3
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
4
3
  import { BANNER } from '../src/mediaTypes.js';
5
4
  const BIDDER_CODE = 'codefuel';
@@ -34,8 +33,7 @@ export const spec = {
34
33
  const devicetype = getDeviceType()
35
34
  const publisher = setOnAny(validBidRequests, 'params.publisher');
36
35
  const cur = CURRENCY;
37
- // const endpointUrl = 'http://localhost:5000/prebid'
38
- const endpointUrl = config.getConfig('codefuel.bidderUrl');
36
+ const endpointUrl = 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid'
39
37
  const timeout = bidderRequest.timeout;
40
38
 
41
39
  validBidRequests.forEach(bid => bid.netRevenue = 'net');
@@ -21,7 +21,7 @@ You will receive the URLs when contacting us.
21
21
  ```
22
22
  pbjs.setConfig({
23
23
  codefuel: {
24
- bidderUrl: 'https://ai-i-codefuel-ds-rtb-us-east-1-k8s-internal.seccint.com/prebid',
24
+ bidderUrl: 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid',
25
25
  usersyncUrl: 'https://usersync-url.com'
26
26
  }
27
27
  });
@@ -74,7 +74,7 @@ pbjs.setConfig({
74
74
 
75
75
  pbjs.setConfig({
76
76
  codefuel: {
77
- bidderUrl: 'https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/'
77
+ bidderUrl: 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid'
78
78
  }
79
79
  });
80
80
  ```
@@ -105,7 +105,7 @@ pbjs.setConfig({
105
105
 
106
106
  pbjs.setConfig({
107
107
  codefuel: {
108
- bidderUrl: 'https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/'
108
+ bidderUrl: 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid'
109
109
  }
110
110
  });
111
111
  ```
@@ -94,7 +94,7 @@ export const spec = {
94
94
  code: 'datablocks',
95
95
 
96
96
  // DATABLOCKS SCOPED OBJECT
97
- db_obj: {metrics_host: 'prebid.datablocks.net', metrics: [], metrics_timer: null, metrics_queue_time: 1000, vis_optout: false, source_id: 0},
97
+ db_obj: {metrics_host: 'prebid.dblks.net', metrics: [], metrics_timer: null, metrics_queue_time: 1000, vis_optout: false, source_id: 0},
98
98
 
99
99
  // STORE THE DATABLOCKS BUYERID IN STORAGE
100
100
  store_dbid: function(dbid) {
@@ -388,12 +388,12 @@ export const spec = {
388
388
  };
389
389
 
390
390
  let sourceId = validRequests[0].params.source_id || 0;
391
- let host = validRequests[0].params.host || 'prebid.datablocks.net';
391
+ let host = validRequests[0].params.host || 'prebid.dblks.net';
392
392
 
393
393
  // RETURN WITH THE REQUEST AND PAYLOAD
394
394
  return {
395
395
  method: 'POST',
396
- url: `https://${sourceId}.${host}/openrtb/?sid=${sourceId}`,
396
+ url: `https://${host}/openrtb/?sid=${sourceId}`,
397
397
  data: {
398
398
  id: bidderRequest.auctionId,
399
399
  imp: imps,
@@ -162,7 +162,7 @@ function buildImpression(bid) {
162
162
  impression = {
163
163
  id: bid.bidId,
164
164
  tagid: bid.params.tagId || '',
165
- secure: window.location.protocol === 'https' ? 1 : 0,
165
+ secure: window.location.protocol === 'https:' ? 1 : 0,
166
166
  displaymanager: 'di_prebid',
167
167
  displaymanagerver: DI_M_V,
168
168
  ext: buildCustomParams(bid)
@@ -1,7 +1,4 @@
1
- import {
2
- BANNER,
3
- NATIVE
4
- } from '../src/mediaTypes.js';
1
+ import { BANNER, NATIVE } from '../src/mediaTypes.js';
5
2
  import { createTrackPixelHtml } from '../src/utils.js';
6
3
 
7
4
  const {
@@ -10,14 +7,21 @@ const {
10
7
  const BIDDER_CODE = 'engageya';
11
8
  const ENDPOINT_URL = 'https://recs.engageya.com/rec-api/getrecs.json';
12
9
  const ENDPOINT_METHOD = 'GET';
10
+ const SUPPORTED_SIZES = [
11
+ [100, 75], [236, 202], [100, 100], [130, 130], [200, 200], [250, 250], [300, 272], [300, 250], [300, 230], [300, 214], [300, 187], [300, 166], [300, 150], [300, 133], [300, 120], [400, 200], [300, 200], [250, 377], [620, 410], [207, 311], [310, 166], [310, 333], [190, 106], [228, 132], [300, 174], [80, 60], [600, 500], [600, 600], [1080, 610], [1080, 610], [624, 350], [650, 1168], [1080, 1920], [300, 374]
12
+ ];
13
13
 
14
- function getPageUrl() {
15
- var pUrl = window.location.href;
16
- if (isInIframe()) {
17
- pUrl = document.referrer ? document.referrer : pUrl;
14
+ function getPageUrl(bidRequest, bidderRequest) {
15
+ if (bidRequest.params.pageUrl && bidRequest.params.pageUrl != '[PAGE_URL]') {
16
+ return bidRequest.params.pageUrl;
18
17
  }
19
- pUrl = encodeURIComponent(pUrl);
20
- return pUrl;
18
+ if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) {
19
+ return bidderRequest.refererInfo.referer;
20
+ }
21
+ const pageUrl = (isInIframe() && document.referrer)
22
+ ? document.referrer
23
+ : window.location.href;
24
+ return encodeURIComponent(pageUrl);
21
25
  }
22
26
 
23
27
  function isInIframe() {
@@ -33,13 +37,14 @@ function getImageSrc(rec) {
33
37
  return rec.thumbnail_path.indexOf('http') === -1 ? 'https:' + rec.thumbnail_path : rec.thumbnail_path;
34
38
  }
35
39
 
36
- function getImpressionTrackers(rec) {
40
+ function getImpressionTrackers(rec, response) {
41
+ const responseTrackers = [response.viewPxl];
37
42
  if (!rec.trackers) {
38
- return [];
43
+ return responseTrackers;
39
44
  }
40
45
  const impressionTrackers = rec.trackers.impressionPixels || [];
41
46
  const viewTrackers = rec.trackers.viewPixels || [];
42
- return [...impressionTrackers, ...viewTrackers];
47
+ return [...impressionTrackers, ...viewTrackers, ...responseTrackers];
43
48
  }
44
49
 
45
50
  function parseNativeResponse(rec, response) {
@@ -56,7 +61,7 @@ function parseNativeResponse(rec, response) {
56
61
  displayUrl: rec.url,
57
62
  cta: '',
58
63
  sponsoredBy: rec.displayName,
59
- impressionTrackers: getImpressionTrackers(rec),
64
+ impressionTrackers: getImpressionTrackers(rec, response),
60
65
  };
61
66
  }
62
67
 
@@ -74,56 +79,65 @@ function parseBannerResponse(rec, response) {
74
79
  }
75
80
  const title = rec.title && rec.title.trim() ? `<div class="eng_tag_ttl" style="display: none">${rec.title}</div>` : '';
76
81
  const displayName = rec.displayName && title ? `<div class="eng_tag_brnd" style="display: none">${rec.displayName}</div>` : '';
77
- const trackers = getImpressionTrackers(rec)
82
+ const trackers = getImpressionTrackers(rec, response)
78
83
  .map(createTrackPixelHtml)
79
84
  .join('');
80
85
  return `<html><body>${style}<div id="ENG_TAG"><a href="${rec.clickUrl}" target=_blank><img class="eng_tag_img" src="${getImageSrc(rec)}" style="width:${response.imageWidth}px;height:${response.imageHeight}px;" alt="${rec.title}"/>${displayName}${title}</a>${trackers}</div></body></html>`;
81
86
  }
82
87
 
88
+ function getImageSize(bidRequest) {
89
+ if (bidRequest.sizes && bidRequest.sizes.length > 0) {
90
+ return bidRequest.sizes[0];
91
+ } else if (bidRequest.nativeParams && bidRequest.nativeParams.image && bidRequest.nativeParams.image.sizes) {
92
+ return bidRequest.nativeParams.image.sizes;
93
+ }
94
+ return [-1, -1];
95
+ }
96
+
97
+ function isValidSize([width, height]) {
98
+ if (!width || !height) {
99
+ return false;
100
+ }
101
+ return SUPPORTED_SIZES.some(([supportedWidth, supportedHeight]) => supportedWidth === width && supportedHeight === height);
102
+ }
103
+
83
104
  export const spec = {
84
105
  code: BIDDER_CODE,
85
106
  supportedMediaTypes: [BANNER, NATIVE],
86
- isBidRequestValid: function (bid) {
87
- return bid && bid.params && bid.params.hasOwnProperty('widgetId') && bid.params.hasOwnProperty('websiteId') && !isNaN(bid.params.widgetId) && !isNaN(bid.params.websiteId);
107
+
108
+ isBidRequestValid: function (bidRequest) {
109
+ return bidRequest &&
110
+ bidRequest.params &&
111
+ bidRequest.params.hasOwnProperty('widgetId') &&
112
+ bidRequest.params.hasOwnProperty('websiteId') &&
113
+ !isNaN(bidRequest.params.widgetId) &&
114
+ !isNaN(bidRequest.params.websiteId) &&
115
+ isValidSize(getImageSize(bidRequest));
88
116
  },
89
117
 
90
118
  buildRequests: function (validBidRequests, bidderRequest) {
91
- var bidRequests = [];
92
- if (validBidRequests && validBidRequests.length > 0) {
93
- validBidRequests.forEach(function (bidRequest) {
94
- if (bidRequest.params) {
95
- var mediaType = bidRequest.hasOwnProperty('nativeParams') ? 1 : 2;
96
- var imageWidth = -1;
97
- var imageHeight = -1;
98
- if (bidRequest.sizes && bidRequest.sizes.length > 0) {
99
- imageWidth = bidRequest.sizes[0][0];
100
- imageHeight = bidRequest.sizes[0][1];
101
- } else if (bidRequest.nativeParams && bidRequest.nativeParams.image && bidRequest.nativeParams.image.sizes) {
102
- imageWidth = bidRequest.nativeParams.image.sizes[0];
103
- imageHeight = bidRequest.nativeParams.image.sizes[1];
104
- }
105
-
106
- var widgetId = bidRequest.params.widgetId;
107
- var websiteId = bidRequest.params.websiteId;
108
- var pageUrl = (bidRequest.params.pageUrl && bidRequest.params.pageUrl != '[PAGE_URL]') ? bidRequest.params.pageUrl : '';
109
- if (!pageUrl) {
110
- pageUrl = (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) ? bidderRequest.refererInfo.referer : getPageUrl();
111
- }
112
- var bidId = bidRequest.bidId;
113
- var finalUrl = ENDPOINT_URL + '?pubid=0&webid=' + websiteId + '&wid=' + widgetId + '&url=' + pageUrl + '&ireqid=' + bidId + '&pbtpid=' + mediaType + '&imw=' + imageWidth + '&imh=' + imageHeight;
114
- if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprApplies && bidderRequest.consentString) {
115
- finalUrl += '&is_gdpr=1&gdpr_consent=' + bidderRequest.consentString;
116
- }
117
- bidRequests.push({
118
- url: finalUrl,
119
- method: ENDPOINT_METHOD,
120
- data: ''
121
- });
122
- }
123
- });
119
+ if (!validBidRequests) {
120
+ return [];
124
121
  }
125
-
126
- return bidRequests;
122
+ return validBidRequests.map(bidRequest => {
123
+ if (bidRequest.params) {
124
+ const mediaType = bidRequest.hasOwnProperty('nativeParams') ? 1 : 2;
125
+ const [imageWidth, imageHeight] = getImageSize(bidRequest);
126
+ const widgetId = bidRequest.params.widgetId;
127
+ const websiteId = bidRequest.params.websiteId;
128
+ const pageUrl = getPageUrl(bidRequest, bidderRequest);
129
+ const bidId = bidRequest.bidId;
130
+ let finalUrl = ENDPOINT_URL + '?pubid=0&webid=' + websiteId + '&wid=' + widgetId + '&url=' + pageUrl + '&ireqid=' + bidId + '&pbtpid=' + mediaType + '&imw=' + imageWidth + '&imh=' + imageHeight;
131
+ if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprApplies && bidderRequest.consentString) {
132
+ finalUrl += '&is_gdpr=1&gdpr_consent=' + bidderRequest.consentString;
133
+ }
134
+ return {
135
+ url: finalUrl,
136
+ method: ENDPOINT_METHOD,
137
+ data: ''
138
+ };
139
+ }
140
+ }).filter(Boolean);
127
141
  },
128
142
 
129
143
  interpretResponse: function (serverResponse, bidRequest) {
@@ -135,12 +149,12 @@ export const spec = {
135
149
  return response.recs.map(rec => {
136
150
  let bid = {
137
151
  requestId: response.ireqId,
138
- cpm: rec.ecpm,
139
152
  width: response.imageWidth,
140
153
  height: response.imageHeight,
141
154
  creativeId: rec.postId,
155
+ cpm: rec.pecpm || (rec.ecpm / 100),
142
156
  currency: 'USD',
143
- netRevenue: false,
157
+ netRevenue: !!rec.pecpm,
144
158
  ttl: 360,
145
159
  meta: { advertiserDomains: rec.domain ? [rec.domain] : [] },
146
160
  }
@@ -1,19 +1,22 @@
1
1
  import { BANNER } from '../src/mediaTypes.js'
2
+ import { config } from '../src/config.js'
2
3
  import { getStorageManager } from '../src/storageManager.js'
3
4
  import { isArray } from '../src/utils.js'
4
5
  import { registerBidder } from '../src/adapters/bidderFactory.js'
5
6
 
6
7
  const storageManager = getStorageManager()
7
8
 
9
+ const GVLID = 1012
8
10
  const BIDDER_CODE = 'glimpse'
9
11
  const ENDPOINT = 'https://api.glimpsevault.io/ads/serving/public/v1/prebid'
10
12
  const LOCAL_STORAGE_KEY = {
11
- glimpse: {
13
+ vault: {
12
14
  jwt: 'gp_vault_jwt',
13
15
  },
14
16
  }
15
17
 
16
18
  export const spec = {
19
+ gvlid: GVLID,
17
20
  code: BIDDER_CODE,
18
21
  supportedMediaTypes: [BANNER],
19
22
 
@@ -37,20 +40,28 @@ export const spec = {
37
40
  * @returns {ServerRequest}
38
41
  */
39
42
  buildRequests: (validBidRequests, bidderRequest) => {
40
- const networkId = window.networkId || -1
41
- const bids = validBidRequests.map(processBidRequest)
43
+ const demo = config.getConfig('glimpse.demo') || false
44
+ const account = config.getConfig('glimpse.account') || -1
45
+ const demand = config.getConfig('glimpse.demand') || 'glimpse'
46
+ const keywords = config.getConfig('glimpse.keywords') || {}
47
+
48
+ const auth = getVaultJwt()
42
49
  const referer = getReferer(bidderRequest)
43
50
  const gdprConsent = getGdprConsentChoice(bidderRequest)
44
- const jwt = getVaultJwt()
51
+ const bids = validBidRequests.map((bidRequest) => {
52
+ return processBidRequest(bidRequest, keywords)
53
+ })
45
54
 
46
55
  const data = {
47
- auth: jwt,
56
+ auth,
48
57
  data: {
49
58
  bidderCode: spec.code,
50
- networkId,
51
- bids,
59
+ demo,
60
+ account,
61
+ demand,
52
62
  referer,
53
63
  gdprConsent,
64
+ bids,
54
65
  }
55
66
  }
56
67
 
@@ -65,10 +76,9 @@ export const spec = {
65
76
  /**
66
77
  * Parse response from Glimpse server
67
78
  * @param bidResponse {ServerResponse}
68
- * @param bidRequest {BidRequest}
69
79
  * @returns {Bid[]}
70
80
  */
71
- interpretResponse: (bidResponse, bidRequest) => {
81
+ interpretResponse: (bidResponse) => {
72
82
  const isValidResponse = isValidBidResponse(bidResponse)
73
83
 
74
84
  if (isValidResponse) {
@@ -81,16 +91,20 @@ export const spec = {
81
91
  },
82
92
  }
83
93
 
84
- function processBidRequest(bidRequest) {
94
+ function processBidRequest(bidRequest, globalKeywords) {
85
95
  const sizes = normalizeSizes(bidRequest.sizes)
86
- const keywords = bidRequest.params.keywords || []
96
+ const bidKeywords = bidRequest.params.keywords || {}
97
+ const keywords = {
98
+ ...globalKeywords,
99
+ ...bidKeywords,
100
+ }
87
101
 
88
102
  return {
103
+ unitCode: bidRequest.adUnitCode,
89
104
  bidId: bidRequest.bidId,
90
105
  placementId: bidRequest.params.placementId,
91
- unitCode: bidRequest.adUnitCode,
92
- sizes,
93
106
  keywords,
107
+ sizes,
94
108
  }
95
109
  }
96
110
 
@@ -124,7 +138,8 @@ function getReferer(bidderRequest) {
124
138
  function getGdprConsentChoice(bidderRequest) {
125
139
  const hasGdprConsent =
126
140
  hasValue(bidderRequest) &&
127
- hasValue(bidderRequest.gdprConsent)
141
+ hasValue(bidderRequest.gdprConsent) &&
142
+ hasStringValue(bidderRequest.gdprConsent.consentString)
128
143
 
129
144
  if (hasGdprConsent) {
130
145
  return bidderRequest.gdprConsent
@@ -138,11 +153,11 @@ function getGdprConsentChoice(bidderRequest) {
138
153
  }
139
154
 
140
155
  function setVaultJwt(auth) {
141
- storageManager.setDataInLocalStorage(LOCAL_STORAGE_KEY.glimpse.jwt, auth)
156
+ storageManager.setDataInLocalStorage(LOCAL_STORAGE_KEY.vault.jwt, auth)
142
157
  }
143
158
 
144
159
  function getVaultJwt() {
145
- return storageManager.getDataFromLocalStorage(LOCAL_STORAGE_KEY.glimpse.jwt) || ''
160
+ return storageManager.getDataFromLocalStorage(LOCAL_STORAGE_KEY.vault.jwt) || ''
146
161
  }
147
162
 
148
163
  function isValidBidResponse(bidResponse) {
@@ -55,15 +55,16 @@ export const appendPbAdSlot = adUnit => {
55
55
  const context = adUnit.ortb2Imp.ext.data;
56
56
  const { customPbAdSlot } = _currentConfig;
57
57
 
58
- if (customPbAdSlot) {
59
- context.pbadslot = customPbAdSlot(adUnit.code, deepAccess(context, 'adserver.adslot'));
58
+ // use context.pbAdSlot if set (if someone set it already, it will take precedence over others)
59
+ if (context.pbadslot) {
60
60
  return;
61
61
  }
62
62
 
63
- // use context.pbAdSlot if set
64
- if (context.pbadslot) {
63
+ if (customPbAdSlot) {
64
+ context.pbadslot = customPbAdSlot(adUnit.code, deepAccess(context, 'adserver.adslot'));
65
65
  return;
66
66
  }
67
+
67
68
  // use data attribute 'data-adslotid' if set
68
69
  try {
69
70
  const adUnitCodeDiv = document.getElementById(adUnit.code);
@@ -78,12 +79,17 @@ export const appendPbAdSlot = adUnit => {
78
79
  return;
79
80
  }
80
81
  context.pbadslot = adUnit.code;
82
+ return true;
81
83
  };
82
84
 
83
85
  export const makeBidRequestsHook = (fn, adUnits, ...args) => {
84
86
  appendGptSlots(adUnits);
85
87
  adUnits.forEach(adUnit => {
86
- appendPbAdSlot(adUnit);
88
+ const usedAdUnitCode = appendPbAdSlot(adUnit);
89
+ // gpid should be set to itself if already set, or to what pbadslot was (as long as it was not adUnit code)
90
+ if (!adUnit.ortb2Imp.ext.gpid && !usedAdUnitCode) {
91
+ adUnit.ortb2Imp.ext.gpid = adUnit.ortb2Imp.ext.data.pbadslot;
92
+ }
87
93
  });
88
94
  return fn.call(this, adUnits, ...args);
89
95
  };
@@ -29,7 +29,7 @@ let hasSynced = false;
29
29
 
30
30
  export const spec = {
31
31
  code: BIDDER_CODE,
32
- aliases: ['playwire'],
32
+ aliases: ['playwire', 'adlivetech'],
33
33
  supportedMediaTypes: [ BANNER, VIDEO ],
34
34
  /**
35
35
  * Determines whether or not the given bid request is valid.
@@ -1,14 +1,14 @@
1
1
  # ID5 Universal ID
2
2
 
3
- The ID5 Universal ID is a shared, neutral identifier that publishers and ad tech platforms can use to recognise users even in environments where 3rd party cookies are not available. The ID5 Universal ID is designed to respect users' privacy choices and publishers’ preferences throughout the advertising value chain. For more information about the ID5 Universal ID and detailed integration docs, please visit [our documentation](https://support.id5.io/portal/en/kb/articles/prebid-js-user-id-module). We also recommend that you sign up for our [release notes](https://id5.io/universal-id/release-notes) to stay up-to-date with any changes to the implementation of the ID5 Universal ID in Prebid.
3
+ The ID5 ID is a shared, neutral identifier that publishers and ad tech platforms can use to recognise users even in environments where 3rd party cookies are not available. The ID5 ID is designed to respect users' privacy choices and publishers’ preferences throughout the advertising value chain. For more information about the ID5 ID and detailed integration docs, please visit [our documentation](https://support.id5.io/portal/en/kb/articles/prebid-js-user-id-module).
4
4
 
5
- ## ID5 Universal ID Registration
5
+ ## ID5 ID Registration
6
6
 
7
- The ID5 Universal ID is free to use, but requires a simple registration with ID5. Please visit [id5.io/universal-id](https://id5.io/universal-id) to sign up and request your ID5 Partner Number to get started.
7
+ The ID5 ID is free to use, but requires a simple registration with ID5. Please visit [our website](https://id5.io/solutions/#publishers) to sign up and request your ID5 Partner Number to get started.
8
8
 
9
- The ID5 privacy policy is at [https://www.id5.io/platform-privacy-policy](https://www.id5.io/platform-privacy-policy).
9
+ The ID5 privacy policy is at [https://id5.io/platform-privacy-policy](https://id5.io/platform-privacy-policy).
10
10
 
11
- ## ID5 Universal ID Configuration
11
+ ## ID5 ID Configuration
12
12
 
13
13
  First, make sure to add the ID5 submodule to your Prebid.js package with:
14
14
 
@@ -46,7 +46,7 @@ pbjs.setConfig({
46
46
  | Param under userSync.userIds[] | Scope | Type | Description | Example |
47
47
  | --- | --- | --- | --- | --- |
48
48
  | name | Required | String | The name of this module: `"id5Id"` | `"id5Id"` |
49
- | params | Required | Object | Details for the ID5 Universal ID. | |
49
+ | params | Required | Object | Details for the ID5 ID. | |
50
50
  | params.partner | Required | Number | This is the ID5 Partner Number obtained from registering with ID5. | `173` |
51
51
  | params.pd | Optional | String | Partner-supplied data used for linking ID5 IDs across domains. See [our documentation](https://support.id5.io/portal/en/kb/articles/passing-partner-data-to-id5) for details on generating the string. Omit the parameter or leave as an empty string if no data to supply | `"MT1iNTBjY..."` |
52
52
  | params.provider | Optional | String | An identifier provided by ID5 to technology partners who manage Prebid setups on behalf of publishers. Reach out to [ID5](mailto:prebid@id5.io) if you have questions about this parameter | `pubmatic-identity-hub` |