Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6545a9c
RM-845 : Initial implementation for risemediatech bid adapter
pritishmd-talentica May 2, 2025
7ba98f5
RM-845 : Added bidder parameter documentation for risemediatech Bid A…
pritishmd-talentica May 4, 2025
994737c
RM-845 : minor modifications
pritishmd-talentica May 4, 2025
21e69ac
RM-845 : Handled es lint errors
pritishmd-talentica May 8, 2025
bc0dbf6
RM-847 : Unit Test for Risemediatech Bid Adapter
pritishmd-talentica May 8, 2025
04fc23d
Updated unit tests
pritishmd-talentica May 14, 2025
1dbbfb9
Modified the bid adapter code and unit tests
pritishmd-talentica May 26, 2025
eeadcc4
Modified prebid js code to remove validations and also added bidfloor…
pritishmd-talentica May 30, 2025
30ad662
added the vastxml field in the response for the video media type
pritishmd-talentica May 30, 2025
5416c2f
Fixed incorrect media type issue
pritishmd-talentica Jun 10, 2025
bdf9ea6
Added test mode impressions support
pritishmd-talentica Jun 26, 2025
d0f9c9c
Added test mode for video ad units
pritishmd-talentica Jun 26, 2025
d9b5de5
Added bidfloor for example video ad unit
pritishmd-talentica Jun 26, 2025
abf2510
Updated default TTL
pritishmd-talentica Jul 3, 2025
e744c13
Minro fixes
pritishmd-talentica Jul 3, 2025
6b3479e
Update docs
pritishmd-talentica Jul 7, 2025
a60344b
Minor changes
pritishmd-talentica Jul 9, 2025
e02c5ce
Minor changes
pritishmd-talentica Jul 9, 2025
63983a6
Code cleanup
pritishmd-talentica Jul 9, 2025
77e12d1
Changes as per review
pritishmd-talentica Jul 9, 2025
7094d28
Semantic changes
pritishmd-talentica Jul 9, 2025
ae9d67e
Added support for Http Status 204 No Bids Scenarios
pritishmd-talentica Jul 14, 2025
af8c54a
Updated failing unit tests.
pritishmd-talentica Jul 14, 2025
44b7d07
Modified the check for no bids
pritishmd-talentica Jul 14, 2025
7f53fd8
Reverted the status check
pritishmd-talentica Jul 15, 2025
ff3a800
linter modifications
pritishmd-talentica Jul 15, 2025
1c80725
Merge pull request #2 from Rise-Media-Technologies/risemedia-bid-adapter
pritishmd-talentica Jul 15, 2025
b0ed498
Updated the documentation for the adapter and formatted adapter
pritishmd-talentica Jul 17, 2025
71de14d
Modified the documentation as per discussion
pritishmd-talentica Jul 18, 2025
9404cd2
Merge pull request #3 from Rise-Media-Technologies/risemedia-bid-adapter
pritishmd-talentica Jul 18, 2025
48fc03c
Merge branch 'master' into master
pritishmd-talentica Jul 22, 2025
13502b8
Merge branch 'prebid:master' into master
pritishmd-talentica Aug 5, 2025
4d909b3
Resolved linter errors from upstream repo PR
pritishmd-talentica Aug 5, 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
214 changes: 214 additions & 0 deletions modules/risemediatechBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
import { logInfo, logWarn } from '../src/utils.js';

const BIDDER_CODE = 'risemediatech';
const ENDPOINT_URL = 'https://dev-ads.risemediatech.com/ads/rtb/prebid/js';
const DEFAULT_CURRENCY = 'USD';
const DEFAULT_TTL = 60;

const converter = ortbConverter({
context: {
netRevenue: true,
ttl: DEFAULT_TTL,
currency: DEFAULT_CURRENCY,
},
imp(buildImp, bidRequest, context) {
logInfo('Building impression object for bidRequest:', bidRequest);
const imp = buildImp(bidRequest, context);
const { mediaTypes } = bidRequest;
if (bidRequest.params) {
if (bidRequest.params.bidfloor) {
logInfo('Setting bid floor for impression:', bidRequest.params.bidfloor);
imp.bidfloor = bidRequest.params.bidfloor;
}
}
if (mediaTypes[BANNER]) {
logInfo('Adding banner media type to impression:', mediaTypes[BANNER]);
imp.banner = { format: mediaTypes[BANNER].sizes.map(([w, h]) => ({ w, h })) };
} else if (mediaTypes[VIDEO]) {
logInfo('Adding video media type to impression:', mediaTypes[VIDEO]);
imp.video = {
...mediaTypes[VIDEO],
// all video parameters are mapped.
};
}

return imp;
},
request(buildRequest, imps, bidderRequest, context) {
logInfo('Building server request with impressions:', imps);
const request = buildRequest(imps, bidderRequest, context);
request.cur = [DEFAULT_CURRENCY];
request.tmax = bidderRequest.timeout;
request.test = bidderRequest.test || 0;

if (Array.isArray(bidderRequest.bids)) {
const hasTestMode = bidderRequest.bids.some(bid => bid.params && bid.params.testMode === 1);
if (hasTestMode) {
request.ext = request.ext || {};
request.ext.test = 1;
logInfo('Test mode detected in bid params, setting test flag in request:', request.ext.test);
}
}

if (bidderRequest.gdprConsent) {
logInfo('Adding GDPR consent information to request:', bidderRequest.gdprConsent);
request.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } };
request.user = { ext: { consent: bidderRequest.gdprConsent.consentString } };
}

if (bidderRequest.uspConsent) {
logInfo('Adding USP consent information to request:', bidderRequest.uspConsent);
request.regs = request.regs || {};
request.regs.ext = request.regs.ext || {};
request.regs.ext.us_privacy = bidderRequest.uspConsent;
}

return request;
},
});

/**
* Validates the bid request.
* @param {Object} bid - The bid request object.
* @returns {boolean} True if the bid request is valid.
*/
const isBidRequestValid = (bid) => {
logInfo('Validating bid request:', bid);

const { mediaTypes } = bid;

// Validate video-specific fields if mediaTypes includes VIDEO
if (mediaTypes?.[VIDEO]) {
const video = mediaTypes[VIDEO];

if (!video.mimes || !Array.isArray(video.mimes) || video.mimes.length === 0) {
logWarn('Invalid video bid request: Missing or invalid mimes.');
return false;
}
if (video.w != null && video.w <= 0) {
logWarn('Invalid video bid request: Invalid width.');
return false;
}
if (video.h != null && video.h <= 0) {
logWarn('Invalid video bid request: Invalid height.');
return false;
}
}

return true;
};

/**
* Builds the server request for the bid.
* @param {Array} validBidRequests - Array of valid bid requests.
* @param {Object} bidderRequest - Additional information about the bid request.
* @returns {Object} Server request object.
*/
const buildRequests = (validBidRequests, bidderRequest) => {
logInfo('Building server request for valid bid requests:', validBidRequests);
const request = converter.toORTB({ bidRequests: validBidRequests, bidderRequest });
logInfo('Converted to ORTB request:', request);
return {
method: 'POST',
url: ENDPOINT_URL,
data: request,
options: {
endpointCompression: true
},
};
};

/**
* Interprets the server response and extracts bid information.
* @param {Object} serverResponse - The response from the server.
* @param {Object} request - The original request sent to the server.
* @returns {Array} Array of bid objects.
*/
const interpretResponse = (serverResponse, request) => {
logInfo('Interpreting server response:', serverResponse);

const bidResp = serverResponse && serverResponse.body;
if (!bidResp || !Array.isArray(bidResp.seatbid)) {
logWarn('Server response is empty, invalid, or does not contain seatbid array.');
return [];
}

const responses = [];
bidResp.seatbid.forEach(seatbid => {
if (Array.isArray(seatbid.bid) && seatbid.bid.length > 0) {
const bid = seatbid.bid[0];
logInfo('Processing bid response:', bid);
const bidResponse = {
requestId: bid.impid,
cpm: bid.price,
currency: bidResp.cur || DEFAULT_CURRENCY,
width: bid.w,
height: bid.h,
ad: bid.adm,
creativeId: bid.crid,
netRevenue: true,
ttl: DEFAULT_TTL,
meta: {
advertiserDomains: bid.adomain || [],
}
}

// Set media type based on bid.mtype
if (bid.mtype == null) {
logWarn('Bid response does not contain media type for bidId: ', bid.id);
bidResponse.mediaType = BANNER;
}
switch (bid.mtype) {
case 1:
bidResponse.mediaType = BANNER;
break;
case 2:
bidResponse.mediaType = VIDEO;
bidResponse.vastXml = bid.adm;
break;
default:
logWarn('Unknown media type: ', bid.mtype, ' for bidId: ', bid.id);
break;
}

// set dealId if present
if (bid.dealid) {
bidResponse.dealId = bid.dealid;
}
logInfo('Interpreted response:', bidResponse, ' for bidId: ', bid.id);
responses.push(bidResponse);
}
});

logInfo('Interpreted bid responses:', responses);
return responses;
};

/**
* Handles user syncs for GDPR, CCPA, and GPP compliance.
* @param {Object} syncOptions - Options for user sync.
* @param {Array} serverResponses - Server responses.
* @param {Object} gdprConsent - GDPR consent information.
* @param {Object} uspConsent - CCPA consent information.
* @param {Object} gppConsent - GPP consent information.
* @returns {Array} Array of user sync objects.
*/
const getUserSyncs = (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => {
// return [{ type, url }];
logInfo('User syncs are not implemented in this adapter yet.');
return null;
};

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER, VIDEO],
isBidRequestValid,
buildRequests,
interpretResponse,
getUserSyncs,
};

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

Module Name : RiseMediaTech Bidder Adapter
Module Type : Bid Adapter
Maintainer : prebid@risemediatech.io
Comment thread
patmmccann marked this conversation as resolved.

# Description
Connects to RiseMediaTech Exchange for bids
RiseMediaTech supports Display & Video(Instream) currently.

This adapter is maintained by Rise Media Technologies, the legal entity behind this implementation. Our official domain is risemediatech.io, which currently redirects to pubrise.ai for operational convenience. We also own the domain risemediatech.com.
Comment thread
patmmccann marked this conversation as resolved.
Rise Media Technologies and PubRise are part of the same parent organization.
# Sample Ad Unit : Banner
```
var adUnits = [
{
code: 'test-banner-div',
mediatypes: {
banner: {
sizes:[
[320,50]
]
}
},
bids:[
{
bidder: 'risemediatech',
params: {
bidfloor: 0.001,
testMode: 1
}
}
]
}
]
```

# Sample Ad Unit : Video
```
var videoAdUnit = [
{
code: 'risemediatech',
mediatypes: {
video: {
playerSize: [640, 480], // required
context: 'instream',
mimes: ['video/mp4','video/webm'],
minduration: 5,
maxduration: 30,
startdelay: 30,
maxseq: 2,
poddur: 30,
protocols: [1,3,4],
}
},
bids:[
{
bidder: 'risemediatech',
params: {
bidfloor: 0.001
testMode: 1
}
}
]
}
]
```
Loading
Loading