prebid.js 6.1.0 → 6.5.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 (184) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/README.md +1 -1
  3. package/browsers.json +13 -29
  4. package/gulpfile.js +87 -82
  5. package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
  6. package/karma.conf.maker.js +2 -2
  7. package/modules/33acrossBidAdapter.js +189 -102
  8. package/modules/adagioBidAdapter.js +1 -1
  9. package/modules/addefendBidAdapter.js +1 -0
  10. package/modules/adkernelBidAdapter.js +146 -61
  11. package/modules/adlooxAdServerVideo.js +2 -2
  12. package/modules/adlooxAnalyticsAdapter.js +4 -4
  13. package/modules/admanBidAdapter.js +1 -0
  14. package/modules/admixerBidAdapter.js +3 -2
  15. package/modules/adnuntiusBidAdapter.js +5 -2
  16. package/modules/adomikAnalyticsAdapter.js +6 -0
  17. package/modules/adplusBidAdapter.js +203 -0
  18. package/modules/adplusBidAdapter.md +39 -0
  19. package/modules/adxcgBidAdapter.js +311 -359
  20. package/modules/adxcgBidAdapter.md +22 -21
  21. package/modules/adyoulikeBidAdapter.js +20 -11
  22. package/modules/aniviewBidAdapter.js +1 -1
  23. package/modules/appnexusBidAdapter.js +19 -3
  24. package/modules/beachfrontBidAdapter.js +14 -17
  25. package/modules/beopBidAdapter.js +6 -4
  26. package/modules/bidViewability.js +3 -3
  27. package/modules/bidViewabilityIO.js +3 -3
  28. package/modules/bliinkBidAdapter.js +1 -1
  29. package/modules/colossussspBidAdapter.js +7 -0
  30. package/modules/compassBidAdapter.js +201 -0
  31. package/modules/compassBidAdapter.md +79 -0
  32. package/modules/consentManagement.js +7 -1
  33. package/modules/craftBidAdapter.js +5 -3
  34. package/modules/criteoBidAdapter.js +1 -1
  35. package/modules/currency.js +2 -2
  36. package/modules/cwireBidAdapter.js +3 -0
  37. package/modules/dailyhuntBidAdapter.js +435 -0
  38. package/modules/dailyhuntBidAdapter.md +4 -0
  39. package/modules/dchain.js +149 -0
  40. package/modules/dchain.md +45 -0
  41. package/modules/docereeBidAdapter.js +10 -1
  42. package/modules/docereeBidAdapter.md +2 -0
  43. package/modules/dspxBidAdapter.js +1 -1
  44. package/modules/emx_digitalBidAdapter.js +9 -1
  45. package/modules/engageyaBidAdapter.js +1 -1
  46. package/modules/feedadBidAdapter.js +2 -2
  47. package/modules/feedadBidAdapter.md +4 -2
  48. package/modules/freewheel-sspBidAdapter.js +6 -0
  49. package/modules/futureads.md +48 -0
  50. package/modules/glimpseBidAdapter.js +16 -3
  51. package/modules/goldbachBidAdapter.js +1176 -0
  52. package/modules/goldbachBidAdapter.md +151 -0
  53. package/modules/gptPreAuction.js +55 -7
  54. package/modules/gridBidAdapter.js +4 -3
  55. package/modules/gumgumBidAdapter.js +7 -3
  56. package/modules/improvedigitalBidAdapter.js +19 -3
  57. package/modules/instreamTracking.js +4 -4
  58. package/modules/intersectionRtdProvider.js +114 -0
  59. package/modules/invibesBidAdapter.js +64 -14
  60. package/modules/invibesBidAdapter.md +2 -1
  61. package/modules/ipromBidAdapter.js +79 -0
  62. package/modules/ixBidAdapter.js +53 -18
  63. package/modules/kinessoIdSystem.js +1 -1
  64. package/modules/limelightDigitalBidAdapter.js +3 -1
  65. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  66. package/modules/livewrappedBidAdapter.js +8 -2
  67. package/modules/loglyliftBidAdapter.js +79 -0
  68. package/modules/loglyliftBidAdapter.md +55 -0
  69. package/modules/lotamePanoramaIdSystem.js +80 -8
  70. package/modules/luponmediaBidAdapter.js +570 -0
  71. package/modules/mediasquareBidAdapter.js +1 -9
  72. package/modules/missenaBidAdapter.js +89 -0
  73. package/modules/nextMillenniumBidAdapter.js +37 -7
  74. package/modules/optimeraRtdProvider.js +8 -1
  75. package/modules/ozoneBidAdapter.js +21 -64
  76. package/modules/prebidServerBidAdapter/index.js +16 -12
  77. package/modules/pubgeniusBidAdapter.js +1 -1
  78. package/modules/pubmaticBidAdapter.js +3 -3
  79. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  80. package/modules/relaidoBidAdapter.js +86 -65
  81. package/modules/richaudienceBidAdapter.js +2 -3
  82. package/modules/rtdModule/index.js +48 -18
  83. package/modules/rubiconBidAdapter.js +31 -19
  84. package/modules/sharedIdSystem.js +27 -1
  85. package/modules/smaatoBidAdapter.js +4 -1
  86. package/modules/smartxBidAdapter.js +17 -1
  87. package/modules/tappxBidAdapter.js +3 -1
  88. package/modules/targetVideoBidAdapter.js +187 -0
  89. package/modules/targetVideoBidAdapter.md +34 -0
  90. package/modules/telariaBidAdapter.js +2 -2
  91. package/modules/trustxBidAdapter.js +8 -16
  92. package/modules/undertoneBidAdapter.js +8 -1
  93. package/modules/userId/index.js +27 -2
  94. package/modules/ventes.md +71 -0
  95. package/modules/ventesBidAdapter.js +104 -64
  96. package/modules/ventesBidAdapter.md +0 -1
  97. package/modules/vidoomyBidAdapter.js +16 -10
  98. package/modules/visxBidAdapter.js +19 -2
  99. package/modules/visxBidAdapter.md +4 -6
  100. package/modules/weboramaRtdProvider.js +288 -73
  101. package/modules/weboramaRtdProvider.md +27 -10
  102. package/modules/yahoosspBidAdapter.js +5 -1
  103. package/modules/yahoosspBidAdapter.md +1 -1
  104. package/modules/yieldmoBidAdapter.js +23 -5
  105. package/modules/yieldoneBidAdapter.js +115 -11
  106. package/modules/zetaSspBidAdapter.md +33 -1
  107. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  108. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  109. package/modules/zeta_global_sspBidAdapter.js +22 -1
  110. package/package.json +1 -1
  111. package/plugins/pbjsGlobals.js +28 -1
  112. package/src/auction.js +5 -4
  113. package/src/config.js +27 -3
  114. package/src/prebid.js +3 -2
  115. package/src/targeting.js +24 -3
  116. package/src/utils.js +53 -8
  117. package/test/helpers/prebidGlobal.js +1 -0
  118. package/test/spec/config_spec.js +279 -0
  119. package/test/spec/integration/faker/googletag.js +6 -0
  120. package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
  121. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  122. package/test/spec/modules/adnuntiusBidAdapter_spec.js +35 -0
  123. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +6 -0
  124. package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
  125. package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
  126. package/test/spec/modules/adyoulikeBidAdapter_spec.js +75 -0
  127. package/test/spec/modules/appnexusBidAdapter_spec.js +49 -1
  128. package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
  129. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  130. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  131. package/test/spec/modules/bidViewability_spec.js +4 -4
  132. package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
  133. package/test/spec/modules/compassBidAdapter_spec.js +397 -0
  134. package/test/spec/modules/consentManagement_spec.js +20 -0
  135. package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
  136. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  137. package/test/spec/modules/dchain_spec.js +329 -0
  138. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  139. package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
  140. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  141. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  142. package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
  143. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  144. package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
  145. package/test/spec/modules/improvedigitalBidAdapter_spec.js +3 -1
  146. package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
  147. package/test/spec/modules/invibesBidAdapter_spec.js +148 -4
  148. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  149. package/test/spec/modules/ixBidAdapter_spec.js +112 -62
  150. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +84 -23
  151. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  152. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  153. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  154. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
  155. package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
  156. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
  157. package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
  158. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +26 -1
  159. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  160. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  161. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -0
  162. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  163. package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
  164. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  165. package/test/spec/modules/realTimeDataModule_spec.js +135 -49
  166. package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
  167. package/test/spec/modules/richaudienceBidAdapter_spec.js +2 -2
  168. package/test/spec/modules/rubiconBidAdapter_spec.js +65 -9
  169. package/test/spec/modules/sharedIdSystem_spec.js +52 -6
  170. package/test/spec/modules/smaatoBidAdapter_spec.js +31 -0
  171. package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
  172. package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
  173. package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
  174. package/test/spec/modules/userId_spec.js +51 -0
  175. package/test/spec/modules/visxBidAdapter_spec.js +120 -4
  176. package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
  177. package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
  178. package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
  179. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  180. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
  181. package/test/spec/unit/core/targeting_spec.js +116 -0
  182. package/test/spec/utils_spec.js +38 -0
  183. package/test/test_deps.js +3 -0
  184. package/test/test_index.js +1 -3
@@ -0,0 +1,79 @@
1
+ import { logError } from '../src/utils.js';
2
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
+
4
+ const BIDDER_CODE = 'iprom';
5
+ const ENDPOINT_URL = 'https://core.iprom.net/programmatic';
6
+ const VERSION = 'v1.0.2';
7
+ const DEFAULT_CURRENCY = 'EUR';
8
+ const DEFAULT_NETREVENUE = true;
9
+ const DEFAULT_TTL = 360;
10
+
11
+ export const spec = {
12
+ code: BIDDER_CODE,
13
+ isBidRequestValid: function ({ bidder, params = {} } = {}) {
14
+ // id parameter checks
15
+ if (!params.id) {
16
+ logError(`${bidder}: Parameter 'id' missing`);
17
+ return false;
18
+ } else if (typeof params.id !== 'string') {
19
+ logError(`${bidder}: Parameter 'id' needs to be a string`);
20
+ return false;
21
+ }
22
+ // dimension parameter checks
23
+ if (!params.dimension) {
24
+ logError(`${bidder}: Required parameter 'dimension' missing`);
25
+ return false;
26
+ } else if (typeof params.dimension !== 'string') {
27
+ logError(`${bidder}: Parameter 'dimension' needs to be a string`);
28
+ return false;
29
+ }
30
+
31
+ return true;
32
+ },
33
+
34
+ buildRequests: function (validBidRequests, bidderRequest) {
35
+ const payload = {
36
+ bids: validBidRequests,
37
+ referer: bidderRequest.refererInfo,
38
+ version: VERSION
39
+ };
40
+ const payloadString = JSON.stringify(payload);
41
+
42
+ return {
43
+ method: 'POST',
44
+ url: ENDPOINT_URL,
45
+ data: payloadString
46
+ };
47
+ },
48
+
49
+ interpretResponse: function (serverResponse, request) {
50
+ let bids = serverResponse.body;
51
+
52
+ const bidResponses = [];
53
+
54
+ bids.forEach(bid => {
55
+ const b = {
56
+ ad: bid.ad,
57
+ requestId: bid.requestId,
58
+ cpm: bid.cpm,
59
+ width: bid.width,
60
+ height: bid.height,
61
+ creativeId: bid.creativeId,
62
+ currency: bid.currency || DEFAULT_CURRENCY,
63
+ netRevenue: bid.netRevenue || DEFAULT_NETREVENUE,
64
+ ttl: bid.ttl || DEFAULT_TTL,
65
+ meta: {},
66
+ };
67
+
68
+ if (bid.aDomains && bid.aDomains.length) {
69
+ b.meta.advertiserDomains = bid.aDomains;
70
+ }
71
+
72
+ bidResponses.push(b);
73
+ });
74
+
75
+ return bidResponses;
76
+ },
77
+ }
78
+
79
+ registerBidder(spec);
@@ -1,8 +1,8 @@
1
- import { deepAccess, parseGPTSingleSizeArray, inIframe, deepClone, logError, logWarn, isFn, contains, isInteger, isArray, deepSetValue, parseQueryStringParameters, isEmpty, mergeDeep, convertTypes } from '../src/utils.js';
1
+ import { deepAccess, parseGPTSingleSizeArray, inIframe, deepClone, logError, logWarn, isFn, contains, isInteger, isArray, deepSetValue, parseQueryStringParameters, isEmpty, mergeDeep, convertTypes, hasDeviceAccess } from '../src/utils.js';
2
2
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
3
3
  import { config } from '../src/config.js';
4
- import { EVENTS } from '../src/constants.json';
5
- import { getStorageManager } from '../src/storageManager.js';
4
+ import CONSTANTS from '../src/constants.json';
5
+ import { getStorageManager, validateStorageEnforcement } from '../src/storageManager.js';
6
6
  import events from '../src/events.js';
7
7
  import find from 'core-js-pure/features/array/find.js';
8
8
  import { registerBidder } from '../src/adapters/bidderFactory.js';
@@ -53,7 +53,12 @@ const SOURCE_RTI_MAPPING = {
53
53
  'neustar.biz': 'fabrickId',
54
54
  'zeotap.com': 'zeotapIdPlus',
55
55
  'uidapi.com': 'UID2',
56
- 'adserver.org': 'TDID'
56
+ 'adserver.org': 'TDID',
57
+ 'id5-sync.com': '', // ID5 Universal ID, configured as id5Id
58
+ 'crwdcntrl.net': '', // Lotame Panorama ID, lotamePanoramaId
59
+ 'epsilon.com': '', // Publisher Link, publinkId
60
+ 'audigent.com': '', // Halo ID from Audigent, haloId
61
+ 'pubcid.org': '' // SharedID, pubcid
57
62
  };
58
63
  const PROVIDERS = [
59
64
  'britepoolid',
@@ -69,7 +74,8 @@ const PROVIDERS = [
69
74
  'quantcastId',
70
75
  'pubcid',
71
76
  'TDID',
72
- 'flocId'
77
+ 'flocId',
78
+ 'pubProvidedId'
73
79
  ];
74
80
  const REQUIRED_VIDEO_PARAMS = ['mimes', 'minduration', 'maxduration']; // note: protocol/protocols is also reqd
75
81
  const VIDEO_PARAMS_ALLOW_LIST = [
@@ -194,7 +200,7 @@ function bidToImp(bid) {
194
200
  imp.id = bid.bidId;
195
201
 
196
202
  imp.ext = {};
197
- imp.ext.siteID = bid.params.siteId;
203
+ imp.ext.siteID = bid.params.siteId.toString();
198
204
 
199
205
  if (bid.params.hasOwnProperty('id') &&
200
206
  (typeof bid.params.id === 'string' || typeof bid.params.id === 'number')) {
@@ -444,16 +450,19 @@ function getEidInfo(allEids, flocData) {
444
450
  let seenSources = {};
445
451
  if (isArray(allEids)) {
446
452
  for (const eid of allEids) {
447
- if (SOURCE_RTI_MAPPING[eid.source] && deepAccess(eid, 'uids.0')) {
453
+ if (SOURCE_RTI_MAPPING.hasOwnProperty(eid.source) && deepAccess(eid, 'uids.0')) {
448
454
  seenSources[eid.source] = true;
449
- eid.uids[0].ext = {
450
- rtiPartner: SOURCE_RTI_MAPPING[eid.source]
451
- };
455
+ if (SOURCE_RTI_MAPPING[eid.source] != '') {
456
+ eid.uids[0].ext = {
457
+ rtiPartner: SOURCE_RTI_MAPPING[eid.source]
458
+ };
459
+ }
452
460
  delete eid.uids[0].atype;
453
461
  toSend.push(eid);
454
462
  }
455
463
  }
456
464
  }
465
+
457
466
  const isValidFlocId = flocData && flocData.id && flocData.version;
458
467
  if (isValidFlocId) {
459
468
  const flocEid = {
@@ -466,6 +475,7 @@ function getEidInfo(allEids, flocData) {
466
475
 
467
476
  return { toSend, seenSources };
468
477
  }
478
+
469
479
  /**
470
480
  * Builds a request object to be sent to the ad server based on bid requests.
471
481
  *
@@ -680,6 +690,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
680
690
 
681
691
  if (impressionObjects.length && BANNER in impressionObjects[0]) {
682
692
  const { id, banner: { topframe }, ext } = impressionObjects[0];
693
+ const gpid = impressions[transactionIds[adUnitIndex]].gpid;
683
694
  const _bannerImpression = {
684
695
  id,
685
696
  banner: {
@@ -688,10 +699,10 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
688
699
  },
689
700
  }
690
701
 
691
- if (ext.dfp_ad_unit_code) {
692
- _bannerImpression.ext = {
693
- dfp_ad_unit_code: ext.dfp_ad_unit_code
694
- }
702
+ if (ext.dfp_ad_unit_code || gpid) {
703
+ _bannerImpression.ext = {};
704
+ _bannerImpression.ext.dfp_ad_unit_code = ext.dfp_ad_unit_code;
705
+ _bannerImpression.ext.gpid = gpid;
695
706
  }
696
707
 
697
708
  if ('bidfloor' in impressionObjects[0]) {
@@ -911,6 +922,7 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
911
922
  bannerImps[validBidRequest.transactionId].ixImps = []
912
923
  }
913
924
  bannerImps[validBidRequest.transactionId].ixImps.push(imp);
925
+ bannerImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid');
914
926
  }
915
927
 
916
928
  if (ixConfig.hasOwnProperty('detectMissingSizes') && ixConfig.detectMissingSizes) {
@@ -991,7 +1003,7 @@ function createMissingBannerImp(bid, imp, newSize) {
991
1003
  *
992
1004
  * @param {ErrorData} data
993
1005
  */
994
- function errorEventHandler(data) {
1006
+ function storeErrorEventData(data) {
995
1007
  if (!storage.localStorageIsEnabled()) {
996
1008
  return;
997
1009
  }
@@ -1033,6 +1045,24 @@ function errorEventHandler(data) {
1033
1045
  storage.setDataInLocalStorage(LOCAL_STORAGE_KEY, JSON.stringify(currentStorage));
1034
1046
  }
1035
1047
 
1048
+ /**
1049
+ * Event handler for storing data into local storage. It will only store data if
1050
+ * local storage premissions are avaliable
1051
+ */
1052
+ function localStorageHandler(data) {
1053
+ if (data.type === 'ERROR' && data.arguments && data.arguments[1] && data.arguments[1].bidder === BIDDER_CODE) {
1054
+ const DEFAULT_ENFORCEMENT_SETTINGS = {
1055
+ hasEnforcementHook: false,
1056
+ valid: hasDeviceAccess()
1057
+ };
1058
+ validateStorageEnforcement(GLOBAL_VENDOR_ID, BIDDER_CODE, DEFAULT_ENFORCEMENT_SETTINGS, (permissions) => {
1059
+ if (permissions.valid) {
1060
+ storeErrorEventData(data);
1061
+ }
1062
+ });
1063
+ }
1064
+ }
1065
+
1036
1066
  /**
1037
1067
  * Get ixdiag stored in LocalStorage and format to be added to request payload
1038
1068
  *
@@ -1129,8 +1159,8 @@ export const spec = {
1129
1159
  */
1130
1160
  isBidRequestValid: function (bid) {
1131
1161
  if (!hasRegisteredHandler) {
1132
- events.on(EVENTS.AUCTION_DEBUG, errorEventHandler);
1133
- events.on(EVENTS.AD_RENDER_FAILED, errorEventHandler);
1162
+ events.on(CONSTANTS.EVENTS.AUCTION_DEBUG, localStorageHandler);
1163
+ events.on(CONSTANTS.EVENTS.AD_RENDER_FAILED, localStorageHandler);
1134
1164
  hasRegisteredHandler = true;
1135
1165
  }
1136
1166
 
@@ -1168,7 +1198,12 @@ export const spec = {
1168
1198
  }
1169
1199
 
1170
1200
  if (typeof bid.params.siteId !== 'string' && typeof bid.params.siteId !== 'number') {
1171
- logError('IX Bid Adapter: siteId must be string or number value.', { bidder: BIDDER_CODE, code: ERROR_CODES.SITE_ID_INVALID_VALUE });
1201
+ logError('IX Bid Adapter: siteId must be string or number type.', { bidder: BIDDER_CODE, code: ERROR_CODES.SITE_ID_INVALID_VALUE });
1202
+ return false;
1203
+ }
1204
+
1205
+ if (typeof bid.params.siteId !== 'string' && isNaN(Number(bid.params.siteId))) {
1206
+ logError('IX Bid Adapter: siteId must valid value', { bidder: BIDDER_CODE, code: ERROR_CODES.SITE_ID_INVALID_VALUE });
1172
1207
  return false;
1173
1208
  }
1174
1209
 
@@ -180,7 +180,7 @@ function kinessoSyncUrl(accountId, consentData) {
180
180
  const usPrivacyString = uspDataHandler.getConsentData();
181
181
  let kinessoSyncUrl = `${ID_SVC}?accountid=${accountId}`;
182
182
  if (usPrivacyString) {
183
- kinessoSyncUrl = `${kinessoSyncUrl}?us_privacy=${usPrivacyString}`;
183
+ kinessoSyncUrl = `${kinessoSyncUrl}&us_privacy=${usPrivacyString}`;
184
184
  }
185
185
  if (!consentData || typeof consentData.gdprApplies !== 'boolean' || !consentData.gdprApplies) return kinessoSyncUrl;
186
186
 
@@ -158,7 +158,9 @@ function buildPlacement(bidRequest) {
158
158
  height: size[1]
159
159
  }
160
160
  }),
161
- type: bidRequest.params.adUnitType.toUpperCase()
161
+ type: bidRequest.params.adUnitType.toUpperCase(),
162
+ publisherId: bidRequest.params.publisherId,
163
+ userIdAsEids: bidRequest.userIdAsEids
162
164
  }
163
165
  }
164
166
  }
@@ -114,6 +114,7 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE
114
114
  let wonBid = cache.auctions[args.auctionId].bids[args.requestId];
115
115
  wonBid.won = true;
116
116
  wonBid.floorData = args.floorData;
117
+ wonBid.rUp = args.rUp;
117
118
  if (wonBid.sendStatus != 0) {
118
119
  livewrappedAnalyticsAdapter.sendEvents();
119
120
  }
@@ -288,7 +289,8 @@ function getWins(gdpr, auctionIds) {
288
289
  auctionId: auctionIdPos,
289
290
  auc: bid.auc,
290
291
  buc: bid.buc,
291
- lw: bid.lw
292
+ lw: bid.lw,
293
+ rUp: bid.rUp
292
294
  });
293
295
  }
294
296
  });
@@ -1,4 +1,4 @@
1
- import { isSafariBrowser, deepAccess, getWindowTop } from '../src/utils.js';
1
+ import { isSafariBrowser, deepAccess, getWindowTop, mergeDeep } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
3
  import { config } from '../src/config.js';
4
4
  import find from 'core-js-pure/features/array/find.js';
@@ -60,11 +60,17 @@ export const spec = {
60
60
  const bundle = find(bidRequests, hasBundleParam);
61
61
  const tid = find(bidRequests, hasTidParam);
62
62
  const schain = bidRequests[0].schain;
63
+ let ortb2 = config.getConfig('ortb2');
64
+ const eids = handleEids(bidRequests);
63
65
  bidUrl = bidUrl ? bidUrl.params.bidUrl : URL;
64
66
  url = url ? url.params.url : (getAppDomain() || getTopWindowLocation(bidderRequest));
65
67
  test = test ? test.params.test : undefined;
66
68
  var adRequests = bidRequests.map(bidToAdRequest);
67
69
 
70
+ if (eids) {
71
+ ortb2 = mergeDeep(ortb2 || {}, eids);
72
+ }
73
+
68
74
  const payload = {
69
75
  auctionId: auctionId ? auctionId.auctionId : undefined,
70
76
  publisherId: publisherId ? publisherId.params.publisherId : undefined,
@@ -86,7 +92,7 @@ export const spec = {
86
92
  cookieSupport: !isSafariBrowser() && storage.cookiesAreEnabled(),
87
93
  rcv: getAdblockerRecovered(),
88
94
  adRequests: [...adRequests],
89
- rtbData: handleEids(bidRequests),
95
+ rtbData: ortb2,
90
96
  schain: schain
91
97
  };
92
98
 
@@ -0,0 +1,79 @@
1
+ import { config } from '../src/config.js';
2
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
+ import { NATIVE } from '../src/mediaTypes.js';
4
+
5
+ const BIDDER_CODE = 'loglylift';
6
+ const ENDPOINT_URL = 'https://bid.logly.co.jp/prebid/client/v1';
7
+
8
+ export const spec = {
9
+ code: BIDDER_CODE,
10
+ supportedMediaTypes: [NATIVE],
11
+
12
+ isBidRequestValid: function (bid) {
13
+ return !!(bid.params && bid.params.adspotId);
14
+ },
15
+
16
+ buildRequests: function (bidRequests, bidderRequest) {
17
+ const requests = [];
18
+ for (let i = 0, len = bidRequests.length; i < len; i++) {
19
+ const request = {
20
+ method: 'POST',
21
+ url: ENDPOINT_URL + '?adspot_id=' + bidRequests[i].params.adspotId,
22
+ data: JSON.stringify(newBidRequest(bidRequests[i], bidderRequest)),
23
+ options: {},
24
+ bidderRequest
25
+ };
26
+ requests.push(request);
27
+ }
28
+ return requests;
29
+ },
30
+
31
+ interpretResponse: function (serverResponse, { bidderRequest }) {
32
+ serverResponse = serverResponse.body;
33
+ const bidResponses = [];
34
+ if (!serverResponse || serverResponse.error) {
35
+ return bidResponses;
36
+ }
37
+ serverResponse.bids.forEach(function (bid) {
38
+ bidResponses.push(bid);
39
+ })
40
+ return bidResponses;
41
+ },
42
+
43
+ getUserSyncs: function (syncOptions, serverResponses) {
44
+ const syncs = [];
45
+
46
+ if (syncOptions.iframeEnabled && serverResponses.length > 0) {
47
+ syncs.push({
48
+ type: 'iframe',
49
+ url: 'https://sync.logly.co.jp/sync/sync.html'
50
+ });
51
+ }
52
+ return syncs;
53
+ }
54
+
55
+ };
56
+
57
+ function newBidRequest(bid, bidderRequest) {
58
+ const currencyObj = config.getConfig('currency');
59
+ const currency = (currencyObj && currencyObj.adServerCurrency) || 'USD';
60
+
61
+ return {
62
+ auctionId: bid.auctionId,
63
+ bidderRequestId: bid.bidderRequestId,
64
+ transactionId: bid.transactionId,
65
+ adUnitCode: bid.adUnitCode,
66
+ bidId: bid.bidId,
67
+ mediaTypes: bid.mediaTypes,
68
+ params: bid.params,
69
+ prebidJsVersion: '$prebid.version$',
70
+ url: window.location.href,
71
+ domain: config.getConfig('publisherDomain'),
72
+ referer: bidderRequest.refererInfo.referer,
73
+ auctionStartTime: bidderRequest.auctionStart,
74
+ currency: currency,
75
+ timeout: config.getConfig('bidderTimeout')
76
+ };
77
+ }
78
+
79
+ registerBidder(spec);
@@ -0,0 +1,55 @@
1
+ # Overview
2
+ ```
3
+ Module Name: LOGLY lift for Publisher
4
+ Module Type: Bidder Adapter
5
+ Maintainer: dev@logly.co.jp
6
+ ```
7
+
8
+ # Description
9
+ Module that connects to Logly's demand sources.
10
+ Currently module supports only native mediaType.
11
+
12
+ # Test Parameters
13
+ ```
14
+ var adUnits = [
15
+ // Native adUnit
16
+ {
17
+ code: 'test-native-code',
18
+ sizes: [[1, 1]],
19
+ mediaTypes: {
20
+ native: {
21
+ title: {
22
+ required: true
23
+ },
24
+ image: {
25
+ required: true
26
+ },
27
+ sponsoredBy: {
28
+ required: true
29
+ }
30
+ }
31
+ },
32
+ bids: [{
33
+ bidder: 'loglylift',
34
+ params: {
35
+ adspotId: 4302078
36
+ }
37
+ }]
38
+ }
39
+ ];
40
+ ```
41
+
42
+ # UserSync example
43
+
44
+ ```
45
+ pbjs.setConfig({
46
+ userSync: {
47
+ filterSettings: {
48
+ iframe: {
49
+ bidders: '*', // '*' represents all bidders
50
+ filter: 'include'
51
+ }
52
+ }
53
+ }
54
+ });
55
+ ```
@@ -4,10 +4,20 @@
4
4
  * @module modules/lotamePanoramaId
5
5
  * @requires module:modules/userId
6
6
  */
7
- import { timestamp, isStr, logError, isBoolean, buildUrl, isEmpty, isArray } from '../src/utils.js';
7
+ import {
8
+ timestamp,
9
+ isStr,
10
+ logError,
11
+ isBoolean,
12
+ buildUrl,
13
+ isEmpty,
14
+ isArray,
15
+ isEmptyStr
16
+ } from '../src/utils.js';
8
17
  import { ajax } from '../src/ajax.js';
9
18
  import { submodule } from '../src/hook.js';
10
19
  import { getStorageManager } from '../src/storageManager.js';
20
+ import { uspDataHandler } from '../src/adapterManager.js';
11
21
 
12
22
  const KEY_ID = 'panoramaId';
13
23
  const KEY_EXPIRY = `${KEY_ID}_expiry`;
@@ -115,14 +125,23 @@ function saveLotameCache(
115
125
 
116
126
  /**
117
127
  * Retrieve all the cached values from cookies and/or local storage
128
+ * @param {Number} clientId
118
129
  */
119
- function getLotameLocalCache() {
130
+ function getLotameLocalCache(clientId = undefined) {
120
131
  let cache = {
121
132
  data: getFromStorage(KEY_ID),
122
133
  expiryTimestampMs: 0,
134
+ clientExpiryTimestampMs: 0,
123
135
  };
124
136
 
125
137
  try {
138
+ if (clientId) {
139
+ const rawClientExpiry = getFromStorage(`${KEY_EXPIRY}_${clientId}`);
140
+ if (isStr(rawClientExpiry)) {
141
+ cache.clientExpiryTimestampMs = parseInt(rawClientExpiry, 10);
142
+ }
143
+ }
144
+
126
145
  const rawExpiry = getFromStorage(KEY_EXPIRY);
127
146
  if (isStr(rawExpiry)) {
128
147
  cache.expiryTimestampMs = parseInt(rawExpiry, 10);
@@ -191,11 +210,25 @@ export const lotamePanoramaIdSubmodule = {
191
210
  */
192
211
  getId(config, consentData, cacheIdObj) {
193
212
  cookieDomain = lotamePanoramaIdSubmodule.findRootDomain();
194
- let localCache = getLotameLocalCache();
213
+ const configParams = (config && config.params) || {};
214
+ const clientId = configParams.clientId;
215
+ const hasCustomClientId = !isEmpty(clientId);
216
+ const localCache = getLotameLocalCache(clientId);
195
217
 
196
- let refreshNeeded = Date.now() > localCache.expiryTimestampMs;
218
+ const hasExpiredPanoId = Date.now() > localCache.expiryTimestampMs;
219
+
220
+ if (hasCustomClientId) {
221
+ const hasFreshClientNoConsent = Date.now() < localCache.clientExpiryTimestampMs;
222
+ if (hasFreshClientNoConsent) {
223
+ // There is no consent
224
+ return {
225
+ id: undefined,
226
+ reason: 'NO_CLIENT_CONSENT',
227
+ };
228
+ }
229
+ }
197
230
 
198
- if (!refreshNeeded) {
231
+ if (!hasExpiredPanoId) {
199
232
  return {
200
233
  id: localCache.data,
201
234
  };
@@ -203,6 +236,18 @@ export const lotamePanoramaIdSubmodule = {
203
236
 
204
237
  const storedUserId = getProfileId();
205
238
 
239
+ // Add CCPA Consent data handling
240
+ const usp = uspDataHandler.getConsentData();
241
+
242
+ let usPrivacy;
243
+ if (typeof usp !== 'undefined' && !isEmpty(usp) && !isEmptyStr(usp)) {
244
+ usPrivacy = usp;
245
+ }
246
+ if (!usPrivacy) {
247
+ // fallback to 1st party cookie
248
+ usPrivacy = getFromStorage('us_privacy');
249
+ }
250
+
206
251
  const resolveIdFunction = function (callback) {
207
252
  let queryParams = {};
208
253
  if (storedUserId) {
@@ -226,6 +271,17 @@ export const lotamePanoramaIdSubmodule = {
226
271
  if (consentString) {
227
272
  queryParams.gdpr_consent = consentString;
228
273
  }
274
+
275
+ // Add usPrivacy to the url
276
+ if (usPrivacy) {
277
+ queryParams.us_privacy = usPrivacy;
278
+ }
279
+
280
+ // Add clientId to the url
281
+ if (hasCustomClientId) {
282
+ queryParams.c = clientId;
283
+ }
284
+
229
285
  const url = buildUrl({
230
286
  protocol: 'https',
231
287
  host: `id.crwdcntrl.net`,
@@ -239,15 +295,31 @@ export const lotamePanoramaIdSubmodule = {
239
295
  if (response) {
240
296
  try {
241
297
  let responseObj = JSON.parse(response);
242
- const shouldUpdateProfileId = !(
298
+ const hasNoConsentErrors = !(
243
299
  isArray(responseObj.errors) &&
244
300
  responseObj.errors.indexOf(MISSING_CORE_CONSENT) !== -1
245
301
  );
246
302
 
303
+ if (hasCustomClientId) {
304
+ if (hasNoConsentErrors) {
305
+ clearLotameCache(`${KEY_EXPIRY}_${clientId}`);
306
+ } else if (isStr(responseObj.no_consent) && responseObj.no_consent === 'CLIENT') {
307
+ saveLotameCache(
308
+ `${KEY_EXPIRY}_${clientId}`,
309
+ responseObj.expiry_ts,
310
+ responseObj.expiry_ts
311
+ );
312
+
313
+ // End Processing
314
+ callback();
315
+ return;
316
+ }
317
+ }
318
+
247
319
  saveLotameCache(KEY_EXPIRY, responseObj.expiry_ts, responseObj.expiry_ts);
248
320
 
249
321
  if (isStr(responseObj.profile_id)) {
250
- if (shouldUpdateProfileId) {
322
+ if (hasNoConsentErrors) {
251
323
  setProfileId(responseObj.profile_id);
252
324
  }
253
325
 
@@ -262,7 +334,7 @@ export const lotamePanoramaIdSubmodule = {
262
334
  clearLotameCache(KEY_ID);
263
335
  }
264
336
  } else {
265
- if (shouldUpdateProfileId) {
337
+ if (hasNoConsentErrors) {
266
338
  clearLotameCache(KEY_PROFILE);
267
339
  }
268
340
  clearLotameCache(KEY_ID);