Skip to content

Commit

Permalink
Brid Bid Adapter: getUserSyncs method and interpretResponse updates
Browse files Browse the repository at this point in the history
  • Loading branch information
grajzer committed Sep 17, 2024
1 parent d55be7c commit f3cd067
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 94 deletions.
2 changes: 2 additions & 0 deletions libraries/targetVideoUtils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const BIDDER_CODE = 'targetVideo';
const TIME_TO_LIVE = 300;
const BANNER_ENDPOINT_URL = 'https://ib.adnxs.com/ut/v3/prebid';
const VIDEO_ENDPOINT_URL = 'https://pbs.prebrid.tv/openrtb2/auction';
const SYNC_URL = 'https://bppb.link/static/';
const VIDEO_PARAMS = [
'api', 'linearity', 'maxduration', 'mimes', 'minduration',
'plcmt', 'playbackmethod', 'protocols', 'startdelay'
Expand All @@ -16,6 +17,7 @@ export {
GVLID,
MARGIN,
BIDDER_CODE,
SYNC_URL,
TIME_TO_LIVE,
BANNER_ENDPOINT_URL,
VIDEO_ENDPOINT_URL,
Expand Down
175 changes: 81 additions & 94 deletions modules/bridBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
import {_each, deepAccess, getDefinedParams, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js';
import {_each, deepAccess, formatQS, getDefinedParams, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js';
import {VIDEO} from '../src/mediaTypes.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {getAd, getSiteObj} from '../libraries/targetVideoUtils/bidderUtils.js'
import {GVLID, SOURCE, SYNC_URL, TIME_TO_LIVE, VIDEO_ENDPOINT_URL, VIDEO_PARAMS} from '../libraries/targetVideoUtils/constants.js';

/**
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
* @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid
* @typedef {import('../src/adapters/bidderFactory.js').BidderRequest} BidderRequest
*/

const SOURCE = 'pbjs';
const BIDDER_CODE = 'brid';
const ENDPOINT_URL = 'https://pbs.prebrid.tv/openrtb2/auction';
const GVLID = 934;
const TIME_TO_LIVE = 300;
const VIDEO_PARAMS = [
'api', 'linearity', 'maxduration', 'mimes', 'minduration', 'plcmt',
'playbackmethod', 'protocols', 'startdelay'
];

export const spec = {

code: BIDDER_CODE,
code: 'brid',
gvlid: GVLID,
supportedMediaTypes: [VIDEO],

Expand Down Expand Up @@ -117,7 +107,7 @@ export const spec = {

requests.push({
method: 'POST',
url: ENDPOINT_URL,
url: VIDEO_ENDPOINT_URL,
data: JSON.stringify(postBody),
options: {
withCredentials: true
Expand All @@ -138,92 +128,89 @@ export const spec = {
*/
interpretResponse: function(serverResponse, bidRequest) {
const response = serverResponse.body;
const bidResponses = [];

_each(response.seatbid, (resp) => {
_each(resp.bid, (bid) => {
const requestId = bidRequest.bidId;
const params = bidRequest.params;

const {ad, adUrl, vastUrl, vastXml} = getAd(bid);

const bidResponse = {
requestId,
params,
cpm: bid.price,
width: bid.w,
height: bid.h,
creativeId: bid.adid,
currency: response.cur,
netRevenue: false,
ttl: TIME_TO_LIVE,
meta: {
advertiserDomains: bid.adomain || []
}
};
let highestBid = null;

if (response && response.seatbid && response.seatbid.length && response.seatbid[0].bid && response.seatbid[0].bid.length) {
_each(response.seatbid, (resp) => {
_each(resp.bid, (bid) => {
const requestId = bidRequest.bidId;
const params = bidRequest.params;

const {ad, adUrl, vastUrl, vastXml} = getAd(bid);

const bidResponse = {
requestId,
params,
cpm: bid.price,
width: bid.w,
height: bid.h,
creativeId: bid.crid || bid.adid,
currency: response.cur,
netRevenue: false,
ttl: TIME_TO_LIVE,
meta: {
advertiserDomains: bid.adomain || []
}
};

if (vastUrl || vastXml) {
bidResponse.mediaType = VIDEO;
if (vastUrl) bidResponse.vastUrl = vastUrl;
if (vastXml) bidResponse.vastXml = vastXml;
} else {
bidResponse.ad = ad;
bidResponse.adUrl = adUrl;
};
if (vastUrl || vastXml) {
bidResponse.mediaType = VIDEO;
if (vastUrl) bidResponse.vastUrl = vastUrl;
if (vastXml) bidResponse.vastXml = vastXml;
} else {
bidResponse.ad = ad;
bidResponse.adUrl = adUrl;
};

bidResponses.push(bidResponse);
if (!highestBid || highestBid.cpm < bidResponse.cpm) {
highestBid = bidResponse;
}
});
});
});
}

return bidResponses;
return highestBid ? [highestBid] : [];
},

}
/**
* Determine the user sync type (either 'iframe' or 'image') based on syncOptions.
* Construct the sync URL by appending required query parameters such as gdpr, ccpa, and coppa consents.
* Return an array containing an object with the sync type and the constructed URL.
*/
getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => {
const params = {
endpoint: 'brid'
};

// Attaching GDPR Consent Params in UserSync url
if (gdprConsent) {
params.gdpr = (gdprConsent.gdprApplies ? 1 : 0);
params.gdpr_consent = encodeURIComponent(gdprConsent.consentString || '');
}

// CCPA
if (uspConsent && typeof uspConsent === 'string') {
params.us_privacy = encodeURIComponent(uspConsent);
}

// GPP Consent
if (gppConsent?.gppString && gppConsent?.applicableSections?.length) {
params.gpp = encodeURIComponent(gppConsent.gppString);
params.gpp_sid = encodeURIComponent(gppConsent?.applicableSections?.join(','));
}

const queryParams = Object.keys(params).length > 0 ? formatQS(params) : '';
let response = [];
if (syncOptions.iframeEnabled) {
response = [{
type: 'iframe',
url: SYNC_URL + 'load-cookie.html?' + queryParams
}];
}

return response;
}

// /**
// * Helper function to get ad
// *
// * @param {object} bid The bid.
// * @return {object} ad object.
// */
// function getAd(bid) {
// let ad, adUrl, vastXml, vastUrl;

// switch (deepAccess(bid, 'ext.prebid.type')) {
// case VIDEO:
// if (bid.adm.substr(0, 4) === 'http') {
// vastUrl = bid.adm;
// } else {
// vastXml = bid.adm;
// };
// break;
// default:
// if (bid.adm && bid.nurl) {
// ad = bid.adm;
// ad += createTrackPixelHtml(decodeURIComponent(bid.nurl));
// } else if (bid.adm) {
// ad = bid.adm;
// } else if (bid.nurl) {
// adUrl = bid.nurl;
// };
// }

// return {ad, adUrl, vastXml, vastUrl};
// }

// /**
// * Helper function to get site object
// *
// * @return {object} siteObj.
// */
// function getSiteObj() {
// const refInfo = (getRefererInfo && getRefererInfo()) || {};

// return {
// page: refInfo.page,
// ref: refInfo.ref,
// domain: refInfo.domain
// };
// }
}

registerBidder(spec);
20 changes: 20 additions & 0 deletions test/spec/modules/bridBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { spec } from '../../../modules/bridBidAdapter.js'
import { SYNC_URL } from '../../../libraries/targetVideoUtils/constants.js';

describe('Brid Bid Adapter', function() {
const videoRequest = [{
Expand Down Expand Up @@ -126,4 +127,23 @@ describe('Brid Bid Adapter', function() {
expect(payload.regs.ext.gdpr).to.be.undefined;
expect(payload.regs.ext.us_privacy).to.equal(uspConsentString);
});

it('Test userSync have only one object and it should have a property type=iframe', function () {
let userSync = spec.getUserSyncs({ iframeEnabled: true });
expect(userSync).to.be.an('array');
expect(userSync.length).to.be.equal(1);
expect(userSync[0]).to.have.property('type');
expect(userSync[0].type).to.be.equal('iframe');
});

it('Test userSync valid sync url for iframe', function () {
let [userSync] = spec.getUserSyncs({ iframeEnabled: true }, {}, {consentString: 'anyString'});
expect(userSync.url).to.contain(SYNC_URL + 'load-cookie.html?endpoint=brid&gdpr=0&gdpr_consent=anyString')
expect(userSync.type).to.be.equal('iframe');
});

it('Test userSyncs iframeEnabled=false', function () {
let userSyncs = spec.getUserSyncs({iframeEnabled: false});
expect(userSyncs).to.have.lengthOf(0);
});
});

0 comments on commit f3cd067

Please sign in to comment.