Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bliink Bid Adapter: enhance request data with eids, bidFloor, device info & domLoadingDuration #10499

Merged
merged 4 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 63 additions & 13 deletions modules/bliinkBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// eslint-disable-next-line prebid/validate-imports
import { registerBidder } from '../src/adapters/bidderFactory.js'
import { config } from '../src/config.js'
import {_each, deepAccess, deepSetValue} from '../src/utils.js'
import { _each, deepAccess, deepSetValue, getWindowSelf, getWindowTop } from '../src/utils.js'
export const BIDDER_CODE = 'bliink'
export const BLIINK_ENDPOINT_ENGINE = 'https://engine.bliink.io/prebid'

Expand All @@ -15,6 +15,7 @@ const BANNER = 'banner'
window.bliinkBid = window.bliinkBid || {};
const supportedMediaTypes = [BANNER, VIDEO]
const aliasBidderCode = ['bk']
const CURRENCY = 'EUR';

/**
* @description get coppa value from config
Expand Down Expand Up @@ -49,9 +50,8 @@ export function getEffectiveConnectionType() {
*/
export function getUserIds(validBidRequests) {
/** @type {Object} */
const firstBidRequest = validBidRequests?.[0]
if (firstBidRequest?.userIds) {
return firstBidRequest.userIds
if (validBidRequests?.[0]?.userIdAsEids) {
return validBidRequests[0].userIdAsEids;
}
}
export function getMetaList(name) {
Expand Down Expand Up @@ -122,6 +122,35 @@ export function getKeywords() {
return [];
}

function canAccessTopWindow() {
try {
if (getWindowTop().location.href) {
return true;
}
} catch (error) {
return false;
}
}

/**
* domLoading feature is computed on window.top if reachable.
*/
export function getDomLoadingDuration() {
let domLoadingDuration = -1;
let performance;

performance = (canAccessTopWindow()) ? getWindowTop().performance : getWindowSelf().performance;

if (performance && performance.timing && performance.timing.navigationStart > 0) {
const val = performance.timing.domLoading - performance.timing.navigationStart;
if (val > 0) {
domLoadingDuration = val;
}
}

return domLoadingDuration;
}

/**
* @param bidRequest
* @return {({cpm, netRevenue: boolean, requestId, width: number, currency, ttl: number, creativeId, height: number}&{mediaType: string, vastXml})|null}
Expand Down Expand Up @@ -151,7 +180,7 @@ export const buildBid = (bidResponse) => {
}
return Object.assign(bid, {
cpm: bidResponse.price,
currency: bidResponse.currency || 'EUR',
currency: bidResponse.currency || CURRENCY,
creativeId: deepAccess(bidResponse, 'extras.deal_id'),
requestId: deepAccess(bidResponse, 'extras.transaction_id'),
width: deepAccess(bidResponse, `creative.${bid.mediaType}.width`) || 1,
Expand Down Expand Up @@ -180,37 +209,58 @@ export const isBidRequestValid = (bid) => {
*/
export const buildRequests = (validBidRequests, bidderRequest) => {
if (!validBidRequests || !bidderRequest || !bidderRequest.bids) return null

const domLoadingDuration = getDomLoadingDuration().toString();
const tags = bidderRequest.bids.map((bid) => {
let bidFloor;
const sizes = bid.sizes.map((size) => ({ w: size[0], h: size[1] }));
const mediaTypes = Object.keys(bid.mediaTypes)
if (typeof bid.getFloor === 'function') {
bidFloor = bid.getFloor({
currency: CURRENCY,
mediaType: mediaTypes[0],
size: sizes[0]
Comment on lines +220 to +221
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but will not support multi format bid requests

});
}
const id = bid.params.tagId
return {
const request = {
sizes: bid.sizes.map((size) => ({ w: size[0], h: size[1] })),
id,
// TODO: bidId is globally unique, is it a good choice for transaction ID (vs ortb2Imp.ext.tid)?
transactionId: bid.bidId,
mediaTypes: Object.keys(bid.mediaTypes),
mediaTypes: mediaTypes,
imageUrl: deepAccess(bid, 'params.imageUrl', ''),
videoUrl: deepAccess(bid, 'params.videoUrl', ''),
refresh: (window.bliinkBid[id] = (window.bliinkBid[id] ?? -1) + 1) || undefined,
};
}
if (bidFloor) {
request.bidFloor = bidFloor
}
return request;
});

let request = {
tags,
pageTitle: document.title,
pageUrl: deepAccess(bidderRequest, 'refererInfo.page'),
pageUrl: deepAccess(bidderRequest, 'refererInfo.page').replace(/\?.*$/, ''),
pageDescription: getMetaValue(META_DESCRIPTION),
keywords: getKeywords().join(','),
ect: getEffectiveConnectionType(),
};

const schain = deepAccess(validBidRequests[0], 'schain')
const userIds = getUserIds(validBidRequests)
const eids = getUserIds(validBidRequests)
const device = bidderRequest.ortb2?.device
if (schain) {
request.schain = schain
}
if (userIds) {
request.userIds = userIds
if (domLoadingDuration > -1) {
request.domLoadingDuration = domLoadingDuration
}
if (device) {
request.device = device
}
if (eids) {
request.eids = eids
}
const gdprConsent = deepAccess(bidderRequest, 'gdprConsent');
if (!!gdprConsent && gdprConsent.gdprApplies) {
Expand Down
98 changes: 79 additions & 19 deletions test/spec/modules/bliinkBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
BLIINK_ENDPOINT_COOKIE_SYNC_IFRAME,
getEffectiveConnectionType,
getUserIds,
getDomLoadingDuration,
} from 'modules/bliinkBidAdapter.js';
import { config } from 'src/config.js';

Expand All @@ -31,6 +32,7 @@ import { config } from 'src/config.js';
*/

const connectionType = getEffectiveConnectionType();
const domLoadingDuration = getDomLoadingDuration().toString();
const getConfigBid = (placement) => {
return {
adUnitCode: '/19968336/test',
Expand All @@ -57,6 +59,7 @@ const getConfigBid = (placement) => {
},
},
},
domLoadingDuration,
ect: connectionType,
params: {
placement: placement,
Expand Down Expand Up @@ -348,11 +351,31 @@ const GetUserIds = [
want: undefined,
},
{
title: 'Should return userIds if exists',
title: 'Should return eids if exists',
args: {
fn: getUserIds([{ userIds: { criteoId: 'testId' } }]),
fn: getUserIds([{ userIdAsEids: [
{
'source': 'criteo.com',
'uids': [
{
'id': 'testId',
'atype': 1
}
]
}
] }]),
},
want: { criteoId: 'testId' },
want: [
{
'source': 'criteo.com',
'uids': [
{
'id': 'testId',
'atype': 1
}
]
}
],
},
];

Expand Down Expand Up @@ -655,12 +678,13 @@ const testsBuildRequests = [
method: 'POST',
url: BLIINK_ENDPOINT_ENGINE,
data: {
domLoadingDuration,
ect: connectionType,
keywords: '',
pageDescription: '',
pageTitle: '',
pageUrl:
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html?pbjs_debug=true',
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html',
tags: [
{
transactionId: '2def0c5b2a7f6e',
Expand Down Expand Up @@ -697,14 +721,15 @@ const testsBuildRequests = [
method: 'POST',
url: BLIINK_ENDPOINT_ENGINE,
data: {
domLoadingDuration,
ect: connectionType,
gdpr: true,
gdprConsent: 'XXXX',
pageDescription: '',
pageTitle: '',
keywords: '',
pageUrl:
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html?pbjs_debug=true',
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html',
tags: [
{
transactionId: '2def0c5b2a7f6e',
Expand Down Expand Up @@ -742,6 +767,7 @@ const testsBuildRequests = [
method: 'POST',
url: BLIINK_ENDPOINT_ENGINE,
data: {
domLoadingDuration,
ect: connectionType,
gdpr: true,
uspConsent: 'uspConsent',
Expand All @@ -750,7 +776,7 @@ const testsBuildRequests = [
pageTitle: '',
keywords: '',
pageUrl:
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html?pbjs_debug=true',
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html',
tags: [
{
transactionId: '2def0c5b2a7f6e',
Expand Down Expand Up @@ -801,14 +827,15 @@ const testsBuildRequests = [
method: 'POST',
url: BLIINK_ENDPOINT_ENGINE,
data: {
domLoadingDuration,
ect: connectionType,
gdpr: true,
gdprConsent: 'XXXX',
pageDescription: '',
pageTitle: '',
keywords: '',
pageUrl:
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html?pbjs_debug=true',
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html',
schain: {
ver: '1.0',
complete: 1,
Expand Down Expand Up @@ -840,16 +867,31 @@ const testsBuildRequests = [
},
},
{
title: 'Should build request with userIds if exists',
title: 'Should build request with eids if exists',
args: {
fn: spec.buildRequests(
[
{
userIds: {
criteoId:
'vG4RRF93V05LRlJUTVVOQTJJJTJGbG1rZWxEeDVvc0NXWE42TzJqU2hG',
netId: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg',
},
userIdAsEids: [
{
'source': 'criteo.com',
'uids': [
{
'id': 'vG4RRF93V05LRlJUTVVOQTJJJTJGbG1rZWxEeDVvc0NXWE42TzJqU2hG',
'atype': 1
}
]
},
{
'source': 'netid.de',
'uids': [
{
'id': 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg',
'atype': 1
}
]
}
],
},
],
Object.assign(getConfigBuildRequest('banner'), {
Expand All @@ -864,18 +906,35 @@ const testsBuildRequests = [
method: 'POST',
url: BLIINK_ENDPOINT_ENGINE,
data: {
domLoadingDuration,
ect: connectionType,
gdpr: true,
gdprConsent: 'XXXX',
pageDescription: '',
pageTitle: '',
keywords: '',
pageUrl:
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html?pbjs_debug=true',
userIds: {
criteoId: 'vG4RRF93V05LRlJUTVVOQTJJJTJGbG1rZWxEeDVvc0NXWE42TzJqU2hG',
netId: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg',
},
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html',
eids: [
{
'source': 'criteo.com',
'uids': [
{
'id': 'vG4RRF93V05LRlJUTVVOQTJJJTJGbG1rZWxEeDVvc0NXWE42TzJqU2hG',
'atype': 1
}
]
},
{
'source': 'netid.de',
'uids': [
{
'id': 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg',
'atype': 1
}
]
}
],
tags: [
{
transactionId: '2def0c5b2a7f6e',
Expand Down Expand Up @@ -1053,6 +1112,7 @@ describe('BLIINK Adapter keywords & coppa true', function () {
method: 'POST',
url: BLIINK_ENDPOINT_ENGINE,
data: {
domLoadingDuration,
ect: connectionType,
gdpr: true,
coppa: 1,
Expand All @@ -1061,7 +1121,7 @@ describe('BLIINK Adapter keywords & coppa true', function () {
pageTitle: '',
keywords: 'Bliink,Saber,Prebid',
pageUrl:
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html?pbjs_debug=true',
'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html',
tags: [
{
transactionId: '2def0c5b2a7f6e',
Expand Down