Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
161 changes: 161 additions & 0 deletions modules/synapseHxBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { logError, isFn, isPlainObject, formatQS } from '../src/utils.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
import { toOrtb26 } from '../libraries/ortb2.5Translator/translator.js';
import { getUserSyncParams } from '../libraries/userSyncUtils/userSyncUtils.js';

const BIDDER_CODE = 'synapsehx';
const METHOD = 'POST';
const ENDPOINT_URL = `https://rtb.hx.compasonline.com/pbjs`;

function getMediaType(bid) {
if (bid.mtype) {
const mtypeToMediaType = { 1: BANNER, 2: VIDEO };
return mtypeToMediaType[bid.mtype];
}
return bid?.ext?.prebid?.type;

Check warning on line 17 in modules/synapseHxBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

17 line is not covered with tests
}

const converter = ortbConverter({
imp(buildImp, bidRequest, context) {
const imp = buildImp(bidRequest, context);

if (bidRequest?.params?.adUnitId) {
imp.tagid = bidRequest.params.adUnitId;
}

const floor = getBidFloor(bidRequest);
if (floor) {
imp.bidfloor = floor;
imp.bidfloorcur = 'USD';
}

return imp;
},
request(buildRequest, imps, bidderRequest, context) {
return buildRequest(imps, bidderRequest, context);
},
bidResponse(buildBidResponse, bid, context) {
const isValidBidType = Object.keys(context.bidRequest.mediaTypes).includes(getMediaType(bid));

if (isValidBidType) {
return buildBidResponse(bid, context);
}

logError('Incorrect bid type for bid: ', bid.id);

Check warning on line 46 in modules/synapseHxBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

46 line is not covered with tests
},
context: {
netRevenue: true,
ttl: 30
},
translator: toOrtb26
Comment thread
patmmccann marked this conversation as resolved.
Outdated
});

function getBidFloor(bid) {
if (isFn(bid.getFloor)) {
const floor = bid.getFloor({
currency: 'USD',
mediaType: '*',
size: '*'
});
if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') {
return floor.floor;
}
}
return bid.params?.floor;
}

function isValidBidFloorCurrency(bid) {
return !bid.ortb2Imp?.bidfloorcur || bid.ortb2Imp.bidfloorcur === 'USD';
}

function isValidParams(bid) {
const tenantId = bid?.params?.tenantId;
const adUnitId = bid?.params?.adUnitId;
return typeof tenantId === 'string' && tenantId.length > 0 &&
(adUnitId == null || (typeof adUnitId === 'string' && adUnitId.length > 0));
}

function makeUrl(bidRequests) {
return `${ENDPOINT_URL}?${formatQS({ pid: bidRequests[0].params.tenantId })}`;
}

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [VIDEO, BANNER],
isBidRequestValid: (bid) => !!bid && isValidParams(bid) && isValidBidFloorCurrency(bid),

buildRequests: (bidRequests, bidderRequest) => {
const data = converter.toORTB({ bidRequests, bidderRequest });

return [{
method: METHOD,
url: makeUrl(bidRequests),
options: {
contentType: 'application/json',

Check warning

Code scanning / CodeQL

Application/json request type in bidder Warning

application/json request type triggers preflight requests and may increase bidder timeouts
Comment thread
patmmccann marked this conversation as resolved.
Outdated
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
withCredentials: true,
crossOrigin: true
},
data: data,
}];
},

interpretResponse: ({ body }, req) => {
if (!body || !body.seatbid || body.seatbid.length === 0) {
return [];

Check warning on line 106 in modules/synapseHxBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

106 line is not covered with tests
}
return converter.fromORTB({
response: body,
request: req.data
});
},

onTimeout: (data) => { },

onBidWon: (bid) => {
if (bid.nurl) {
const url = new URL(bid.nurl);
url.searchParams.set('cpm', bid.cpm);
fetch(url.toString(), { method: 'GET', keepalive: true }).catch(err =>
logError('Error triggering win notification', err)

Check warning on line 121 in modules/synapseHxBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

117-121 lines are not covered with tests
);
}
},

onSetTargeting: (bid) => { },

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

if (serverResponses && (syncOptions.iframeEnabled || syncOptions.pixelEnabled)) {
const params = formatQS(getUserSyncParams(gdprConsent, uspConsent, gppConsent));

if (syncOptions.iframeEnabled) {
serverResponses.forEach(response => {
const iframeUrl = response?.body?.ext?.[BIDDER_CODE]?.sync?.iframe;
if (iframeUrl) {
syncs.push({
type: "iframe",
url: `${iframeUrl}${params ? `${iframeUrl.lastIndexOf('?') !== -1 ? '&' : '?'}${params}` : ''}`,
});
}
});
} else if (syncOptions.pixelEnabled) {
serverResponses.forEach(response => {
const images = response?.body?.ext?.[BIDDER_CODE]?.sync?.image || [];
images.forEach(image => {
syncs.push({
type: "image",
url: `${image}${params ? `${image.lastIndexOf('?') !== -1 ? '&' : '?'}${params}` : ''}`,
});
});
});
}
}

return syncs;
}
};

registerBidder(spec);
76 changes: 76 additions & 0 deletions modules/synapseHxBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Overview

```
Module Name: Synapse HX Bidder Adapter
Module Type: Bidder Adapter
Maintainer: prebid@compas-inc.com
```

# Description

The Synapse HX Bidder Adapter enables publishers to integrate with Synapse HX exchange for banner and video ad formats. The adapter supports OpenRTB standards and processes bid requests efficiently using the Prebid.js framework.

# Test Parameters

## Sample Banner Ad Unit
```
var adUnits = [
{
code: 'test-div',
mediaTypes: {
banner: {
sizes: [[300,250]]
}
},
bids: [
{
bidder: 'synapsehx',
params: {
// REQUIRED - Synapse HX tenant identifier
tenantId: 'your-account-id',
// OPTIONAL - Synapse HX ad unit identifier
adUnitId: 'ad-unit-id'
}
}
]
}
];
```

## Sample Video Ad Unit
```
var videoAdUnits = [
{
code: 'test-div-video',
mediaTypes: {
video: {
context: 'instream',
placement: 1,
playerSize: [640, 360],
mimes: ['video/mp4'],
protocols: [2, 3, 5, 6],
api: [2],
maxduration: 30,
linearity: 1,
playbackmethod: [2]
}
},
bids: [
{
bidder: 'synapsehx',
params: {
// REQUIRED - Synapse HX tenant identifier
tenantId: 'your-account-id',
// OPTIONAL - Synapse HX ad unit identifier
adUnitId: 'ad-unit-id'
}
}
]
}
];
```

# Additional Notes
- The adapter processes requests via OpenRTB 2.6 standards.
- Ensure that the `tenantId` parameter is set correctly for your integration.
- The `adUnitId` parameter is optional.
Loading
Loading