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

Medianet Bid Adapter: passing uidsAsEids in adapter and log refactor #11924

Merged
merged 2 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
148 changes: 108 additions & 40 deletions modules/medianetBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import {
buildUrl,
deepAccess,
formatQS,
getWindowTop,
isArray,
isEmpty,
isEmptyStr,
isStr,
logError,
logInfo,
triggerPixel
safeJSONEncode,
deepClone,
deepSetValue
} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {config} from '../src/config.js';
Expand All @@ -18,6 +20,7 @@ import {Renderer} from '../src/Renderer.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import {getGlobal} from '../src/prebidGlobal.js';
import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
import {ajax} from '../src/ajax.js';

/**
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
Expand All @@ -35,27 +38,20 @@ const SLOT_VISIBILITY = {
ABOVE_THE_FOLD: 1,
BELOW_THE_FOLD: 2
};
const EVENTS = {
export const EVENTS = {
TIMEOUT_EVENT_NAME: 'client_timeout',
BID_WON_EVENT_NAME: 'client_bid_won'
BID_WON_EVENT_NAME: 'client_bid_won',
SET_TARGETING: 'client_set_targeting',
BIDDER_ERROR: 'client_bidder_error'
};
const EVENT_PIXEL_URL = 'qsearch-a.akamaihd.net/log';
export const EVENT_PIXEL_URL = 'https://navvy.media.net/log';
const OUTSTREAM = 'outstream';

// TODO: this should be picked from bidderRequest
let refererInfo = getRefererInfo();

let mnData = {};
let pageMeta;

window.mnet = window.mnet || {};
window.mnet.queue = window.mnet.queue || [];

mnData.urlData = {
domain: refererInfo.domain,
page: refererInfo.page,
isTop: refererInfo.reachedTop
};

const aliases = [
{ code: TRUSTEDSTACK_CODE, gvlid: 1288 },
];
Expand Down Expand Up @@ -85,20 +81,20 @@ function siteDetails(site, bidderRequest) {
}

function getPageMeta() {
if (mnData.pageMeta) {
return mnData.pageMeta;
if (pageMeta) {
return pageMeta;
}
let canonicalUrl = getUrlFromSelector('link[rel="canonical"]', 'href');
let ogUrl = getUrlFromSelector('meta[property="og:url"]', 'content');
let twitterUrl = getUrlFromSelector('meta[name="twitter:url"]', 'content');

mnData.pageMeta = Object.assign({},
pageMeta = Object.assign({},
canonicalUrl && { 'canonical_url': canonicalUrl },
ogUrl && { 'og_url': ogUrl },
twitterUrl && { 'twitter_url': twitterUrl }
);

return mnData.pageMeta;
return pageMeta;
}

function getUrlFromSelector(selector, attribute) {
Expand Down Expand Up @@ -338,14 +334,23 @@ function getBidderURL(bidderCode, cid) {
return url + '?cid=' + encodeURIComponent(cid);
}

function ortb2Data(ortb2, bidRequests) {
const ortb2Object = deepClone(ortb2);
const eids = deepAccess(bidRequests, '0.userIdAsEids');
if (eids) {
deepSetValue(ortb2Object, 'user.ext.eids', eids)
}
return ortb2Object;
}

function generatePayload(bidRequests, bidderRequests) {
return {
site: siteDetails(bidRequests[0].params.site, bidderRequests),
ext: extParams(bidRequests[0], bidderRequests),
// TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781
id: bidRequests[0].auctionId,
imp: bidRequests.map(request => slotParams(request, bidderRequests)),
ortb2: bidderRequests.ortb2,
ortb2: ortb2Data(bidderRequests.ortb2, bidRequests),
tmax: bidderRequests.timeout
}
}
Expand All @@ -363,38 +368,78 @@ function fetchCookieSyncUrls(response) {
return [];
}

function getLoggingData(event, data) {
data = (isArray(data) && data) || [];

let params = {};
function getEventData(event) {
const params = {};
const referrerInfo = getRefererInfo();
params.logid = 'kfk';
params.evtid = 'projectevents';
params.project = 'prebid';
params.acid = deepAccess(data, '0.auctionId') || '';
params.pbver = '$prebid.version$';
params.cid = getGlobal().medianetGlobals.cid || '';
params.crid = data.map((adunit) => deepAccess(adunit, 'params.0.crid') || adunit.adUnitCode).join('|');
params.adunit_count = data.length || 0;
params.dn = mnData.urlData.domain || '';
params.requrl = mnData.urlData.page || '';
params.istop = mnData.urlData.isTop || '';
params.dn = encodeURIComponent(referrerInfo.domain || '');
params.requrl = encodeURIComponent(referrerInfo.page || '');
params.event = event.name || '';
params.value = event.value || '';
params.rd = event.related_data || '';
return params;
}

function getBidData(bid) {
const params = {};
params.acid = bid.auctionId || '';
params.crid = deepAccess(bid, 'params.crid') || deepAccess(bid, 'params.0.crid') || bid.adUnitCode || '';
params.ext = safeJSONEncode(bid.ext) || '';

const rawobj = deepClone(bid);
delete rawobj.ad;
delete rawobj.vastXml;
params.rawobj = safeJSONEncode(rawobj);
return params;
}

function logEvent (event, data) {
let getParams = {
protocol: 'https',
hostname: EVENT_PIXEL_URL,
search: getLoggingData(event, data)
};
triggerPixel(buildUrl(getParams));
function getLoggingData(event, bids) {
const logData = {};
bids.forEach?.((bid) => {
let bidData = getBidData(bid);
Object.keys(bidData).forEach((key) => {
logData[key] = logData[key] || [];
logData[key].push(encodeURIComponent(bidData[key]));
});
});
return Object.assign({}, getEventData(event), logData)
}

function firePostLog(url, payload) {
try {
const isSent = window.navigator.sendBeacon(url, payload);
Copy link
Collaborator

Choose a reason for hiding this comment

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

We require our methods for network traffic

Copy link
Contributor

Choose a reason for hiding this comment

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

We have removed sendBeacon() for now since Prebid doesn't currently support it. We suggest adding sendBeacon() to Prebid, as it is the most reliable for analytics use cases, as mentioned in https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon .

Copy link
Collaborator

Choose a reason for hiding this comment

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

fetch keepalive is better :) but firefox is still working on adding support

if (!isSent) {
fireAjaxLog(url, payload);
}
} catch (e) {
fireAjaxLog(url, payload);
}
}

function fireAjaxLog(url, payload) {
ajax(url,
{
success: () => undefined,
error: () => undefined
},
payload,
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about the keepalive option?

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense, have added the same.

{
method: 'POST'
}
);
}

function logEvent(event, data) {
const logData = getLoggingData(event, data);
firePostLog(EVENT_PIXEL_URL, formatQS(logData));
}

function clearMnData() {
mnData = {};
function clearPageMeta() {
pageMeta = undefined;
}

function addRenderer(bid) {
Expand Down Expand Up @@ -550,7 +595,30 @@ export const spec = {
} catch (e) {}
},

clearMnData,
onSetTargeting: (bid) => {
try {
let eventData = {
name: EVENTS.SET_TARGETING,
value: bid.cpm
};
const enableSendAllBids = config.getConfig('enableSendAllBids');
if (!enableSendAllBids) {
logEvent(eventData, [bid]);
}
} catch (e) {}
},

onBidderError: ({error, bidderRequest}) => {
try {
let eventData = {
name: EVENTS.BIDDER_ERROR,
related_data: `timedOut:${error.timedOut}|status:${error.status}|message:${error.reason.message}`
};
logEvent(eventData, bidderRequest.bids);
} catch (e) {}
},

clearPageMeta,

getWindowSize,
};
Expand Down
8 changes: 8 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,14 @@ export function safeJSONParse(data) {
} catch (e) {}
}

export function safeJSONEncode(data) {
try {
return JSON.stringify(data);
} catch (e) {
return '';
}
}

/**
* Returns a memoized version of `fn`.
*
Expand Down
Loading
Loading