Skip to content

Commit

Permalink
Appnexus bid adapter add ortb2 device (prebid#11788)
Browse files Browse the repository at this point in the history
* AppNexus Bid Adapter: Add full ORTB2 device data to request payload

* AppNexus Bid Adapter: Add test to verify presence of ORTB2 device data in request

* AppNexus Bid Adapter: Convert ORTB2 device data to AppNexus format

---------

Co-authored-by: Bohdan V <25197509+BohdanVV@users.noreply.github.com>
  • Loading branch information
jwrosewell and BohdanVV authored Jul 10, 2024
1 parent 37d742c commit 5b4797e
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
56 changes: 55 additions & 1 deletion modules/appnexusBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
logError,
logInfo,
logMessage,
logWarn
logWarn,
mergeDeep
} from '../src/utils.js';
import {Renderer} from '../src/Renderer.js';
import {config} from '../src/config.js';
Expand Down Expand Up @@ -103,6 +104,28 @@ const VIEWABILITY_URL_START = /\/\/cdn\.adnxs\.com\/v|\/\/cdn\.adnxs\-simple\.co
const VIEWABILITY_FILE_NAME = 'trk.js';
const GVLID = 32;
const storage = getStorageManager({bidderCode: BIDDER_CODE});
// ORTB2 device types according to the OpenRTB specification
const ORTB2_DEVICE_TYPE = {
MOBILE_TABLET: 1,
PERSONAL_COMPUTER: 2,
CONNECTED_TV: 3,
PHONE: 4,
TABLET: 5,
CONNECTED_DEVICE: 6,
SET_TOP_BOX: 7,
OOH_DEVICE: 8
};
// Map of ORTB2 device types to AppNexus device types
const ORTB2_DEVICE_TYPE_MAP = new Map([
[ORTB2_DEVICE_TYPE.MOBILE_TABLET, 'Mobile/Tablet - General'],
[ORTB2_DEVICE_TYPE.PERSONAL_COMPUTER, 'Personal Computer'],
[ORTB2_DEVICE_TYPE.CONNECTED_TV, 'Connected TV'],
[ORTB2_DEVICE_TYPE.PHONE, 'Phone'],
[ORTB2_DEVICE_TYPE.TABLET, 'Tablet'],
[ORTB2_DEVICE_TYPE.CONNECTED_DEVICE, 'Connected Device'],
[ORTB2_DEVICE_TYPE.SET_TOP_BOX, 'Set Top Box'],
[ORTB2_DEVICE_TYPE.OOH_DEVICE, 'OOH Device'],
]);

export const spec = {
code: BIDDER_CODE,
Expand Down Expand Up @@ -247,6 +270,12 @@ export const spec = {
payload.app = appIdObj;
}

// if present, convert and merge device object from ortb2 into `payload.device`
if (bidderRequest?.ortb2?.device) {
payload.device = payload.device || {};
mergeDeep(payload.device, convertORTB2DeviceDataToAppNexusDeviceObject(bidderRequest.ortb2.device));
}

// grab the ortb2 keyword data (if it exists) and convert from the comma list string format to object format
let ortb2 = deepClone(bidderRequest && bidderRequest.ortb2);

Expand Down Expand Up @@ -1196,4 +1225,29 @@ function getBidFloor(bid) {
return null;
}

// Convert device data to a format that AppNexus expects
function convertORTB2DeviceDataToAppNexusDeviceObject(ortb2DeviceData) {
const _device = {
useragent: ortb2DeviceData.ua,
devicetype: ORTB2_DEVICE_TYPE_MAP.get(ortb2DeviceData.devicetype),
make: ortb2DeviceData.make,
model: ortb2DeviceData.model,
os: ortb2DeviceData.os,
os_version: ortb2DeviceData.osv,
w: ortb2DeviceData.w,
h: ortb2DeviceData.h,
ppi: ortb2DeviceData.ppi,
pxratio: ortb2DeviceData.pxratio,
};

// filter out any empty values and return the object
return Object.keys(_device)
.reduce((r, key) => {
if (_device[key]) {
r[key] = _device[key];
}
return r;
}, {});
}

registerBidder(spec);
36 changes: 36 additions & 0 deletions test/spec/modules/appnexusBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,42 @@ describe('AppNexusAdapter', function () {
expect(payload.tags[0].video_frameworks).to.deep.equal([1, 4])
});

it('should convert and include ORTB2 device data when available', function () {
const bidRequest = deepClone(bidRequests[0]);
const bidderRequest = {
ortb2: {
device: {
w: 980,
h: 1720,
dnt: 0,
ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/125.0.6422.80 Mobile/15E148 Safari/604.1',
language: 'en',
devicetype: 1,
make: 'Apple',
model: 'iPhone 12 Pro Max',
os: 'iOS',
osv: '17.4',
},
},
};

const expectedDeviceResult = {
useragent: bidderRequest.ortb2.device.ua,
devicetype: 'Mobile/Tablet - General',
make: bidderRequest.ortb2.device.make,
model: bidderRequest.ortb2.device.model,
os: bidderRequest.ortb2.device.os,
os_version: bidderRequest.ortb2.device.osv,
w: bidderRequest.ortb2.device.w,
h: bidderRequest.ortb2.device.h,
};

const request = spec.buildRequests([bidRequest], bidderRequest);
const payload = JSON.parse(request.data);

expect(payload.device).to.deep.equal(expectedDeviceResult);
});

it('should add video property when adUnit includes a renderer', function () {
const videoData = {
mediaTypes: {
Expand Down

0 comments on commit 5b4797e

Please sign in to comment.