Skip to content

AdSmartx Bid Adapter : New Bidder Adapter#14559

Open
pritishmd-talentica wants to merge 12 commits intoprebid:masterfrom
smart-exchange-ai-digital:master
Open

AdSmartx Bid Adapter : New Bidder Adapter#14559
pritishmd-talentica wants to merge 12 commits intoprebid:masterfrom
smart-exchange-ai-digital:master

Conversation

@pritishmd-talentica
Copy link
Contributor

@pritishmd-talentica pritishmd-talentica commented Mar 6, 2026

Type of change

  • Bugfix

  • Feature

  • [ x] New bidder adapter

  • [ x] Updated bidder adapter RiseMediaTech Bidder Adapter

  • Code style update (formatting, local variables)

  • Refactoring (no functional changes, no api changes)

  • Build related changes

  • CI related changes

  • Does this change affect user-facing APIs or examples documented on http://prebid.org?

  • Other

Description of change

Added a bidder adapter for AdSmartX
Maintainer : prebid@aidigital.com

Sample Ad Unit : Banner

    var adUnits = [
        {
            code: 'test-banner-div',
            mediaTypes: {
                banner: {
                    sizes:[
                        [320,50]
                    ]
                }
            },
            bids:[
                {
                    bidder: 'adsmartx',
                    params: {
                        bidfloor: 0.001,        
                        testMode: 1,
                        sspId: 123456,
                        siteId: 987654,
                        sspUserId: 'u1234'
                    }
                }
            ]
        }
    ]

Sample Ad Unit : Video

    var videoAdUnit = [
        {
            code: 'adsmartx',
            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: 'adsmartx',
                    params: {
                        bidfloor: 0.001,
                        testMode: 1,
                        sspId: 123456,
                        siteId: 987654,
                        sspUserId: 'u1234'
                    }
                }
            ]
        }
    ]

Other information

Documentation PR:
prebid/prebid.github.io#6467

Copilot AI review requested due to automatic review settings March 6, 2026 17:29
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c4fe9eae4c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const responses = [];
bidResp.seatbid.forEach(seatbid => {
if (!Array.isArray(seatbid.bid) || seatbid.bid.length === 0) return;
const bid = seatbid.bid[0];

Choose a reason for hiding this comment

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

P1 Badge Iterate all bids in each seatbid entry

interpretResponse only reads seatbid.bid[0], so additional bids in the same seatbid are dropped. If the exchange returns multiple bids for multiple impressions in one seatbid (a valid ORTB response shape), this adapter will silently lose eligible bids and reduce auction competitiveness/revenue.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The ad server will return only one bid that has won the auction conducted in our ad server but since the ad server is OpenRTB compliant, the bid variable is an array.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new AdSmartX bidder adapter and introduces shared ORTB conversion/response/sync utilities, also refactoring the existing RiseMediaTech adapter to use those utilities.

Changes:

  • Added adsmartx bidder adapter (module + in-repo markdown doc).
  • Added shared helper library libraries/adsmartxUtils/bidderUtils.js (converter, request builder, response interpreter, user sync builder).
  • Updated/added unit tests for adsmartx and adjusted one RiseMediaTech response expectation.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
modules/adsmartxBidAdapter.js New AdSmartX bidder adapter wired to shared bidderUtils helpers.
modules/adsmartxBidAdapter.md New adapter documentation (currently missing bid params table).
libraries/adsmartxUtils/bidderUtils.js New shared ORTB converter/request/response/sync helpers used by adapters.
modules/risemediatechBidAdapter.js Refactored to use adsmartxUtils helpers; behavior changes in consent mapping and user sync return.
test/spec/modules/adsmartxBidAdapter_spec.js New AdSmartX adapter tests (currently contains JS syntax errors).
test/spec/libraries/adsmartxUtils/bidderUtils_spec.js New unit tests for shared bidderUtils helpers.
test/spec/modules/risemediatechBidAdapter_spec.js Adjusted expectation for unknown mtype to default to banner.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +92 to +97
request.user = request.user || {};
}
if (bidderRequest.gdprConsent) {
logInfo('Adding GDPR consent information to request:', bidderRequest.gdprConsent);
request.regs.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
request.user.consent = bidderRequest.gdprConsent.consentString;
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

createConverter currently maps GDPR consent to request.regs.gdpr and request.user.consent. This is a behavioral change vs the previous risemediatech adapter implementation and will fail existing tests that expect regs.ext.gdpr and user.ext.consent (e.g. test/spec/modules/risemediatechBidAdapter_spec.js). Please keep the same ORTB field locations as before (or update the adapter + tests together and confirm the endpoint expects the new fields).

Suggested change
request.user = request.user || {};
}
if (bidderRequest.gdprConsent) {
logInfo('Adding GDPR consent information to request:', bidderRequest.gdprConsent);
request.regs.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
request.user.consent = bidderRequest.gdprConsent.consentString;
request.regs.ext = request.regs.ext || {};
request.user = request.user || {};
request.user.ext = request.user.ext || {};
}
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;

Copilot uses AI. Check for mistakes.
Comment on lines +182 to +193
const bidResponse = {
requestId: bid.impid,
cpm: bid.price,
currency: bidResp.cur || defaultCurrency,
width: bid.w,
height: bid.h,
ad: bid.adm,
creativeId: bid.crid,
netRevenue: true,
ttl: defaultTtl,
meta: { advertiserDomains: bid.adomain || [] },
};
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

interpretResponse unconditionally uses bid.price for cpm and pushes the bid even if price is missing/undefined. That produces bid objects with cpm: undefined which will be filtered out later (or cause downstream issues). Consider skipping bids that are missing required OpenRTB fields like impid and price (and optionally adm).

Copilot uses AI. Check for mistakes.
Connects to AdSmartX Exchange for bids
AdSmartX supports Display & Video(Instream) currently.

This adapter is maintained by Smart Exchange, the legal entity behind this implementation. Our official domain is [AI Digital](https://www.aidigital.com/).
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

This module doc is missing a "Bid Parameters" section/table (required/optional params, types, descriptions) which is the established format for bidder adapter docs in this repo (see many other modules/*BidAdapter.md files). Please add a parameter table for bidfloor, testMode, sspId, siteId, sspUserId, etc. so integrators know what to pass.

Suggested change
This adapter is maintained by Smart Exchange, the legal entity behind this implementation. Our official domain is [AI Digital](https://www.aidigital.com/).
This adapter is maintained by Smart Exchange, the legal entity behind this implementation. Our official domain is [AI Digital](https://www.aidigital.com/).
# Bid Parameters
| Name | Scope | Type | Required | Description |
|------------|--------------|---------|----------|-----------------------------------------------------------------------------|
| `sspId` | Banner,Video | number | Yes | Publisher/SSP identifier assigned by AdSmartX. |
| `siteId` | Banner,Video | number | Yes | Site or app identifier assigned by AdSmartX. |
| `bidfloor` | Banner,Video | number | No | Minimum bid price in USD for the impression. |
| `testMode` | Banner,Video | number | No | Test mode flag (e.g. `1` to enable test requests; omit or `0` for live). |
| `sspUserId`| Banner,Video | string | No | External user identifier to help AdSmartX recognize the user (if desired). |

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +35
// TODO: set gvlid once confirmed with AI Digital / AdSmartX team
gvlid: undefined,
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Setting gvlid: undefined is unusual and makes it look like the adapter intentionally declares a GVL ID value. Since gvlid is optional, it’s clearer to omit the property entirely until you have the correct numeric ID (or set a real value once assigned).

Suggested change
// TODO: set gvlid once confirmed with AI Digital / AdSmartX team
gvlid: undefined,
// TODO: add numeric gvlid once confirmed with AI Digital / AdSmartX team

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +23
logInfo('Using SSP user ID from bid params:', bidParams.sspUserId);
return bidParams.sspUserId;
}
const ortb2UserId = deepAccess(bidderRequest, 'ortb2.user.id');
if (ortb2UserId) {
logInfo('Using SSP user ID from ORTB2 user.id:', ortb2UserId);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Be careful about logging user identifiers: getPublisherUserId logs the raw sspUserId / ortb2.user.id. Even though logInfo is gated by debug, it can still expose user IDs in console logs. Consider removing these logs or redacting/truncating the ID value.

Suggested change
logInfo('Using SSP user ID from bid params:', bidParams.sspUserId);
return bidParams.sspUserId;
}
const ortb2UserId = deepAccess(bidderRequest, 'ortb2.user.id');
if (ortb2UserId) {
logInfo('Using SSP user ID from ORTB2 user.id:', ortb2UserId);
logInfo('Using SSP user ID from bid params');
return bidParams.sspUserId;
}
const ortb2UserId = deepAccess(bidderRequest, 'ortb2.user.id');
if (ortb2UserId) {
logInfo('Using SSP user ID from ORTB2 user.id');

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +82
video: {
w: 640,
h: 480
// mimes missing
}
}
};
expect(spec.isBidRequestValid(invalidVideoRequest)).to.equal(false);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

This test file contains invalid object literal syntax (missing commas / braces), which will prevent the test suite from even parsing. For example, h: 480 is missing a trailing comma and the surrounding braces/commas are inconsistent in this block; please fix the syntax throughout the file and run the linter/tests to catch similar issues.

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +9
import { logInfo } from '../src/utils.js';
import {
createConverter,
isBidRequestValid as validateBidRequest,
createBuildRequests,
interpretResponse as interpretResponseUtil,
} from '../libraries/adsmartxUtils/bidderUtils.js';
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The PR description is for adding a new AdSmartX adapter, but this change also refactors the existing risemediatech adapter to depend on the new libraries/adsmartxUtils/* helpers. Please call this out in the PR description (or split into a separate refactor PR), since it changes behavior for an existing bidder adapter and increases review risk.

Copilot uses AI. Check for mistakes.
type: syncOptions.iframeEnabled ? 'iframe' : 'image',
url: syncUrl + queryString,
}];
logInfo('Returning user syncs:', syncs);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

createGetUserSyncs logs the full sync URL (including gdpr_consent / gpp strings) via logInfo('Returning user syncs:', syncs). That can leak consent strings into logs when debug is enabled. Consider removing this log line or logging only the sync type without query parameters.

Suggested change
logInfo('Returning user syncs:', syncs);
// Log only non-sensitive metadata to avoid leaking consent strings in URLs
logInfo('Returning user syncs:', syncs.map(sync => ({ type: sync.type })));

Copilot uses AI. Check for mistakes.
Comment on lines +346 to +355
h: 250,
crid: 'creative123',
adomain: ['example.com']
// mtype missing
}
]
}
]
}
};
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Another syntax error here: adomain: ['example.com'] is missing a trailing comma before the comment, which will break parsing. There are multiple similar missing commas in response fixtures in this spec; please ensure all object/array literals are valid JS.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants