Skip to content

Commit

Permalink
Programmatica Bid Adapter : initial release (#10598)
Browse files Browse the repository at this point in the history
* add programmatica bid adapter

* add more tests
  • Loading branch information
Hamper authored Oct 30, 2023
1 parent faff309 commit 0e61728
Show file tree
Hide file tree
Showing 3 changed files with 462 additions and 0 deletions.
153 changes: 153 additions & 0 deletions modules/programmaticaBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { hasPurpose1Consent } from '../src/utils/gpdr.js';
import { deepAccess, parseSizesInput, isArray } from '../src/utils.js';

const BIDDER_CODE = 'programmatica';
const DEFAULT_ENDPOINT = 'asr.programmatica.com';
const SYNC_ENDPOINT = 'sync.programmatica.com';
const ADOMAIN = 'programmatica.com';
const TIME_TO_LIVE = 360;

export const spec = {
code: BIDDER_CODE,

isBidRequestValid: function(bid) {
let valid = bid.params.siteId && bid.params.placementId;

return !!valid;
},

buildRequests: function(validBidRequests, bidderRequest) {
let requests = [];
for (const bid of validBidRequests) {
let endpoint = bid.params.endpoint || DEFAULT_ENDPOINT;

requests.push({
method: 'GET',
url: `https://${endpoint}/get`,
data: {
site_id: bid.params.siteId,
placement_id: bid.params.placementId,
prebid: true,
},
bidRequest: bid,
});
}

return requests;
},

interpretResponse: function(serverResponse, request) {
if (!serverResponse?.body?.content?.data) {
return [];
}

const bidResponses = [];
const body = serverResponse.body;

let mediaType = BANNER;
let ad, vastXml;
let width;
let height;

let sizes = getSize(body.size);
if (isArray(sizes)) {
[width, height] = sizes;
}

if (body.type.format != '') {
// banner
ad = body.content.data;
if (body.content.imps?.length) {
for (const imp of body.content.imps) {
ad += `<script src="${imp}"></script>`;
}
}
} else {
// video
vastXml = body.content.data;
mediaType = VIDEO;

if (!width || !height) {
const pSize = deepAccess(request.bidRequest, 'mediaTypes.video.playerSize');
const reqSize = getSize(pSize);
if (isArray(reqSize)) {
[width, height] = reqSize;
}
}
}

const bidResponse = {
requestId: request.bidRequest.bidId,
cpm: body.cpm,
currency: body.currency || 'USD',
width: parseInt(width),
height: parseInt(height),
creativeId: body.id,
netRevenue: true,
ttl: TIME_TO_LIVE,
ad: ad,
mediaType: mediaType,
vastXml: vastXml,
meta: {
advertiserDomains: [ADOMAIN],
}
};

if ((mediaType === VIDEO && request.bidRequest.mediaTypes?.video) || (mediaType === BANNER && request.bidRequest.mediaTypes?.banner)) {
bidResponses.push(bidResponse);
}

return bidResponses;
},

getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
const syncs = []

if (!hasPurpose1Consent(gdprConsent)) {
return syncs;
}

let params = `usp=${uspConsent ?? ''}&consent=${gdprConsent?.consentString ?? ''}`;
if (typeof gdprConsent?.gdprApplies === 'boolean') {
params += `&gdpr=${Number(gdprConsent.gdprApplies)}`;
}

if (syncOptions.iframeEnabled) {
syncs.push({
type: 'iframe',
url: `//${SYNC_ENDPOINT}/match/sp.ifr?${params}`
});
}

if (syncOptions.pixelEnabled) {
syncs.push({
type: 'image',
url: `//${SYNC_ENDPOINT}/match/sp?${params}`
});
}

return syncs;
},

onTimeout: function(timeoutData) {},
onBidWon: function(bid) {},
onSetTargeting: function(bid) {},
onBidderError: function() {},
supportedMediaTypes: [ BANNER, VIDEO ]
}

registerBidder(spec);

function getSize(paramSizes) {
const parsedSizes = parseSizesInput(paramSizes);
const sizes = parsedSizes.map(size => {
const [width, height] = size.split('x');
const w = parseInt(width, 10);
const h = parseInt(height, 10);
return [w, h];
});

return sizes[0] || null;
}
46 changes: 46 additions & 0 deletions modules/programmaticaBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Overview

```
Module Name: Programmatica Bid Adapter
Module Type: Bidder Adapter
Maintainer: [email protected]
```

# Description
Connects to Programmatica server for bids.
Module supports banner and video mediaType.

# Test Parameters

```
var adUnits = [{
code: '/test/div',
mediaTypes: {
banner: {
sizes: [[300, 250]]
}
},
bids: [{
bidder: 'programmatica',
params: {
siteId: 'cga9l34ipgja79esubrg',
placementId: 'cgim20sipgj0vj1cb510'
}
}]
},
{
code: '/test/div',
mediaTypes: {
video: {
playerSize: [[640, 360]]
}
},
bids: [{
bidder: 'programmatica',
params: {
siteId: 'cga9l34ipgja79esubrg',
placementId: 'cioghpcipgj8r721e9ag'
}
}]
},];
```
Loading

0 comments on commit 0e61728

Please sign in to comment.