Skip to content

Commit

Permalink
Merge branch 'master' of github.com:prebid/Prebid.js
Browse files Browse the repository at this point in the history
  • Loading branch information
Laslo Chechur committed Jul 28, 2021
2 parents 804e9cf + e130657 commit 8e285e3
Show file tree
Hide file tree
Showing 7 changed files with 331 additions and 210 deletions.
35 changes: 35 additions & 0 deletions integrationExamples/gpt/permutiveRtdProvider_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,41 @@
]
}
});
pbjs.setBidderConfig({
bidders: ['appnexus', 'rubicon'],
config: {
ortb2: {
site: {
name: "example",
domain: "page.example.com",
cat: ["IAB2"],
sectioncat: ["IAB2-2"],
pagecat: ["IAB2-2"],
page: "https://page.example.com/here.html",
ref: "https://ref.example.com",
keywords: "power tools, drills",
search: "drill",
content: {}
},
user: {
yob: 1985,
gender: 'm',
keywords: 'a,b',
data: [
{
name: 'www.dataprovider1.com',
ext: { taxonomyname: 'iab_audience_taxonomy' },
segment: [{ id: '687' }, { id: '123' }]
},
{
name: 'permutive.com',
segment: [{ id: '1' }]
}
]
}
}
}
});
pbjs.addAdUnits(adUnits);
requestBids();
});
Expand Down
5 changes: 5 additions & 0 deletions modules/adyoulikeBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ export const spec = {
}
if (mediatype === VIDEO) {
accumulator[bidReq.bidId].Video = bidReq.mediaTypes.video;

const size = bidReq.mediaTypes.video.playerSize;
if (Array.isArray(size) && !Array.isArray(size[0])) {
accumulator[bidReq.bidId].Video.playerSize = [size];
}
}
return accumulator;
}, {}),
Expand Down
23 changes: 14 additions & 9 deletions modules/beachfrontBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { VIDEO, BANNER } from '../src/mediaTypes.js';
import find from 'core-js-pure/features/array/find.js';
import includes from 'core-js-pure/features/array/includes.js';

const ADAPTER_VERSION = '1.16';
const ADAPTER_VERSION = '1.17';
const ADAPTER_NAME = 'BFIO_PREBID';
const OUTSTREAM = 'outstream';
const CURRENCY = 'USD';
Expand All @@ -21,7 +21,8 @@ export const DEFAULT_MIMES = ['video/mp4', 'application/javascript'];
export const SUPPORTED_USER_IDS = [
{ key: 'tdid', source: 'adserver.org', rtiPartner: 'TDID', queryParam: 'tdid' },
{ key: 'idl_env', source: 'liveramp.com', rtiPartner: 'idl', queryParam: 'idl' },
{ key: 'uid2.id', source: 'uidapi.com', rtiPartner: 'UID2', queryParam: 'uid2' }
{ key: 'uid2.id', source: 'uidapi.com', rtiPartner: 'UID2', queryParam: 'uid2' },
{ key: 'haloId', source: 'audigent.com', atype: 1, queryParam: 'haloid' }
];

let appId = '';
Expand Down Expand Up @@ -294,19 +295,23 @@ function getEids(bid) {
}

function getUserId(bid) {
return ({ key, source, rtiPartner }) => {
return ({ key, source, rtiPartner, atype }) => {
let id = utils.deepAccess(bid, `userId.${key}`);
return id ? formatEid(id, source, rtiPartner) : null;
return id ? formatEid(id, source, rtiPartner, atype) : null;
};
}

function formatEid(id, source, rtiPartner) {
function formatEid(id, source, rtiPartner, atype) {
let uid = { id };
if (rtiPartner) {
uid.ext = { rtiPartner };
}
if (atype) {
uid.atype = atype;
}
return {
source,
uids: [{
id,
ext: { rtiPartner }
}]
uids: [uid]
};
}

Expand Down
183 changes: 137 additions & 46 deletions modules/permutiveRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,63 +9,141 @@ import { getGlobal } from '../src/prebidGlobal.js'
import { submodule } from '../src/hook.js'
import { getStorageManager } from '../src/storageManager.js'
import { deepSetValue, deepAccess, isFn, mergeDeep, logError } from '../src/utils.js'
import { config } from '../src/config.js'
import includes from 'core-js-pure/features/array/includes.js'
const MODULE_NAME = 'permutive'

export const storage = getStorageManager(null, MODULE_NAME)

function init (config, userConsent) {
function init (moduleConfig, userConsent) {
return true
}

/**
* Set segment targeting from cache and then try to wait for Permutive
* to initialise to get realtime segment targeting
*/
export function initSegments (reqBidsConfigObj, callback, customConfig) {
* Set segment targeting from cache and then try to wait for Permutive
* to initialise to get realtime segment targeting
* @param {Object} reqBidsConfigObj
* @param {function} callback - Called when submodule is done
* @param {customModuleConfig} reqBidsConfigObj - Publisher config for module
*/
export function initSegments (reqBidsConfigObj, callback, customModuleConfig) {
const permutiveOnPage = isPermutiveOnPage()
const config = mergeDeep({
waitForIt: false,
params: {
maxSegs: 500,
acBidders: [],
overwrites: {}
}
}, customConfig)
const moduleConfig = getModuleConfig(customModuleConfig)
const segmentData = getSegments(moduleConfig.params.maxSegs)

setSegments(reqBidsConfigObj, config)
setSegments(reqBidsConfigObj, moduleConfig, segmentData)

if (config.waitForIt && permutiveOnPage) {
if (moduleConfig.waitForIt && permutiveOnPage) {
window.permutive.ready(function () {
setSegments(reqBidsConfigObj, config)
setSegments(reqBidsConfigObj, moduleConfig, segmentData)
callback()
}, 'realtime')
} else {
callback()
}
}

function setSegments (reqBidsConfigObj, config) {
const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits
const data = getSegments(config.params.maxSegs)
/**
* Merges segments into existing bidder config
* @param {Object} customModuleConfig - Publisher config for module
* @return {Object} Merged defatul and custom config
*/
function getModuleConfig (customModuleConfig) {
return mergeDeep({
waitForIt: false,
params: {
maxSegs: 500,
acBidders: [],
overwrites: {}
}
}, customModuleConfig)
}

/**
* Sets ortb2 config for ac bidders
* @param {Object} auctionDetails
* @param {Object} customModuleConfig - Publisher config for module
*/
export function setBidderRtb (auctionDetails, customModuleConfig) {
const bidderConfig = config.getBidderConfig()
const moduleConfig = getModuleConfig(customModuleConfig)
const acBidders = deepAccess(moduleConfig, 'params.acBidders')
const maxSegs = deepAccess(moduleConfig, 'params.maxSegs')
const segmentData = getSegments(maxSegs)

acBidders.forEach(function (bidder) {
const currConfig = bidderConfig[bidder] || {}
const nextConfig = mergeOrtbConfig(currConfig, segmentData)

config.setBidderConfig({
bidders: [bidder],
config: nextConfig
})
})
}

/**
* Merges segments into existing bidder config
* @param {Object} currConfig - Current bidder config
* @param {Object} segmentData - Segment data
* @return {Object} Merged ortb2 object
*/
function mergeOrtbConfig (currConfig, segmentData) {
const segment = segmentData.ac.map(seg => {
return { id: seg }
})
const name = 'permutive.com'
const ortbConfig = mergeDeep({}, currConfig)
const currSegments = deepAccess(ortbConfig, 'ortb2.user.data') || []
const userSegment = currSegments
.filter(el => el.name !== name)
.concat({ name, segment })

deepSetValue(ortbConfig, 'ortb2.user.data', userSegment)

return ortbConfig
}

/**
* Set segments on bid request object
* @param {Object} reqBidsConfigObj - Bid request object
* @param {Object} moduleConfig - Module configuration
* @param {Object} segmentData - Segment object
*/
function setSegments (reqBidsConfigObj, moduleConfig, segmentData) {
const adUnits = (reqBidsConfigObj && reqBidsConfigObj.adUnits) || getGlobal().adUnits
const utils = { deepSetValue, deepAccess, isFn, mergeDeep }
const aliasMap = {
appnexusAst: 'appnexus'
}

if (!adUnits) {
return
}

adUnits.forEach(adUnit => {
adUnit.bids.forEach(bid => {
const { bidder } = bid
const acEnabled = isAcEnabled(config, bidder)
const customFn = getCustomBidderFn(config, bidder)
let { bidder } = bid
if (typeof aliasMap[bidder] !== 'undefined') {
bidder = aliasMap[bidder]
}
const acEnabled = isAcEnabled(moduleConfig, bidder)
const customFn = getCustomBidderFn(moduleConfig, bidder)
const defaultFn = getDefaultBidderFn(bidder)

if (customFn) {
customFn(bid, data, acEnabled, utils, defaultFn)
customFn(bid, segmentData, acEnabled, utils, defaultFn)
} else if (defaultFn) {
defaultFn(bid, data, acEnabled)
defaultFn(bid, segmentData, acEnabled)
}
})
})
}

/**
* Catch and log errors
* @param {function} fn - Function to safely evaluate
*/
function makeSafe (fn) {
try {
fn()
Expand All @@ -74,8 +152,8 @@ function makeSafe (fn) {
}
}

function getCustomBidderFn (config, bidder) {
const overwriteFn = deepAccess(config, `params.overwrites.${bidder}`)
function getCustomBidderFn (moduleConfig, bidder) {
const overwriteFn = deepAccess(moduleConfig, `params.overwrites.${bidder}`)

if (overwriteFn && isFn(overwriteFn)) {
return overwriteFn
Expand All @@ -85,13 +163,13 @@ function getCustomBidderFn (config, bidder) {
}

/**
* Returns a function that receives a `bid` object, a `data` object and a `acEnabled` boolean
* and which will set the right segment targeting keys for `bid` based on `data` and `acEnabled`
* @param {string} bidder
* @param {object} data
*/
* Returns a function that receives a `bid` object, a `data` object and a `acEnabled` boolean
* and which will set the right segment targeting keys for `bid` based on `data` and `acEnabled`
* @param {string} bidder - Bidder name
* @return {Object} Bidder function
*/
function getDefaultBidderFn (bidder) {
const bidderMapper = {
const bidderMap = {
appnexus: function (bid, data, acEnabled) {
if (acEnabled && data.ac && data.ac.length) {
deepSetValue(bid, 'params.keywords.p_standard', data.ac)
Expand All @@ -117,32 +195,37 @@ function getDefaultBidderFn (bidder) {
deepSetValue(bid, 'params.customData.0.targeting.p_standard', data.ac)
}

return bid
},
trustx: function (bid, data, acEnabled) {
if (acEnabled && data.ac && data.ac.length) {
deepSetValue(bid, 'params.keywords.p_standard', data.ac)
}

return bid
}
}

return bidderMapper[bidder]
return bidderMap[bidder]
}

export function isAcEnabled (config, bidder) {
const acBidders = deepAccess(config, 'params.acBidders') || []
/**
* Check whether ac is enabled for bidder
* @param {Object} moduleConfig - Module configuration
* @param {string} bidder - Bidder name
* @return {boolean}
*/
export function isAcEnabled (moduleConfig, bidder) {
const acBidders = deepAccess(moduleConfig, 'params.acBidders') || []
return includes(acBidders, bidder)
}

/**
* Check whether Permutive is on page
* @return {boolean}
*/
export function isPermutiveOnPage () {
return typeof window.permutive !== 'undefined' && typeof window.permutive.ready === 'function'
}

/**
* Returns all relevant segment IDs in an object
*/
* Get all relevant segment IDs in an object
* @param {number} maxSegs - Maximum number of segments to be included
* @return {Object}
*/
export function getSegments (maxSegs) {
const legacySegs = readSegments('_psegs').map(Number).filter(seg => seg >= 1000000).map(String)
const _ppam = readSegments('_ppam')
Expand All @@ -166,6 +249,7 @@ export function getSegments (maxSegs) {
* Gets an array of segment IDs from LocalStorage
* or returns an empty array
* @param {string} key
* @return {string[]|number[]}
*/
function readSegments (key) {
try {
Expand All @@ -178,9 +262,16 @@ function readSegments (key) {
/** @type {RtdSubmodule} */
export const permutiveSubmodule = {
name: MODULE_NAME,
getBidRequestData: function (reqBidsConfigObj, callback, customConfig) {
getBidRequestData: function (reqBidsConfigObj, callback, customModuleConfig) {
makeSafe(function () {
// Legacy route with custom parameters
initSegments(reqBidsConfigObj, callback, customModuleConfig)
})
},
onAuctionInitEvent: function (auctionDetails, customModuleConfig) {
makeSafe(function () {
initSegments(reqBidsConfigObj, callback, customConfig)
// Route for bidders supporting ORTB2
setBidderRtb(auctionDetails, customModuleConfig)
})
},
init: init
Expand Down
Loading

0 comments on commit 8e285e3

Please sign in to comment.