forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'prebid:master' into master
- Loading branch information
Showing
115 changed files
with
7,910 additions
and
1,749 deletions.
There are no files selected for viewing
114 changes: 114 additions & 0 deletions
114
integrationExamples/gpt/rewardedInterestIdSystem_example.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<title>Rewarded Interest ID Example</title> | ||
<script> | ||
const FAILSAFE_TIMEOUT = 2000; | ||
const adUnits = [ | ||
{ | ||
code: 'test-div', | ||
mediaTypes: { | ||
banner: { | ||
sizes: [[300, 250], [300, 600], [728, 90]] | ||
}, | ||
}, | ||
bids: [ | ||
{ | ||
bidder: 'rubicon', | ||
params: { | ||
accountId: '1001', | ||
siteId: '113932', | ||
zoneId: '535510' | ||
} | ||
} | ||
] | ||
} | ||
]; | ||
var pbjs = pbjs || {}; | ||
pbjs.que = pbjs.que || []; | ||
</script> | ||
<script src="../../build/dev/prebid.js" async></script> | ||
|
||
<script> | ||
var googletag = googletag || {}; | ||
googletag.cmd = googletag.cmd || []; | ||
googletag.cmd.push(function () { | ||
googletag.pubads().disableInitialLoad(); | ||
}); | ||
|
||
pbjs.que.push(function () { | ||
pbjs.setConfig({ | ||
debug: true, | ||
userSync: { | ||
userIds: [ | ||
{ | ||
name: 'rewardedInterestId', | ||
}, | ||
], | ||
syncDelay: 5000, | ||
auctionDelay: 1000, | ||
} | ||
}); | ||
pbjs.addAdUnits(adUnits); | ||
pbjs.requestBids({ | ||
bidsBackHandler: sendAdserverRequest | ||
}); | ||
}); | ||
|
||
function sendAdserverRequest() { | ||
if (pbjs.adserverRequestSent) return; | ||
pbjs.adserverRequestSent = true; | ||
googletag.cmd.push(function () { | ||
pbjs.que.push(function () { | ||
pbjs.setTargetingForGPTAsync(); | ||
googletag.pubads().refresh(); | ||
}); | ||
}); | ||
} | ||
|
||
setTimeout(function () { | ||
sendAdserverRequest(); | ||
}, FAILSAFE_TIMEOUT); | ||
</script> | ||
|
||
<script> | ||
(function () { | ||
var gads = document.createElement('script'); | ||
gads.async = true; | ||
gads.type = 'text/javascript'; | ||
gads.src = 'https://securepubads.g.doubleclick.net/tag/js/gpt.js'; | ||
var node = document.getElementsByTagName('script')[0]; | ||
node.parentNode.insertBefore(gads, node); | ||
})(); | ||
</script> | ||
|
||
<script> | ||
googletag.cmd.push(function () { | ||
googletag.defineSlot('/112115922/FL_PB_MedRect', [[300, 250], [300, 600], [728, 90]], 'test-div').addService(googletag.pubads()); | ||
googletag.pubads().enableSingleRequest(); | ||
googletag.enableServices(); | ||
}); | ||
</script> | ||
</head> | ||
|
||
<body> | ||
<script> | ||
pbjs.que.push(function () { | ||
pbjs.getUserIdsAsync().then(ids => { | ||
document.getElementById('ids-div').innerHTML = JSON.stringify(ids, null, ' '); | ||
document.getElementById('eids-div').innerHTML = JSON.stringify(pbjs.getUserIdsAsEids(), null, ' '); | ||
}); | ||
}); | ||
</script> | ||
|
||
<h2>Rewarded Interest ID Example</h2> | ||
|
||
<h4>Generated IDs:</h4> | ||
<pre id="ids-div" style="border:1px solid #333; padding:5px; overflow: auto"></pre> | ||
|
||
<h4>Generated EIDs</h4> | ||
<pre id="eids-div" style="border:1px solid #333; padding:5px; overflow: auto"></pre> | ||
</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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { isEmpty, parseUrl } from '../../src/utils.js'; | ||
import {config} from '../../src/config.js'; | ||
import { createNativeRequest, createBannerRequest, createVideoRequest } from './index.js'; | ||
import { convertOrtbRequestToProprietaryNative } from '../../src/native.js'; | ||
|
||
export const buildRequests = (validBidRequests, bidderRequest, endpointURL, defaultCur) => { | ||
validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); | ||
if (!validBidRequests.length || !bidderRequest) return []; | ||
|
||
const endpoint = endpointURL.replace('hash', validBidRequests[0].params.placementId); | ||
const imp = validBidRequests.map((br) => { | ||
const impObject = { id: br.bidId, secure: 1 }; | ||
if (br.mediaTypes.banner) impObject.banner = createBannerRequest(br); | ||
else if (br.mediaTypes.video) impObject.video = createVideoRequest(br); | ||
else if (br.mediaTypes.native) impObject.native = { id: br.transactionId, ver: '1.2', request: createNativeRequest(br) }; | ||
return impObject; | ||
}); | ||
|
||
const page = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; | ||
const data = { | ||
id: bidderRequest.bidderRequestId, | ||
cur: [defaultCur], | ||
device: { w: screen.width, h: screen.height, language: navigator.language?.split('-')[0], ua: navigator.userAgent }, | ||
site: { domain: parseUrl(page).hostname, page: page }, | ||
tmax: bidderRequest.timeout, | ||
imp, | ||
}; | ||
|
||
if (bidderRequest.refererInfo.ref) data.site.ref = bidderRequest.refererInfo.ref; | ||
if (bidderRequest.gdprConsent) { | ||
data.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } }; | ||
data.user = { ext: { consent: bidderRequest.gdprConsent.consentString || '' } }; | ||
} | ||
if (bidderRequest.uspConsent) data.regs.ext.us_privacy = bidderRequest.uspConsent; | ||
if (config.getConfig('coppa')) data.regs.coppa = 1; | ||
if (validBidRequests[0].schain) data.source = { ext: { schain: validBidRequests[0].schain } }; | ||
|
||
return { method: 'POST', url: endpoint, data }; | ||
}; | ||
|
||
export const interpretResponse = (serverResponse, defaultCur, parseNative) => { | ||
if (!serverResponse || isEmpty(serverResponse.body)) return []; | ||
|
||
let bids = []; | ||
serverResponse.body.seatbid.forEach(response => { | ||
response.bid.forEach(bid => { | ||
const mediaType = bid.ext?.mediaType || 'banner'; | ||
|
||
const bidObj = { | ||
requestId: bid.impid, | ||
cpm: bid.price, | ||
width: bid.w, | ||
height: bid.h, | ||
ttl: 1200, | ||
currency: defaultCur, | ||
netRevenue: true, | ||
creativeId: bid.crid, | ||
dealId: bid.dealid || null, | ||
mediaType, | ||
}; | ||
|
||
switch (mediaType) { | ||
case 'video': | ||
bidObj.vastUrl = bid.adm; | ||
break; | ||
case 'native': | ||
bidObj.native = parseNative(bid.adm); | ||
break; | ||
default: | ||
bidObj.ad = bid.adm; | ||
} | ||
|
||
bids.push(bidObj); | ||
}); | ||
}); | ||
|
||
return bids; | ||
}; |
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,95 @@ | ||
import { NATIVE_ASSETS, NATIVE_ASSETS_IDS } from './nativeAssets.js'; | ||
|
||
/** | ||
* Builds a native request object based on the bid request | ||
* @param {object} br - The bid request | ||
* @returns {object} The native request object | ||
*/ | ||
export function createNativeRequest(br) { | ||
let impObject = { | ||
ver: '1.2', | ||
assets: [] | ||
}; | ||
|
||
Object.keys(br.mediaTypes.native).forEach((key) => { | ||
const props = NATIVE_ASSETS[key]; | ||
if (props) { | ||
const asset = { | ||
required: br.mediaTypes.native[key].required ? 1 : 0, | ||
id: props.id, | ||
[props.name]: {} | ||
}; | ||
|
||
if (props.type) asset[props.name]['type'] = props.type; | ||
if (br.mediaTypes.native[key].len) asset[props.name]['len'] = br.mediaTypes.native[key].len; | ||
if (br.mediaTypes.native[key].sizes && br.mediaTypes.native[key].sizes[0]) { | ||
asset[props.name]['w'] = br.mediaTypes.native[key].sizes[0]; | ||
asset[props.name]['h'] = br.mediaTypes.native[key].sizes[1]; | ||
} | ||
|
||
impObject.assets.push(asset); | ||
} | ||
}); | ||
|
||
return impObject; | ||
} | ||
|
||
/** | ||
* Builds a banner request object based on the bid request | ||
* @param {object} br - The bid request | ||
* @returns {object} The banner request object | ||
*/ | ||
export function createBannerRequest(br) { | ||
let size = br.mediaTypes.banner.sizes?.[0] || [300, 250]; | ||
return { id: br.transactionId, w: size[0], h: size[1] }; | ||
} | ||
|
||
/** | ||
* Builds a video request object based on the bid request | ||
* @param {object} br - The bid request | ||
* @returns {object} The video request object | ||
*/ | ||
export function createVideoRequest(br) { | ||
let videoObj = { id: br.transactionId }; | ||
const supportedParams = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'skip', 'minbitrate', 'maxbitrate', 'api', 'linearity']; | ||
|
||
supportedParams.forEach((param) => { | ||
if (br.mediaTypes.video[param] !== undefined) { | ||
videoObj[param] = br.mediaTypes.video[param]; | ||
} | ||
}); | ||
|
||
const playerSize = br.mediaTypes.video.playerSize; | ||
if (playerSize) { | ||
videoObj.w = Array.isArray(playerSize[0]) ? playerSize[0][0] : playerSize[0]; | ||
videoObj.h = Array.isArray(playerSize[0]) ? playerSize[0][1] : playerSize[1]; | ||
} else { | ||
videoObj.w = 640; | ||
videoObj.h = 480; | ||
} | ||
|
||
return videoObj; | ||
} | ||
|
||
/** | ||
* Parses the native ad response | ||
* @param {object} adm - The native ad response | ||
* @returns {object} Parsed native ad object | ||
*/ | ||
export function parseNative(adm) { | ||
let bid = { | ||
clickUrl: adm.native.link?.url, | ||
impressionTrackers: adm.native.imptrackers || [], | ||
clickTrackers: adm.native.link?.clicktrackers || [], | ||
jstracker: adm.native.jstracker || [] | ||
}; | ||
adm.native.assets.forEach((asset) => { | ||
const kind = NATIVE_ASSETS_IDS[asset.id]; | ||
const content = kind && asset[NATIVE_ASSETS[kind].name]; | ||
if (content) { | ||
bid[kind] = content.text || content.value || { url: content.url, width: content.w, height: content.h }; | ||
} | ||
}); | ||
|
||
return bid; | ||
} |
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,23 @@ | ||
/** | ||
* IDs and asset types for native ad assets. | ||
*/ | ||
export const NATIVE_ASSETS_IDS = { | ||
1: 'title', | ||
2: 'icon', | ||
3: 'image', | ||
4: 'body', | ||
5: 'sponsoredBy', | ||
6: 'cta' | ||
}; | ||
|
||
/** | ||
* Native assets definition for mapping purposes. | ||
*/ | ||
export const NATIVE_ASSETS = { | ||
title: { id: 1, name: 'title' }, | ||
icon: { id: 2, type: 1, name: 'img' }, | ||
image: { id: 3, type: 3, name: 'img' }, | ||
body: { id: 4, type: 2, name: 'data' }, | ||
sponsoredBy: { id: 5, type: 1, name: 'data' }, | ||
cta: { id: 6, type: 12, name: 'data' } | ||
}; |
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
File renamed without changes.
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,64 @@ | ||
import { getWindowTop, logError, getWindowLocation, getWindowSelf } from '../../src/utils.js'; | ||
|
||
/** | ||
* Determines if the script is running inside an iframe and retrieves the URL. | ||
* @return {string} The encoded vrref value representing the relevant URL. | ||
*/ | ||
export function getReferrer() { | ||
try { | ||
if (getWindowSelf() === getWindowTop()) { | ||
return encodeURIComponent(getWindowLocation().href); | ||
} else { | ||
return encodeURIComponent(getWindowTop().location.href); | ||
} | ||
} catch (error) { | ||
logError(`Error accessing location: ${error}`); | ||
return ''; | ||
} | ||
} | ||
|
||
/** | ||
* Appends `vrref` and `fui` parameters to the provided URL. | ||
* If the referrer URL is available, it appends `vrref` with the relevant referrer value based on the domain. | ||
* Otherwise, it appends `fui=1`. If a domain name is provided, it may also append `vrref` with the domain. | ||
* @param {string} url - The URL to append parameters to. | ||
* @param {string} domainName - The domain name used to determine the relevant referrer. | ||
* @return {string} The modified URL with appended `vrref` or `fui` parameters. | ||
*/ | ||
export function appendVrrefAndFui(url, domainName) { | ||
const fullUrl = getReferrer(); | ||
if (fullUrl) { | ||
return (url += '&vrref=' + getRelevantRefferer(domainName, fullUrl)); | ||
} | ||
url += '&fui=1'; // Full Url Issue | ||
url += '&vrref=' + encodeURIComponent(domainName || ''); | ||
return url; | ||
} | ||
|
||
/** | ||
* Get the relevant referrer based on full URL and domain | ||
* @param {string} domainName The domain name to compare | ||
* @param {string} fullUrl The full URL to analyze | ||
* @return {string} The relevant referrer | ||
*/ | ||
export function getRelevantRefferer(domainName, fullUrl) { | ||
if (domainName && isDomainIncluded(fullUrl, domainName)) { | ||
return fullUrl; | ||
} | ||
return domainName ? encodeURIComponent(domainName) : fullUrl; | ||
} | ||
|
||
/** | ||
* Checks if the provided domain name is included in the full URL. | ||
* @param {string} fullUrl - The full URL to check. | ||
* @param {string} domainName - The domain name to search for within the URL. | ||
* @return {boolean} `True` if the domain name is found in the URL, `false` otherwise. | ||
*/ | ||
export function isDomainIncluded(fullUrl, domainName) { | ||
try { | ||
return fullUrl.includes(domainName); | ||
} catch (error) { | ||
logError(`Invalid URL provided: ${error}`); | ||
return false; | ||
} | ||
} |
Oops, something went wrong.