Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3577f49
Migrate valuad prebid.js to 9.35.0 (bridgeupp requires 9.24+)
Mar 19, 2025
44409ef
Fix s2s config ad server currency
Mar 19, 2025
cf9479f
Add valuadBidAdapter with all enhancements from 9.14.0
Mar 20, 2025
4b20d4c
Remove rise adapter
natanavra Mar 23, 2025
043d949
Remove s2s adapters in favor of valuad bid adapter
natanavra Mar 23, 2025
6f59f66
Import 9.14.0 changes
natanavra Mar 23, 2025
c1472ed
Revert smart and yandex adServerCurrency wrong setting
natanavra Mar 23, 2025
289bdc2
Added support for onBidWon + fix for Regs
pixelgroup-israel Mar 24, 2025
e14a0ba
Remove ad creative/html from the bid won event
natanavra Mar 24, 2025
274639f
Fixed Coppa and uspConsent
pixelgroup-israel Mar 24, 2025
37369f3
Replace smartadserver URL transform with a change in the adapter
natanavra Mar 24, 2025
c9ff3f6
Fix style
natanavra Mar 25, 2025
5ed6cde
Fix setting _VALUAD.serverData wrong response field
natanavra Mar 25, 2025
773f98b
Update bid won to send data to valuad analytics server
natanavra Mar 25, 2025
10473be
Added support for schain
pixelgroup-israel Mar 26, 2025
43f09a7
Added support for Eids
pixelgroup-israel Mar 26, 2025
d889fa8
Added support for extended ortb2 data
pixelgroup-israel Mar 26, 2025
b888061
Added support for video impressions
pixelgroup-israel Mar 26, 2025
e53c27a
Added support for native banners
pixelgroup-israel Mar 26, 2025
d141a58
Added timeout data to request
pixelgroup-israel Mar 26, 2025
bb26378
Added RTD data
pixelgroup-israel Mar 26, 2025
2f5813b
Improved storage handeling
pixelgroup-israel Mar 26, 2025
7d1e8a0
Added memory management for observers
pixelgroup-israel Mar 26, 2025
9781b1d
Update code to most recent working copy live in maariv
natanavra Apr 10, 2025
027b656
Organize functions for simplicity
natanavra Apr 17, 2025
1716b6e
Added unit testing for the adapter + added try-catch on ortbConvertor…
pixelgroup-israel Apr 21, 2025
97cb0af
Removed video and native and added a test ad unit
pixelgroup-israel Apr 21, 2025
894fedb
Added md file for prebid website
pixelgroup-israel Apr 22, 2025
3b8020d
Valuad bid adapter initial release
natanavra Apr 22, 2025
7985dbe
Update window size calls to use utils
natanavra Apr 22, 2025
fa7d511
Update valuad.md based on adagio, adipolo and copper6ssp
natanavra Apr 22, 2025
f7a5e68
Removed checks for video and native
pixelgroup-israel Apr 22, 2025
562f6fd
Merge branch '9.35.0-20250326' into 9.40.0-submit
natanavra Apr 22, 2025
768dcae
Update window size calls to use util
natanavra Apr 22, 2025
8ac1889
Remove irrelevant tests
natanavra Apr 22, 2025
64d098f
Merge branch 'prebid:master' into master
natanavra May 4, 2025
81d4506
Merge branch 'prebid:master' into master
natanavra May 6, 2025
28eff2b
Merge branch 'prebid:master' into master
natanavra May 7, 2025
269560d
Fixed tests to run without using global
pixelgroup-israel May 7, 2025
54ddb74
Update tests to not pollute global space
natanavra May 7, 2025
f1eb854
Removed global window reference and removed un-required test
pixelgroup-israel May 8, 2025
8b5bc25
Remove window reference and unused tests
natanavra May 8, 2025
a7d3e4d
Merge branch 'prebid:master' into master
natanavra May 8, 2025
5f0b246
Fix test device language check
natanavra May 8, 2025
88e6005
Removed session and pageview enrichment data
pixelgroup-israel Jun 4, 2025
5b21493
Removed redundant enrichment functions
tal-px Jun 4, 2025
ab209f9
Updated the adapter to use information we already have in the request…
pixelgroup-israel Jun 5, 2025
38b4983
Merge branch 'master' into master
natanavra Jun 5, 2025
18b0d5d
Remove unused code
Jun 5, 2025
f45d486
Removed unnecessary viewabilty functions and used the percentInView l…
pixelgroup-israel Jun 8, 2025
fd26621
Removed redundant reassembling of the gdprConsent object
pixelgroup-israel Jun 8, 2025
896253e
Merge branch '9.40.0-submit'
Jun 8, 2025
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
238 changes: 238 additions & 0 deletions modules/valuadBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
import {
deepAccess,
deepSetValue,
logInfo,
triggerPixel,
getWindowSelf,
getWindowTop
} from '../src/utils.js';
import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js';
import { config } from '../src/config.js';
import { getBoundingBox, percentInView } from '../libraries/percentInView/percentInView.js';

const BIDDER_CODE = 'valuad';
const AD_URL = 'https://rtb.valuad.io/adapter';
const WON_URL = 'https://hb-dot-valuad.appspot.com/adapter/win';

function _isIframe() {
try {
return getWindowSelf() !== getWindowTop();
} catch (e) {
return true;
}
}

function _isViewabilityMeasurable(element) {
return !_isIframe() && element !== null;
}

function _getViewability(element, topWin, { w, h } = {}) {
return topWin.document.visibilityState === 'visible' ? percentInView(element, { w, h }) : 0;
}

// Enhanced ORTBConverter with additional data
Comment thread
natanavra marked this conversation as resolved.
const converter = ortbConverter({
context: {
netRevenue: true,
ttl: 30
},
request(buildRequest, imps, bidderRequest, context) {
const request = buildRequest(imps, bidderRequest, context);

const gdpr = deepAccess(bidderRequest, 'gdprConsent') || {};
const uspConsent = deepAccess(bidderRequest, 'uspConsent') || '';
const coppa = config.getConfig('coppa') === true ? 1 : 0;
const { gpp, gpp_sid: gppSid } = deepAccess(bidderRequest, 'ortb2.regs', {});
const dsa = deepAccess(bidderRequest, 'ortb2.regs.ext.dsa');

deepSetValue(request, 'regs', {
gdpr: gdpr.gdprApplies ? 1 : 0,
coppa: coppa,
us_privacy: uspConsent,
ext: {
gdpr_conset: gdpr.consentString || '',
gpp: gpp || '',
gppSid: gppSid || [],
dsa: dsa,
}
});

deepSetValue(request, 'device.js', 1);
deepSetValue(request, 'device.geo', {});

// Add bid parameters
if (bidderRequest && bidderRequest.bids && bidderRequest.bids.length) {
deepSetValue(request, 'ext.params', bidderRequest.bids[0].params);
}

// Set currency to USD
deepSetValue(request, 'cur', ['USD']);

// Add schain if present
const schain = deepAccess(bidderRequest.bids[0], 'schain');
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You won't need this in prebid 10, we're moving schain

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

// Add eids if present
const eids = deepAccess(bidderRequest.bids[0], 'userIdAsEids');
if (eids) {
deepSetValue(request, 'user.ext.eids', eids);
}

const ortb2 = bidderRequest.ortb2 || {};
if (ortb2.site?.ext?.data) {
deepSetValue(request, 'site.ext.data', {
...request.site.ext.data,
...ortb2.site.ext.data
});
}

const tmax = bidderRequest.timeout;
if (tmax) {
deepSetValue(request, 'tmax', tmax);
}

return request;
},

imp(buildImp, bid, context) {
const imp = buildImp(bid, context);

const mediaType = Object.keys(bid.mediaTypes)[0];
let adSize;

if (mediaType === BANNER) {
adSize = bid.mediaTypes.banner.sizes && bid.mediaTypes.banner.sizes[0];
}

if (!adSize) { adSize = [0, 0]; }

const size = {w: adSize[0], h: adSize[1]};

const element = document.getElementById(bid.adUnitCode) || document.getElementById(getGptSlotInfoForAdUnitCode(bid.adUnitCode)?.divId);
const viewabilityAmount = _isViewabilityMeasurable(element) ? _getViewability(element, getWindowTop(), size) : 0;

const rect = getBoundingBox(element, size);
const position = `${Math.round(rect.left + window.pageXOffset)}x${Math.round(rect.top + window.pageYOffset)}`;

deepSetValue(imp, 'ext.data.viewability', viewabilityAmount);
deepSetValue(imp, 'ext.data.position', position);

// Handle price floors
if (typeof bid.getFloor === 'function') {
try {
let size;

if (mediaType === BANNER) {
size = bid.mediaTypes.banner.sizes && bid.mediaTypes.banner.sizes[0];
}

if (size) {
const floor = bid.getFloor({
currency: 'USD',
mediaType,
size
});

if (floor && !isNaN(floor.floor) && floor.currency === 'USD') {
imp.bidfloor = floor.floor;
imp.bidfloorcur = 'USD';
}
}
} catch (e) {
logInfo('Valuad: Error getting floor', e);
}
}

return imp;
},

bidResponse(buildBidResponse, bid, context) {
let bidResponse;
try {
bidResponse = buildBidResponse(bid, context);

if (bidResponse) {
if (bid.vbid) {
bidResponse.vbid = bid.vbid;
}
if (context.bidRequest?.params?.placementId) {
bidResponse.vid = context.bidRequest.params.placementId;
}
}
} catch (e) {
logInfo('[VALUAD CONVERTER] Error calling buildBidResponse:', e, 'Bid:', bid);
return;
}
return bidResponse;
},
});

function isBidRequestValid(bid = {}) {
const { params, bidId, mediaTypes } = bid;

const foundKeys = bid && bid.params && bid.params.placementId;
let valid = Boolean(bidId && params && foundKeys);

if (mediaTypes && mediaTypes[BANNER]) {
valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
} else {
valid = false;
}

return valid;
}

function buildRequests(validBidRequests = [], bidderRequest = {}) {
const data = converter.toORTB({ validBidRequests, bidderRequest });

return [{
method: 'POST',
url: AD_URL,
data
}];
}

function interpretResponse(response, request) {
// Restore original call, remove logging and safe navigation
const bidResponses = converter.fromORTB({response: response.body, request: request.data}).bids;

return bidResponses;
}

function getUserSyncs(syncOptions, serverResponses) {
if (!serverResponses.length || serverResponses[0].body === '' || !serverResponses[0].body.userSyncs) {
return false;
}

return serverResponses[0].body.userSyncs.map(sync => ({
type: sync.type === 'iframe' ? 'iframe' : 'image',
url: sync.url
}));
}

function onBidWon(bid) {
const {
adUnitCode, adUnitId, auctionId, bidder, cpm, currency, originalCpm, originalCurrency, size, vbid, vid,
} = bid;
const bidStr = JSON.stringify({
adUnitCode, adUnitId, auctionId, bidder, cpm, currency, originalCpm, originalCurrency, size, vbid, vid,
});
const encodedBidStr = window.btoa(bidStr);
triggerPixel(WON_URL + '?b=' + encodedBidStr);
}

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],
isBidRequestValid,
buildRequests,
interpretResponse,
getUserSyncs,
onBidWon,
};
registerBidder(spec);
30 changes: 30 additions & 0 deletions modules/valuadBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Overview

**Module Name**: Valuad Bid Adapter
**Module Type**: Bidder Adapter
**Maintainer**: natan@valuad.io

# Description


Module that connects to Valuad.io demand sources.
Valuad bid adapter supports Banner format only.

# Test Parameters

```js
const adUnits = [{
code: 'valuad-test-div',
mediaTypes: {
banner: {
sizes: [[300, 250]]
}
},
bids: [{
bidder: 'valuad',
params: {
placementId: '00000', // REQUIRED
}
}]
}];
```
Loading