forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pubx.ai RTD Provider - Initial Release (prebid#11300)
* Add pubx RTD module * Add pubx RTD module documentation * Add basic tests for pubx RTD module * Fix the failing tests * Added logic to fetch floors and set to auction * Updated setDataToConfig to attach floors data to bidder requests object * pubx rtd module: * fetch floor rules * timeout defaults * floors config customizations * pubx on/off from floors response * move fetch floors to init and also wait for it before auction * TESTS: update * replace createFloorsDataForAuction to avoid circular dep - WIP * reset default floors when no floor response is received * TESTS: add test * tag integration - fetch floors api events * * Remove coonsole.log * move __pubxFloorRulesPromise__ to window * Remove unused var error * TESTS: add getBidRequestData, refactor stubs * TESTS: setFloorsApiStatus * TESTS: add fetchFloorRules * remove useRtd * make endpoint potional and take pubxId form provider config * TESTS: use xhr to fakeServer instead of sinon * make default data optional * update README * TEST: update tests * add integration example * remove floorProvider from default config * fix linting * update readme.md --------- Co-authored-by: Phaneendra Hegde <phaneendra@pubx.ai> Co-authored-by: Phaneendra Hegde <pnhegde@users.noreply.github.com>
- Loading branch information
1 parent
d9b3207
commit a5094b3
Showing
5 changed files
with
725 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
<html> | ||
<head> | ||
<title>Individual Ad Unit Refresh Example</title> | ||
<script async src="//www.googletagservices.com/tag/js/gpt.js"></script> | ||
<script async src="http://localhost:9999/build/dev/prebid.js"></script> | ||
<script> | ||
var sizes = [[300, 250]]; | ||
var PREBID_TIMEOUT = 1000; | ||
|
||
var googletag = googletag || {}; | ||
googletag.cmd = googletag.cmd || []; | ||
|
||
var pbjs = pbjs || {}; | ||
pbjs.que = pbjs.que || []; | ||
|
||
var adUnits = [ | ||
{ | ||
code: "/19968336/header-bid-tag-0", | ||
mediaTypes: { | ||
banner: { | ||
sizes: sizes, | ||
}, | ||
}, | ||
bids: [ | ||
{ | ||
bidder: "appnexus", | ||
params: { | ||
placementId: 13144370, | ||
}, | ||
cpm: 2.5, | ||
ad: '<html><body><img src="https://files.prebid.org/creatives/prebid300x250.png"></body></html>', | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
pbjs.que.push(function () { | ||
pbjs.addAdUnits(adUnits); | ||
|
||
// ----------------------------------------------- | ||
// pubxai RTD module | ||
|
||
pbjs.setConfig({ | ||
debug: "true", | ||
realTimeData: { | ||
auctionDelay: 2500, | ||
dataProviders: [ | ||
{ | ||
name: "pubxai", | ||
waitForIt: true, | ||
params: { | ||
pubxId: "74d8356b-35a7-514b-c648-e7e4ad72af63", | ||
endpoint: "http://localhost:3001/floors", // (optional) | ||
floorMin: 3, // (optional) | ||
enforcement: { | ||
bidAdjustment: true, | ||
enforceJS: false, | ||
}, // (optional) | ||
data: { | ||
currency: "USD", | ||
modelVersion: "default", | ||
schema: { fields: ["gptSlot", "mediaType", "size"] }, | ||
values: { "*|banner|*": 0.02 }, | ||
}, // (optional) | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
// ----------------------------------------------- | ||
}); | ||
</script> | ||
|
||
<script> | ||
var slot1; | ||
googletag.cmd.push(function () { | ||
slot1 = googletag | ||
.defineSlot("/19968336/header-bid-tag-0", [[300, 250]], "div-1") | ||
.addService(googletag.pubads()); | ||
googletag.pubads().disableInitialLoad(); | ||
googletag.pubads().enableSingleRequest(); | ||
googletag.enableServices(); | ||
}); | ||
|
||
function refreshBid() { | ||
pbjs.que.push(function () { | ||
pbjs.requestBids({ | ||
timeout: PREBID_TIMEOUT, | ||
adUnitCodes: ["/19968336/header-bid-tag-0"], | ||
bidsBackHandler: function () { | ||
pbjs.setTargetingForGPTAsync(["/19968336/header-bid-tag-0"]); | ||
googletag.pubads().refresh([slot1]); | ||
}, | ||
}); | ||
}); | ||
} | ||
</script> | ||
</head> | ||
|
||
<body> | ||
<h1>Individual Ad Unit Refresh Example</h1> | ||
<h5>Div-1</h5> | ||
<p><button onclick="refreshBid()">Refresh Ad Unit</button></p> | ||
<div id="div-1"> | ||
<script type="text/javascript"> | ||
googletag.cmd.push(function () { | ||
googletag.display("div-1"); | ||
}); | ||
</script> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import { ajax } from '../src/ajax.js'; | ||
import { config } from '../src/config.js'; | ||
import { submodule } from '../src/hook.js'; | ||
import { deepAccess } from '../src/utils.js'; | ||
/** | ||
* This RTD module has a dependency on the priceFloors module. | ||
* We utilize the createFloorsDataForAuction function from the priceFloors module to incorporate price floors data into the current auction. | ||
*/ | ||
import { createFloorsDataForAuction } from './priceFloors.js'; // eslint-disable-line prebid/validate-imports | ||
|
||
const MODULE_NAME = 'realTimeData'; | ||
const SUBMODULE_NAME = 'pubxai'; | ||
window.__pubxFloorRulesPromise__ = null; | ||
export const FloorsApiStatus = Object.freeze({ | ||
IN_PROGRESS: 'IN_PROGRESS', | ||
SUCCESS: 'SUCCESS', | ||
ERROR: 'ERROR', | ||
}); | ||
export const FLOORS_EVENT_HANDLE = 'floorsApi'; | ||
export const FLOORS_END_POINT = 'https://floor.pbxai.com/'; | ||
export const FLOOR_PROVIDER = 'PubxFloorProvider'; | ||
|
||
export const getFloorsConfig = (provider, floorsResponse) => { | ||
const floorsConfig = { | ||
floors: { | ||
enforcement: { floorDeals: true }, | ||
data: floorsResponse, | ||
}, | ||
}; | ||
const { floorMin, enforcement } = deepAccess(provider, 'params'); | ||
if (floorMin) { | ||
floorsConfig.floors.floorMin = floorMin; | ||
} | ||
if (enforcement) { | ||
floorsConfig.floors.enforcement = enforcement; | ||
} | ||
return floorsConfig; | ||
}; | ||
|
||
export const setFloorsConfig = (provider, data) => { | ||
if (data) { | ||
const floorsConfig = getFloorsConfig(provider, data); | ||
config.setConfig(floorsConfig); | ||
window.__pubxLoaded__ = true; | ||
window.__pubxFloorsConfig__ = floorsConfig; | ||
} else { | ||
config.setConfig({ floors: window.__pubxPrevFloorsConfig__ }); | ||
window.__pubxLoaded__ = false; | ||
window.__pubxFloorsConfig__ = null; | ||
} | ||
}; | ||
|
||
export const setDefaultPriceFloors = (provider) => { | ||
const { data } = deepAccess(provider, 'params'); | ||
if (data !== undefined) { | ||
data.floorProvider = FLOOR_PROVIDER; | ||
setFloorsConfig(provider, data); | ||
} | ||
}; | ||
|
||
export const setPriceFloors = async (provider) => { | ||
window.__pubxPrevFloorsConfig__ = config.getConfig('floors'); | ||
setDefaultPriceFloors(provider); | ||
return fetchFloorRules(provider) | ||
.then((floorsResponse) => { | ||
setFloorsConfig(provider, floorsResponse); | ||
setFloorsApiStatus(FloorsApiStatus.SUCCESS); | ||
}) | ||
.catch((_) => { | ||
setFloorsApiStatus(FloorsApiStatus.ERROR); | ||
}); | ||
}; | ||
|
||
export const setFloorsApiStatus = (status) => { | ||
window.__pubxFloorsApiStatus__ = status; | ||
window.dispatchEvent( | ||
new CustomEvent(FLOORS_EVENT_HANDLE, { detail: { status } }) | ||
); | ||
}; | ||
|
||
export const getUrl = (provider) => { | ||
const { pubxId, endpoint } = deepAccess(provider, 'params'); | ||
return `${endpoint || FLOORS_END_POINT}?pubxId=${pubxId}&page=${ | ||
window.location.href | ||
}`; | ||
}; | ||
|
||
export const fetchFloorRules = async (provider) => { | ||
return new Promise((resolve, reject) => { | ||
setFloorsApiStatus(FloorsApiStatus.IN_PROGRESS); | ||
ajax(getUrl(provider), { | ||
success: (responseText, response) => { | ||
try { | ||
if (response && response.response) { | ||
const floorsResponse = JSON.parse(response.response); | ||
resolve(floorsResponse); | ||
} else { | ||
resolve(null); | ||
} | ||
} catch (error) { | ||
reject(error); | ||
} | ||
}, | ||
error: (responseText, response) => { | ||
reject(response); | ||
}, | ||
}); | ||
}); | ||
}; | ||
|
||
const init = (provider) => { | ||
window.__pubxFloorRulesPromise__ = setPriceFloors(provider); | ||
return true; | ||
}; | ||
|
||
const getBidRequestData = (() => { | ||
let floorsAttached = false; | ||
return (reqBidsConfigObj, onDone) => { | ||
if (!floorsAttached) { | ||
createFloorsDataForAuction( | ||
reqBidsConfigObj.adUnits, | ||
reqBidsConfigObj.auctionId | ||
); | ||
window.__pubxFloorRulesPromise__.then(() => { | ||
createFloorsDataForAuction( | ||
reqBidsConfigObj.adUnits, | ||
reqBidsConfigObj.auctionId | ||
); | ||
onDone(); | ||
}); | ||
floorsAttached = true; | ||
} | ||
}; | ||
})(); | ||
|
||
export const pubxaiSubmodule = { | ||
name: SUBMODULE_NAME, | ||
init, | ||
getBidRequestData, | ||
}; | ||
|
||
export const beforeInit = () => { | ||
submodule(MODULE_NAME, pubxaiSubmodule); | ||
}; | ||
|
||
beforeInit(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
## Overview | ||
|
||
- Module Name: pubX.ai RTD Provider | ||
- Module Type: RTD Adapter | ||
- Maintainer: phaneendra@pubx.ai | ||
|
||
## Description | ||
|
||
This RTD module, provided by pubx.ai, is used to set dynamic floors within Prebid. | ||
|
||
## Usage | ||
|
||
Ensure that the following modules are listed when building Prebid: `priceFloors`. | ||
For example: | ||
|
||
```shell | ||
gulp build --modules=priceFloors | ||
``` | ||
|
||
To compile the RTD module into your Prebid build: | ||
|
||
```shell | ||
gulp build --modules=rtdModule,pubxaiRtdProvider | ||
``` | ||
|
||
To utilize the pubX.ai RTD module, add `realTimeData` with the parameters mentioned below to the Prebid config. | ||
|
||
```js | ||
const AUCTION_DELAY = 100; | ||
pbjs.setConfig({ | ||
// rest of the config | ||
..., | ||
realTimeData: { | ||
auctionDelay: AUCTION_DELAY, | ||
dataProviders: { | ||
name: "pubxai", | ||
waitForIt: true, | ||
params: { | ||
pubxId: `<publisher_id>`, | ||
endpoint: `<publisher_endpoint>`, // (optional) | ||
floorMin: `<floorMin>`, // (optional) | ||
enforcement: `<enforcement>`, // (optional) | ||
data: `<defaultConfig>` // (optional) | ||
} | ||
} | ||
} | ||
// rest of the config | ||
..., | ||
}); | ||
``` | ||
|
||
## Parameters | ||
|
||
| Name | Type | Description | Default | | ||
| :----------------- | :------ | :------------------------------------------------------------- | :------------------------- | | ||
| name | String | Name of the real-time data module | Always `pubxai` | | ||
| waitForIt | Boolean | Should be `true` if an `auctionDelay` is defined (optional) | `false` | | ||
| params | Object | | | | ||
| params.pubxId | String | Publisher ID | | | ||
| params.endpoint | String | URL to retrieve floor data (optional) | `https://floor.pbxai.com/` | | ||
| params.floorMin | Number | Minimum CPM floor (optional) | `None` | | ||
| params.enforcement | Object | Enforcement behavior within the Price Floors Module (optional) | `None` | | ||
| params.data | Object | Default floor data provided by pubX.ai (optional) | `None` | | ||
|
||
## What Should Change in the Bid Request? | ||
|
||
There are no direct changes in the bid request due to our RTD module, but floor configuration will be set using the price floors module. These changes will be reflected in adunit bids or bidder requests as floor data. | ||
|
Oops, something went wrong.