Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make GetIdAndPreferences async to handle library load and data sync #48

Open
wants to merge 2 commits into
base: paf
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"netIdSystem",
"nextrollIdSystem",
"novatiqIdSystem",
"pafIdSystem",
"oneKeyIdSystem",
"parrableIdSystem",
"pubProvidedIdSystem",
"publinkIdSystem",
Expand Down Expand Up @@ -61,7 +61,7 @@
"jwplayerRtdProvider",
"medianetRtdProvider",
"optimeraRtdProvider",
"pafRtdProvider",
"oneKeyRtdProvider",
"permutiveRtdProvider",
"reconciliationRtdProvider",
"sirdataRtdProvider",
Expand Down
33 changes: 23 additions & 10 deletions modules/pafIdSystem.js → modules/oneKeyIdSystem.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
/**
* This module adds pafData to the User ID module
* This module adds Onekey data to the User ID module
* The {@link module:modules/userId} module is required
* @module modules/swanIdSystem
* @module modules/oneKeyIdSystem
* @requires module:modules/userId
*/

import {submodule} from '../src/hook.js';

window.PAF = window.PAF || {};
window.PAF.queue = window.PAF.queue || [];

/** @type {Submodule} */
export const pafIdSubmodule = {
export const oneKeyIdSubmodule = {
/**
* used to link submodule with config
* @type {string}
*/
name: 'pafData',
name: 'oneKeyData',
/**
* decode the stored data value for passing to bid requests
* @function decode
Expand All @@ -32,12 +35,22 @@ export const pafIdSubmodule = {
* @returns {IdResponse|undefined}
*/
getId(config, consentData) {
if (window.PAF && window.PAF.getIdsAndPreferences()) {
return {id: window.PAF.getIdsAndPreferences()};
} else {
return undefined;
}
const idResponseCallback = function (callbackResp) {
window.PAF.queue.push(function() {
if (config.params === undefined || config.params.proxyHostName === undefined) {
callbackResp();
return
}
const options = {
proxyHostName: config.params.proxyHostName,
callback: callbackResp
};
window.PAF.getIdsAndPreferencesAsync(options);
});
};

return { callback: idResponseCallback };
}
};

submodule('userId', pafIdSubmodule);
submodule('userId', oneKeyIdSubmodule);
26 changes: 13 additions & 13 deletions modules/pafIdSystem.md → modules/oneKeyIdSystem.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
# Prebid Addressability Framework (OneKey)

The PAF real-time data module in Prebid has been built so that publishers
can quickly and easily setup the Prebid Addressability Framework and utilize OneKey.
This module is used along with the pafRtdProvider to pass PAF data to your partners.
Both modules are required. This module will pass paData to your partners
while the pafRtdProvider will pass the transmission requests.
The OneKey real-time data module in Prebid has been built so that publishers
can quickly and easily setup the OneKey Addressability Framework.
This module is used along with the oneKeyRtdProvider to pass OneKey data to your partners.
Both modules are required. This module will pass oneKeyData to your partners
while the oneKeyRtdProvider will pass the transmission requests.

Background information:
- [prebid/addressability-framework](https://github.com/prebid/addressability-framework)
- [prebid/paf-mvp-implementation](https://github.com/prebid/paf-mvp-implementation)

## PAF Configuration
## OneKey Configuration

The pafData module depends on paf-lib.js existing in the page.
The oneKeyData module depends on paf-lib.js existing in the page.

Compile the pafData module into your Prebid build.
You will also want to add the pafRtdProvider module as well.
Compile the oneKeyData module into your Prebid build.
You will also want to add the oneKeyRtdProvider module as well.

`gulp build --modules=userId,pafIdSystem,rtdModule,pafRtdProvider,appnexusBidAdapter`
`gulp build --modules=userId,oneKeyIdSystem,rtdModule,oneKeyRtdProvider,appnexusBidAdapter`

There are no custom configuration parameters for PAF. The module
will retrieve the PAF data from the page if available and pass the
There are no custom configuration parameters for OneKey. The module
will retrieve the OneKey data from the page if available and pass the
information to bidders. Here is a configuration example:

```javascript
pbjs.setConfig({
userSync: {
userIds: [{
name: "pafData",
name: "oneKeyData",
params: {}
}]
}],
Expand Down
71 changes: 43 additions & 28 deletions modules/pafRtdProvider.js → modules/oneKeyRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { mergeDeep, isPlainObject, logError, logMessage, deepSetValue, generateU
import { getGlobal } from '../src/prebidGlobal.js';
import {config} from '../src/config.js';

const SUBMODULE_NAME = 'paf';
const SUBMODULE_NAME = 'oneKey';

window.PAF = window.PAF || {};
window.PAF.queue = window.PAF.queue || [];

/**
*
Expand All @@ -14,28 +17,40 @@ const SUBMODULE_NAME = 'paf';
* @param {Object} userConsent
*/
export function getBidRequestData(reqBidsConfigObj, onDone, rtdConfig, userConsent) {
let idsAndPreferences;
const adUnits = (reqBidsConfigObj.adUnits || getGlobal().adUnits);

if (rtdConfig.params && rtdConfig.params.proxyHostName && window.PAF) {
idsAndPreferences = window.PAF.getIdsAndPreferences();
if (!idsAndPreferences) {
onDone();
logMessage(SUBMODULE_NAME, 'No id and preferences. Not creating Seed.');
return;
}

let transactionIds = [];
for (var i = 0; i < adUnits.length; i++) {
const uuid = generateUUID();
transactionIds.push(uuid)
deepSetValue(adUnits[i], `ortb2Imp.ext.data.paf.transaction_id`, uuid)
}

window.PAF.generateSeed({proxyHostName: rtdConfig.params.proxyHostName, callback: function (seed) { setData(seed, rtdConfig, onDone); }}, transactionIds)
} else {
if (rtdConfig.params === undefined || rtdConfig.params.proxyHostName === undefined) {
onDone();
return
}
window.PAF.queue.push(function() {
const idsAndPreferencesAsyncOptions = {
proxyHostName: rtdConfig.params.proxyHostName,
callback: function (idsAndPreferences) {
if (!idsAndPreferences) {
onDone();
logMessage(SUBMODULE_NAME, 'No id and preferences. Not creating Seed.');
return;
}

const adUnits = (reqBidsConfigObj.adUnits || getGlobal().adUnits);
let transactionIds = [];
for (var i = 0; i < adUnits.length; i++) {
const uuid = generateUUID();
transactionIds.push(uuid)
deepSetValue(adUnits[i], `ortb2Imp.ext.data.paf.transaction_id`, uuid)
}

const generateSeedOption = {
proxyHostName: rtdConfig.params.proxyHostName,
callback: function (seed) {
setData(seed, rtdConfig, onDone);
}
}
window.PAF.generateSeed(generateSeedOption, transactionIds)
}
};

window.PAF.getIdsAndPreferencesAsync(idsAndPreferencesAsyncOptions);
});
}

/**
Expand All @@ -62,7 +77,7 @@ export function setData(seed, rtdConfig, onDone) {
return;
}
logMessage(SUBMODULE_NAME, 'Created Seed:', seed);
const pafOrtb2 = {
const okOrtb2 = {
ortb2: {
user: {
ext: {
Expand All @@ -78,7 +93,7 @@ export function setData(seed, rtdConfig, onDone) {

if (rtdConfig.params && rtdConfig.params.bidders) {
let bidderConfig = config.getBidderConfig();
logMessage(SUBMODULE_NAME, `set ortb2 for: ${rtdConfig.params.bidders}`, pafOrtb2);
logMessage(SUBMODULE_NAME, `set ortb2 for: ${rtdConfig.params.bidders}`, okOrtb2);
rtdConfig.params.bidders.forEach(bidder => {
let bidderOptions = {};
if (isPlainObject(bidderConfig[bidder])) {
Expand All @@ -87,19 +102,19 @@ export function setData(seed, rtdConfig, onDone) {

config.setBidderConfig({
bidders: [bidder],
config: mergeLazy(bidderOptions, pafOrtb2)
config: mergeLazy(bidderOptions, okOrtb2)
});
});
} else {
let ortb2 = config.getConfig('ortb2') || {};
logMessage(SUBMODULE_NAME, 'set ortb2:', pafOrtb2);
config.setConfig({ortb2: mergeLazy(ortb2, pafOrtb2.ortb2)});
logMessage(SUBMODULE_NAME, 'set ortb2:', okOrtb2);
config.setConfig({ortb2: mergeLazy(ortb2, okOrtb2.ortb2)});
}
onDone();
}

/** @type {RtdSubmodule} */
export const pafDataSubmodule = {
export const oneKeyDataSubmodule = {
/**
* used to link submodule with realTimeData
* @type {string}
Expand All @@ -110,7 +125,7 @@ export const pafDataSubmodule = {
};

function registerSubModule() {
submodule('realTimeData', pafDataSubmodule);
submodule('realTimeData', oneKeyDataSubmodule);
}

registerSubModule();
24 changes: 12 additions & 12 deletions modules/pafRtdProvider.md → modules/oneKeyRtdProvider.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
## Prebid Addressability Framework Real-time Data Submodule

The PAF real-time data module in Prebid has been built so that publishers
can quickly and easily setup the Prebid Addressability Framework and utilize OneKey.
This module is used along with the pafIdSysytem to pass PAF data to your partners.
The OneKey real-time data module in Prebid has been built so that publishers
can quickly and easily setup the OneKey Addressability Framework.
This module is used along with the oneKeyIdSystem to pass OneKey data to your partners.
Both modules are required. This module will pass transmission requests to your partners
while the pafIdSystem will pass the pafData.
while the oneKeyIdSystem will pass the oneKeyData.

Background information:
- [prebid/addressability-framework](https://github.com/prebid/addressability-framework)
- [prebid/paf-mvp-implementation](https://github.com/prebid/paf-mvp-implementation)

### Publisher Usage

The paf RTD module depends on paf-lib.js existing in the page.
The OneKey RTD module depends on paf-lib.js existing in the page.

Compile the paf RTD module into your Prebid build:
Compile the OneKey RTD module into your Prebid build:

`gulp build --modules=userId,pafIdSystem,rtdModule,pafRtdProvider,appnexusBidAdapter`
`gulp build --modules=userId,oneKeyIdSystem,rtdModule,oneKeyRtdProvider,appnexusBidAdapter`

Add the PAF RTD provider to your Prebid config. In this example we will configure
Add the OneKey RTD provider to your Prebid config. In this example we will configure
a sample proxyHostName. See the "Parameter Descriptions" below for more detailed information
of the configuration parameters.

Expand All @@ -41,14 +41,14 @@ pbjs.setConfig(
}
```

### Parameter Descriptions for the PAF Configuration Section
### Parameter Descriptions for the OneKey Configuration Section

| Name |Type | Description | Notes |
| :------------ | :------------ | :------------ |:------------ |
| name | String | Real time data module name | Always 'paf' |
| name | String | Real time data module name | Always 'oneKey' |
| waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false |
| params | Object | | |
| params.proxyHostName | String | servername of the PAF Proxy which will generate seeds. | Required |
| params.proxyHostName | String | servername of the OneKey Proxy which will generate seeds. | Required |
| params.bidders | Array | List of bidders to restrict the data to. | Optional |

### Data for bidders
Expand Down Expand Up @@ -93,7 +93,7 @@ The following is an example of the format of the data:

### Bidder Responses

Bidders who are part of the Prebid Addressability Framework and receive PAF
Bidders who are part of the OneKey Addressability Framework and receive OneKey
transmissions are required to return transmission responses as outlined in
[prebid/addressability-framework](https://github.com/prebid/addressability-framework/blob/main/mvp-spec/ad-auction.md). Transmission responses should be appended to bids
along with the releveant content_id using the meta.paf field. The paf-lib will
Expand Down
4 changes: 2 additions & 2 deletions modules/userId/eids.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ export const USER_IDS_CONFIG = {
}
},

// PAF Data
'pafData': {
// OneKey Data
'oneKeyData': {
getValue: function(data) {
if (data && Array.isArray(data.identifiers) && data.identifiers[0]) {
return data.identifiers[0].value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { pafIdSubmodule } from 'modules/pafIdSystem'
import { oneKeyIdSubmodule } from 'modules/oneKeyIdSystem'
import { config } from 'src/config.js';
import {find} from 'src/polyfill.js';
import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js';
Expand Down Expand Up @@ -34,7 +34,7 @@ function getConfigMock() {
userSync: {
syncDelay: 0,
userIds: [{
name: 'pafData'
name: 'oneKeyData'
}]
}
}
Expand All @@ -55,29 +55,31 @@ function getAdUnitMock(code = 'adUnit-code') {
};
}

describe('pafData module', function () {
it('returns undefined if paf-lib is not found', function () {
const moduleIdResponse = pafIdSubmodule.getId();
expect(moduleIdResponse).to.be.undefined;
})
it('returns undefined if no Data', function () {
window.PAF = {
getIdsAndPreferences() {
return undefined;
}
}
const moduleIdResponse = pafIdSubmodule.getId();
expect(moduleIdResponse).to.be.undefined;
})
it('gets pafData from page context', function () {
window.PAF = {
getIdsAndPreferences() {
return idsAndPrefs;
}
}
const moduleIdResponse = pafIdSubmodule.getId();
expect(moduleIdResponse).to.deep.equal({id: idsAndPrefs});
})
describe('oneKeyData module', function () {
it('create PAF object with operation queue if they don\'t exist yet and return object with callback', function () {
const moduleIdResponse = oneKeyIdSubmodule.getId();
expect(window.PAF.queue.length).to.equal(1);
expect(moduleIdResponse.callback).to.be.an('function');
});

// it('returns undefined if no Data', function () {
// window.PAF = {
// getIdsAndPreferences() {
// return undefined;
// }
// }
// const moduleIdResponse = oneKeyIdSubmodule.getId();
// expect(moduleIdResponse).to.be.undefined;
// })
// it('gets pafData from page context', function () {
// window.PAF = {
// getIdsAndPreferences() {
// return idsAndPrefs;
// }
// }
// const moduleIdResponse = pafIdSubmodule.getId();
// expect(moduleIdResponse).to.deep.equal({id: idsAndPrefs});
// })

// this test format was copied from other id module tests
// but it is failing on the hook and im not sure why, if someone
Expand Down
Loading