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

51Degrees RTD submodule: small improvements and fixes #12302

Merged
merged 4 commits into from
Oct 9, 2024
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
1 change: 1 addition & 0 deletions modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
],
"rtdModule": [
"1plusXRtdProvider",
"51DegreesRtdProvider",
"a1MediaRtdProvider",
"aaxBlockmeterRtdProvider",
"adagioRtdProvider",
Expand Down
130 changes: 95 additions & 35 deletions modules/51DegreesRtdProvider.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {loadExternalScript} from '../src/adloader.js';
import {submodule} from '../src/hook.js';
import {prefixLog, deepAccess, mergeDeep} from '../src/utils.js';
import {
deepAccess,
deepSetValue,
mergeDeep,
prefixLog,
} from '../src/utils.js';

const MODULE_NAME = '51Degrees';
export const LOG_PREFIX = `[${MODULE_NAME} RTD Submodule]:`;
Expand Down Expand Up @@ -48,17 +53,49 @@ const ORTB_DEVICE_TYPE_MAP = new Map([
*/
export const extractConfig = (moduleConfig, reqBidsConfigObj) => {
// Resource key
const resourceKey = deepAccess(moduleConfig, 'params.resourceKey');
let resourceKey = deepAccess(moduleConfig, 'params.resourceKey');
// On-premise JS URL
const onPremiseJSUrl = deepAccess(moduleConfig, 'params.onPremiseJSUrl');
let onPremiseJSUrl = deepAccess(moduleConfig, 'params.onPremiseJSUrl');

// Trim the values
if (typeof resourceKey === 'string') {
resourceKey = resourceKey.trim();
}
if (typeof onPremiseJSUrl === 'string') {
onPremiseJSUrl = onPremiseJSUrl.trim();
}

// If this module is configured via a 3rd party wrapper, both form inputs
// might be mandatory. To handle this, 0 can be used as a value to skip
// the parameter.
if (typeof resourceKey === 'string' && resourceKey.trim() === '0') {
resourceKey = undefined;
}
if (typeof onPremiseJSUrl === 'string' && onPremiseJSUrl.trim() === '0') {
onPremiseJSUrl = undefined;
}

// Verify that onPremiseJSUrl is a valid URL: either a full URL, relative
// path (/path/to/file.js), or a protocol-relative URL (//example.com/path/to/file.js)
if (typeof onPremiseJSUrl === 'string' && onPremiseJSUrl.length && !(
onPremiseJSUrl.startsWith('https://') ||
onPremiseJSUrl.startsWith('http://') ||
onPremiseJSUrl.startsWith('/'))
) {
throw new Error(LOG_PREFIX + ' Invalid URL format for onPremiseJSUrl in moduleConfig');
}

// Verify that one of the parameters is provided,
// but not both at the same time
if (!resourceKey && !onPremiseJSUrl) {
throw new Error(LOG_PREFIX + ' Missing parameter resourceKey or onPremiseJSUrl in moduleConfig');
} else if (resourceKey && onPremiseJSUrl) {
throw new Error(LOG_PREFIX + ' Only one of resourceKey or onPremiseJSUrl should be provided in moduleConfig');
}

// Verify that the resource key is not the one provided as an example
if (resourceKey === '<YOUR_RESOURCE_KEY>') {
throw new Error(LOG_PREFIX + ' replace <YOUR_RESOURCE_KEY> in configuration with a resource key obtained from https://configure.51degrees.com/tWrhNfY6');
throw new Error(LOG_PREFIX + ' replace <YOUR_RESOURCE_KEY> in configuration with a resource key obtained from https://configure.51degrees.com/HNZ75HT1');
}

return {resourceKey, onPremiseJSUrl};
Expand Down Expand Up @@ -112,33 +149,57 @@ export const is51DegreesMetaPresent = () => {
* @param {string} key The key to set
* @param {any} value The value to set
*/
export const setOrtb2KeyIfNotEmpty = (obj, key, value) => {
export const deepSetNotEmptyValue = (obj, key, value) => {
if (!key) {
throw new Error(LOG_PREFIX + ' Key is required');
}

if (value) {
obj[key] = value;
deepSetValue(obj, key, value);
}
}

/**
* Converts all 51Degrees data to ORTB2 format
*
* @param {Object} data51 Response from 51Degrees API
* @param {Object} [data51.device] Device data
*
* @returns {Object} Enriched ORTB2 object
*/
export const convert51DegreesDataToOrtb2 = (data51) => {
let ortb2Data = {};

if (!data51) {
return ortb2Data;
}

ortb2Data = convert51DegreesDeviceToOrtb2(data51.device);

// placeholder for the next 51Degrees RTD submodule update

return ortb2Data;
};

/**
* Converts 51Degrees device data to ORTB2 format
*
* @param {Object} device
* @param {Object} device 51Degrees device object
* @param {string} [device.deviceid] Device ID (unique 51Degrees identifier)
* @param {string} [device.devicetype]
* @param {string} [device.hardwarevendor]
* @param {string} [device.hardwaremodel]
* @param {string[]} [device.hardwarename]
* @param {string} [device.platformname]
* @param {string} [device.platformversion]
* @param {number} [device.screenpixelsheight]
* @param {number} [device.screenpixelswidth]
* @param {number} [device.pixelratio]
* @param {number} [device.screeninchesheight]
* @param {string} [device.devicetype] Device type
* @param {string} [device.hardwarevendor] Hardware vendor
* @param {string} [device.hardwaremodel] Hardware model
* @param {string[]} [device.hardwarename] Hardware name
* @param {string} [device.platformname] Platform name
* @param {string} [device.platformversion] Platform version
* @param {number} [device.screenpixelsheight] Screen height in pixels
* @param {number} [device.screenpixelswidth] Screen width in pixels
* @param {number} [device.screenpixelsphysicalheight] Screen physical height in pixels
* @param {number} [device.screenpixelsphysicalwidth] Screen physical width in pixels
* @param {number} [device.pixelratio] Pixel ratio
* @param {number} [device.screeninchesheight] Screen height in inches
*
* @returns {Object}
* @returns {Object} Enriched ORTB2 object
*/
export const convert51DegreesDeviceToOrtb2 = (device) => {
const ortb2Device = {};
Expand All @@ -154,27 +215,26 @@ export const convert51DegreesDeviceToOrtb2 = (device) => {
: null
);

const devicePhysicalPPI = device.screenpixelsphysicalheight && device.screeninchesheight
? Math.round(device.screenpixelsphysicalheight / device.screeninchesheight)
: null;

const devicePPI = device.screenpixelsheight && device.screeninchesheight
? Math.round(device.screenpixelsheight / device.screeninchesheight)
: null;

setOrtb2KeyIfNotEmpty(ortb2Device, 'devicetype', ORTB_DEVICE_TYPE_MAP.get(device.devicetype));
setOrtb2KeyIfNotEmpty(ortb2Device, 'make', device.hardwarevendor);
setOrtb2KeyIfNotEmpty(ortb2Device, 'model', deviceModel);
setOrtb2KeyIfNotEmpty(ortb2Device, 'os', device.platformname);
setOrtb2KeyIfNotEmpty(ortb2Device, 'osv', device.platformversion);
setOrtb2KeyIfNotEmpty(ortb2Device, 'h', device.screenpixelsheight);
setOrtb2KeyIfNotEmpty(ortb2Device, 'w', device.screenpixelswidth);
setOrtb2KeyIfNotEmpty(ortb2Device, 'pxratio', device.pixelratio);
setOrtb2KeyIfNotEmpty(ortb2Device, 'ppi', devicePPI);

if (device.deviceid) {
ortb2Device.ext = {
'fiftyonedegrees_deviceId': device.deviceid
};
}
deepSetNotEmptyValue(ortb2Device, 'devicetype', ORTB_DEVICE_TYPE_MAP.get(device.devicetype));
deepSetNotEmptyValue(ortb2Device, 'make', device.hardwarevendor);
deepSetNotEmptyValue(ortb2Device, 'model', deviceModel);
deepSetNotEmptyValue(ortb2Device, 'os', device.platformname);
deepSetNotEmptyValue(ortb2Device, 'osv', device.platformversion);
deepSetNotEmptyValue(ortb2Device, 'h', device.screenpixelsphysicalheight || device.screenpixelsheight);
deepSetNotEmptyValue(ortb2Device, 'w', device.screenpixelsphysicalwidth || device.screenpixelswidth);
deepSetNotEmptyValue(ortb2Device, 'pxratio', device.pixelratio);
deepSetNotEmptyValue(ortb2Device, 'ppi', devicePhysicalPPI || devicePPI);
deepSetNotEmptyValue(ortb2Device, 'ext.fiftyonedegrees_deviceId', device.deviceid);

return ortb2Device;
return {device: ortb2Device};
}

/**
Expand Down Expand Up @@ -211,7 +271,7 @@ export const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, user
logMessage('51Degrees raw data: ', data);
mergeDeep(
reqBidsConfigObj.ortb2Fragments.global,
{device: convert51DegreesDeviceToOrtb2(data.device)},
convert51DegreesDataToOrtb2(data),
);
logMessage('reqBidsConfigObj: ', reqBidsConfigObj);
callback();
Expand Down
Loading