Skip to content

Commit

Permalink
setupad Bid Adapter: initial commit (prebid#11008)
Browse files Browse the repository at this point in the history
* create setupadBidAdapter

* add setupadBidAdapter

* update setupadBidAdapter

* update metrics collection

* update analytics collection

* update getUserSyncs

* add setupadAnalyticsAdapter.js

* test setupadAnalyticsAdapter

* remove test: 1

* add GVLID && bug fixes && test updates

* remove setupadAnalyticsAdapter

* add userID module handling

* add GVLID && bug fixes && test updates

* remove setupadAnalyticsAdapter

* add userID module handling

* clean up && seat bugfix

* clean up logs

* add userID module handling

* update md && clean up

* Send setupad only on bidRequested

* Fix bidResponse and bidWon responses

* Improve bidResponse and bidWon logic

* Revert changes to specific files

* Remove test parameter

* Fix multiple bidResponse and bidTimeout calls to getPixelUrl

* eslint errors fixes(brackets added)

* Add extra checks for events

* Fix BIDDER_CODE const

* update reporting endpoint

* update setupadBidAdapter_spec.js REPORT_ENDPOINT

* update readme

* Revert "Merge branch 'prebid:master' into setupad-adapter"

This reverts commit 1c14dbe, reversing
changes made to 7fe9ea5.

* Revert "Revert "Merge branch 'prebid:master' into setupad-adapter""

This reverts commit a34e3e4.

* # This is a combination of 20 commits.
# This is the 1st commit message:

add setupadBidAdapter

# This is the commit message #2:

update setupadBidAdapter

# This is the commit message #3:

update metrics collection

# This is the commit message #4:

update analytics collection

# This is the commit message #5:

update getUserSyncs

# This is the commit message #6:

add setupadAnalyticsAdapter.js

# This is the commit message #7:

test setupadAnalyticsAdapter

# This is the commit message #8:

remove test: 1

# This is the commit message #9:

add GVLID && bug fixes && test updates

# This is the commit message #10:

remove setupadAnalyticsAdapter

# This is the commit message #11:

add userID module handling

# This is the commit message #12:

clean up && seat bugfix

# This is the commit message #13:

add userID module handling

# This is the commit message #14:

add GVLID && bug fixes && test updates

# This is the commit message #15:

remove setupadAnalyticsAdapter

# This is the commit message #16:

add userID module handling

# This is the commit message #17:

clean up logs

# This is the commit message #18:

update md && clean up

# This is the commit message #19:

Send setupad only on bidRequested

# This is the commit message #20:

Fix bidResponse and bidWon responses

* # This is a combination of 22 commits.tree 8abae7e6dffc9a21ad11770713ba485fc610028a
parent cecfce3
author pavel <pavel@setupad.com> 1706627437 +0200
committer pavel <pavel@setupad.com> 1706627437 +0200
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEqGYI3KX/FkbObQG8FABtd4pCs/AFAmW5EW0ACgkQFABtd4pC
 s/CK3w//WWJSFUlycnnNKTV2XfdcBjooOeZZvjpXVthwr09CCC4uO//kw4bPluhn
 f5fcVFdXzrY1AZ6ch8Wo3msX/Pkso014jIGd5aIWcHpNYFtffACwH/40Y8AcJNZd
 bsOZxVK0awPTz/RihC5eY+0J3cP+iFWP/FlYJoHEQIBXq/Eg6mWoAhxwpL/JvxbY
 QbLFWsRn2ckQ6ftOZgm3/jh8VLaG1zWbWImlWEs5Zel+CorJBTniTj58VbApelYD
 TFMgbSR2I4NGVaqNIrHePnSMsDATxalQ2nZPwY6raKCHWIbvoUPIn/OpDMMbKgC7
 nCwounNmObxFVoj3xusAZppzHpKPasY8xKWb2Kr7zfhZArsOMC6B7fYqQNK0cWG3
 8RR/10oheJD9M2kRlfLiqnRv7ExY08SQ/ZMo9LA8BeRUGBXhh6++8FKhKIHvX1gL
 k1R5W6c+NNWP+PDFsmrFpMn+LpYdl84I7yfYK5dHuw80od7f1wuAVYpswi6Cziy9
 /KY6/rfENvUrGTmWSh5GdDBel89ACCfFkasIKB92xhzKTfjzF/DXkc8XQZOMbt1j
 CsILgWMNfLPMo4Dlgdx/tYCSLLBNEtZ1/hhUcFQ3+0TzLf0GtMkvMnlBnDinqe1n
 1P30fQ2I5W5NJKDPrCOnRymI6QOAPFXtMF11R81mbB9H8asft/E=
 =oJtZ
 -----END PGP SIGNATURE-----

bugfixes

# This is the commit message #22:

Remove test parameter

* # This is a combination of 26 commits.
parent cecfce3
author pavel <pavel@setupad.com> 1706627437 +0200
committer pavel <pavel@setupad.com> 1706627437 +0200
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEqGYI3KX/FkbObQG8FABtd4pCs/AFAmW5EW0ACgkQFABtd4pC
 s/CK3w//WWJSFUlycnnNKTV2XfdcBjooOeZZvjpXVthwr09CCC4uO//kw4bPluhn
 f5fcVFdXzrY1AZ6ch8Wo3msX/Pkso014jIGd5aIWcHpNYFtffACwH/40Y8AcJNZd
 bsOZxVK0awPTz/RihC5eY+0J3cP+iFWP/FlYJoHEQIBXq/Eg6mWoAhxwpL/JvxbY
 QbLFWsRn2ckQ6ftOZgm3/jh8VLaG1zWbWImlWEs5Zel+CorJBTniTj58VbApelYD
 TFMgbSR2I4NGVaqNIrHePnSMsDATxalQ2nZPwY6raKCHWIbvoUPIn/OpDMMbKgC7
 nCwounNmObxFVoj3xusAZppzHpKPasY8xKWb2Kr7zfhZArsOMC6B7fYqQNK0cWG3
 8RR/10oheJD9M2kRlfLiqnRv7ExY08SQ/ZMo9LA8BeRUGBXhh6++8FKhKIHvX1gL
 k1R5W6c+NNWP+PDFsmrFpMn+LpYdl84I7yfYK5dHuw80od7f1wuAVYpswi6Cziy9
 /KY6/rfENvUrGTmWSh5GdDBel89ACCfFkasIKB92xhzKTfjzF/DXkc8XQZOMbt1j
 CsILgWMNfLPMo4Dlgdx/tYCSLLBNEtZ1/hhUcFQ3+0TzLf0GtMkvMnlBnDinqe1n
 1P30fQ2I5W5NJKDPrCOnRymI6QOAPFXtMF11R81mbB9H8asft/E=
 =oJtZ
 -----END PGP SIGNATURE-----

bugfixes

# This is the commit message #22:

Remove test parameter

# This is the commit message #23:

Fix multiple bidResponse and bidTimeout calls to getPixelUrl

# This is the commit message #25:

eslint errors fixes(brackets added)

# This is the commit message #26:

Add extra checks for events

* parent 75178b9
author pavel <pavel@setupad.com> 1706627694 +0200
committer pavel <pavel@setupad.com> 1706627694 +0200
gpgsig -----BEGIN PGP SIGNATURE-----

 iQIzBAABCAAdFiEEqGYI3KX/FkbObQG8FABtd4pCs/AFAmW5Em4ACgkQFABtd4pC
 s/BBUQ/+NXyHoxPM185YJLG9M1ySC/5vTT9W5mfwQ93cVDLCeuGnpsnmi4S21NuQ
 b7gSeokFjwztvVOUmh/xqMp4lTsvL53TUd00b1k4KGVSqgcF00Foit5g8fOGLYsI
 DAoqphYV6MWjpAun+II+ELY8QUkHR1cjTc7PEGtmf+8RnptGVdyJ6C9Ab8u9TQTY
 Apj5Srhfo3Tl8S+WScOxwwB/uqEJR4fhIrJyzFzdLDEb2olSPyrQUs87vQXlhEnK
 buPEg2F5JsRH6sw11Xp3TFNSZGxNnBSlTh9dixou5md4yRCv5a2TMef667N0BVDp
 lGgc7mCrRKXyqzphmmeHudiscEGFjtUPObXoHutSVw22wdARFCTpNFKBLLFn4v8o
 Zv1OvFdNprvHsoeW0HVlZdU7OKnDTRrko6DHk2AahxojjvAFEWuDsGYZNjhdQwRR
 lK1zm+SFQnKI0Eojd+f84fvKod9geGs640jyH/x5R4eYm4yjZb8SkRtd3cca88wS
 OuGq9LIkbU428b46l7VnDwudldTXPUU8eKfUtFRjdGtIWH9I3tK6TsRoCfTcXkv0
 smxYiiU1XHjAkkPFWQWEeFdfZ071snFKVWouU0AoKiq+PdRoS8+3AJqIQUjlA2sH
 AybnSkv9KxY/Rs1bnvMubsQm1GF66qVrbxBU6FILBv1JZYwj4yA=
 =Gbog
 -----END PGP SIGNATURE-----

bugfixes

update setupadBidAdapter_spec.js REPORT_ENDPOINT

update readme

Revert "Merge branch 'prebid:master' into setupad-adapter"

This reverts commit 1c14dbe, reversing
changes made to 7fe9ea5.

Revert "Revert "Merge branch 'prebid:master' into setupad-adapter""

This reverts commit a34e3e4.

* change double quote to single quote

---------

Co-authored-by: pavel <pavel@setupad.com>
Co-authored-by: Elgars Grodnis <elgars@setupad.com>

* bugfix setupadBidAdapter

remove getAdEl, spelling correction

* add onBidWon event

onBidWon event handling moved from custom to native onBidWon method

* minor bugfixes && remove funk getSiteObj && getDeviceObj

---------

Co-authored-by: pavel <pavel@setupad.com>
Co-authored-by: Elgars Grodnis <elgars@setupad.com>
  • Loading branch information
3 people authored Mar 19, 2024
1 parent 90822c6 commit 48113b1
Show file tree
Hide file tree
Showing 3 changed files with 654 additions and 0 deletions.
271 changes: 271 additions & 0 deletions modules/setupadBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
import {
_each,
createTrackPixelHtml,
deepAccess,
isStr,
getBidIdParameter,
triggerPixel,
logWarn,
} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';

const BIDDER_CODE = 'setupad';
const ENDPOINT = 'https://prebid.setupad.io/openrtb2/auction';
const SYNC_ENDPOINT = 'https://cookie.stpd.cloud/sync?';
const REPORT_ENDPOINT = 'https://adapter-analytics.setupad.io/api/adapter-analytics';
const GVLID = 1241;
const TIME_TO_LIVE = 360;
const biddersCreativeIds = {};

function getEids(bidRequest) {
if (deepAccess(bidRequest, 'userIdAsEids')) return bidRequest.userIdAsEids;
}

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],
gvlid: GVLID,

isBidRequestValid: function (bid) {
return !!(bid.params.placement_id && isStr(bid.params.placement_id));
},

buildRequests: function (validBidRequests, bidderRequest) {
const requests = [];

_each(validBidRequests, function (bid) {
const id = getBidIdParameter('placement_id', bid.params);
const accountId = getBidIdParameter('account_id', bid.params);
const auctionId = bid.auctionId;
const bidId = bid.bidId;
const eids = getEids(bid) || undefined;
let sizes = bid.sizes;
if (sizes && !Array.isArray(sizes[0])) sizes = [sizes];

const site = {
page: bidderRequest?.refererInfo?.page,
ref: bidderRequest?.refererInfo?.ref,
domain: bidderRequest?.refererInfo?.domain,
};
const device = {
w: bidderRequest?.ortb2?.device?.w,
h: bidderRequest?.ortb2?.device?.h,
};

const payload = {
id: bid?.bidderRequestId,
ext: {
prebid: {
storedrequest: {
id: accountId || 'default',
},
},
},
user: { ext: { eids } },
device,
site,
imp: [],
};

const imp = {
id: bid.adUnitCode,
ext: {
prebid: {
storedrequest: { id },
},
},
};

if (deepAccess(bid, 'mediaTypes.banner')) {
imp.banner = {
format: (sizes || []).map((s) => {
return { w: s[0], h: s[1] };
}),
};
}

payload.imp.push(imp);

const gdprConsent = bidderRequest && bidderRequest.gdprConsent;
const uspConsent = bidderRequest && bidderRequest.uspConsent;

if (gdprConsent || uspConsent) {
payload.regs = { ext: {} };

if (uspConsent) payload.regs.ext.us_privacy = uspConsent;

if (gdprConsent) {
if (typeof gdprConsent.gdprApplies !== 'undefined') {
payload.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0;
}

if (typeof gdprConsent.consentString !== 'undefined') {
payload.user.ext.consent = gdprConsent.consentString;
}
}
}
const params = bid.params;

requests.push({
method: 'POST',
url: ENDPOINT,
data: JSON.stringify(payload),
options: {
contentType: 'text/plain',
withCredentials: true,
},

bidId,
params,
auctionId,
});
});

return requests;
},

interpretResponse: function (serverResponse, bidRequest) {
if (
!serverResponse ||
!serverResponse.body ||
typeof serverResponse.body != 'object' ||
Object.keys(serverResponse.body).length === 0
) {
logWarn('no response or body is malformed');
return [];
}

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

_each(serverBody.seatbid, (res) => {
_each(res.bid, (bid) => {
const requestId = bidRequest.bidId;
const params = bidRequest.params;
const { ad, adUrl } = getAd(bid);

const bidResponse = {
requestId,
params,
cpm: bid.price,
width: bid.w,
height: bid.h,
creativeId: bid.id,
currency: serverBody.cur,
netRevenue: true,
ttl: TIME_TO_LIVE,
meta: {
advertiserDomains: bid.adomain || [],
},
};

// set a seat for creativeId for triggerPixel url
biddersCreativeIds[bidResponse.creativeId] = res.seat;

bidResponse.ad = ad;
bidResponse.adUrl = adUrl;
bidResponses.push(bidResponse);
});
});

return bidResponses;
},

getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) {
if (!responses?.length) return [];

const syncs = [];
const bidders = getBidders(responses);

if (syncOptions.iframeEnabled && bidders) {
const queryParams = [];

queryParams.push(`bidders=${bidders}`);
queryParams.push('gdpr=' + +gdprConsent.gdprApplies);
queryParams.push('gdpr_consent=' + gdprConsent.consentString);
queryParams.push('usp_consent=' + (uspConsent || ''));

const strQueryParams = queryParams.join('&');

syncs.push({
type: 'iframe',
url: SYNC_ENDPOINT + strQueryParams + '&type=iframe',
});

return syncs;
}

return [];
},

onBidWon: function (bid) {
let bidder = bid.bidder || bid.bidderCode;
const auctionId = bid.auctionId;
if (bidder !== BIDDER_CODE) return;

let params;
if (bid.params) {
params = Array.isArray(bid.params) ? bid.params : [bid.params];
} else {
if (Array.isArray(bid.bids)) {
params = bid.bids.map((singleBid) => singleBid.params);
}
}

if (!params?.length) return;

const placementIdsArray = [];
params.forEach((param) => {
if (!param.placement_id) return;
placementIdsArray.push(param.placement_id);
});

const placementIds = (placementIdsArray.length && placementIdsArray.join(';')) || '';

if (!placementIds) return;

let extraBidParams = '';

// find the winning bidder by using creativeId as identification
if (biddersCreativeIds.hasOwnProperty(bid.creativeId) && biddersCreativeIds[bid.creativeId]) {
bidder = biddersCreativeIds[bid.creativeId];
}

// Add extra parameters
extraBidParams = `&cpm=${bid.originalCpm}&currency=${bid.originalCurrency}`;

const url = `${REPORT_ENDPOINT}?event=bidWon&bidder=${bidder}&placementIds=${placementIds}&auctionId=${auctionId}${extraBidParams}&timestamp=${Date.now()}`;
triggerPixel(url);
},
};

function getBidders(serverResponse) {
const bidders = serverResponse
.map((res) => Object.keys(res.body.ext.responsetimemillis || []))
.flat(1);

if (bidders.length) {
return encodeURIComponent(JSON.stringify([...new Set(bidders)]));
}
}

function getAd(bid) {
let ad, adUrl;

switch (deepAccess(bid, 'ext.prebid.type')) {
default:
if (bid.adm && bid.nurl) {
ad = bid.adm;
ad += createTrackPixelHtml(decodeURIComponent(bid.nurl));
} else if (bid.adm) {
ad = bid.adm;
} else if (bid.nurl) {
adUrl = bid.nurl;
}
}

return { ad, adUrl };
}

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

```text
Module Name: Setupad Bid Adapter
Module Type: Bidder Adapter
Maintainer: it@setupad.com
```

# Description

Module that connects to Setupad's demand sources.

# Test Parameters

```js
const adUnits = [
{
code: 'test-div',
mediaTypes: {
banner: {
sizes: [[300, 250]],
},
},
bids: [
{
bidder: 'setupad',
params: {
placement_id: '123', //required
account_id: '123', //optional
},
},
],
},
];
```
Loading

0 comments on commit 48113b1

Please sign in to comment.