Skip to content

Commit

Permalink
Digital Matter Bid Adapter : overhaul adapter (#12203)
Browse files Browse the repository at this point in the history
* Digital Matter Bid Adapter: Refactor Adapter

* Digital Matter Bid Adapter: add aliases
  • Loading branch information
digital-matter authored Sep 24, 2024
1 parent d693107 commit fa9c7e6
Show file tree
Hide file tree
Showing 3 changed files with 427 additions and 447 deletions.
213 changes: 199 additions & 14 deletions modules/digitalMatterBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,208 @@
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {deepAccess, deepSetValue, getDNT, inIframe, logWarn, parseSizesInput} from '../src/utils.js';
import {config} from '../src/config.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {
buildRequests,
getUserSyncs,
interpretResponse,
isBidRequestValid
} from '../libraries/xeUtils/bidderUtils.js';
import {BANNER} from '../src/mediaTypes.js';
import {hasPurpose1Consent} from '../src/utils/gdpr.js';

const BIDDER_CODE = 'digitalmatter';
const ENDPOINT = 'https://prebid.di-change.live';
const BIDDER_CODE = 'digitalMatter';
const ENDPOINT_URL = 'https://adx.digitalmatter.services/'

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],
aliases: ['dichange', 'digitalmatter'],
supportedMediaTypes: [BANNER, VIDEO],
isBidRequestValid,
buildRequests: (validBidRequests, bidderRequest) => buildRequests(validBidRequests, bidderRequest, ENDPOINT),
interpretResponse,
getUserSyncs
bidParameters: ['accountId', 'siteId'],
isBidRequestValid: function (bid) {
if (typeof bid.params !== 'object') {
return false;
}
if (!hasBannerMediaType(bid)) {
logWarn('Invalid bid request: missing required mediaType - banner');
return false;
}

return !!(bid.params.accountId && bid.params.siteId)
},
buildRequests: function (validBidRequests, bidderRequest) {
const common = bidderRequest.ortb2 || {};
const site = common.site;
const tid = common?.source?.tid;
const {user} = common || {};

if (!site.page) {
site.page = bidderRequest.refererInfo.page;
}

const device = getDevice(common.device);
const schain = getByKey(validBidRequests, 'schain');
const eids = getByKey(validBidRequests, 'userIdAsEids');
const currency = config.getConfig('currency')
const cur = currency && [currency];

const imp = validBidRequests.map((bid, id) => {
const {accountId, siteId} = bid.params;
const bannerParams = deepAccess(bid, 'mediaTypes.banner');
const position = deepAccess(bid, 'mediaTypes.banner.pos') ?? 0;

return {
id: bid.adUnitCode,
bidId: bid.bidId,
accountId: accountId,
adUnitCode: bid.adUnitCode,
siteId: siteId,
banner: {
pos: position,
topframe: inIframe() ? 0 : 1,
format: bannerParams.sizes.map(sizeArr => ({
w: sizeArr[0],
h: sizeArr[1]
}))
},
sizes: parseSizesInput(bannerParams.sizes),
};
});

const ext = {
prebid: {
targeting: {
includewinners: true,
includebidderkeys: false
}
}
};

const payload = {
id: bidderRequest.bidderRequestId,
tid,
site,
device,
user,
cur,
imp,
test: config.getConfig('debug') ? 1 : 0,
tmax: bidderRequest.timeout,
start: bidderRequest.auctionStart,
ext
};

if (schain) {
deepSetValue(payload, 'source.ext.schain', schain);
}

if (eids) {
deepSetValue(payload, 'user.ext.eids', eids);
}

if (deepAccess(bidderRequest, 'gdprConsent.gdprApplies') !== undefined) {
deepSetValue(payload, 'user.ext.consent', bidderRequest.gdprConsent.consentString);
deepSetValue(payload, 'regs.ext.gdpr', bidderRequest.gdprConsent.gdprApplies & 1);
}

const payloadString = JSON.stringify(payload);
return {
method: 'POST',
url: ENDPOINT_URL + 'openrtb2/auction',
data: payloadString,
};
},
interpretResponse: function (serverResponse) {
const body = serverResponse.body || serverResponse;
const {cur} = body;
const bids = [];

if (body && body.bids && Array.isArray(body.bids)) {
body.bids.forEach(bidItem => {
const bid = {
requestId: bidItem.bidid,
adomain: bidItem.adomain,
cpm: bidItem.cpm,
currency: cur,
netRevenue: true,
ttl: bidItem.ttl || 300,
creativeId: bidItem.creativeid,
width: bidItem.width,
height: bidItem.height,
dealId: bidItem.dealid,
ad: bidItem.ad,
meta: bidItem.meta,
};

bids.push(bid);
});
}

return bids
},
getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent, gppConsent) {
if (usersSynced) {
return [];
}

const userSyncs = [];

function checkGppStatus(gppConsent) {
if (gppConsent && Array.isArray(gppConsent.applicableSections)) {
return gppConsent.applicableSections.every(sec => typeof sec === 'number' && sec <= 5);
}
return true;
}

if (hasPurpose1Consent(gdprConsent) && checkGppStatus(gppConsent)) {
responses.forEach(response => {
if (response.body.ext && response.body.ext.usersync) {
try {
const userSync = response.body.ext.usersync;

userSync.forEach((element) => {
let url = element.url;
let type = element.type;

if (url) {
if ((type === 'image' || type === 'redirect') && syncOptions.pixelEnabled) {
userSyncs.push({type: 'image', url: url});
} else if (type === 'iframe' && syncOptions.iframeEnabled) {
userSyncs.push({type: 'iframe', url: url});
}
}
})
} catch (e) {
//
}
}
});
}

return userSyncs;
}
}

let usersSynced = false;

function hasBannerMediaType(bidRequest) {
return !!deepAccess(bidRequest, 'mediaTypes.banner');
}

function getDevice(data) {
let dnt = data.dnt;
if (!dnt) {
dnt = getDNT() ? 1 : 0;
}
return {
w: data.w || window.innerWidth,
h: data.h || window.innerHeight,
ua: data.ua || navigator.userAgent,
dnt: dnt,
language: data.language || navigator.language,
}
}

function getByKey(collection, key) {
for (let i = 0, result; i < collection.length; i++) {
result = deepAccess(collection[i], key);
if (result) {
return result;
}
}
}

registerBidder(spec);
68 changes: 28 additions & 40 deletions modules/digitalMatterBidAdapter.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,38 @@
# Overview

```
Module Name: Digital Matter Bidder Adapter
Module Type: Digital Matter Bidder Adapter
Maintainer: di-change@digitalmatter.ai
Module Name: Digital Matter Bid Adapter
Module Type: Digital Matter Bid Adapter
Maintainer: prebid@digitalmatter.ai
```

# Test Parameters
```
# Description

Module that connects to Digital Matter demand sources

# Banner Test Parameters

```js
var adUnits = [
{
code: 'test-banner',
mediaTypes: {
banner: {
sizes: [[300, 250]],
}
},
bids: [
{
bidder: 'digitalmatter',
params: {
env: 'digitalmatter',
pid: '40',
ext: {}
}
}
{
code: "test-banner",
mediaTypes: {
banner: {
sizes: [
[300, 250],
[300, 600]
]
}
},
{
code: 'test-video',
sizes: [ [ 640, 480 ] ],
mediaTypes: {
video: {
playerSize: [640, 480],
context: 'instream',
skipppable: true
}
},
bids: [{
bidder: 'digitalmatter',
params: {
env: 'digitalmatter',
pid: '40',
ext: {}
}
}]
}
bids: [
{
bidder: "digitalMatter",
params: {
accountId: "1_demo_1", // string, required
siteId: "1-demo-1" // string, required
}
}
]
}
];
```
Loading

0 comments on commit fa9c7e6

Please sign in to comment.