prebid.js 7.24.0 → 7.26.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 (191) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adgenerationBidAdapter.js +1 -1
  5. package/dist/admaticBidAdapter.js +1 -1
  6. package/dist/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/ajaBidAdapter.js +1 -1
  10. package/dist/amxBidAdapter.js +1 -1
  11. package/dist/amxIdSystem.js +1 -1
  12. package/dist/appierAnalyticsAdapter.js +1 -1
  13. package/dist/appnexusBidAdapter.js +1 -1
  14. package/dist/asoBidAdapter.js +1 -1
  15. package/dist/axonixBidAdapter.js +1 -1
  16. package/dist/beopBidAdapter.js +1 -1
  17. package/dist/bidglassBidAdapter.js +1 -1
  18. package/dist/big-richmediaBidAdapter.js +1 -1
  19. package/dist/bridgewellBidAdapter.js +1 -1
  20. package/dist/brightMountainMediaBidAdapter.js +1 -1
  21. package/dist/captifyRtdProvider.js +1 -0
  22. package/dist/carodaBidAdapter.js +1 -1
  23. package/dist/chtnwBidAdapter.js +1 -1
  24. package/dist/concertBidAdapter.js +1 -1
  25. package/dist/connectadBidAdapter.js +1 -1
  26. package/dist/consumableBidAdapter.js +1 -1
  27. package/dist/conversantBidAdapter.js +1 -1
  28. package/dist/craftBidAdapter.js +1 -1
  29. package/dist/criteoBidAdapter.js +1 -1
  30. package/dist/discoveryBidAdapter.js +1 -1
  31. package/dist/dspxBidAdapter.js +1 -1
  32. package/dist/eplanningBidAdapter.js +1 -1
  33. package/dist/finativeBidAdapter.js +1 -1
  34. package/dist/glimpseBidAdapter.js +1 -1
  35. package/dist/gmosspBidAdapter.js +1 -1
  36. package/dist/goldbachBidAdapter.js +1 -1
  37. package/dist/gridBidAdapter.js +1 -1
  38. package/dist/gridNMBidAdapter.js +1 -1
  39. package/dist/gumgumBidAdapter.js +1 -1
  40. package/dist/h12mediaBidAdapter.js +1 -1
  41. package/dist/id5IdSystem.js +1 -1
  42. package/dist/improvedigitalBidAdapter.js +1 -1
  43. package/dist/inmarBidAdapter.js +1 -1
  44. package/dist/insticatorBidAdapter.js +1 -1
  45. package/dist/ixBidAdapter.js +1 -1
  46. package/dist/justpremiumBidAdapter.js +1 -1
  47. package/dist/kargoBidAdapter.js +1 -1
  48. package/dist/konduitAnalyticsAdapter.js +1 -1
  49. package/dist/kueezBidAdapter.js +1 -1
  50. package/dist/kueezRtbBidAdapter.js +1 -1
  51. package/dist/lassoBidAdapter.js +1 -1
  52. package/dist/lifestreetBidAdapter.js +1 -1
  53. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  54. package/dist/logicadBidAdapter.js +1 -1
  55. package/dist/loglyliftBidAdapter.js +1 -1
  56. package/dist/magniteAnalyticsAdapter.js +1 -1
  57. package/dist/malltvAnalyticsAdapter.js +1 -1
  58. package/dist/marsmediaBidAdapter.js +1 -1
  59. package/dist/mediafuseBidAdapter.js +1 -1
  60. package/dist/mediasquareBidAdapter.js +1 -1
  61. package/dist/mgidBidAdapter.js +1 -1
  62. package/dist/microadBidAdapter.js +1 -1
  63. package/dist/minutemediaBidAdapter.js +1 -1
  64. package/dist/nextMillenniumBidAdapter.js +1 -1
  65. package/dist/not-for-prod/prebid.js +154 -120
  66. package/dist/oguryBidAdapter.js +1 -1
  67. package/dist/onetagBidAdapter.js +1 -1
  68. package/dist/ooloAnalyticsAdapter.js +1 -1
  69. package/dist/outbrainBidAdapter.js +1 -1
  70. package/dist/parrableIdSystem.js +1 -1
  71. package/dist/pixfutureBidAdapter.js +1 -1
  72. package/dist/prebid-core.js +1 -1
  73. package/dist/publinkIdSystem.js +1 -1
  74. package/dist/pubmaticBidAdapter.js +1 -1
  75. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  76. package/dist/pxyzBidAdapter.js +1 -1
  77. package/dist/quantcastBidAdapter.js +1 -1
  78. package/dist/readpeakBidAdapter.js +1 -1
  79. package/dist/relaidoBidAdapter.js +1 -1
  80. package/dist/rhythmoneBidAdapter.js +1 -1
  81. package/dist/riseBidAdapter.js +1 -1
  82. package/dist/rubiconAnalyticsAdapter.js +1 -1
  83. package/dist/rubiconBidAdapter.js +1 -1
  84. package/dist/seedingAllianceBidAdapter.js +1 -1
  85. package/dist/seedtagBidAdapter.js +1 -1
  86. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  87. package/dist/sharethroughBidAdapter.js +1 -1
  88. package/dist/shinezBidAdapter.js +1 -1
  89. package/dist/smaatoBidAdapter.js +1 -1
  90. package/dist/smartadserverBidAdapter.js +1 -1
  91. package/dist/smartxBidAdapter.js +1 -1
  92. package/dist/smartytechBidAdapter.js +1 -0
  93. package/dist/smilewantedBidAdapter.js +1 -1
  94. package/dist/sonobiBidAdapter.js +1 -1
  95. package/dist/sovrnAnalyticsAdapter.js +1 -1
  96. package/dist/sovrnBidAdapter.js +1 -1
  97. package/dist/sspBCBidAdapter.js +1 -1
  98. package/dist/sublimeBidAdapter.js +1 -1
  99. package/dist/synacormediaBidAdapter.js +1 -1
  100. package/dist/taboolaBidAdapter.js +1 -1
  101. package/dist/tappxBidAdapter.js +1 -1
  102. package/dist/targetVideoBidAdapter.js +1 -1
  103. package/dist/teadsBidAdapter.js +1 -1
  104. package/dist/trionBidAdapter.js +1 -1
  105. package/dist/tripleliftBidAdapter.js +1 -1
  106. package/dist/ttdBidAdapter.js +1 -1
  107. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  108. package/dist/underdogmediaBidAdapter.js +1 -1
  109. package/dist/undertoneBidAdapter.js +1 -1
  110. package/dist/userId.js +1 -1
  111. package/dist/vidazooBidAdapter.js +1 -1
  112. package/dist/videobyteBidAdapter.js +1 -1
  113. package/dist/viqeoBidAdapter.js +1 -0
  114. package/dist/visxBidAdapter.js +1 -1
  115. package/dist/vuukleBidAdapter.js +1 -1
  116. package/dist/widespaceBidAdapter.js +1 -1
  117. package/dist/winrBidAdapter.js +1 -1
  118. package/dist/yahoosspBidAdapter.js +1 -1
  119. package/dist/yieldlabBidAdapter.js +1 -1
  120. package/dist/yieldmoBidAdapter.js +1 -1
  121. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  122. package/dist/zeta_global_sspBidAdapter.js +1 -1
  123. package/dist/zeusPrimeRtdProvider.js +31 -0
  124. package/integrationExamples/gpt/captifyRtdProvider_example.html +167 -0
  125. package/modules/.submodules.json +3 -1
  126. package/modules/adagioBidAdapter.js +1 -1
  127. package/modules/admaticBidAdapter.js +108 -59
  128. package/modules/admaticBidAdapter.md +2 -2
  129. package/modules/beopBidAdapter.js +17 -2
  130. package/modules/captifyRtdProvider.js +146 -0
  131. package/modules/captifyRtdProvider.md +68 -0
  132. package/modules/concertBidAdapter.js +17 -3
  133. package/modules/conversantAnalyticsAdapter.md +12 -13
  134. package/modules/conversantBidAdapter.md +3 -3
  135. package/modules/discoveryBidAdapter.js +38 -17
  136. package/modules/discoveryBidAdapter.md +7 -6
  137. package/modules/gridBidAdapter.js +440 -22
  138. package/modules/kargoBidAdapter.js +14 -8
  139. package/modules/magniteAnalyticsAdapter.js +1 -1
  140. package/modules/microadBidAdapter.js +22 -11
  141. package/modules/nextMillenniumBidAdapter.js +20 -24
  142. package/modules/oguryBidAdapter.js +5 -2
  143. package/modules/pubmaticBidAdapter.js +1 -1
  144. package/modules/seedtagBidAdapter.js +9 -4
  145. package/modules/smartadserverBidAdapter.js +6 -2
  146. package/modules/smartxBidAdapter.js +10 -7
  147. package/modules/smartytechBidAdapter.js +78 -0
  148. package/modules/smartytechBidAdapter.md +44 -0
  149. package/modules/taboolaBidAdapter.js +3 -3
  150. package/modules/taboolaBidAdapter.md +0 -2
  151. package/modules/tappxBidAdapter.js +21 -6
  152. package/modules/ttdBidAdapter.js +4 -3
  153. package/modules/userId/index.js +1 -1
  154. package/modules/vidazooBidAdapter.js +29 -3
  155. package/modules/viqeoBidAdapter.js +180 -0
  156. package/modules/viqeoBidAdapter.md +56 -0
  157. package/modules/yieldlabBidAdapter.js +19 -8
  158. package/modules/yieldmoBidAdapter.js +22 -8
  159. package/modules/yieldoneBidAdapter.js +60 -8
  160. package/modules/yieldoneBidAdapter.md +109 -9
  161. package/modules/zeta_global_sspBidAdapter.js +4 -0
  162. package/modules/zeusPrimeRtdProvider.js +357 -0
  163. package/modules/zeusPrimeRtdProvider.md +60 -0
  164. package/package.json +1 -1
  165. package/src/adloader.js +0 -1
  166. package/test/spec/modules/adagioBidAdapter_spec.js +2 -2
  167. package/test/spec/modules/admaticBidAdapter_spec.js +262 -3
  168. package/test/spec/modules/beopBidAdapter_spec.js +52 -0
  169. package/test/spec/modules/captifyRtdProvider_spec.js +253 -0
  170. package/test/spec/modules/concertBidAdapter_spec.js +26 -15
  171. package/test/spec/modules/discoveryBidAdapter_spec.js +9 -8
  172. package/test/spec/modules/gridBidAdapter_spec.js +289 -1
  173. package/test/spec/modules/kargoBidAdapter_spec.js +76 -4
  174. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +20 -0
  175. package/test/spec/modules/microadBidAdapter_spec.js +48 -0
  176. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +4 -3
  177. package/test/spec/modules/oguryBidAdapter_spec.js +27 -5
  178. package/test/spec/modules/pubmaticBidAdapter_spec.js +2 -2
  179. package/test/spec/modules/seedtagBidAdapter_spec.js +34 -10
  180. package/test/spec/modules/smartadserverBidAdapter_spec.js +80 -0
  181. package/test/spec/modules/smartxBidAdapter_spec.js +32 -0
  182. package/test/spec/modules/smartytechBidAdapter_spec.js +162 -0
  183. package/test/spec/modules/taboolaBidAdapter_spec.js +0 -77
  184. package/test/spec/modules/ttdBidAdapter_spec.js +13 -0
  185. package/test/spec/modules/vidazooBidAdapter_spec.js +1 -0
  186. package/test/spec/modules/viqeoBidAdapter_spec.js +124 -0
  187. package/test/spec/modules/yieldlabBidAdapter_spec.js +125 -0
  188. package/test/spec/modules/yieldmoBidAdapter_spec.js +3 -4
  189. package/test/spec/modules/yieldoneBidAdapter_spec.js +30 -6
  190. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +16 -1
  191. package/test/spec/modules/zeusPrimeRtdProvider_spec.js +410 -0
@@ -1,94 +1,93 @@
1
1
  import { getValue, logError, deepAccess, getBidIdParameter, isArray } from '../src/utils.js';
2
- import { loadExternalScript } from '../src/adloader.js';
3
- import {registerBidder} from '../src/adapters/bidderFactory.js';
4
-
5
- const ENDPOINT_URL = 'https://layer.serve.admatic.com.tr/pb';
6
- const SYNC_URL = 'https://cdn.serve.admatic.com.tr/showad/sync.js';
2
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
+ import { BANNER, VIDEO } from '../src/mediaTypes.js';
4
+ const SYNC_URL = 'https://cdn.serve.admatic.com.tr/showad/sync.html';
7
5
  const BIDDER_CODE = 'admatic';
8
-
9
6
  export const spec = {
10
- code: 'admatic',
11
- supportedMediaTypes: ['video', 'banner'],
12
- /**
13
- * Determines whether or not the given bid request is valid.
14
- *
15
- * @param {BidRequest} bid The bid params to validate.
16
- * @return boolean True if this is a valid bid, and false otherwise.
7
+ code: BIDDER_CODE,
8
+ aliases: [
9
+ {code: 'pixad'}
10
+ ],
11
+ supportedMediaTypes: [BANNER, VIDEO],
12
+ /** f
13
+ * @param {object} bid
14
+ * @return {boolean}
17
15
  */
18
- isBidRequestValid: function(bid) {
16
+ isBidRequestValid: (bid) => {
19
17
  let isValid = false;
20
- if (typeof bid.params !== 'undefined') {
21
- let isValidNetworkId = _validateId(getValue(bid.params, 'networkId'));
22
- isValid = isValidNetworkId;// && isValidTypeId;
18
+ if (bid?.params) {
19
+ const isValidNetworkId = _validateId(getValue(bid.params, 'networkId'));
20
+ const isValidHost = _validateString(getValue(bid.params, 'host'));
21
+ isValid = isValidNetworkId && isValidHost;
23
22
  }
24
23
 
25
24
  if (!isValid) {
26
- logError('AdMatic networkId parameters are required. Bid aborted.');
25
+ logError(`${bid.bidder} networkId and host parameters are required. Bid aborted.`);
27
26
  }
28
27
  return isValid;
29
28
  },
29
+
30
30
  /**
31
- * Make a server request from the list of BidRequests.
32
- *
33
- * @param {validBidRequests[]} an array of bids
34
- * @return ServerRequest Info describing the request to the server.
31
+ * @param {BidRequest[]} validBidRequests
32
+ * @return {ServerRequest}
35
33
  */
36
- buildRequests: function(validBidRequests, bidderRequest) {
34
+ buildRequests: (validBidRequests, bidderRequest) => {
37
35
  const bids = validBidRequests.map(buildRequestObject);
38
36
  const networkId = getValue(validBidRequests[0].params, 'networkId');
37
+ const host = getValue(validBidRequests[0].params, 'host');
39
38
  const currency = getValue(validBidRequests[0].params, 'currency') || 'TRY';
40
-
41
- setTimeout(() => {
42
- loadExternalScript(SYNC_URL, BIDDER_CODE);
43
- }, bidderRequest.timeout);
39
+ const bidderName = validBidRequests[0].bidder;
44
40
 
45
41
  const payload = {
46
- 'user': {
47
- 'ua': navigator.userAgent
42
+ user: {
43
+ ua: navigator.userAgent
48
44
  },
49
- 'blacklist': [],
50
- 'site': {
51
- 'page': location.href,
52
- 'ref': location.origin,
53
- 'publisher': {
54
- 'name': location.hostname,
55
- 'publisherId': networkId
45
+ blacklist: [],
46
+ site: {
47
+ page: location.href,
48
+ ref: location.origin,
49
+ publisher: {
50
+ name: location.hostname,
51
+ publisherId: networkId
56
52
  }
57
53
  },
58
54
  imp: bids,
59
55
  ext: {
60
- 'cur': currency,
61
- 'type': 'admatic'
56
+ cur: currency,
57
+ bidder: bidderName
62
58
  }
63
59
  };
64
60
 
65
- const payloadString = JSON.stringify(payload);
66
- return {
67
- method: 'POST',
68
- url: ENDPOINT_URL,
69
- data: payloadString,
70
- options: {
71
- contentType: 'application/json'
72
- }
73
- };
61
+ if (payload) {
62
+ return { method: 'POST', url: `https://${host}/pb?bidder=${bidderName}`, data: payload, options: { contentType: 'application/json' } };
63
+ }
64
+ },
65
+
66
+ getUserSyncs: function (syncOptions, responses) {
67
+ if (syncOptions.iframeEnabled) {
68
+ return [{
69
+ type: 'iframe',
70
+ url: SYNC_URL
71
+ }];
72
+ }
74
73
  },
74
+
75
75
  /**
76
- * Unpack the response from the server into a list of bids.
77
- *
78
- * @param {*} serverResponse A successful response from the server.
79
- * @return {Bid[]} An array of bids which were nested inside the server.
76
+ * @param {*} response
77
+ * @param {ServerRequest} request
78
+ * @return {Bid[]}
80
79
  */
81
80
  interpretResponse: (response, request) => {
82
81
  const body = response.body || response;
83
82
  const bidResponses = [];
84
- if (body.data.length > 0) {
85
- body.data.forEach(function (bid) {
83
+ if (body && body?.data && isArray(body.data)) {
84
+ body.data.forEach(bid => {
86
85
  const resbid = {
87
86
  requestId: bid.id,
88
87
  cpm: bid.price,
89
88
  width: bid.width,
90
89
  height: bid.height,
91
- currency: body.cur,
90
+ currency: body.cur || 'TRY',
92
91
  netRevenue: true,
93
92
  ad: bid.party_tag,
94
93
  creativeId: bid.creative_id,
@@ -96,22 +95,68 @@ export const spec = {
96
95
  advertiserDomains: bid && bid.adomain ? bid.adomain : []
97
96
  },
98
97
  ttl: 360,
99
- bidder: 'admatic',
100
- timeToRespond: 1,
101
- requestTimestamp: 1
98
+ bidder: bid.bidder
102
99
  };
100
+
103
101
  bidResponses.push(resbid);
104
102
  });
105
- };
103
+ }
106
104
  return bidResponses;
107
105
  }
108
106
  };
109
107
 
108
+ function enrichSlotWithFloors(slot, bidRequest) {
109
+ try {
110
+ const slotFloors = {};
111
+
112
+ if (bidRequest.getFloor) {
113
+ if (bidRequest.mediaTypes?.banner) {
114
+ slotFloors.banner = {};
115
+ const bannerSizes = parseSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes'))
116
+ bannerSizes.forEach(bannerSize => slotFloors.banner[parseSize(bannerSize).toString()] = bidRequest.getFloor({ size: bannerSize, mediaType: BANNER }));
117
+ }
118
+
119
+ if (bidRequest.mediaTypes?.video) {
120
+ slotFloors.video = {};
121
+ const videoSizes = parseSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize'))
122
+ videoSizes.forEach(videoSize => slotFloors.video[parseSize(videoSize).toString()] = bidRequest.getFloor({ size: videoSize, mediaType: VIDEO }));
123
+ }
124
+
125
+ if (Object.keys(slotFloors).length > 0) {
126
+ if (!slot) {
127
+ slot = {}
128
+ }
129
+ Object.assign(slot, {
130
+ floors: slotFloors
131
+ });
132
+ }
133
+ }
134
+ } catch (e) {
135
+ logError('Could not parse floors from Prebid: ' + e);
136
+ }
137
+ }
138
+
139
+ function parseSizes(sizes, parser = s => s) {
140
+ if (sizes == undefined) {
141
+ return [];
142
+ }
143
+ if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]])
144
+ return sizes.map(size => parser(size));
145
+ }
146
+ return [parser(sizes)]; // or a single one ? (ie. [728,90])
147
+ }
148
+
149
+ function parseSize(size) {
150
+ return size[0] + 'x' + size[1];
151
+ }
152
+
110
153
  function buildRequestObject(bid) {
111
154
  const reqObj = {};
112
155
  reqObj.size = getSizes(bid);
113
156
  reqObj.id = getBidIdParameter('bidId', bid);
114
- reqObj.floor = getValue(bid.params, 'floor') || 0.01;
157
+
158
+ enrichSlotWithFloors(reqObj, bid);
159
+
115
160
  return reqObj;
116
161
  }
117
162
 
@@ -144,4 +189,8 @@ function _validateId(id) {
144
189
  return (parseInt(id) > 0);
145
190
  }
146
191
 
192
+ function _validateString(str) {
193
+ return (typeof str == 'string');
194
+ }
195
+
147
196
  registerBidder(spec);
@@ -19,7 +19,7 @@ Use `admatic` as bidder.
19
19
  bidder: 'admatic',
20
20
  params: {
21
21
  networkId: 12345,
22
- floor: 0.5
22
+ host: 'layer.serve.admatic.com.tr'
23
23
  }
24
24
  }]
25
25
  },{
@@ -29,7 +29,7 @@ Use `admatic` as bidder.
29
29
  bidder: 'admatic',
30
30
  params: {
31
31
  networkId: 12345,
32
- floor: 0.5
32
+ host: 'layer.serve.admatic.com.tr'
33
33
  }
34
34
  }]
35
35
  }];
@@ -1,4 +1,4 @@
1
- import { deepAccess, isArray, logWarn, triggerPixel, buildUrl, logInfo, getValue, getBidIdParameter } from '../src/utils.js';
1
+ import { deepAccess, isArray, isStr, logWarn, triggerPixel, buildUrl, logInfo, getValue, getBidIdParameter } from '../src/utils.js';
2
2
  import { getRefererInfo } from '../src/refererDetection.js';
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
4
  import { config } from '../src/config.js';
@@ -40,6 +40,19 @@ export const spec = {
40
40
  const pageUrl = getPageUrl(bidderRequest.refererInfo, window);
41
41
  const gdpr = bidderRequest.gdprConsent;
42
42
  const firstSlot = slots[0];
43
+ const kwdsFromRequest = firstSlot.kwds;
44
+ let keywords = [];
45
+ if (kwdsFromRequest) {
46
+ if (isArray(kwdsFromRequest)) {
47
+ keywords = kwdsFromRequest;
48
+ } else if (isStr(kwdsFromRequest)) {
49
+ if (kwdsFromRequest.indexOf(',') != -1) {
50
+ keywords = kwdsFromRequest.split(',').map((e) => { return e.trim() });
51
+ } else {
52
+ keywords.push(kwdsFromRequest);
53
+ }
54
+ }
55
+ }
43
56
  const payloadObject = {
44
57
  at: new Date().toString(),
45
58
  nid: firstSlot.nid,
@@ -47,12 +60,13 @@ export const spec = {
47
60
  pid: firstSlot.pid,
48
61
  url: pageUrl,
49
62
  lang: (window.navigator.language || window.navigator.languages[0]),
50
- kwds: bidderRequest.ortb2?.site?.keywords || [],
63
+ kwds: keywords,
51
64
  dbg: false,
52
65
  slts: slots,
53
66
  is_amp: deepAccess(bidderRequest, 'referrerInfo.isAmp'),
54
67
  tc_string: (gdpr && gdpr.gdprApplies) ? gdpr.consentString : null,
55
68
  };
69
+
56
70
  const payloadString = JSON.stringify(payloadObject);
57
71
  return {
58
72
  method: 'POST',
@@ -129,6 +143,7 @@ function beOpRequestSlotsMaker(bid) {
129
143
  sizes: isArray(bannerSizes) ? bannerSizes : bid.sizes,
130
144
  flr: floor,
131
145
  pid: getValue(bid.params, 'accountId'),
146
+ kwds: getValue(bid.params, 'keywords'),
132
147
  nid: getValue(bid.params, 'networkId'),
133
148
  nptnid: getValue(bid.params, 'networkPartnerId'),
134
149
  bid: getBidIdParameter('bidId', bid),
@@ -0,0 +1,146 @@
1
+ /**
2
+ * This module adds Captify real time data provider module
3
+ * The {@link module:modules/realTimeData} module is required
4
+ * The module will fetch segments (page-centric) from Captify live-classification server
5
+ * @module modules/captifyRtdProvider
6
+ * @requires module:modules/realTimeData
7
+ */
8
+ import { submodule } from '../src/hook.js';
9
+ import { getRefererInfo } from '../src/refererDetection.js';
10
+ import { ajax } from '../src/ajax.js';
11
+ import { config } from '../src/config.js';
12
+ import {deepAccess, isArray, isEmptyStr, isNumber, logError} from '../src/utils.js';
13
+ import {getGlobal} from '../src/prebidGlobal.js';
14
+
15
+ const MODULE_NAME = 'realTimeData';
16
+ const SUBMODULE_NAME = 'CaptifyRTDModule';
17
+ const DEFAULT_LC_URL = 'https://live-classification.cpx.to/prebid-segments';
18
+
19
+ const STATUS = {
20
+ SUCCESS: 200,
21
+ ACCEPTED: 202,
22
+ };
23
+
24
+ /**
25
+ * Set `appnexusAuctionKeywords` that appnexus bidder will read and send in request to Xandr
26
+ * @param {Array<number>} segments captify segments for Appnexus(Xandr) system, in form of [id1, id2, id3]
27
+ * where id1, id2, id3 - actual Xandr segment ids with keywords enabled
28
+ */
29
+ export function setAppnexusSegments(segments) {
30
+ config.setConfig({
31
+ appnexusAuctionKeywords: {
32
+ 'captify_segments': segments,
33
+ },
34
+ })
35
+ }
36
+
37
+ /**
38
+ * Function returns only bidders that contained both, in moduleConfig and at least one adUnit.
39
+ * @param {Array<string>} bidders Contains list of bidders, to set targeting for
40
+ * @param {Object} data Response of live-classification service
41
+ */
42
+ export function addSegmentData(bidders, data) {
43
+ for (const bidder of bidders) {
44
+ if (bidder === 'appnexus') { setAppnexusSegments(data['xandr']) }
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Function returns only bidders that contained in both, moduleConfig and at least one adUnit.
50
+ * @param {Object} moduleConfig Config object passed to the module
51
+ * @param {Object} reqBidsConfigObj Config object for the bidders; each adapter has its own entry
52
+ */
53
+ export function getMatchingBidders(moduleConfig, reqBidsConfigObj) {
54
+ const biddersFromConf = deepAccess(moduleConfig, 'params.bidders');
55
+
56
+ const adUnitBidders = reqBidsConfigObj.adUnits
57
+ .flatMap(({bids}) => bids.map(({bidder}) => bidder))
58
+ .filter((e, i, a) => a.indexOf(e) === i);
59
+
60
+ if (!isArray(adUnitBidders) || !adUnitBidders.length) {
61
+ logError(SUBMODULE_NAME, 'Missing parameter bidders in bidRequestConfig');
62
+ return [];
63
+ }
64
+
65
+ return biddersFromConf.filter(bidder => adUnitBidders.includes(bidder));
66
+ }
67
+
68
+ /**
69
+ * Main function that sets Captify targeting for various bidders
70
+ * @param {Object} moduleConfig Config object passed to the module
71
+ * @param {Function} onDone callback function that executed when everything is done
72
+ * @param {Object} reqBidsConfigObj Config object for the bidders; each adapter has its own entry
73
+ * @param {Object} gcv contains data related to user consent, if applies
74
+ */
75
+ export function setCaptifyTargeting(reqBidsConfigObj, onDone, moduleConfig, gcv) {
76
+ const pbjsVer = getGlobal();
77
+ const ref = getRefererInfo().referer;
78
+ const url = document.URL;
79
+ const pubId = moduleConfig.params.pubId;
80
+ const bidders = getMatchingBidders(moduleConfig, reqBidsConfigObj)
81
+ const requestBody = {
82
+ pubId,
83
+ ref,
84
+ url,
85
+ pbjsVer,
86
+ gcv
87
+ };
88
+ let requestUrl = moduleConfig.params.url;
89
+ if (!requestUrl || isEmptyStr(requestUrl)) {
90
+ requestUrl = DEFAULT_LC_URL;
91
+ }
92
+
93
+ if (!bidders.length) {
94
+ logError(SUBMODULE_NAME, 'There are no matched bidders to work with');
95
+ return;
96
+ }
97
+
98
+ ajax(requestUrl, {
99
+ success: function (response, req) {
100
+ if (req.status === STATUS.SUCCESS) {
101
+ try {
102
+ const data = JSON.parse(response);
103
+ if (data) {
104
+ addSegmentData(bidders, data);
105
+ }
106
+ } catch (e) {
107
+ logError(SUBMODULE_NAME, 'Unable to parse live-classification data' + e);
108
+ }
109
+ }
110
+ onDone();
111
+ },
112
+ error: function () {
113
+ onDone();
114
+ logError(SUBMODULE_NAME, 'Unable to get live-classification data');
115
+ }
116
+ },
117
+ JSON.stringify(requestBody),
118
+ {
119
+ contentType: 'application/json',
120
+ method: 'POST',
121
+ });
122
+ }
123
+
124
+ export function init(moduleConfig, userConsent) {
125
+ // Validate bidders
126
+ const biddersFromConf = deepAccess(moduleConfig, 'params.bidders');
127
+ if (!isArray(biddersFromConf) || !biddersFromConf.length) {
128
+ logError(SUBMODULE_NAME, 'Missing parameter bidders in moduleConfig');
129
+ return false
130
+ }
131
+ const publisherId = deepAccess(moduleConfig, 'params.pubId');
132
+ // Publisher Id
133
+ if (!isNumber(publisherId)) {
134
+ logError(SUBMODULE_NAME, 'Missing parameter pubId in moduleConfig');
135
+ return false
136
+ }
137
+ return true
138
+ }
139
+
140
+ export const captifySubmodule = {
141
+ name: SUBMODULE_NAME,
142
+ init: init,
143
+ setCaptifyTargeting
144
+ };
145
+
146
+ submodule(MODULE_NAME, captifySubmodule);
@@ -0,0 +1,68 @@
1
+ # Captify Real-Time Data Submodule
2
+
3
+ # Overview
4
+
5
+ Module Name: Captify Rtd Provider
6
+ Module Type: Rtd Provider
7
+ Layout: integrationExamples/gpt/captifyRtdProvider_example.html
8
+ Maintainer: prebid@captify.tech
9
+
10
+ # Description
11
+
12
+ Captify uses publisher first-party on-site search data to power machine learning algorithms to create a suite of
13
+ contextual based targeting solutions that activate in a cookieless environment.
14
+
15
+ The RTD submodule allows bid requests to be classified by our live-classification service on the first ad call,
16
+ maximising value for publishers by increasing scale for advertisers.
17
+
18
+ Segments will be attached to bid request objects sent to different SSPs in order to optimize targeting.
19
+
20
+ Contact prebid@captify.tech for information.
21
+
22
+ ### Publisher Usage
23
+
24
+ Compile the Captify RTD module into your Prebid build:
25
+
26
+ `npm ci && gulp build --modules=rtdModule,appnexusBidAdapter,captifyRtdProvider`
27
+
28
+ Add the Captify RTD provider to your Prebid config.
29
+
30
+ ```javascript
31
+ pbjs.setConfig({
32
+ realTimeData: {
33
+ auctionDelay: 1000,
34
+ dataProviders: [
35
+ {
36
+ name: "CaptifyRTDModule",
37
+ waitForIt: true,
38
+ params: {
39
+ pubId: 123456,
40
+ bidders: ['appnexus'],
41
+ }
42
+ }
43
+ ]
44
+ }
45
+ });
46
+ ```
47
+
48
+ ### Parameter Description
49
+ This module is configured as part of the `realTimeData.dataProviders` object.
50
+
51
+ | Name |Type | Description |Mandatory | Notes |
52
+ | :------------- | :------------ | :------------------------------------------------------------------ |:---------|:------------ |
53
+ | name | String | Real time data module name | yes | Always 'CaptifyRTDModule' |
54
+ | waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (recommended) | no | Default `false` |
55
+ | params | Object | | | |
56
+ | params.pubId | Integer | Partner ID, required to get results and provided by Captify | yes | Use 123456 for tests and speak to your Captify account manager to receive your pubId |
57
+ | params.bidders | Array<String> | List of bidders for which you would like data to be set | yes | Currently only 'appnexus' supported |
58
+ | params.url | String | Captify live-classification service url | no | Defaults to `https://live-classification.cpx.to/prebid-segments`
59
+
60
+ ### Testing
61
+
62
+ To view an example of available segments returned by Captify:
63
+
64
+ `gulp serve --modules=rtdModule,captifyRtdProvider,appnexusBidAdapter`
65
+
66
+ and then point your browser at:
67
+
68
+ `http://localhost:9999/integrationExamples/gpt/captifyRtdProvider_example.html?pbjs_debug=true`
@@ -1,4 +1,4 @@
1
- import { logWarn, logMessage, debugTurnedOn, generateUUID } from '../src/utils.js';
1
+ import { logWarn, logMessage, debugTurnedOn, generateUUID, deepAccess } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
3
  import { getStorageManager } from '../src/storageManager.js';
4
4
  import { hasPurpose1Consent } from '../src/utils/gpdr.js';
@@ -178,7 +178,7 @@ export const spec = {
178
178
 
179
179
  registerBidder(spec);
180
180
 
181
- const storage = getStorageManager({bidderCode: BIDDER_CODE});
181
+ export const storage = getStorageManager({bidderCode: BIDDER_CODE});
182
182
 
183
183
  /**
184
184
  * Check or generate a UID for the current user.
@@ -188,10 +188,24 @@ function getUid(bidderRequest) {
188
188
  return false;
189
189
  }
190
190
 
191
- const CONCERT_UID_KEY = 'c_uid';
191
+ const sharedId = deepAccess(bidderRequest, 'userId._sharedid.id');
192
192
 
193
+ if (sharedId) {
194
+ return sharedId;
195
+ }
196
+
197
+ const LEGACY_CONCERT_UID_KEY = 'c_uid';
198
+ const CONCERT_UID_KEY = 'vmconcert_uid';
199
+
200
+ const legacyUid = storage.getDataFromLocalStorage(LEGACY_CONCERT_UID_KEY);
193
201
  let uid = storage.getDataFromLocalStorage(CONCERT_UID_KEY);
194
202
 
203
+ if (legacyUid) {
204
+ uid = legacyUid;
205
+ storage.setDataInLocalStorage(CONCERT_UID_KEY, uid);
206
+ storage.removeDataFromLocalStorage(LEGACY_CONCERT_UID_KEY);
207
+ }
208
+
195
209
  if (!uid) {
196
210
  uid = generateUUID();
197
211
  storage.setDataInLocalStorage(CONCERT_UID_KEY, uid);
@@ -1,37 +1,36 @@
1
1
  # Overview
2
- - Module Name: Conversant Bidder Adapter
2
+ - Module Name: Epsilon Analytics Adapter
3
3
  - Module Type: Analytics Adapter
4
- - Maintainer: mediapsr@conversantmedia.com
4
+ - Maintainer: mediapsr@epsilon.com
5
5
 
6
6
  ## Description
7
7
 
8
- Analytics adapter for Conversant is used to track performance of Prebid auctions. See the usage below for how to
8
+ Analytics adapter for Epsilon (formerly Conversant) is used to track performance of Prebid auctions. See the usage below for how to
9
9
  configure the adapter for your webpage. To enable analytics and gain access to the data publishers will need
10
- to contact their Conversant representative.
10
+ to contact their Epsilon representative (publishersupport@epsilon.com).
11
11
 
12
12
  ## Setup
13
13
 
14
- Before any analytics are recorded for your website you will need to have a Conversant representative turn
14
+ Before any analytics are recorded for your website you will need to have an Epsilon representative turn
15
15
  on Prebid analytics for your website.
16
16
 
17
- The simplest configuration to add Conversant Prebid analytics to your page is as follows:
17
+ The simplest configuration to add Epsilon Prebid analytics to your page is as follows:
18
18
 
19
19
  ```
20
20
  pbjs.que.push(function() {
21
21
  pbjs.enableAnalytics({
22
22
  provider: 'conversant',
23
23
  options: {
24
- site_id: '<YOUR_SITE_ID>'
24
+ site_id: <YOUR_SITE_ID>
25
25
  }
26
26
  })
27
27
  });
28
28
  ```
29
29
 
30
- Additionally the following options are supported:
30
+ Additionally, the following options are supported:
31
31
 
32
- - **sampleRate**: Expects an integer from 0 to 100. By default only 50% (corresponds to a value of 50) of instances are enabled
33
- for Conversant Prebid Analytics. This field allows the publisher to override that percentage to sample
34
- at a higher or lower rate. '0' would completely disable sampling and '100' would capture every instance.
32
+ - **cnvr_sampling**: Sample rate for analytics data. Value should be between 0 and 1 (inclusive), 0 == never sample,
33
+ 1 == always sample, 0.5 == send analytics 50% of the time.
35
34
 
36
35
  ### Complete Example
37
36
  ```
@@ -39,8 +38,8 @@ at a higher or lower rate. '0' would completely disable sampling and '100' would
39
38
  pbjs.enableAnalytics({
40
39
  provider: 'conversant',
41
40
  options: {
42
- site_id: '1234',
43
- sampleRate: 90
41
+ site_id: 1234,
42
+ cnvr_sampling: 0.9
44
43
  }
45
44
  })
46
45
  });
@@ -1,12 +1,12 @@
1
1
  # Overview
2
2
 
3
- - Module Name: Conversant Bidder Adapter
3
+ - Module Name: Epsilon Bidder Adapter
4
4
  - Module Type: Bidder Adapter
5
- - Maintainer: mediapsr@conversantmedia.com
5
+ - Maintainer: mediapsr@epsilon.com
6
6
 
7
7
  # Description
8
8
 
9
- Module that connects to Conversant's demand sources. Supports banners and videos.
9
+ Module that connects to Epsilon's (formerly Conversant) demand sources. Supports banners and videos.
10
10
 
11
11
  # Test Parameters
12
12
  ```