From 325c162276d43804a01ae815513b595b865977ec Mon Sep 17 00:00:00 2001 From: Alexander Bogdanov Date: Mon, 15 Nov 2021 17:03:22 +0700 Subject: [PATCH 01/29] Alkimi bid adapter --- modules/alkimiAdapter.js | 105 ++++++++++++++++ modules/alkimiAdapter.md | 29 +++++ test/spec/modules/alkimiAdapter_spec.js | 161 ++++++++++++++++++++++++ 3 files changed, 295 insertions(+) create mode 100644 modules/alkimiAdapter.js create mode 100644 modules/alkimiAdapter.md create mode 100644 test/spec/modules/alkimiAdapter_spec.js diff --git a/modules/alkimiAdapter.js b/modules/alkimiAdapter.js new file mode 100644 index 00000000000..705057f5c77 --- /dev/null +++ b/modules/alkimiAdapter.js @@ -0,0 +1,105 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { deepClone, deepAccess } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { VIDEO } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'alkimi'; +export const ENDPOINT = 'https://exchange-qa.alkimi.asteriosoft.com/bid?prebid=true' + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: ['banner', 'video'], + + isBidRequestValid: function (bid) { + return !!(bid.params && bid.params.bidFloor && bid.params.publisherToken); + }, + + buildRequests: function (validBidRequests, bidderRequest) { + let bids = []; + validBidRequests.forEach(bidRequest => { + let sizes = prepareSizes(bidRequest.sizes) + + bids.push({ + bidId: bidRequest.bidId, + publisherToken: bidRequest.params.publisherToken, + pos: bidRequest.params.pos, + bidFloor: bidRequest.params.bidFloor, + width: sizes[0].width, + height: sizes[0].height, + impMediaType: getFormatType(bidRequest) + }) + }) + + let payload = { + requestId: bidderRequest.bidderRequestId, + bids, + referer: bidderRequest.refererInfo.referer + } + + const options = { + contentType: 'application/json', + customHeaders: { + 'Rtb-Direct': true + } + } + + return { + method: 'POST', + url: ENDPOINT, + data: payload, + options + }; + }, + + interpretResponse: function (serverResponse, request) { + const serverBody = serverResponse.body; + if (!serverBody || typeof serverBody !== 'object') { + return []; + } + + const { prebidResponse } = serverBody; + if (!prebidResponse || typeof prebidResponse !== 'object') { + return []; + } + + let bids = []; + prebidResponse.forEach(bidResponse => { + let bid = deepClone(bidResponse); + bid.cpm = parseFloat(bidResponse.cpm); + + // banner or video + if (VIDEO === bid.format) { + bid.vastXml = bid.ad; + } + + bid.meta = {}; + bid.meta.advertiserDomains = bid.adomain || []; + + bids.push(bid); + }) + + return bids; + }, + + onBidWon: function (bid) { + if (bid.winUrl) { + const cpm = bid.cpm; + const winUrl = bid.winUrl.replace(/\$\{AUCTION_PRICE\}/, cpm); + ajax(winUrl, null); + return true; + } + return false; + } +} + +function prepareSizes(sizes) { + return sizes && sizes.map(size => ({ width: size[0], height: size[1] })); +} + +const getFormatType = bidRequest => { + if (deepAccess(bidRequest, 'mediaTypes.banner')) return 'Banner' + if (deepAccess(bidRequest, 'mediaTypes.video')) return 'Video' + if (deepAccess(bidRequest, 'mediaTypes.audio')) return 'Audio' +} + +registerBidder(spec); diff --git a/modules/alkimiAdapter.md b/modules/alkimiAdapter.md new file mode 100644 index 00000000000..dbaea323ef3 --- /dev/null +++ b/modules/alkimiAdapter.md @@ -0,0 +1,29 @@ +# Overview + +``` +Module Name: Alkimi Bidder Adapter +Module Type: Bidder Adapter +Maintainer: abogdanov@asteriosoft.com +``` + +# Description + +Connects to Alkimi Bidder for bids. +Alkimi bid adapter supports Banner and Video ads. + +# Test Parameters +``` +const adUnits = [ + { + bids: [ + { + bidder: 'alkimi', + params: { + bidFloor: 0.1 + publisherToken: '?????????????????????', // zoneToken provided by Alkimi + } + } + ] + } +]; +``` diff --git a/test/spec/modules/alkimiAdapter_spec.js b/test/spec/modules/alkimiAdapter_spec.js new file mode 100644 index 00000000000..055fb9eb026 --- /dev/null +++ b/test/spec/modules/alkimiAdapter_spec.js @@ -0,0 +1,161 @@ +import { expect } from 'chai' +import { ENDPOINT, spec } from 'modules/alkimiAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' + +const REQUEST = { + 'bidId': '456', + 'bidder': 'alkimi', + 'sizes': [[300, 250]], + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]] + } + }, + 'params': { + bidFloor: 0.1, + publisherToken: 'e64782a4-8e68-4c38-965b-80ccf115d46f', + pos: 7 + } +} + +const BIDDER_BANNER_RESPONSE = { + 'prebidResponse': [{ + 'ad': '
test
', + 'requestId': 'e64782a4-8e68-4c38-965b-80ccf115d46d', + 'cpm': 900.5, + 'currency': 'USD', + 'width': 640, + 'height': 480, + 'ttl': 300, + 'creativeId': 1, + 'netRevenue': true, + 'winUrl': 'http://test.com', + 'format': 'banner', + 'adomain': ['test.com'] + }] +} + +const BIDDER_VIDEO_RESPONSE = { + 'prebidResponse': [{ + 'ad': 'vast', + 'requestId': 'e64782a4-8e68-4c38-965b-80ccf115d46z', + 'cpm': 800.4, + 'currency': 'USD', + 'width': 1024, + 'height': 768, + 'ttl': 200, + 'creativeId': 2, + 'netRevenue': true, + 'winUrl': 'http://test.com', + 'format': 'video', + 'adomain': ['test.com'] + }] +} + +const BIDDER_NO_BID_RESPONSE = '' + +describe('alkimiAdapter', function () { + const adapter = newBidder(spec) + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function') + }) + }) + + describe('isBidRequestValid', function () { + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(REQUEST)).to.equal(true) + }) + + it('should return false when required params are not passed', function () { + let bid = Object.assign({}, REQUEST) + delete bid.params.publisherToken + expect(spec.isBidRequestValid(bid)).to.equal(false) + + bid = Object.assign({}, REQUEST) + delete bid.params.bidFloor + expect(spec.isBidRequestValid(bid)).to.equal(false) + + bid = Object.assign({}, REQUEST) + delete bid.params + expect(spec.isBidRequestValid(bid)).to.equal(false) + }) + }) + + describe('buildRequests', function () { + let bidRequests = [REQUEST] + const bidderRequest = spec.buildRequests(bidRequests, { + bidderRequestId: '123', + refererInfo: { + referer: 'http://test.com/path.html' + } + }) + + it('sends bid request to ENDPOINT via POST', function () { + expect(bidderRequest.method).to.equal('POST') + expect(bidderRequest.data.requestId).to.equal('123') + expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') + expect(bidderRequest.data.bids).to.deep.contains({ bidId: '456', publisherToken: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner' }) + expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true }) + expect(bidderRequest.options.contentType).to.equal('application/json') + expect(bidderRequest.url).to.equal(ENDPOINT) + }) + }) + + describe('interpretResponse', function () { + it('handles banner request : should get correct bid response', function () { + const result = spec.interpretResponse({ body: BIDDER_BANNER_RESPONSE }, {}) + + expect(result[0]).to.have.property('ad').equal('
test
') + expect(result[0]).to.have.property('requestId').equal('e64782a4-8e68-4c38-965b-80ccf115d46d') + expect(result[0]).to.have.property('cpm').equal(900.5) + expect(result[0]).to.have.property('currency').equal('USD') + expect(result[0]).to.have.property('width').equal(640) + expect(result[0]).to.have.property('height').equal(480) + expect(result[0]).to.have.property('ttl').equal(300) + expect(result[0]).to.have.property('creativeId').equal(1) + expect(result[0]).to.have.property('netRevenue').equal(true) + expect(result[0]).to.have.property('winUrl').equal('http://test.com') + expect(result[0]).to.have.property('format').equal('banner') + expect(result[0].meta).to.exist.property('advertiserDomains') + expect(result[0].meta).to.have.property('advertiserDomains').lengthOf(1) + }) + + it('handles video request : should get correct bid response', function () { + const result = spec.interpretResponse({ body: BIDDER_VIDEO_RESPONSE }, {}) + + expect(result[0]).to.have.property('ad').equal('vast') + expect(result[0]).to.have.property('requestId').equal('e64782a4-8e68-4c38-965b-80ccf115d46z') + expect(result[0]).to.have.property('cpm').equal(800.4) + expect(result[0]).to.have.property('currency').equal('USD') + expect(result[0]).to.have.property('width').equal(1024) + expect(result[0]).to.have.property('height').equal(768) + expect(result[0]).to.have.property('ttl').equal(200) + expect(result[0]).to.have.property('creativeId').equal(2) + expect(result[0]).to.have.property('netRevenue').equal(true) + expect(result[0]).to.have.property('winUrl').equal('http://test.com') + expect(result[0]).to.have.property('format').equal('video') + expect(result[0]).to.have.property('vastXml').equal('vast') + expect(result[0].meta).to.exist.property('advertiserDomains') + expect(result[0].meta).to.have.property('advertiserDomains').lengthOf(1) + }) + + it('handles no bid response : should get empty array', function () { + let result = spec.interpretResponse({ body: undefined }, {}) + expect(result).to.deep.equal([]) + + result = spec.interpretResponse({ body: BIDDER_NO_BID_RESPONSE }, {}) + expect(result).to.deep.equal([]) + }) + }) + + describe('onBidWon', function () { + it('handles banner win: should get true', function () { + const win = BIDDER_BANNER_RESPONSE.prebidResponse[0] + const bidWonResult = spec.onBidWon(win) + + expect(bidWonResult).to.equal(true) + }) + }) +}) From df09e0d10b110e7e63f2a515dd738b69e5f3f49f Mon Sep 17 00:00:00 2001 From: Alexander Bogdanov Date: Wed, 17 Nov 2021 10:50:58 +0700 Subject: [PATCH 02/29] Alkimi bid adapter --- modules/alkimiAdapter.js | 4 ++-- modules/alkimiAdapter.md | 4 ++-- test/spec/modules/alkimiAdapter_spec.js | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/alkimiAdapter.js b/modules/alkimiAdapter.js index 705057f5c77..e89212e614a 100644 --- a/modules/alkimiAdapter.js +++ b/modules/alkimiAdapter.js @@ -11,7 +11,7 @@ export const spec = { supportedMediaTypes: ['banner', 'video'], isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.bidFloor && bid.params.publisherToken); + return !!(bid.params && bid.params.bidFloor && bid.params.token); }, buildRequests: function (validBidRequests, bidderRequest) { @@ -21,7 +21,7 @@ export const spec = { bids.push({ bidId: bidRequest.bidId, - publisherToken: bidRequest.params.publisherToken, + token: bidRequest.params.token, pos: bidRequest.params.pos, bidFloor: bidRequest.params.bidFloor, width: sizes[0].width, diff --git a/modules/alkimiAdapter.md b/modules/alkimiAdapter.md index dbaea323ef3..92a7c2aefe1 100644 --- a/modules/alkimiAdapter.md +++ b/modules/alkimiAdapter.md @@ -19,8 +19,8 @@ const adUnits = [ { bidder: 'alkimi', params: { - bidFloor: 0.1 - publisherToken: '?????????????????????', // zoneToken provided by Alkimi + bidFloor: 0.1, + token: '?????????????????????', // Publisher Token provided by Alkimi } } ] diff --git a/test/spec/modules/alkimiAdapter_spec.js b/test/spec/modules/alkimiAdapter_spec.js index 055fb9eb026..6013b2bfbee 100644 --- a/test/spec/modules/alkimiAdapter_spec.js +++ b/test/spec/modules/alkimiAdapter_spec.js @@ -13,7 +13,7 @@ const REQUEST = { }, 'params': { bidFloor: 0.1, - publisherToken: 'e64782a4-8e68-4c38-965b-80ccf115d46f', + token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7 } } @@ -70,7 +70,7 @@ describe('alkimiAdapter', function () { it('should return false when required params are not passed', function () { let bid = Object.assign({}, REQUEST) - delete bid.params.publisherToken + delete bid.params.token expect(spec.isBidRequestValid(bid)).to.equal(false) bid = Object.assign({}, REQUEST) @@ -96,7 +96,7 @@ describe('alkimiAdapter', function () { expect(bidderRequest.method).to.equal('POST') expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') - expect(bidderRequest.data.bids).to.deep.contains({ bidId: '456', publisherToken: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner' }) + expect(bidderRequest.data.bids).to.deep.contains({ bidId: '456', token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner' }) expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true }) expect(bidderRequest.options.contentType).to.equal('application/json') expect(bidderRequest.url).to.equal(ENDPOINT) From b3e36881c248a6aebd2d8c2a4507162d800b4dbf Mon Sep 17 00:00:00 2001 From: Alexander Bogdanov Date: Wed, 17 Nov 2021 16:17:43 +0700 Subject: [PATCH 03/29] Alkimi bid adapter --- modules/alkimiAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/alkimiAdapter.js b/modules/alkimiAdapter.js index e89212e614a..cdd0dabc68c 100644 --- a/modules/alkimiAdapter.js +++ b/modules/alkimiAdapter.js @@ -4,7 +4,7 @@ import { ajax } from '../src/ajax.js'; import { VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'alkimi'; -export const ENDPOINT = 'https://exchange-qa.alkimi.asteriosoft.com/bid?prebid=true' +export const ENDPOINT = 'https://exchange-dev.alkimi.asteriosoft.com/bid?prebid=true' export const spec = { code: BIDDER_CODE, @@ -68,7 +68,7 @@ export const spec = { bid.cpm = parseFloat(bidResponse.cpm); // banner or video - if (VIDEO === bid.format) { + if (VIDEO === bid.mediaType) { bid.vastXml = bid.ad; } From 144cda7ab87bafaa182985a91d74138a5613e98a Mon Sep 17 00:00:00 2001 From: Alexander Bogdanov Date: Mon, 7 Feb 2022 11:42:22 +0700 Subject: [PATCH 04/29] alkimi adapter --- modules/alkimiAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/alkimiAdapter.js b/modules/alkimiAdapter.js index cdd0dabc68c..db2760914b1 100644 --- a/modules/alkimiAdapter.js +++ b/modules/alkimiAdapter.js @@ -4,7 +4,7 @@ import { ajax } from '../src/ajax.js'; import { VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'alkimi'; -export const ENDPOINT = 'https://exchange-dev.alkimi.asteriosoft.com/bid?prebid=true' +export const ENDPOINT = 'https://exchange-dev.alkimi.asteriosoft.com/bid?prebid=true'; export const spec = { code: BIDDER_CODE, From c14dcd2fb6acf306f91a4eec057053188d47385b Mon Sep 17 00:00:00 2001 From: Alexander Bogdanov Date: Tue, 8 Feb 2022 13:18:20 +0700 Subject: [PATCH 05/29] onBidWon change --- modules/alkimiAdapter.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/modules/alkimiAdapter.js b/modules/alkimiAdapter.js index db2760914b1..d819fb76d5e 100644 --- a/modules/alkimiAdapter.js +++ b/modules/alkimiAdapter.js @@ -2,6 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { deepClone, deepAccess } from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'alkimi'; export const ENDPOINT = 'https://exchange-dev.alkimi.asteriosoft.com/bid?prebid=true'; @@ -16,11 +17,11 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { let bids = []; + let bidIds = []; validBidRequests.forEach(bidRequest => { let sizes = prepareSizes(bidRequest.sizes) bids.push({ - bidId: bidRequest.bidId, token: bidRequest.params.token, pos: bidRequest.params.pos, bidFloor: bidRequest.params.bidFloor, @@ -28,12 +29,17 @@ export const spec = { height: sizes[0].height, impMediaType: getFormatType(bidRequest) }) + bidIds.push(bidRequest.bidId) }) + const alkimiConfig = config.getConfig('alkimi'); + let payload = { requestId: bidderRequest.bidderRequestId, bids, - referer: bidderRequest.refererInfo.referer + bidIds, + referer: bidderRequest.refererInfo.referer, + signature: alkimiConfig && alkimiConfig.signature } const options = { @@ -82,13 +88,21 @@ export const spec = { }, onBidWon: function (bid) { - if (bid.winUrl) { - const cpm = bid.cpm; - const winUrl = bid.winUrl.replace(/\$\{AUCTION_PRICE\}/, cpm); - ajax(winUrl, null); - return true; + let winUrl; + if (bid.winUrl || bid.vastUrl) { + winUrl = bid.winUrl ? bid.winUrl : bid.vastUrl; + winUrl = winUrl.replace(/\$\{AUCTION_PRICE\}/, bid.cpm); + } else if (bid.ad) { + let trackImg = bid.ad.match(/(?!^)/); + bid.ad = bid.ad.replace(trackImg[0], ''); + winUrl = trackImg[0].split('"')[1]; + winUrl = winUrl.replace(/\$%7BAUCTION_PRICE%7D/, bid.cpm); + } else { + return false; } - return false; + + ajax(winUrl, null); + return true; } } From ddec9979c8e0604ccb495283d9dbd223d23329c7 Mon Sep 17 00:00:00 2001 From: Alexander Bogdanov Date: Tue, 8 Feb 2022 15:37:48 +0700 Subject: [PATCH 06/29] sign utils --- modules/alkimiAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/alkimiAdapter.js b/modules/alkimiAdapter.js index d819fb76d5e..b8f6a3c2c31 100644 --- a/modules/alkimiAdapter.js +++ b/modules/alkimiAdapter.js @@ -36,7 +36,7 @@ export const spec = { let payload = { requestId: bidderRequest.bidderRequestId, - bids, + signRequest: { bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID }, bidIds, referer: bidderRequest.refererInfo.referer, signature: alkimiConfig && alkimiConfig.signature From 068c546806a1ac3f7c8818416e5f3126bbfb8f21 Mon Sep 17 00:00:00 2001 From: Alexander Bogdanov Date: Thu, 24 Feb 2022 14:57:50 +0700 Subject: [PATCH 07/29] auction ID as bid request ID --- modules/alkimiAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/alkimiAdapter.js b/modules/alkimiAdapter.js index b8f6a3c2c31..a68f2478e55 100644 --- a/modules/alkimiAdapter.js +++ b/modules/alkimiAdapter.js @@ -35,7 +35,7 @@ export const spec = { const alkimiConfig = config.getConfig('alkimi'); let payload = { - requestId: bidderRequest.bidderRequestId, + requestId: bidderRequest.auctionId, signRequest: { bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID }, bidIds, referer: bidderRequest.refererInfo.referer, From bf432c4d60f3cd26e0efb2b06f0b131cbcd199f0 Mon Sep 17 00:00:00 2001 From: alexander bogdanov Date: Wed, 27 Apr 2022 13:12:40 +0700 Subject: [PATCH 08/29] unit test fixes --- .../{alkimiAdapter.js => alkimiBidAdapter.js} | 2 +- .../{alkimiAdapter.md => alkimiBidAdapter.md} | 0 ...apter_spec.js => alkimiBidAdapter_spec.js} | 19 +++++++++++-------- 3 files changed, 12 insertions(+), 9 deletions(-) rename modules/{alkimiAdapter.js => alkimiBidAdapter.js} (97%) rename modules/{alkimiAdapter.md => alkimiBidAdapter.md} (100%) rename test/spec/modules/{alkimiAdapter_spec.js => alkimiBidAdapter_spec.js} (88%) diff --git a/modules/alkimiAdapter.js b/modules/alkimiBidAdapter.js similarity index 97% rename from modules/alkimiAdapter.js rename to modules/alkimiBidAdapter.js index a68f2478e55..261fd9dee68 100644 --- a/modules/alkimiAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -5,7 +5,7 @@ import { VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; const BIDDER_CODE = 'alkimi'; -export const ENDPOINT = 'https://exchange-dev.alkimi.asteriosoft.com/bid?prebid=true'; +export const ENDPOINT = 'https://exchange.alkimi-onboarding.com/bid?prebid=true'; export const spec = { code: BIDDER_CODE, diff --git a/modules/alkimiAdapter.md b/modules/alkimiBidAdapter.md similarity index 100% rename from modules/alkimiAdapter.md rename to modules/alkimiBidAdapter.md diff --git a/test/spec/modules/alkimiAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js similarity index 88% rename from test/spec/modules/alkimiAdapter_spec.js rename to test/spec/modules/alkimiBidAdapter_spec.js index 6013b2bfbee..58a5a3b54ab 100644 --- a/test/spec/modules/alkimiAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai' -import { ENDPOINT, spec } from 'modules/alkimiAdapter.js' +import { ENDPOINT, spec } from 'modules/alkimiBidAdapter.js' import { newBidder } from 'src/adapters/bidderFactory.js' const REQUEST = { @@ -30,7 +30,7 @@ const BIDDER_BANNER_RESPONSE = { 'creativeId': 1, 'netRevenue': true, 'winUrl': 'http://test.com', - 'format': 'banner', + 'mediaType': 'banner', 'adomain': ['test.com'] }] } @@ -47,14 +47,14 @@ const BIDDER_VIDEO_RESPONSE = { 'creativeId': 2, 'netRevenue': true, 'winUrl': 'http://test.com', - 'format': 'video', + 'mediaType': 'video', 'adomain': ['test.com'] }] } const BIDDER_NO_BID_RESPONSE = '' -describe('alkimiAdapter', function () { +describe('alkimiBidAdapter', function () { const adapter = newBidder(spec) describe('inherited functions', function () { @@ -86,7 +86,7 @@ describe('alkimiAdapter', function () { describe('buildRequests', function () { let bidRequests = [REQUEST] const bidderRequest = spec.buildRequests(bidRequests, { - bidderRequestId: '123', + auctionId: '123', refererInfo: { referer: 'http://test.com/path.html' } @@ -96,7 +96,10 @@ describe('alkimiAdapter', function () { expect(bidderRequest.method).to.equal('POST') expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') - expect(bidderRequest.data.bids).to.deep.contains({ bidId: '456', token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner' }) + expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner' }) + expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) + expect(bidderRequest.data.bidIds).to.deep.contains('456') + expect(bidderRequest.data.signature).to.equal(undefined) expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true }) expect(bidderRequest.options.contentType).to.equal('application/json') expect(bidderRequest.url).to.equal(ENDPOINT) @@ -117,7 +120,7 @@ describe('alkimiAdapter', function () { expect(result[0]).to.have.property('creativeId').equal(1) expect(result[0]).to.have.property('netRevenue').equal(true) expect(result[0]).to.have.property('winUrl').equal('http://test.com') - expect(result[0]).to.have.property('format').equal('banner') + expect(result[0]).to.have.property('mediaType').equal('banner') expect(result[0].meta).to.exist.property('advertiserDomains') expect(result[0].meta).to.have.property('advertiserDomains').lengthOf(1) }) @@ -135,7 +138,7 @@ describe('alkimiAdapter', function () { expect(result[0]).to.have.property('creativeId').equal(2) expect(result[0]).to.have.property('netRevenue').equal(true) expect(result[0]).to.have.property('winUrl').equal('http://test.com') - expect(result[0]).to.have.property('format').equal('video') + expect(result[0]).to.have.property('mediaType').equal('video') expect(result[0]).to.have.property('vastXml').equal('vast') expect(result[0].meta).to.exist.property('advertiserDomains') expect(result[0].meta).to.have.property('advertiserDomains').lengthOf(1) From 76afe9b6d9e6e2fc42f39eed410b39c652255125 Mon Sep 17 00:00:00 2001 From: motors Date: Wed, 11 May 2022 16:46:09 +0700 Subject: [PATCH 09/29] change maintainer info --- modules/alkimiBidAdapter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/alkimiBidAdapter.md b/modules/alkimiBidAdapter.md index 92a7c2aefe1..0d76f7e63ab 100644 --- a/modules/alkimiBidAdapter.md +++ b/modules/alkimiBidAdapter.md @@ -3,7 +3,7 @@ ``` Module Name: Alkimi Bidder Adapter Module Type: Bidder Adapter -Maintainer: abogdanov@asteriosoft.com +Maintainer: kalidas@alkimiexchange.com ``` # Description From 7dc389dad79979d9ceba034abc33a7fc4e24d637 Mon Sep 17 00:00:00 2001 From: Kalidas Engaiahraj Date: Mon, 16 May 2022 18:54:25 +0100 Subject: [PATCH 10/29] Updated the ad unit params --- modules/alkimiBidAdapter.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/alkimiBidAdapter.md b/modules/alkimiBidAdapter.md index 0d76f7e63ab..2d1fd42c70f 100644 --- a/modules/alkimiBidAdapter.md +++ b/modules/alkimiBidAdapter.md @@ -15,15 +15,21 @@ Alkimi bid adapter supports Banner and Video ads. ``` const adUnits = [ { - bids: [ + code: 'banner1', + mediaTypes: { + banner: { // Media Type can be banner or video or ... + sizes: [[300, 250]], + } + }, + bids: [ { bidder: 'alkimi', params: { - bidFloor: 0.1, - token: '?????????????????????', // Publisher Token provided by Alkimi + bidFloor: 0.5, + token: 'a6b042a5-2d68-4170-a051-77fbaf00203a', // Publisher Token(Id) provided by Alkimi } } ] } -]; +] ``` From ea2a9bffdc80b589fbfdd102aa6f442e6db94da3 Mon Sep 17 00:00:00 2001 From: Nikulin Mikhail Date: Tue, 31 May 2022 19:02:39 +0200 Subject: [PATCH 11/29] features support added --- modules/alkimiBidAdapter.js | 23 ++++++++++- test/spec/modules/alkimiBidAdapter_spec.js | 44 +++++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 261fd9dee68..d76af4b14e9 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -18,9 +18,13 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { let bids = []; let bidIds = []; + let eids; validBidRequests.forEach(bidRequest => { let sizes = prepareSizes(bidRequest.sizes) + if (bidRequest.userIdAsEids) { + eids = eids || bidRequest.userIdAsEids + } bids.push({ token: bidRequest.params.token, pos: bidRequest.params.pos, @@ -39,7 +43,24 @@ export const spec = { signRequest: { bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID }, bidIds, referer: bidderRequest.refererInfo.referer, - signature: alkimiConfig && alkimiConfig.signature + signature: alkimiConfig && alkimiConfig.signature, + schain: validBidRequests[0].schain, + cpp: config.getConfig('coppa') ? 1 : 0 + } + + if (bidderRequest && bidderRequest.gdprConsent) { + payload.gdprConsent = { + consentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : false, + consentString: bidderRequest.gdprConsent.consentString + } + } + + if (bidderRequest.uspConsent) { + payload.uspConsent = bidderRequest.uspConsent; + } + + if (eids) { + payload.eids = eids } const options = { diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index 58a5a3b54ab..e0b1df9cae8 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -15,6 +15,28 @@ const REQUEST = { bidFloor: 0.1, token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7 + }, + 'userIdAsEids': [{ + 'source': 'criteo.com', + 'uids': [{ + 'id': 'test', + 'atype': 1 + }] + }, { + 'source': 'pubcid.org', + 'uids': [{ + 'id': 'test', + 'atype': 1 + }] + }], + 'schain': { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'alkimi-onboarding.com', + sid: '00001', + hp: 1 + }] } } @@ -89,13 +111,33 @@ describe('alkimiBidAdapter', function () { auctionId: '123', refererInfo: { referer: 'http://test.com/path.html' - } + }, + gdprConsent: { + consentString: 'test-consent', + vendorData: {}, + gdprApplies: true + }, + uspConsent: 'uspConsent' + }) + + it('should return a properly formatted request with eids defined', function () { + expect(bidderRequest.data.eids).to.deep.equal(REQUEST.userIdAsEids) + }) + + it('should return a properly formatted request with gdpr defined', function () { + expect(bidderRequest.data.gdprConsent.consentRequired).to.equal(true) + expect(bidderRequest.data.gdprConsent.consentString).to.equal('test-consent') + }) + + it('should return a properly formatted request with uspConsent defined', function () { + expect(bidderRequest.data.uspConsent).to.equal('uspConsent') }) it('sends bid request to ENDPOINT via POST', function () { expect(bidderRequest.method).to.equal('POST') expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') + expect(bidderRequest.data.schain).to.deep.contains({ver: '1.0', complete: 1, nodes: [{asi: 'alkimi-onboarding.com', sid: '00001', hp: 1}]}) expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner' }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') From 74f8e1272b96e0b2bd9e8cdb40bd3ed093e3be55 Mon Sep 17 00:00:00 2001 From: alexander bogdanov Date: Wed, 24 Aug 2022 16:09:00 +0200 Subject: [PATCH 12/29] transfer adUnitCode --- modules/alkimiBidAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index ac8b5af9533..fe5a050f436 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -31,7 +31,8 @@ export const spec = { bidFloor: bidRequest.params.bidFloor, width: sizes[0].width, height: sizes[0].height, - impMediaType: getFormatType(bidRequest) + impMediaType: getFormatType(bidRequest), + adUnitCode: bidRequest.adUnitCode }) bidIds.push(bidRequest.bidId) }) From 0a0d8e8bacd18d0b6279942aa90abd92fee6b30c Mon Sep 17 00:00:00 2001 From: alexander bogdanov Date: Wed, 24 Aug 2022 17:38:39 +0200 Subject: [PATCH 13/29] transfer adUnitCode: test --- test/spec/modules/alkimiBidAdapter_spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index c98c81b706e..1ae9bb56df4 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -6,6 +6,7 @@ const REQUEST = { 'bidId': '456', 'bidder': 'alkimi', 'sizes': [[300, 250]], + 'adUnitCode': 'bannerAdUnitCode', 'mediaTypes': { 'banner': { 'sizes': [[300, 250]] @@ -138,7 +139,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') expect(bidderRequest.data.schain).to.deep.contains({ver: '1.0', complete: 1, nodes: [{asi: 'alkimi-onboarding.com', sid: '00001', hp: 1}]}) - expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner' }) + expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner', adUnitCode: 'bannerAdUnitCode' }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined) From 41b6ca3de83d4130dea5da7bfc000fceb1c55b8a Mon Sep 17 00:00:00 2001 From: Aleksandr Bogdanov Date: Thu, 22 Dec 2022 15:34:37 +0100 Subject: [PATCH 14/29] AlkimiBidAdapter getFloor() using --- modules/alkimiBidAdapter.js | 29 +++++++++++++++++----- test/spec/modules/alkimiBidAdapter_spec.js | 18 +++++++++++--- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index fe5a050f436..a96b245d786 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -20,18 +20,20 @@ export const spec = { let bidIds = []; let eids; validBidRequests.forEach(bidRequest => { - let sizes = prepareSizes(bidRequest.sizes) + let formatType = getFormatType(bidRequest) + let alkimiSizes = prepareAlkimiSizes(bidRequest.sizes) if (bidRequest.userIdAsEids) { eids = eids || bidRequest.userIdAsEids } + bids.push({ token: bidRequest.params.token, pos: bidRequest.params.pos, - bidFloor: bidRequest.params.bidFloor, - width: sizes[0].width, - height: sizes[0].height, - impMediaType: getFormatType(bidRequest), + bidFloor: getBidFloor(bidRequest, formatType), + width: alkimiSizes[0].width, + height: alkimiSizes[0].height, + impMediaType: formatType, adUnitCode: bidRequest.adUnitCode }) bidIds.push(bidRequest.bidId) @@ -128,10 +130,25 @@ export const spec = { } } -function prepareSizes(sizes) { +function prepareAlkimiSizes(sizes) { return sizes && sizes.map(size => ({ width: size[0], height: size[1] })); } +function prepareBidFloorSize(sizes) { + return sizes && sizes.length === 1 ? sizes[0] : '*'; +} + +function getBidFloor(bidRequest, formatType) { + if (typeof bidRequest.getFloor === 'function') { + const bidFloorSize = prepareBidFloorSize(bidRequest.sizes) + const floor = bidRequest.getFloor({ currency: 'USD', mediaType: formatType.toLowerCase(), size: bidFloorSize }); + if (floor && !isNaN(floor.floor) && (floor.currency === 'USD')) { + return floor.floor; + } + } + return bidRequest.params.bidFloor; +} + const getFormatType = bidRequest => { if (deepAccess(bidRequest, 'mediaTypes.banner')) return 'Banner' if (deepAccess(bidRequest, 'mediaTypes.video')) return 'Video' diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index 1ae9bb56df4..92e5d28f42a 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -108,7 +108,7 @@ describe('alkimiBidAdapter', function () { describe('buildRequests', function () { let bidRequests = [REQUEST] - const bidderRequest = spec.buildRequests(bidRequests, { + let requestData = { auctionId: '123', refererInfo: { page: 'http://test.com/path.html' @@ -119,7 +119,8 @@ describe('alkimiBidAdapter', function () { gdprApplies: true }, uspConsent: 'uspConsent' - }) + } + const bidderRequest = spec.buildRequests(bidRequests, requestData) it('should return a properly formatted request with eids defined', function () { expect(bidderRequest.data.eids).to.deep.equal(REQUEST.userIdAsEids) @@ -138,7 +139,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.method).to.equal('POST') expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') - expect(bidderRequest.data.schain).to.deep.contains({ver: '1.0', complete: 1, nodes: [{asi: 'alkimi-onboarding.com', sid: '00001', hp: 1}]}) + expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner', adUnitCode: 'bannerAdUnitCode' }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') @@ -147,6 +148,17 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.options.contentType).to.equal('application/json') expect(bidderRequest.url).to.equal(ENDPOINT) }) + + it('sends bidFloor when configured', () => { + const requestWithFloor = Object.assign({}, REQUEST); + requestWithFloor.getFloor = function (arg) { + if (arg.currency === 'USD' && arg.mediaType === 'banner' && JSON.stringify(arg.size) === JSON.stringify([300, 250])) { + return { currency: 'USD', floor: 0.3 } + } + } + const bidderRequestFloor = spec.buildRequests([requestWithFloor], requestData); + expect(bidderRequestFloor.data.signRequest.bids[0].bidFloor).to.be.equal(0.3); + }); }) describe('interpretResponse', function () { From dfcf4e8593840c01f0e36fb0f168420390597876 Mon Sep 17 00:00:00 2001 From: mik Date: Wed, 8 Feb 2023 09:52:41 +0100 Subject: [PATCH 15/29] ALK-504 Multi size ad slot support --- modules/alkimiBidAdapter.js | 9 +++++---- test/spec/modules/alkimiBidAdapter_spec.js | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index a96b245d786..9f38b54e12f 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -21,7 +21,7 @@ export const spec = { let eids; validBidRequests.forEach(bidRequest => { let formatType = getFormatType(bidRequest) - let alkimiSizes = prepareAlkimiSizes(bidRequest.sizes) + let sizes = prepareSizes(bidRequest.sizes) if (bidRequest.userIdAsEids) { eids = eids || bidRequest.userIdAsEids @@ -31,8 +31,9 @@ export const spec = { token: bidRequest.params.token, pos: bidRequest.params.pos, bidFloor: getBidFloor(bidRequest, formatType), - width: alkimiSizes[0].width, - height: alkimiSizes[0].height, + sizes: sizes.length > 1 ? sizes : [], + width: sizes[0].width, + height: sizes[0].height, impMediaType: formatType, adUnitCode: bidRequest.adUnitCode }) @@ -130,7 +131,7 @@ export const spec = { } } -function prepareAlkimiSizes(sizes) { +function prepareSizes(sizes) { return sizes && sizes.map(size => ({ width: size[0], height: size[1] })); } diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index 92e5d28f42a..f4c119ff050 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -140,7 +140,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) - expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, width: 300, height: 250, impMediaType: 'Banner', adUnitCode: 'bannerAdUnitCode' }) + expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, sizes: [], width: 300, height: 250, impMediaType: 'Banner', adUnitCode: 'bannerAdUnitCode' }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined) From 1a9fe8770e78104859e32c56280cad6865e0716c Mon Sep 17 00:00:00 2001 From: mik Date: Mon, 13 Feb 2023 12:42:18 +0100 Subject: [PATCH 16/29] ALK-504 Multi size ad slot support --- modules/alkimiBidAdapter.js | 58 ++++++++++++---------- test/spec/modules/alkimiBidAdapter_spec.js | 2 +- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 9f38b54e12f..69b3fdae3d8 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -1,8 +1,8 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { deepClone, deepAccess } from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; -import { VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {deepClone, deepAccess} from '../src/utils.js'; +import {ajax} from '../src/ajax.js'; +import {VIDEO} from '../src/mediaTypes.js'; +import {config} from '../src/config.js'; const BIDDER_CODE = 'alkimi'; export const ENDPOINT = 'https://exchange.alkimi-onboarding.com/bid?prebid=true'; @@ -20,8 +20,7 @@ export const spec = { let bidIds = []; let eids; validBidRequests.forEach(bidRequest => { - let formatType = getFormatType(bidRequest) - let sizes = prepareSizes(bidRequest.sizes) + let formatTypes = getFormatType(bidRequest) if (bidRequest.userIdAsEids) { eids = eids || bidRequest.userIdAsEids @@ -30,11 +29,10 @@ export const spec = { bids.push({ token: bidRequest.params.token, pos: bidRequest.params.pos, - bidFloor: getBidFloor(bidRequest, formatType), - sizes: sizes.length > 1 ? sizes : [], - width: sizes[0].width, - height: sizes[0].height, - impMediaType: formatType, + bidFloor: getBidFloor(bidRequest, formatTypes), + sizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes')), + playerSizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize')), + impMediaTypes: formatTypes, adUnitCode: bidRequest.adUnitCode }) bidIds.push(bidRequest.bidId) @@ -44,7 +42,7 @@ export const spec = { let payload = { requestId: bidderRequest.auctionId, - signRequest: { bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID }, + signRequest: {bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID}, bidIds, referer: bidderRequest.refererInfo.page, signature: alkimiConfig && alkimiConfig.signature, @@ -88,7 +86,7 @@ export const spec = { return []; } - const { prebidResponse } = serverBody; + const {prebidResponse} = serverBody; if (!prebidResponse || typeof prebidResponse !== 'object') { return []; } @@ -116,7 +114,7 @@ export const spec = { let winUrl; if (bid.winUrl || bid.vastUrl) { winUrl = bid.winUrl ? bid.winUrl : bid.vastUrl; - winUrl = winUrl.replace(/\$\{AUCTION_PRICE\}/, bid.cpm); + winUrl = winUrl.replace(/\$\{AUCTION_PRICE}/, bid.cpm); } else if (bid.ad) { let trackImg = bid.ad.match(/(?!^)/); bid.ad = bid.ad.replace(trackImg[0], ''); @@ -132,28 +130,34 @@ export const spec = { } function prepareSizes(sizes) { - return sizes && sizes.map(size => ({ width: size[0], height: size[1] })); + return sizes ? sizes.map(size => ({width: size[0], height: size[1]})) : [] } function prepareBidFloorSize(sizes) { - return sizes && sizes.length === 1 ? sizes[0] : '*'; + return sizes && sizes.length === 1 ? sizes : ['*']; } -function getBidFloor(bidRequest, formatType) { +function getBidFloor(bidRequest, formatTypes) { + let minFloor if (typeof bidRequest.getFloor === 'function') { - const bidFloorSize = prepareBidFloorSize(bidRequest.sizes) - const floor = bidRequest.getFloor({ currency: 'USD', mediaType: formatType.toLowerCase(), size: bidFloorSize }); - if (floor && !isNaN(floor.floor) && (floor.currency === 'USD')) { - return floor.floor; - } + const bidFloorSizes = prepareBidFloorSize(bidRequest.sizes) + formatTypes.forEach(formatType => { + bidFloorSizes.forEach(bidFloorSize => { + const floor = bidRequest.getFloor({currency: 'USD', mediaType: formatType.toLowerCase(), size: bidFloorSize}); + if (floor && !isNaN(floor.floor) && (floor.currency === 'USD')) { + minFloor = !minFloor || floor.floor < minFloor ? floor.floor : minFloor + } + }) + }) } - return bidRequest.params.bidFloor; + return minFloor || bidRequest.params.bidFloor; } const getFormatType = bidRequest => { - if (deepAccess(bidRequest, 'mediaTypes.banner')) return 'Banner' - if (deepAccess(bidRequest, 'mediaTypes.video')) return 'Video' - if (deepAccess(bidRequest, 'mediaTypes.audio')) return 'Audio' + let formats = [] + if (deepAccess(bidRequest, 'mediaTypes.banner')) formats.push('Banner') + if (deepAccess(bidRequest, 'mediaTypes.video')) formats.push('Video') + return formats } registerBidder(spec); diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index f4c119ff050..a396e5b8139 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -140,7 +140,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) - expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, sizes: [], width: 300, height: 250, impMediaType: 'Banner', adUnitCode: 'bannerAdUnitCode' }) + expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, sizes: [{width: 300, height: 250}], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode' }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined) From b72563235bb16ab744018374c6e7e3719f4eee74 Mon Sep 17 00:00:00 2001 From: Aleksandr Bogdanov Date: Thu, 13 Jul 2023 12:02:00 +0200 Subject: [PATCH 17/29] Support new OpenRTB parameters --- modules/alkimiBidAdapter.js | 15 ++++++++++++--- test/spec/modules/alkimiBidAdapter_spec.js | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index c087b3061a0..e860faf59b3 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -1,5 +1,5 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {deepAccess, deepClone} from '../src/utils.js'; +import {deepAccess, deepClone, getDNT} from '../src/utils.js'; import {ajax} from '../src/ajax.js'; import {VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; @@ -29,11 +29,15 @@ export const spec = { bids.push({ token: bidRequest.params.token, pos: bidRequest.params.pos, + instl: bidRequest.params.instl, + exp: bidRequest.params.exp, bidFloor: getBidFloor(bidRequest, formatTypes), sizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes')), playerSizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize')), impMediaTypes: formatTypes, - adUnitCode: bidRequest.adUnitCode + adUnitCode: bidRequest.adUnitCode, + video: deepAccess(bidRequest, 'mediaTypes.video'), + banner: deepAccess(bidRequest, 'mediaTypes.banner') }) bidIds.push(bidRequest.bidId) }) @@ -48,7 +52,12 @@ export const spec = { referer: bidderRequest.refererInfo.page, signature: alkimiConfig && alkimiConfig.signature, schain: validBidRequests[0].schain, - cpp: config.getConfig('coppa') ? 1 : 0 + cpp: config.getConfig('coppa') ? 1 : 0, + device: { + dnt: getDNT() ? 1 : 0, + w: screen.width, + h: screen.height + } } if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index a396e5b8139..e75c87a5372 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -140,7 +140,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) - expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, sizes: [{width: 300, height: 250}], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode' }) + expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, sizes: [{ width: 300, height: 250 }], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode', instl: undefined, exp: undefined, banner: { sizes: [[300, 250]] }, video: undefined }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined) From 36c2b78cdf522e4eb66b16a985c43213e5d8dcfa Mon Sep 17 00:00:00 2001 From: Aleksandr Bogdanov Date: Mon, 24 Jul 2023 10:34:15 +0200 Subject: [PATCH 18/29] Support new oRTB2 parameters --- modules/alkimiBidAdapter.js | 10 +++++++--- test/spec/modules/alkimiBidAdapter_spec.js | 3 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index e860faf59b3..2a8179693d0 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -1,5 +1,5 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {deepAccess, deepClone, getDNT} from '../src/utils.js'; +import {deepAccess, deepClone, getDNT, generateUUID} from '../src/utils.js'; import {ajax} from '../src/ajax.js'; import {VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; @@ -45,8 +45,7 @@ export const spec = { const alkimiConfig = config.getConfig('alkimi'); let payload = { - // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 - requestId: bidderRequest.auctionId, + requestId: generateUUID(), signRequest: {bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID}, bidIds, referer: bidderRequest.refererInfo.page, @@ -57,6 +56,11 @@ export const spec = { dnt: getDNT() ? 1 : 0, w: screen.width, h: screen.height + }, + ortb2: { + at: bidderRequest.ortb2?.at, + bcat: bidderRequest.ortb2?.bcat, + wseat: bidderRequest.ortb2?.wseat } } diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index e75c87a5372..6ddc076e9a8 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -109,7 +109,6 @@ describe('alkimiBidAdapter', function () { describe('buildRequests', function () { let bidRequests = [REQUEST] let requestData = { - auctionId: '123', refererInfo: { page: 'http://test.com/path.html' }, @@ -137,7 +136,7 @@ describe('alkimiBidAdapter', function () { it('sends bid request to ENDPOINT via POST', function () { expect(bidderRequest.method).to.equal('POST') - expect(bidderRequest.data.requestId).to.equal('123') + expect(bidderRequest.data.requestId).to.not.equal(undefined) expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, sizes: [{ width: 300, height: 250 }], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode', instl: undefined, exp: undefined, banner: { sizes: [[300, 250]] }, video: undefined }) From 77c4113102c1d14ec4513281846cb0749ebd0176 Mon Sep 17 00:00:00 2001 From: Aleksandr Bogdanov Date: Mon, 31 Jul 2023 23:36:45 +0200 Subject: [PATCH 19/29] remove pos parameter --- modules/alkimiBidAdapter.js | 3 +-- test/spec/modules/alkimiBidAdapter_spec.js | 9 ++------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 2a8179693d0..64a46779a06 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -12,7 +12,7 @@ export const spec = { supportedMediaTypes: ['banner', 'video'], isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.bidFloor && bid.params.token); + return !!(bid.params && bid.params.token); }, buildRequests: function (validBidRequests, bidderRequest) { @@ -28,7 +28,6 @@ export const spec = { bids.push({ token: bidRequest.params.token, - pos: bidRequest.params.pos, instl: bidRequest.params.instl, exp: bidRequest.params.exp, bidFloor: getBidFloor(bidRequest, formatTypes), diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index 6ddc076e9a8..08f00186358 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -14,8 +14,7 @@ const REQUEST = { }, 'params': { bidFloor: 0.1, - token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', - pos: 7 + token: 'e64782a4-8e68-4c38-965b-80ccf115d46f' }, 'userIdAsEids': [{ 'source': 'criteo.com', @@ -96,10 +95,6 @@ describe('alkimiBidAdapter', function () { delete bid.params.token expect(spec.isBidRequestValid(bid)).to.equal(false) - bid = Object.assign({}, REQUEST) - delete bid.params.bidFloor - expect(spec.isBidRequestValid(bid)).to.equal(false) - bid = Object.assign({}, REQUEST) delete bid.params expect(spec.isBidRequestValid(bid)).to.equal(false) @@ -139,7 +134,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.requestId).to.not.equal(undefined) expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) - expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, bidFloor: 0.1, sizes: [{ width: 300, height: 250 }], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode', instl: undefined, exp: undefined, banner: { sizes: [[300, 250]] }, video: undefined }) + expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', bidFloor: 0.1, sizes: [{ width: 300, height: 250 }], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode', instl: undefined, exp: undefined, banner: { sizes: [[300, 250]] }, video: undefined }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined) From f32111f3838f7dcf6fbc4762297b97b73d5de6e7 Mon Sep 17 00:00:00 2001 From: Aleksandr Bogdanov Date: Thu, 24 Aug 2023 12:35:43 +0200 Subject: [PATCH 20/29] Add gvl_id into Alkimi adapter --- modules/alkimiBidAdapter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 64a46779a06..6274ad2bf1c 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -5,10 +5,12 @@ import {VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; const BIDDER_CODE = 'alkimi'; +const GVLID = 1169; export const ENDPOINT = 'https://exchange.alkimi-onboarding.com/bid?prebid=true'; export const spec = { code: BIDDER_CODE, + gvlid: GVLID, supportedMediaTypes: ['banner', 'video'], isBidRequestValid: function (bid) { From 57bd14471f4419c1d7b722ad6e3b1d591c8994d8 Mon Sep 17 00:00:00 2001 From: Kalidas Date: Thu, 21 Sep 2023 10:24:26 +0100 Subject: [PATCH 21/29] Insert keywords into bid-request param --- modules/alkimiBidAdapter.js | 3 +++ test/spec/modules/alkimiBidAdapter_spec.js | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 6274ad2bf1c..81d993e9ac8 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -59,6 +59,9 @@ export const spec = { h: screen.height }, ortb2: { + site: { + keywords: bidderRequest.ortb2?.site?.keywords + }, at: bidderRequest.ortb2?.at, bcat: bidderRequest.ortb2?.bcat, wseat: bidderRequest.ortb2?.wseat diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index 08f00186358..3101fac7500 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -112,7 +112,15 @@ describe('alkimiBidAdapter', function () { vendorData: {}, gdprApplies: true }, - uspConsent: 'uspConsent' + uspConsent: 'uspConsent', + ortb2: { + site: { + keywords: 'test1, test2' + }, + at: 2, + bcat: ['BSW1', 'BSW2'], + wseat: ['16', '165'] + } } const bidderRequest = spec.buildRequests(bidRequests, requestData) @@ -138,6 +146,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined) + expect(bidderRequest.data.ortb2).to.deep.contains({ at: 2, wseat: ['16', '165'], bcat: ['BSW1', 'BSW2'], site: { keywords: 'test1, test2' }, }) expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true }) expect(bidderRequest.options.contentType).to.equal('application/json') expect(bidderRequest.url).to.equal(ENDPOINT) From 3b63de9da8ffd2d62bd94886c135c5d8861cc17b Mon Sep 17 00:00:00 2001 From: Kalidas Date: Tue, 26 Sep 2023 18:15:06 +0100 Subject: [PATCH 22/29] Resolve AUCTION_PRICE macro on prebid-server for VAST ads --- modules/alkimiBidAdapter.js | 25 +++++++--------------- test/spec/modules/alkimiBidAdapter_spec.js | 6 +++--- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 81d993e9ac8..53f6460434f 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -1,7 +1,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {deepAccess, deepClone, getDNT, generateUUID} from '../src/utils.js'; +import {deepAccess, deepClone, getDNT, generateUUID, replaceAuctionPrice} from '../src/utils.js'; import {ajax} from '../src/ajax.js'; -import {VIDEO} from '../src/mediaTypes.js'; +import {VIDEO, BANNER} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; const BIDDER_CODE = 'alkimi'; @@ -116,7 +116,7 @@ export const spec = { // banner or video if (VIDEO === bid.mediaType) { - bid.vastXml = bid.ad; + bid.vastUrl = replaceAuctionPrice(bid.winUrl, bid.cpm); } bid.meta = {}; @@ -129,21 +129,12 @@ export const spec = { }, onBidWon: function (bid) { - let winUrl; - if (bid.winUrl || bid.vastUrl) { - winUrl = bid.winUrl ? bid.winUrl : bid.vastUrl; - winUrl = winUrl.replace(/\$\{AUCTION_PRICE}/, bid.cpm); - } else if (bid.ad) { - let trackImg = bid.ad.match(/(?!^)/); - bid.ad = bid.ad.replace(trackImg[0], ''); - winUrl = trackImg[0].split('"')[1]; - winUrl = winUrl.replace(/\$%7BAUCTION_PRICE%7D/, bid.cpm); - } else { - return false; + if (BANNER == bid.mediaType && bid.winUrl) { + const winUrl = replaceAuctionPrice(bid.winUrl, bid.cpm); + ajax(winUrl, null); + return true; } - - ajax(winUrl, null); - return true; + return false; } } diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index 3101fac7500..90a9e409e69 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -68,7 +68,7 @@ const BIDDER_VIDEO_RESPONSE = { 'ttl': 200, 'creativeId': 2, 'netRevenue': true, - 'winUrl': 'http://test.com', + 'winUrl': 'http://test.com?price=${AUCTION_PRICE}', 'mediaType': 'video', 'adomain': ['test.com'] }] @@ -195,9 +195,9 @@ describe('alkimiBidAdapter', function () { expect(result[0]).to.have.property('ttl').equal(200) expect(result[0]).to.have.property('creativeId').equal(2) expect(result[0]).to.have.property('netRevenue').equal(true) - expect(result[0]).to.have.property('winUrl').equal('http://test.com') + expect(result[0]).to.have.property('winUrl').equal('http://test.com?price=${AUCTION_PRICE}') expect(result[0]).to.have.property('mediaType').equal('video') - expect(result[0]).to.have.property('vastXml').equal('vast') + expect(result[0]).to.have.property('vastUrl').equal('http://test.com?price=800.4') expect(result[0].meta).to.exist.property('advertiserDomains') expect(result[0].meta).to.have.property('advertiserDomains').lengthOf(1) }) From 012f13f86db5c3a3baf7014e535da403eb767e62 Mon Sep 17 00:00:00 2001 From: Kalidas Date: Thu, 23 Nov 2023 17:32:43 +0000 Subject: [PATCH 23/29] Added support for full page auction --- modules/alkimiBidAdapter.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 53f6460434f..d6cee98c3a4 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -43,7 +43,9 @@ export const spec = { bidIds.push(bidRequest.bidId) }) - const alkimiConfig = config.getConfig('alkimi'); + const alkimiConfig = config.getConfig('alkimi') + const fullPageAuction = bidderRequest.ortb2?.source?.ext?.full_page_auction + const source = fullPageAuction != undefined ? { ext: { full_page_auction: fullPageAuction } } : undefined let payload = { requestId: generateUUID(), @@ -59,6 +61,7 @@ export const spec = { h: screen.height }, ortb2: { + source, site: { keywords: bidderRequest.ortb2?.site?.keywords }, From 8c682ac3aabc4e4164a82b9dee773588fcc766ec Mon Sep 17 00:00:00 2001 From: Kalidas Date: Tue, 13 Feb 2024 12:14:16 +0000 Subject: [PATCH 24/29] Added custom user object --- modules/alkimiBidAdapter.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index d6cee98c3a4..d4e7cab8ed1 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -46,6 +46,8 @@ export const spec = { const alkimiConfig = config.getConfig('alkimi') const fullPageAuction = bidderRequest.ortb2?.source?.ext?.full_page_auction const source = fullPageAuction != undefined ? { ext: { full_page_auction: fullPageAuction } } : undefined + const walletID = alkimiConfig && alkimiConfig.walletID + const user = walletID != undefined ? { ext: { walletID: walletID } } : undefined let payload = { requestId: generateUUID(), @@ -62,6 +64,7 @@ export const spec = { }, ortb2: { source, + user, site: { keywords: bidderRequest.ortb2?.site?.keywords }, From 03c89be33911a1ff067bd52d1b05523653231c48 Mon Sep 17 00:00:00 2001 From: Aleksandr Bogdanov Date: Wed, 20 Mar 2024 11:01:55 +0100 Subject: [PATCH 25/29] userParams in request object --- modules/alkimiBidAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index d4e7cab8ed1..1e5eeb75155 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -47,7 +47,8 @@ export const spec = { const fullPageAuction = bidderRequest.ortb2?.source?.ext?.full_page_auction const source = fullPageAuction != undefined ? { ext: { full_page_auction: fullPageAuction } } : undefined const walletID = alkimiConfig && alkimiConfig.walletID - const user = walletID != undefined ? { ext: { walletID: walletID } } : undefined + const userParams = alkimiConfig && alkimiConfig.userParams + const user = (walletID != undefined || userParams != undefined) ? { ext: { walletID, userParams } } : undefined let payload = { requestId: generateUUID(), From b89f91778239fb45f2e145f6469bdf7c0a946daf Mon Sep 17 00:00:00 2001 From: Kalidas Date: Thu, 11 Apr 2024 11:13:03 +0100 Subject: [PATCH 26/29] Handling user-sync url, store user id and passing custom params --- modules/alkimiBidAdapter.js | 51 +++++++++++++++++++--- test/spec/modules/alkimiBidAdapter_spec.js | 16 ++++--- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 1e5eeb75155..c124d5d12dd 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -1,12 +1,15 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {deepAccess, deepClone, getDNT, generateUUID, replaceAuctionPrice} from '../src/utils.js'; import {ajax} from '../src/ajax.js'; +import {getStorageManager} from '../src/storageManager.js'; import {VIDEO, BANNER} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; const BIDDER_CODE = 'alkimi'; const GVLID = 1169; +const USER_ID_KEY = 'alkimiUserID'; export const ENDPOINT = 'https://exchange.alkimi-onboarding.com/bid?prebid=true'; +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); export const spec = { code: BIDDER_CODE, @@ -43,12 +46,16 @@ export const spec = { bidIds.push(bidRequest.bidId) }) + const ortb2 = bidderRequest.ortb2 + const site = ortb2?.site + + const id = getUserId() const alkimiConfig = config.getConfig('alkimi') - const fullPageAuction = bidderRequest.ortb2?.source?.ext?.full_page_auction + const fullPageAuction = ortb2?.source?.ext?.full_page_auction const source = fullPageAuction != undefined ? { ext: { full_page_auction: fullPageAuction } } : undefined const walletID = alkimiConfig && alkimiConfig.walletID const userParams = alkimiConfig && alkimiConfig.userParams - const user = (walletID != undefined || userParams != undefined) ? { ext: { walletID, userParams } } : undefined + const user = (walletID != undefined || userParams != undefined || id != undefined) ? { id, ext: { walletID, userParams } } : undefined let payload = { requestId: generateUUID(), @@ -67,11 +74,14 @@ export const spec = { source, user, site: { - keywords: bidderRequest.ortb2?.site?.keywords + keywords: site?.keywords, + sectioncat: site?.sectioncat, + pagecat: site?.pagecat, + cat: site?.cat }, - at: bidderRequest.ortb2?.at, - bcat: bidderRequest.ortb2?.bcat, - wseat: bidderRequest.ortb2?.wseat + at: ortb2?.at, + bcat: ortb2?.bcat, + wseat: ortb2?.wseat } } @@ -142,6 +152,24 @@ export const spec = { return true; } return false; + }, + + getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { + if (syncOptions.iframeEnabled && serverResponses.length > 0) { + const serverBody = serverResponses[0].body; + if (!serverBody || typeof serverBody !== 'object') return []; + + const { iframeList } = serverBody; + if (!iframeList || typeof iframeList !== 'object') return []; + + const urls = []; + iframeList.forEach(url => { + urls.push({type: 'iframe', url}); + }) + + return urls; + } + return []; } } @@ -176,4 +204,15 @@ const getFormatType = bidRequest => { return formats } +const getUserId = () => { + if (storage.localStorageIsEnabled()) { + let userId = storage.getDataFromLocalStorage(USER_ID_KEY) + if (!userId) { + userId = generateUUID() + storage.setDataInLocalStorage(USER_ID_KEY, userId) + } + return userId + } +} + registerBidder(spec); diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index 90a9e409e69..e551d98fa07 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -91,11 +91,11 @@ describe('alkimiBidAdapter', function () { }) it('should return false when required params are not passed', function () { - let bid = Object.assign({}, REQUEST) + let bid = JSON.parse(JSON.stringify(REQUEST)) delete bid.params.token expect(spec.isBidRequestValid(bid)).to.equal(false) - bid = Object.assign({}, REQUEST) + bid = JSON.parse(JSON.stringify(REQUEST)) delete bid.params expect(spec.isBidRequestValid(bid)).to.equal(false) }) @@ -115,29 +115,35 @@ describe('alkimiBidAdapter', function () { uspConsent: 'uspConsent', ortb2: { site: { - keywords: 'test1, test2' + keywords: 'test1, test2', + cat: ['IAB2'], + pagecat: ['IAB3'], + sectioncat: ['IAB4'] }, at: 2, bcat: ['BSW1', 'BSW2'], wseat: ['16', '165'] } } - const bidderRequest = spec.buildRequests(bidRequests, requestData) it('should return a properly formatted request with eids defined', function () { + const bidderRequest = spec.buildRequests(bidRequests, requestData) expect(bidderRequest.data.eids).to.deep.equal(REQUEST.userIdAsEids) }) it('should return a properly formatted request with gdpr defined', function () { + const bidderRequest = spec.buildRequests(bidRequests, requestData) expect(bidderRequest.data.gdprConsent.consentRequired).to.equal(true) expect(bidderRequest.data.gdprConsent.consentString).to.equal('test-consent') }) it('should return a properly formatted request with uspConsent defined', function () { + const bidderRequest = spec.buildRequests(bidRequests, requestData) expect(bidderRequest.data.uspConsent).to.equal('uspConsent') }) it('sends bid request to ENDPOINT via POST', function () { + const bidderRequest = spec.buildRequests(bidRequests, requestData) expect(bidderRequest.method).to.equal('POST') expect(bidderRequest.data.requestId).to.not.equal(undefined) expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') @@ -146,7 +152,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined) - expect(bidderRequest.data.ortb2).to.deep.contains({ at: 2, wseat: ['16', '165'], bcat: ['BSW1', 'BSW2'], site: { keywords: 'test1, test2' }, }) + expect(bidderRequest.data.ortb2).to.deep.contains({ at: 2, wseat: ['16', '165'], bcat: ['BSW1', 'BSW2'], site: { keywords: 'test1, test2', cat: ['IAB2'], pagecat: ['IAB3'], sectioncat: ['IAB4'] } }) expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true }) expect(bidderRequest.options.contentType).to.equal('application/json') expect(bidderRequest.url).to.equal(ENDPOINT) From 14a55e553ed80eba20669c5c752d9ab3736e2175 Mon Sep 17 00:00:00 2001 From: Kalidas Date: Fri, 12 Apr 2024 11:54:16 +0100 Subject: [PATCH 27/29] Renamed the full_page_auction to fpa --- modules/alkimiBidAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index c124d5d12dd..af4fc21a224 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -51,8 +51,8 @@ export const spec = { const id = getUserId() const alkimiConfig = config.getConfig('alkimi') - const fullPageAuction = ortb2?.source?.ext?.full_page_auction - const source = fullPageAuction != undefined ? { ext: { full_page_auction: fullPageAuction } } : undefined + const fpa = ortb2?.source?.ext?.fpa + const source = fpa != undefined ? { ext: { fpa } } : undefined const walletID = alkimiConfig && alkimiConfig.walletID const userParams = alkimiConfig && alkimiConfig.userParams const user = (walletID != undefined || userParams != undefined || id != undefined) ? { id, ext: { walletID, userParams } } : undefined From bfeb356bad9c6525ab8fdb30283f0da14a18c863 Mon Sep 17 00:00:00 2001 From: Kalidas Date: Fri, 19 Apr 2024 15:13:15 +0100 Subject: [PATCH 28/29] Updated the review comment --- modules/alkimiBidAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index af4fc21a224..3bd995cc112 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -122,7 +122,7 @@ export const spec = { } const {prebidResponse} = serverBody; - if (!prebidResponse || typeof prebidResponse !== 'object') { + if (!Array.isArray(prebidResponse)) { return []; } @@ -160,7 +160,7 @@ export const spec = { if (!serverBody || typeof serverBody !== 'object') return []; const { iframeList } = serverBody; - if (!iframeList || typeof iframeList !== 'object') return []; + if (!Array.isArray(iframeList)) return []; const urls = []; iframeList.forEach(url => { From 83b9436abc664766cd6647fbe9fe73380057ab34 Mon Sep 17 00:00:00 2001 From: Kalidas Date: Tue, 11 Feb 2025 16:05:32 +0000 Subject: [PATCH 29/29] Added support for Imp extention object --- modules/alkimiBidAdapter.js | 4 +++- test/spec/modules/alkimiBidAdapter_spec.js | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 3bd995cc112..f52c3ec7703 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -41,7 +41,8 @@ export const spec = { impMediaTypes: formatTypes, adUnitCode: bidRequest.adUnitCode, video: deepAccess(bidRequest, 'mediaTypes.video'), - banner: deepAccess(bidRequest, 'mediaTypes.banner') + banner: deepAccess(bidRequest, 'mediaTypes.banner'), + ext: bidRequest.ortb2Imp?.ext }) bidIds.push(bidRequest.bidId) }) @@ -81,6 +82,7 @@ export const spec = { }, at: ortb2?.at, bcat: ortb2?.bcat, + badv: ortb2?.badv, wseat: ortb2?.wseat } } diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index e551d98fa07..d642afd2b26 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -7,6 +7,12 @@ const REQUEST = { 'bidder': 'alkimi', 'sizes': [[300, 250]], 'adUnitCode': 'bannerAdUnitCode', + 'ortb2Imp': { + 'ext': { + 'gpid': '/111/banner#300x250', + 'tid': 'e64782a4-8e68-4c38-965b-80ccf115d46a' + } + }, 'mediaTypes': { 'banner': { 'sizes': [[300, 250]] @@ -148,7 +154,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.data.requestId).to.not.equal(undefined) expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) - expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', bidFloor: 0.1, sizes: [{ width: 300, height: 250 }], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode', instl: undefined, exp: undefined, banner: { sizes: [[300, 250]] }, video: undefined }) + expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', bidFloor: 0.1, sizes: [{ width: 300, height: 250 }], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode', instl: undefined, exp: undefined, banner: { sizes: [[300, 250]] }, video: undefined, ext: { gpid: '/111/banner#300x250', tid: 'e64782a4-8e68-4c38-965b-80ccf115d46a' } }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') expect(bidderRequest.data.signature).to.equal(undefined)