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

Nexverse Bid Adapter : initial relese #12297

Merged
merged 20 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
126 changes: 126 additions & 0 deletions integrationExamples/gpt/nexverse.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<!--
This page calls a single bidder for a single ad slot. It can be considered a "hello world" example for using
Prebid with the Google Publisher Tag.
It also makes a good test page for new adapter PR submissions. Simply set your server's Bid Params object in the
bids array inside the adUnits, and it will use your adapter to load an ad.
NOTE that many ad servers won't send back an ad if the URL is localhost... so you might need to
set an alias in your /etc/hosts file so that you can load this page from a different domain.
-->

<html>

<head>
<title>NexVerse Prebid.Js Demo</title>
<script async src="../../build/dev/prebid.js"></script>
<script async src="https://www.googletagservices.com/tag/js/gpt.js"></script>
<script>
var FAILSAFE_TIMEOUT = 3300;
var PREBID_TIMEOUT = 1000;

var adUnits = [{
code: 'div-banner-native-1',
mediaTypes: {
banner: {
sizes: [[970, 90]],
}
},

// Replace this object to test a new Adapter!
bids: [{
bidder: 'nexverse',
params: {
uid: '77d4a2eb3d209ce6c7691dc79fcab358',
pubId: '24051',
pubEpid: '34561'
},
isDebug: false // Optional, i.e True for debug mode
}]

},{
code: 'div-banner-native-2',
mediaTypes: {
banner: {
sizes: [[300, 250]],
}
},

// Replace this object to test a new Adapter!
bids: [{
bidder: 'nexverse',
params: {
uid: '77d4a2eb3d209ce6c7691dc79fcab358',
pubId: '24051',
pubEpid: '34561'
},
isDebug: false // Optional, i.e True for debug mode
}]

}];

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];

</script>

<script>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function () {
googletag.pubads().disableInitialLoad();
});

pbjs.que.push(function () {
pbjs.addAdUnits(adUnits);

pbjs.requestBids({
bidsBackHandler: sendAdserverRequest,
timeout: PREBID_TIMEOUT
});
});

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>
googletag.cmd.push(function () {
googletag.defineSlot('/19968336/header-bid-tag-0', [[970, 90]], 'div-banner-native-1').addService(googletag.pubads());
googletag.defineSlot('/19968336/header-bid-tag-1', [[300, 250]], 'div-banner-native-2').addService(googletag.pubads());

googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
</head>

<body>
<h2>Nexverse Prebid.js Test</h2>
<h5>Div-1</h5>
<div id='div-banner-native-1'>
<script type='text/javascript'>
googletag.cmd.push(function () { googletag.display('div-banner-native-1'); });
</script>
</div>

<h5>Div-2</h5>
<div id='div-banner-native-2'>
<script type='text/javascript'>
googletag.cmd.push(function () { googletag.display('div-banner-native-2'); });
</script>
</div>
</body>

</html>
130 changes: 130 additions & 0 deletions libraries/nexverseUtils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { logError, logInfo, logWarn, generateUUID } from '../../src/utils.js';

const LOG_WARN_PREFIX = '[Nexverse warn]: ';
const LOG_ERROR_PREFIX = '[Nexverse error]: ';
const LOG_INFO_PREFIX = '[Nexverse info]: ';
const NEXVERSE_USER_COOKIE_KEY = 'user_nexverse';

/**
* Determines the device model (if possible).
* @returns {string} The device model or a fallback message if not identifiable.
*/
export function getDeviceModel() {
const ua = navigator.userAgent;
if (/iPhone/i.test(ua)) {
return 'iPhone';
} else if (/iPad/i.test(ua)) {
return 'iPad';
} else if (/Android/i.test(ua)) {
const match = ua.match(/Android.*;\s([a-zA-Z0-9\s]+)\sBuild/);
return match ? match[1].trim() : 'Unknown Android Device';
} else if (/Windows Phone/i.test(ua)) {
return 'Windows Phone';
} else if (/Macintosh/i.test(ua)) {
return 'Mac';
} else if (/Linux/i.test(ua)) {
return 'Linux';
} else if (/Windows/i.test(ua)) {
return 'Windows PC';
}
return '';
}

/**
* Prepapre the endpoint URL based on passed bid request.
* @param {string} bidderEndPoint - Bidder End Point.
* @param {object} bid - Bid details.
* @returns {string} The Endpoint URL with required parameters.
*/
export function buildEndpointUrl(bidderEndPoint, bid) {
const { uid, pubId, pubEpid } = bid.params;
const isDebug = bid.isDebug;
let endPoint = `${bidderEndPoint}?uid=${encodeURIComponent(uid)}&pub_id=${encodeURIComponent(pubId)}&pub_epid=${encodeURIComponent(pubEpid)}`;
if (isDebug) {
endPoint = `${endPoint}&test=1`;
}
return endPoint;
}
/**
* Validates the bid request to ensure all required parameters are present.
* @param {Object} bid - The bid request object.
* @returns {boolean} True if the bid request is valid, false otherwise.
*/
export function isBidRequestValid(bid) {
const isValid = !!(
bid.params &&
bid.params.uid && bid.params.uid.trim() &&
bid.params.pubId && bid.params.pubId.trim() &&
bid.params.pubEpid && bid.params.pubEpid.trim()
);
if (!isValid) {
logError(`${LOG_ERROR_PREFIX} Missing required bid parameters.`);
}

return isValid;
}

/**
* Parses the native response from the server into Prebid's native format.
*
* @param {string} adm - The adm field from the bid response (JSON string).
* @returns {Object} The parsed native response object.
*/
export function parseNativeResponse(adm) {
try {
const admObj = JSON.parse(adm);
return admObj.native;
} catch (e) {
printLog('error', `Error parsing native response: `, e)
logError(`${LOG_ERROR_PREFIX} Error parsing native response: `, e);
return {};
}
}

/**
* Parses the native response from the server into Prebid's native format.
* @param {type} type - Type of log. default is info
* @param {args} args - Log data.
*/
export function printLog(type, ...args) {
// Determine the prefix based on the log type
const prefixes = {
error: LOG_ERROR_PREFIX,
warning: LOG_WARN_PREFIX, // Assuming warning uses the same prefix as error
info: LOG_INFO_PREFIX
};

// Construct the log message by joining all arguments into a single string
const logMessage = args
.map(arg => (arg instanceof Error ? `${arg.name}: ${arg.message}` : arg))
.join(' '); // Join all arguments into a single string with a space separator
// Add prefix and punctuation (for info type)
const formattedMessage = `${prefixes[type] || LOG_INFO_PREFIX} ${logMessage}${type === 'info' ? '.' : ''}`;
// Map the log type to its corresponding log function
const logFunctions = {
error: logError,
warning: logWarn,
info: logInfo
};

// Call the appropriate log function (defaulting to logInfo)
(logFunctions[type] || logInfo)(formattedMessage);
}
/**
* Get or Create Uid for First Party Cookie
*/
export const getUid = (storage) => {
let nexverseUid = storage.getCookie(NEXVERSE_USER_COOKIE_KEY);
if (!nexverseUid) {
nexverseUid = generateUUID();
}
try {
const expirationInMs = 60 * 60 * 24 * 1000; // 1 day in milliseconds
const expirationTime = new Date(Date.now() + expirationInMs); // Set expiration time
// Set the cookie with the expiration date
storage.setCookie(NEXVERSE_USER_COOKIE_KEY, nexverseUid, expirationTime.toUTCString());
} catch (e) {
printLog('error', `Failed to set UID cookie: ${e.message}`);
}
return nexverseUid;
};
Loading
Loading