Skip to content

New Bid Adapter: Ezoic - #15503

Open
austinbyron wants to merge 3 commits into
prebid:masterfrom
ezoic:add-ezoic-bid-adapter
Open

New Bid Adapter: Ezoic#15503
austinbyron wants to merge 3 commits into
prebid:masterfrom
ezoic:add-ezoic-bid-adapter

Conversation

@austinbyron

Copy link
Copy Markdown

Type of change

  • New bidder adapter

Description of change

Adds the Ezoic bid adapter (banner, video, native).

Ezoic is a publisher monetization platform serving demand across a large network of site inventory (GVL ID 347). This adapter connects to Ezoic's Prebid demand endpoint and intentionally mirrors the param contract of the Ezoic Prebid Server adapter that is already merged upstream (static/bidder-params/ezoic.json): a single optional placementId param. No params are required — publisher domains are registered and approved during Ezoic onboarding, and everything else flows through standard Prebid mechanisms (ortb2, the floors module, user ID eids, GDPR/GPP/USP consent).

  • Media types: banner, video (instream + outstream VAST), native (ORTB)

  • Floors: standard Prebid floors module (getFloor)

  • User sync: iframe sync carrying GDPR/GPP/USP consent; cookie reads/writes happen server-side inside the frame

  • Outstream: adapter returns VAST and does not bundle a renderer; standard core validation applies (publisher renderer or cache-based setup)

  • contact email of the adapter's maintainer: prebid@ezoic.com

  • official adapter submission

Docs PR: prebid/prebid.github.io#6712

Other information

Server-side counterpart: Ezoic adapter in prebid-server (merged). Unit tests cover request building, param filtering, floors, multi-format sizing, video/native payloads, response interpretation, user syncs, and consent handling (41 specs).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 Ezoic bidder adapter to Prebid.js, including banner/video/native support, request/response handling, and supporting documentation/types/tests to align with Prebid module standards.

Changes:

  • Introduces ezoic bidder implementation (request building with ORTB2 metadata + floors support, bid normalization for banner/video/native, iframe user sync with consent propagation).
  • Adds comprehensive unit tests covering request construction, floors integration, multiformat behavior, response interpretation, and user sync consent parameters.
  • Adds module documentation and TypeScript bidder params typing (placementId optional).

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
modules/ezoicBidAdapter.js New bidder adapter implementation (buildRequests/interpretResponse/user sync + metadata handling).
test/spec/modules/ezoicBidAdapter_spec.js Unit tests validating request payloads, floors, multiformat sizing, bid normalization, and user sync URLs.
modules/ezoicBidAdapter.md Adapter documentation (params, outstream expectations, user sync config).
modules/ezoicBidAdapter.d.ts TypeScript definitions for ezoic bidder params.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread modules/ezoicBidAdapter.js Outdated
bids: validBidRequests,
},
options: {
contentType: 'application/json',

expect(request.method).to.equal('POST');
expect(request.url).to.equal(ENDPOINT);
expect(request.options.contentType).to.equal('application/json');

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

Copy link
Copy Markdown

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: 888378b65d

ℹ️ 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".

Comment thread modules/ezoicBidAdapter.js Outdated
bids: validBidRequests,
},
options: {
contentType: 'application/json',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use text/plain for cross-origin bidder POSTs

On publisher pages outside g.ezoic.net, this non-safelisted Content-Type forces the browser to complete a CORS OPTIONS preflight before sending every bid request, consuming the bidder timeout and potentially turning valid bids into timeouts. Keep the JSON-encoded body but use the bidder factory's text/plain default, or explicitly specify text/plain, to avoid the extra round trip.

AGENTS.md reference: AGENTS.md:L65-L65

Useful? React with 👍 / 👎.

Comment thread modules/ezoicBidAdapter.js Outdated
Comment on lines +221 to +224
const floor = bid.getFloor({
currency: DEFAULT_CURRENCY,
mediaType: nativeOnly ? NATIVE : (videoOnly ? VIDEO : BANNER),
size: nativeOnly ? '*' : (videoOnly ? getPrimaryVideoSize(bid) : getPrimaryBannerSize(bid)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve per-format floors on multiformat requests

For a multiformat ad unit with format-specific floors, this always queries the banner floor whenever banner is present (or the video floor for video-plus-native) and attaches that single value to an impression offering every format. A high banner floor can therefore suppress otherwise valid video/native demand, while a low banner floor causes avoidable responses that core must reject against another format's floor; query and preserve floors for each offered format, or use the least restrictive floor when the endpoint only accepts one.

AGENTS.md reference: AGENTS.md:L76-L76

Useful? React with 👍 / 👎.

@austinbyron

Copy link
Copy Markdown
Author

Addressed both review points in cac1c0d:

  • Content type: switched the bid POST to text/plain (JSON body unchanged) so the request stays a CORS simple request — no OPTIONS preflight consuming bidder-timeout budget. The endpoint parses the body as JSON regardless of the header.
  • Multiformat floors: getFloor is now queried with mediaType: '*', size: '*' when an ad unit offers more than one format, so a single format's floor no longer suppresses the other formats' demand. Single-format units keep their precise per-type/size floor lookup.

Lint clean, 42 specs pass (added a multiformat wildcard-floor spec and updated the contentType assertion).

@github-actions

Copy link
Copy Markdown

Whoa there partner! This project is migrating to typescript. Consider changing the new JS files to TS, with well-defined types for what interacts with the prebid public API (for example: bid params and configuration). Thanks!

  • modules/ezoicBidAdapter.js

@github-actions

Copy link
Copy Markdown

This PR introduces changes that may not work on all browsers. According to Babel, the following polyfills may be needed, and they are not automatically included:

  • Changes to modules/ezoicBidAdapter.js may need:
    • es.array-buffer.detached
    • es.array-buffer.transfer
    • es.array-buffer.transfer-to-fixed-length
    • es.iterator.constructor
    • es.iterator.filter
    • es.iterator.find
    • es.iterator.map
    • es.iterator.reduce
    • es.json.stringify
    • es.typed-array.to-reversed
    • es.typed-array.to-sorted
    • es.typed-array.with
    • esnext.array-buffer.detached
    • esnext.array-buffer.transfer
    • esnext.array-buffer.transfer-to-fixed-length
    • esnext.iterator.constructor
    • esnext.iterator.filter
    • esnext.iterator.find
    • esnext.iterator.map
    • esnext.iterator.reduce
    • esnext.json.parse
    • esnext.typed-array.to-reversed
    • esnext.typed-array.to-sorted
    • esnext.typed-array.with
    • esnext.uint8-array.set-from-base64
    • esnext.uint8-array.set-from-hex
    • esnext.uint8-array.to-base64
    • esnext.uint8-array.to-hex
    • web.url-search-params.delete
    • web.url-search-params.has
    • web.url-search-params.size
  • Changes to test/spec/modules/ezoicBidAdapter_spec.js may need:
    • es.json.stringify
    • esnext.json.parse
    • web.url-search-params.delete
    • web.url-search-params.has
    • web.url-search-params.size

The best way to address this is to provide good test coverage, as normal PR checks run unit tests on older browsers.

@review-assignment-bot
review-assignment-bot Bot requested a review from osazos August 23, 2026 00:49
Bare sinon.restore() restores the global default sandbox, which wipes
justIdSystem_spec's file-load-time getAtm stub when the two specs share
a Karma chunk (ezoic* runs before justId* alphabetically), failing its
"getId basic / all ok" test. Switch to a per-test sandbox and replace
the mid-test global restore with a retargeted stub.
@austinbyron

Copy link
Copy Markdown
Author

Fixed the unit-test chunk 4 failure in 2d369a2.

Root cause: our spec's afterEach called bare sinon.restore(), which restores sinon's global default sandbox — not just our stubs. justIdSystem_spec.js creates its jtUtils.getAtm stub once at file load time on that same default sandbox, so when the chunk split put our spec in the same Karma process ahead of it (which is what changed in the re-run — master's spec list shifted the chunk boundaries), our restore wiped that stub and JustId's "getId basic / all ok" failed with Cannot read properties of undefined (reading 'uid').

Fix: switched our spec to a per-test sinon.createSandbox() (and replaced a mid-test global restore with a retargeted stub). No changes outside our spec file.

Verified locally: gulp test-only --file=test/spec/modules/ezoicBidAdapter_spec.js --file=test/spec/modules/justIdSystem_spec.js reproduces the CI failure on the previous commit and passes 54/54 with this fix.

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.

2 participants