Skip to content

Commit

Permalink
1plusX Rtd Provider : add First Party Cookie ID option (#11493)
Browse files Browse the repository at this point in the history
* 1plusX: Add First Party Cookie ID Option

* 1plusX: Remove Empty Test Case

* 1plusX Rtd Provider: Improve Documentation
  • Loading branch information
luca1x authored May 21, 2024
1 parent 8d4c170 commit 1848b66
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 31 deletions.
39 changes: 30 additions & 9 deletions modules/1plusXRtdProvider.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { submodule } from '../src/hook.js';
import { MODULE_TYPE_RTD } from '../src/activities/modules.js';
import { ajax } from '../src/ajax.js';
import { getStorageManager, STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE } from '../src/storageManager.js';
import {
logMessage, logError,
deepAccess, deepSetValue, mergeDeep,
Expand All @@ -13,6 +15,9 @@ const ORTB2_NAME = '1plusX.com'
const PAPI_VERSION = 'v1.0';
const LOG_PREFIX = '[1plusX RTD Module]: ';
const OPE_FPID = 'ope_fpid'

export const fpidStorage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: MODULE_NAME });

export const segtaxes = {
// cf. https://github.com/InteractiveAdvertisingBureau/openrtb/pull/108
AUDIENCE: 526,
Expand Down Expand Up @@ -53,7 +58,19 @@ export const extractConfig = (moduleConfig, reqBidsConfigObj) => {
throw new Error('No bidRequestConfig bidder found in moduleConfig bidders');
}

return { customerId, timeout, bidders };
const fpidStorageType = deepAccess(moduleConfig, 'params.fpidStorageType',
STORAGE_TYPE_LOCALSTORAGE)

if (
fpidStorageType !== STORAGE_TYPE_COOKIES &&
fpidStorageType !== STORAGE_TYPE_LOCALSTORAGE
) {
throw new Error(
`fpidStorageType must be ${STORAGE_TYPE_LOCALSTORAGE} or ${STORAGE_TYPE_COOKIES}`
)
}

return { customerId, timeout, bidders, fpidStorageType };
}

/**
Expand Down Expand Up @@ -81,16 +98,20 @@ export const extractConsent = ({ gdpr }) => {
}

/**
* Extracts the OPE first party id field from local storage
* Extracts the OPE first party id field
* @param {string} fpidStorageType indicates where fpid should be read from
* @returns fpid string if found, else null
*/
export const extractFpid = () => {
export const extractFpid = (fpidStorageType) => {
try {
const fpid = window.localStorage.getItem(OPE_FPID);
if (fpid) {
return fpid;
switch (fpidStorageType) {
case STORAGE_TYPE_COOKIES: return fpidStorage.getCookie(OPE_FPID)
case STORAGE_TYPE_LOCALSTORAGE: return fpidStorage.getDataFromLocalStorage(OPE_FPID)
default: {
logError(`Got unknown fpidStorageType ${fpidStorageType}. Aborting...`)
return null
}
}
return null;
} catch (error) {
return null;
}
Expand Down Expand Up @@ -231,10 +252,10 @@ const init = (config, userConsent) => {
const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, userConsent) => {
try {
// Get the required config
const { customerId, bidders } = extractConfig(moduleConfig, reqBidsConfigObj);
const { customerId, bidders, fpidStorageType } = extractConfig(moduleConfig, reqBidsConfigObj);
const { ortb2Fragments: { bidder: biddersOrtb2 } } = reqBidsConfigObj;
// Get PAPI URL
const papiUrl = getPapiUrl(customerId, extractConsent(userConsent) || {}, extractFpid())
const papiUrl = getPapiUrl(customerId, extractConsent(userConsent) || {}, extractFpid(fpidStorageType))
// Call PAPI
getTargetingDataFromPapi(papiUrl)
.then((papiResponse) => {
Expand Down
19 changes: 10 additions & 9 deletions modules/1plusXRtdProvider.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ pbjs.setConfig({

### Parameters

| Name | Type | Description | Default |
| :---------------- | :------------ | :--------------------------------------------------------------- |:----------------- |
| name | String | Real time data module name | Always '1plusX' |
| waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (optional) | `false` |
| params | Object | | |
| params.customerId | String | Your 1plusX customer id | |
| params.bidders | Array<string> | List of bidders for which you would like data to be set | |
| params.timeout | Integer | timeout (ms) | 1000ms |

| Name | Type | Description | Default |
| :------------------------ | :------------ | :--------------------------------------------------------------- |:----------------- |
| name | String | Real time data module name | Always '1plusX' |
| waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (optional) | `false` |
| params | Object | | |
| params.customerId | String | Your 1plusX customer id | |
| params.bidders | Array<string> | List of bidders for which you would like data to be set | |
| params.timeout | Integer | timeout (ms) | 1000ms |
| params.fpidStorageType | String | Specifies where the 1plusX fpid should be read from. Either | html5 |
| | | "html5" (local storage) or "cookie" (first party cookie) | |
## Testing

To view an example of how the 1plusX RTD module works :
Expand Down
32 changes: 19 additions & 13 deletions test/spec/modules/1plusXRtdProvider_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
updateBidderConfig,
} from 'modules/1plusXRtdProvider';
import {deepClone} from '../../../src/utils.js';
import { STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE } from 'src/storageManager.js';

describe('1plusXRtdProvider', () => {
// Fake server config
Expand Down Expand Up @@ -126,6 +127,7 @@ describe('1plusXRtdProvider', () => {
const customerId = 'test';
const timeout = 1000;
const bidders = ['appnexus'];
const fpidStorageType = STORAGE_TYPE_LOCALSTORAGE

it('Throws an error if no customerId is specified', () => {
const moduleConfig = { params: { timeout, bidders } };
Expand All @@ -141,13 +143,14 @@ describe('1plusXRtdProvider', () => {
expect(() => extractConfig(moduleConfig, reqBidsConfigEmpty)).to.throw();
})
it('Returns an object containing the parameters specified', () => {
const moduleConfig = { params: { customerId, timeout, bidders } };
const expectedKeys = ['customerId', 'timeout', 'bidders']
const moduleConfig = { params: { customerId, timeout, bidders, fpidStorageType } };
const expectedKeys = ['customerId', 'timeout', 'bidders', 'fpidStorageType']
const extractedConfig = extractConfig(moduleConfig, reqBidsConfigObj);
expect(extractedConfig).to.be.an('object').and.to.have.all.keys(expectedKeys);
expect(extractedConfig.customerId).to.equal(customerId);
expect(extractedConfig.timeout).to.equal(timeout);
expect(extractedConfig.bidders).to.deep.equal(bidders);
expect(extractedConfig.fpidStorageType).to.equal(fpidStorageType)
})
/* 1plusX RTD module may only use bidders that are both specified in :
- the bid request configuration
Expand All @@ -166,6 +169,20 @@ describe('1plusXRtdProvider', () => {
const moduleConfig = { params: { customerId, timeout, bidders } };
expect(() => extractConfig(moduleConfig, reqBidsConfigObj)).to.throw();
})
it('Throws an error if wrong fpidStorageType is provided', () => {
const moduleConfig = { params: { customerId, timeout, bidders, fpidStorageType: 'bogus' } };
expect(() => extractConfig(moduleConfig, reqBidsConfigObj).to.throw())
})
it('Defaults fpidStorageType to localStorage', () => {
const moduleConfig = { params: { customerId, timeout, bidders } };
const extractedConfig = extractConfig(moduleConfig, reqBidsConfigObj);
expect(extractedConfig.fpidStorageType).to.equal(STORAGE_TYPE_LOCALSTORAGE)
})
it('Correctly instantiates fpidStorageType to cookie store if instructed', () => {
const moduleConfig = { params: { customerId, timeout, bidders, fpidStorageType: STORAGE_TYPE_COOKIES } };
const extractedConfig = extractConfig(moduleConfig, reqBidsConfigObj);
expect(extractedConfig.fpidStorageType).to.equal(STORAGE_TYPE_COOKIES)
})
})

describe('buildOrtb2Updates', () => {
Expand Down Expand Up @@ -284,17 +301,6 @@ describe('1plusXRtdProvider', () => {
})
})

describe('extractFpid', () => {
it('correctly extracts an ope fpid if present', () => {
window.localStorage.setItem('ope_fpid', 'oneplusx_test_key')
const id1 = extractFpid()
window.localStorage.removeItem('ope_fpid')
const id2 = extractFpid()
expect(id1).to.equal('oneplusx_test_key')
expect(id2).to.equal(null)
})
})

describe('getPapiUrl', () => {
const customer = 'acme'
const consent = {
Expand Down

0 comments on commit 1848b66

Please sign in to comment.