Skip to content

Commit

Permalink
Merge pull request #34 from prebid/master
Browse files Browse the repository at this point in the history
Update fork grupawp
  • Loading branch information
wojciech-bialy-wpm authored Mar 1, 2024
2 parents 7b8d1a7 + 9427cd3 commit 2dc6ce6
Show file tree
Hide file tree
Showing 115 changed files with 4,637 additions and 480 deletions.
3 changes: 1 addition & 2 deletions integrationExamples/gpt/gdpr_hello_world.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@
pbjs.setConfig({
consentManagement: {
cmpApi: 'iab',
timeout: 5000,
allowAuctionWithoutConsent: true
timeout: 5000
},
pubcid: {
enable: false
Expand Down
2 changes: 1 addition & 1 deletion libraries/appnexusUtils/anKeywords.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function convertKeywordStringToANMap(keyStr) {
}

/**
* @param {Array<String>} kwarray: keywords as an array of strings
* @param {Array<String>} kwarray keywords as an array of strings
* @return {{}} appnexus-style keyword map
*/
function convertKeywordsToANMap(kwarray) {
Expand Down
2 changes: 1 addition & 1 deletion libraries/keywords/keywords.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const ORTB_KEYWORDS_PATHS = ['user.keywords'].concat(
);

/**
* @param commaSeparatedKeywords: any number of either keyword arrays, or comma-separated keyword strings
* @param commaSeparatedKeywords any number of either keyword arrays, or comma-separated keyword strings
* @returns an array with all unique keywords contained across all inputs
*/
export function mergeKeywords(...commaSeparatedKeywords) {
Expand Down
2 changes: 2 additions & 0 deletions libraries/objectGuard/objectGuard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {isData, objectTransformer, sessionedApplies} from '../../src/activities/
import {deepAccess, deepClone, deepEqual, deepSetValue} from '../../src/utils.js';

/**
* @typedef {import('../src/activities/redactor.js').TransformationRuleDef} TransformationRuleDef
* @typedef {import('../src/adapters/bidderFactory.js').TransformationRule} TransformationRule
* @typedef {Object} ObjectGuard
* @property {*} obj a view on the guarded object
* @property {function(): void} verify a function that checks for and rolls back disallowed changes to the guarded object
Expand Down
4 changes: 4 additions & 0 deletions libraries/objectGuard/ortbGuard.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import {
import {objectGuard, writeProtectRule} from './objectGuard.js';
import {mergeDeep} from '../../src/utils.js';

/**
* @typedef {import('./objectGuard.js').ObjectGuard} ObjectGuard
*/

function ortb2EnrichRules(isAllowed = isActivityAllowed) {
return [
{
Expand Down
63 changes: 63 additions & 0 deletions libraries/percentInView/percentInView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

function getBoundingBox(element, {w, h} = {}) {
let {width, height, left, top, right, bottom} = element.getBoundingClientRect();

if ((width === 0 || height === 0) && w && h) {
width = w;
height = h;
right = left + w;
bottom = top + h;
}

return {width, height, left, top, right, bottom};
}

function getIntersectionOfRects(rects) {
const bbox = {
left: rects[0].left, right: rects[0].right, top: rects[0].top, bottom: rects[0].bottom
};

for (let i = 1; i < rects.length; ++i) {
bbox.left = Math.max(bbox.left, rects[i].left);
bbox.right = Math.min(bbox.right, rects[i].right);

if (bbox.left >= bbox.right) {
return null;
}

bbox.top = Math.max(bbox.top, rects[i].top);
bbox.bottom = Math.min(bbox.bottom, rects[i].bottom);

if (bbox.top >= bbox.bottom) {
return null;
}
}

bbox.width = bbox.right - bbox.left;
bbox.height = bbox.bottom - bbox.top;

return bbox;
}

export const percentInView = (element, topWin, {w, h} = {}) => {
const elementBoundingBox = getBoundingBox(element, {w, h});

// Obtain the intersection of the element and the viewport
const elementInViewBoundingBox = getIntersectionOfRects([{
left: 0, top: 0, right: topWin.innerWidth, bottom: topWin.innerHeight
}, elementBoundingBox]);

let elementInViewArea, elementTotalArea;

if (elementInViewBoundingBox !== null) {
// Some or all of the element is in view
elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height;
elementTotalArea = elementBoundingBox.width * elementBoundingBox.height;

return ((elementInViewArea / elementTotalArea) * 100);
}

// No overlap between element and the viewport; therefore, the element
// lies completely out of view
return 0;
}
1 change: 1 addition & 0 deletions libraries/video/shared/parentModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export function ParentModule(submoduleBuilder_) {
}

/**
* @typedef {import('../../../modules/videoModule/coreVideo.js').vendorSubmoduleDirectory} vendorSubmoduleDirectory
* @typedef {Object} SubmoduleBuilder
* @summary Instantiates submodules
* @param {vendorSubmoduleDirectory} submoduleDirectory_
Expand Down
4 changes: 2 additions & 2 deletions modules/33acrossIdSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pbjs.setConfig({
storage: {
name: "33acrossId",
type: "html5",
expires: 90,
expires: 30,
refreshInSeconds: 8*3600
},
params: {
Expand All @@ -41,7 +41,7 @@ The following settings are available for the `storage` property in the `userSync
| --- | --- | --- | --- | --- |
| name | Required | String| Name of the cookie or HTML5 local storage where the user ID will be stored | `"33acrossId"` |
| type | Required | String | `"html5"` (preferred) or `"cookie"` | `"html5"` |
| expires | Strongly Recommended | Number | How long (in days) the user ID information will be stored. 33Across recommends `90`. | `90` |
| expires | Strongly Recommended | Number | How long (in days) the user ID information will be stored. 33Across recommends `30`. | `30` |
| refreshInSeconds | Strongly Recommended | Number | The interval (in seconds) for refreshing the user ID. 33Across recommends no more than 8 hours between refreshes. | `8*3600` |

### Params
Expand Down
204 changes: 204 additions & 0 deletions modules/BTBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { deepSetValue, isPlainObject, logWarn } from '../src/utils.js';
import { BANNER } from '../src/mediaTypes.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js';

const BIDDER_CODE = 'blockthrough';
const GVLID = 815;
const ENDPOINT_URL = 'https://pbs.btloader.com/openrtb2/auction';
const SYNC_URL = 'https://cdn.btloader.com/user_sync.html';

const CONVERTER = ortbConverter({
context: {
netRevenue: true,
ttl: 60,
},
imp,
request,
bidResponse,
});

/**
* Builds an impression object for the ORTB 2.5 request.
*
* @param {function} buildImp - The function for building an imp object.
* @param {Object} bidRequest - The bid request object.
* @param {Object} context - The context object.
* @returns {Object} The ORTB 2.5 imp object.
*/
function imp(buildImp, bidRequest, context) {
const imp = buildImp(bidRequest, context);
const { params, ortb2Imp } = bidRequest;

if (params) {
deepSetValue(imp, 'ext', params);
}
if (ortb2Imp?.ext?.gpid) {
deepSetValue(imp, 'ext.gpid', ortb2Imp.ext.gpid);
}

return imp;
}

/**
* Builds a request object for the ORTB 2.5 request.
*
* @param {function} buildRequest - The function for building a request object.
* @param {Array} imps - An array of ORTB 2.5 impression objects.
* @param {Object} bidderRequest - The bidder request object.
* @param {Object} context - The context object.
* @returns {Object} The ORTB 2.5 request object.
*/
function request(buildRequest, imps, bidderRequest, context) {
const request = buildRequest(imps, bidderRequest, context);
deepSetValue(request, 'ext.prebid.channel', {
name: 'pbjs',
version: '$prebid.version$',
});

if (window.location.href.includes('btServerTest=true')) {
request.test = 1;
}

return request;
}

/**
* Processes a bid response using the provided build function, bid, and context.
*
* @param {Function} buildBidResponse - The function to build the bid response.
* @param {Object} bid - The bid object to include in the bid response.
* @param {Object} context - The context object containing additional information.
* @returns {Object} - The processed bid response.
*/
function bidResponse(buildBidResponse, bid, context) {
const bidResponse = buildBidResponse(bid, context);
const { seat } = context.seatbid || {};
bidResponse.btBidderCode = seat;

return bidResponse;
}

/**
* Checks if a bid request is valid.
*
* @param {Object} bid - The bid request object.
* @returns {boolean} True if the bid request is valid, false otherwise.
*/
function isBidRequestValid(bid) {
if (!isPlainObject(bid.params) || !Object.keys(bid.params).length) {
logWarn('BT Bid Adapter: bid params must be provided.');
return false;
}

return true;
}

/**
* Builds the bid requests for the BT Service.
*
* @param {Array} validBidRequests - An array of valid bid request objects.
* @param {Object} bidderRequest - The bidder request object.
* @returns {Array} An array of BT Service bid requests.
*/
function buildRequests(validBidRequests, bidderRequest) {
const data = CONVERTER.toORTB({
bidRequests: validBidRequests,
bidderRequest,
});

return [
{
method: 'POST',
url: ENDPOINT_URL,
data,
bids: validBidRequests,
},
];
}

/**
* Interprets the server response and maps it to bids.
*
* @param {Object} serverResponse - The server response object.
* @param {Object} request - The request object.
* @returns {Array} An array of bid objects.
*/
function interpretResponse(serverResponse, request) {
if (!serverResponse || !request) {
return [];
}

return CONVERTER.fromORTB({
response: serverResponse.body,
request: request.data,
}).bids;
}

/**
* Generates user synchronization data based on provided options and consents.
*
* @param {Object} syncOptions - Synchronization options.
* @param {Object[]} serverResponses - An array of server responses.
* @param {Object} gdprConsent - GDPR consent information.
* @param {string} uspConsent - US Privacy consent string.
* @param {Object} gppConsent - Google Publisher Policies (GPP) consent information.
* @returns {Object[]} An array of user synchronization objects.
*/
function getUserSyncs(
syncOptions,
serverResponses,
gdprConsent,
uspConsent,
gppConsent
) {
if (!syncOptions.iframeEnabled || !serverResponses?.length) {
return [];
}

const bidderCodes = new Set();
serverResponses.forEach((serverResponse) => {
if (serverResponse?.body?.ext?.responsetimemillis) {
Object.keys(serverResponse.body.ext.responsetimemillis).forEach(
bidderCodes.add,
bidderCodes
);
}
});

if (!bidderCodes.size) {
return [];
}

const syncs = [];
const syncUrl = new URL(SYNC_URL);
syncUrl.searchParams.set('bidders', [...bidderCodes].join(','));

if (gdprConsent) {
syncUrl.searchParams.set('gdpr', Number(gdprConsent.gdprApplies));
syncUrl.searchParams.set('gdpr_consent', gdprConsent.consentString);
}
if (gppConsent) {
syncUrl.searchParams.set('gpp', gppConsent.gppString);
syncUrl.searchParams.set('gpp_sid', gppConsent.applicableSections);
}
if (uspConsent) {
syncUrl.searchParams.set('us_privacy', uspConsent);
}

syncs.push({ type: 'iframe', url: syncUrl.href });

return syncs;
}

export const spec = {
code: BIDDER_CODE,
gvlid: GVLID,
supportedMediaTypes: [BANNER],
isBidRequestValid,
buildRequests,
interpretResponse,
getUserSyncs,
};

registerBidder(spec);
Loading

0 comments on commit 2dc6ce6

Please sign in to comment.