Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yandex: use ortb2 info & Core: add webdriver flag #11110

Merged
merged 5 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
49 changes: 22 additions & 27 deletions modules/yandexBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { formatQS, deepAccess, deepSetValue, triggerPixel, _each, _map } from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, NATIVE } from '../src/mediaTypes.js'
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import { config } from '../src/config.js';
import { BANNER, NATIVE } from '../src/mediaTypes.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import { _each, _map, deepAccess, deepSetValue, formatQS, triggerPixel } from '../src/utils.js';

/**
* @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid
Expand Down Expand Up @@ -53,7 +53,7 @@ const DEFAULT_CURRENCY = 'EUR';
/**
* @type {MediaType[]}
*/
const SUPPORTED_MEDIA_TYPES = [ BANNER, NATIVE ];
const SUPPORTED_MEDIA_TYPES = [BANNER, NATIVE];
const SSP_ID = 10500;

const IMAGE_ASSET_TYPES = {
Expand Down Expand Up @@ -121,15 +121,7 @@ export const spec = {
buildRequests: function(validBidRequests, bidderRequest) {
validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);

let referrer = '';
let domain = '';
let page = '';

if (bidderRequest && bidderRequest.refererInfo) {
referrer = bidderRequest.refererInfo.ref;
domain = bidderRequest.refererInfo.domain;
page = bidderRequest.refererInfo.page;
}
const ortb2 = bidderRequest.ortb2;

let timeout = null;
if (bidderRequest) {
Expand All @@ -146,7 +138,7 @@ export const spec = {

const queryParams = {
'imp-id': impId,
'target-ref': targetRef || domain,
'target-ref': targetRef || ortb2?.site?.domain,
'ssp-id': SSP_ID,
};

Expand Down Expand Up @@ -177,24 +169,20 @@ export const spec = {
const data = {
id: bidRequest.bidId,
imp: [imp],
site: {
ref: referrer,
page,
domain,
},
site: ortb2?.site,
tmax: timeout,
user: ortb2?.user,
device: {
...ortb2?.device,
ext: getDeviceExt(),
},
};

const eids = deepAccess(bidRequest, 'userIdAsEids');
if (eids && eids.length) {
deepSetValue(data, 'user.ext.eids', eids);
}

const userData = deepAccess(bidRequest, 'ortb2.user.data');
if (userData && userData.length) {
deepSetValue(data, 'user.data', userData);
}

const queryParamsString = formatQS(queryParams);
return {
method: 'POST',
Expand Down Expand Up @@ -274,8 +262,8 @@ function getBidfloor(bidRequest) {
const floorInfo = bidRequest.getFloor({
currency: DEFAULT_CURRENCY,
mediaType: type,
size: bidRequest.sizes || '*' }
)
size: bidRequest.sizes || '*'
})
floors.push(floorInfo);
}
});
Expand Down Expand Up @@ -332,7 +320,7 @@ function mapNative(bidRequest) {
}

function mapAsset(assetCode, adUnitAssetParams, nativeAsset) {
const [ nativeAssetId, nativeAssetType ] = nativeAsset;
const [nativeAssetId, nativeAssetType] = nativeAsset;
const asset = {
id: nativeAssetId,
};
Expand Down Expand Up @@ -493,4 +481,11 @@ function addRTT(url, rtt) {
return url;
}

/** @returns {{webdriver: boolean}} */
function getDeviceExt() {
return {
webdriver: self.navigator?.webdriver === true
chernodub marked this conversation as resolved.
Show resolved Hide resolved
};
}

registerBidder(spec);
1 change: 1 addition & 0 deletions src/auction.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
* @property {refererInfo} refererInfo - referer info object
* @property {string} [tid] - random UUID (used for s2s)
* @property {string} [src] - s2s or client (used for s2s)
* @property {import('./types/ortb2.js').Ortb2.Ortb2Object} [ortb2] Global (not specific to any adUnit) first party data to use for all requests in this auction.
*/

/**
Expand Down
41 changes: 41 additions & 0 deletions src/types/ortb2.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export namespace Ortb2 {
patmmccann marked this conversation as resolved.
Show resolved Hide resolved
type Site = {
page?: string;
ref?: string;
domain?: string;
publisher?: {
domain?: string;
};
keywords?: string;
};

type Device = {
w?: number;
h?: number;
dnt?: 0 | 1;
ua?: string;
language: string;
sua?: {
source?: number;
platform: unknown;
browsers: unknown[];
mobile: number;
chernodub marked this conversation as resolved.
Show resolved Hide resolved
};
};

type Regs = {
coppa?: unknown;
ext?: { gdpr?: unknown; us_privacy?: unknown };
};

type User = {
ext?: unknown;
};

type Ortb2Object = {
Copy link
Collaborator

@patmmccann patmmccann Feb 20, 2024

Choose a reason for hiding this comment

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

this is incomplete, ortb object might have site, dooh, or app, but not more than one. Do you intend to list them all out?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I'll add the props dooh, app. I couldn't find their exact definition based on the usage, so I'll just use unknown. If needed, these could definitely be extended in the future.

Copy link
Contributor Author

@chernodub chernodub Feb 21, 2024

Choose a reason for hiding this comment

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

Probably would be a good idea to port https://github.com/prebid/openrtb/tree/main/openrtb2 to TS sometime in the future. Should we create an issue for that?

Copy link
Collaborator

Choose a reason for hiding this comment

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

i think #5218 kind of covers it

Copy link
Collaborator

Choose a reason for hiding this comment

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

#5097 actually...

site?: Site;
device?: Device;
regs?: Regs;
user?: User;
};
}
107 changes: 88 additions & 19 deletions test/spec/modules/yandexBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { assert, expect } from 'chai';
import { spec, NATIVE_ASSETS } from 'modules/yandexBidAdapter.js';
import { NATIVE_ASSETS, spec } from 'modules/yandexBidAdapter.js';
import * as utils from 'src/utils.js';
import { BANNER, NATIVE } from '../../../src/mediaTypes';
import { config } from '../../../src/config';
import { BANNER, NATIVE } from '../../../src/mediaTypes';

describe('Yandex adapter', function () {
describe('isBidRequestValid', function () {
Expand Down Expand Up @@ -41,11 +41,45 @@ describe('Yandex adapter', function () {
});

describe('buildRequests', function () {
/** @type {import('../../../src/auction').BidderRequest} */
const bidderRequest = {
refererInfo: {
domain: 'ya.ru',
ref: 'https://ya.ru/',
page: 'https://ya.ru/',
ortb2: {
site: {
domain: 'ya.ru',
ref: 'https://ya.ru/',
page: 'https://ya.ru/',
publisher: {
domain: 'ya.ru',
},
},
device: {
w: 1600,
h: 900,
dnt: 0,
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
language: 'en',
sua: {
source: 1,
platform: {
brand: 'macOS',
},
browsers: [
{
brand: 'Not_A Brand',
version: ['8'],
},
{
brand: 'Chromium',
version: ['120'],
},
{
brand: 'Google Chrome',
version: ['120'],
},
],
mobile: 0,
},
},
},
gdprConsent: {
gdprApplies: 1,
Expand Down Expand Up @@ -107,12 +141,10 @@ describe('Yandex adapter', function () {
});

it('should send eids and ortb2 user data if defined', function() {
const bidRequestExtra = {
userIdAsEids: [{
source: 'sharedid.org',
uids: [{ id: '01', atype: 1 }],
}],
const bidderRequestWithUserData = {
...bidderRequest,
ortb2: {
...bidderRequest.ortb2,
user: {
data: [
{
Expand All @@ -127,17 +159,24 @@ describe('Yandex adapter', function () {
},
],
},
},
}
};
const bidRequestExtra = {
userIdAsEids: [{
source: 'sharedid.org',
uids: [{ id: '01', atype: 1 }],
}],
};

const expected = {
ext: {
eids: bidRequestExtra.userIdAsEids,
},
data: bidRequestExtra.ortb2.user.data,
data: bidderRequestWithUserData.ortb2.user.data,
};

const bannerRequest = getBidRequest(bidRequestExtra);
const requests = spec.buildRequests([bannerRequest], bidderRequest);
const requests = spec.buildRequests([bannerRequest], bidderRequestWithUserData);

expect(requests).to.have.lengthOf(1);
const request = requests[0];
Expand All @@ -149,6 +188,31 @@ describe('Yandex adapter', function () {
expect(data.user).to.deep.equal(expected);
});

it('should send device with webdriver ext', function() {
const expected = {
device: {
...bidderRequest.ortb2.device,
ext: {
webdriver: true
}
}
};

const requests = spec.buildRequests([getBidRequest()], bidderRequest);

expect(requests[0].data.device).to.deep.equal(expected.device);
});

it('should send site', function() {
const expected = {
site: bidderRequest.ortb2.site
};

const requests = spec.buildRequests([getBidRequest()], bidderRequest);

expect(requests[0].data.site).to.deep.equal(expected.site);
});

describe('banner', () => {
it('should create valid banner object', () => {
const bannerRequest = getBidRequest({
Expand Down Expand Up @@ -496,41 +560,46 @@ describe('Yandex adapter', function () {
});

it('Should not trigger pixel if bid does not contain nurl', function() {
const result = spec.onBidWon({});
spec.onBidWon({});

expect(utils.triggerPixel.callCount).to.equal(0)
})

it('Should trigger pixel if bid has nurl', function() {
const result = spec.onBidWon({
spec.onBidWon({
nurl: 'https://example.com/some-tracker',
timeToRespond: 378,
});

expect(utils.triggerPixel.callCount).to.equal(1)
expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker?rtt=378')
})

it('Should trigger pixel if bid has nurl with path & params', function() {
const result = spec.onBidWon({
spec.onBidWon({
nurl: 'https://example.com/some-tracker/abcdxyz?param1=1&param2=2',
timeToRespond: 378,
});

expect(utils.triggerPixel.callCount).to.equal(1)
expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker/abcdxyz?param1=1&param2=2&rtt=378')
})

it('Should trigger pixel if bid has nurl with path & params and rtt macros', function() {
const result = spec.onBidWon({
spec.onBidWon({
nurl: 'https://example.com/some-tracker/abcdxyz?param1=1&param2=2&custom-rtt=${RTT}',
timeToRespond: 378,
});

expect(utils.triggerPixel.callCount).to.equal(1)
expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker/abcdxyz?param1=1&param2=2&custom-rtt=378')
})

it('Should trigger pixel if bid has nurl and there is no timeToRespond param, but has rtt macros in nurl', function() {
const result = spec.onBidWon({
spec.onBidWon({
nurl: 'https://example.com/some-tracker/abcdxyz?param1=1&param2=2&custom-rtt=${RTT}',
});

expect(utils.triggerPixel.callCount).to.equal(1)
expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker/abcdxyz?param1=1&param2=2&custom-rtt=-1')
})
Expand Down