From 451dacbce8301f4c3aa9af3a97024f0060497ca7 Mon Sep 17 00:00:00 2001 From: Gaby Date: Wed, 8 Jan 2020 12:47:02 +0100 Subject: [PATCH 1/6] add prebid version of adapter --- modules/sublimeBidAdapter.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index 63f851c5b4d..f4a81ff37a7 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -6,7 +6,7 @@ const DEFAULT_BID_HOST = 'pbjs.sskzlabs.com'; const DEFAULT_CURRENCY = 'EUR'; const DEFAULT_PROTOCOL = 'https'; const DEFAULT_TTL = 600; -const SUBLIME_VERSION = '0.4.0'; +const SUBLIME_VERSION = '0.5.1'; export const spec = { code: BIDDER_CODE, @@ -31,7 +31,7 @@ export const spec = { */ buildRequests: (validBidRequests, bidderRequest) => { let commonPayload = { - sublimeVersion: SUBLIME_VERSION, + pbav: SUBLIME_VERSION, // Current Prebid params prebidVersion: '$prebid.version$', currencyCode: config.getConfig('currency.adServerCurrency') || DEFAULT_CURRENCY, @@ -123,6 +123,7 @@ export const spec = { netRevenue: response.netRevenue || true, ttl: response.ttl || DEFAULT_TTL, ad: response.ad, + pbav: SUBLIME_VERSION }; bidResponses.push(bidResponse); From e0feea2e320872aebcaef4887cd22bb6ce6325a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o?= <51166933+SublimeLeo@users.noreply.github.com> Date: Fri, 13 Mar 2020 16:44:50 +0100 Subject: [PATCH 2/6] Feature/update sublime adapter (#21) * Update sublimeBidAdapter to 0.5.1 * Add tests for private functions * Remove window.sublime * Update pixel name for bid event --- modules/sublimeBidAdapter.js | 305 +++++++++++++------- test/spec/modules/sublimeBidAdapter_spec.js | 29 +- 2 files changed, 221 insertions(+), 113 deletions(-) diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index f4a81ff37a7..515eaa3b8c2 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -1,136 +1,217 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; +import * as utils from '../src/utils.js'; +import * as url from '../src/url.js'; const BIDDER_CODE = 'sublime'; const DEFAULT_BID_HOST = 'pbjs.sskzlabs.com'; const DEFAULT_CURRENCY = 'EUR'; const DEFAULT_PROTOCOL = 'https'; const DEFAULT_TTL = 600; +const SUBLIME_ANTENNA = 'antenna.ayads.co'; const SUBLIME_VERSION = '0.5.1'; -export const spec = { - code: BIDDER_CODE, - aliases: [], +/** + * Debug log message + * @param {String} msg + * @param {Object=} obj + */ +export function log(msg, obj) { + utils.logInfo('SublimeBidAdapter - ' + msg, obj); +} + +// Default state +export const state = { + zoneId: '', + transactionId: '' +}; + +/** + * Set a new state + * @param {Object} value + */ +export function setState(value) { + Object.assign(state, value); + log('State has been updated :', state); +} + +/** + * Send pixel to our debug endpoint + * @param {string} eventName - Event name that will be send in the e= query string + * @param {Boolean=} isMandatoryPixel - If set to true, will always send the pixel + */ +export function sendEvent(eventName, isMandatoryPixel = false) { + const shoudSendPixel = (isMandatoryPixel || state.debug); + const ts = Date.now(); + const eventObject = { + t: ts, + tse: ts, + z: state.zoneId, + e: eventName, + src: 'pa', + puid: state.transactionId, + trId: state.transactionId, + ver: SUBLIME_VERSION, + }; + + if (shoudSendPixel) { + log('Sending pixel for event: ' + eventName, eventObject); + + const queryString = url.formatQS(eventObject); + utils.triggerPixel('https://' + SUBLIME_ANTENNA + '/?' + queryString); + } else { + log('Not sending pixel for event (use debug: true to send it): ' + eventName, eventObject); + } +} + +/** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return {Boolean} True if this is a valid bid, and false otherwise. + */ +function isBidRequestValid(bid) { + return !!Number(bid.params.zoneId); +} + +/** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} validBidRequests - An array of bids + * @param {Object} bidderRequest - Info describing the request to the server. + * @return {ServerRequest|ServerRequest[]} - Info describing the request to the server. + */ +function buildRequests(validBidRequests, bidderRequest) { + const commonPayload = { + pbav: SUBLIME_VERSION, + // Current Prebid params + prebidVersion: '$prebid.version$', + currencyCode: config.getConfig('currency.adServerCurrency') || DEFAULT_CURRENCY, + timeout: (typeof bidderRequest === 'object' && !!bidderRequest) ? bidderRequest.timeout : config.getConfig('bidderTimeout'), + }; + + // RefererInfo + if (bidderRequest && bidderRequest.refererInfo) { + commonPayload.referer = bidderRequest.refererInfo.referer; + commonPayload.numIframes = bidderRequest.refererInfo.numIframes; + } + // GDPR handling + if (bidderRequest && bidderRequest.gdprConsent) { + commonPayload.gdprConsent = bidderRequest.gdprConsent.consentString; + commonPayload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side + } + + return validBidRequests.map(bid => { + const bidHost = bid.params.bidHost || DEFAULT_BID_HOST; + const protocol = bid.params.protocol || DEFAULT_PROTOCOL; + + setState({ + transactionId: bid.transactionId, + zoneId: bid.params.zoneId, + debug: bid.params.debug || false, + }); - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return !!bid.params.zoneId; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests An array of bids - * @param {Object} bidderRequest - Info describing the request to the server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - let commonPayload = { - pbav: SUBLIME_VERSION, - // Current Prebid params - prebidVersion: '$prebid.version$', - currencyCode: config.getConfig('currency.adServerCurrency') || DEFAULT_CURRENCY, - timeout: config.getConfig('bidderTimeout'), + const bidPayload = { + adUnitCode: bid.adUnitCode, + auctionId: bid.auctionId, + bidder: bid.bidder, + bidderRequestId: bid.bidderRequestId, + bidRequestsCount: bid.bidRequestsCount, + requestId: bid.bidId, + sizes: bid.sizes.map(size => ({ + w: size[0], + h: size[1], + })), + transactionId: bid.transactionId, + zoneId: bid.params.zoneId, }; - // RefererInfo - if (bidderRequest && bidderRequest.refererInfo) { - commonPayload.referer = bidderRequest.refererInfo.referer; - commonPayload.numIframes = bidderRequest.refererInfo.numIframes; + const payload = Object.assign({}, commonPayload, bidPayload); + + return { + method: 'POST', + url: protocol + '://' + bidHost + '/bid', + data: payload, + options: { + contentType: 'application/json', + withCredentials: true + }, } - // GDPR handling - if (bidderRequest && bidderRequest.gdprConsent) { - commonPayload.gdprConsent = bidderRequest.gdprConsent.consentString; - commonPayload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side + }); +} + +/** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @param {*} bidRequest An object with bid request informations + * @return {Bid[]} An array of bids which were nested inside the server. + */ +function interpretResponse(serverResponse, bidRequest) { + const bidResponses = []; + const response = serverResponse.body; + + sendEvent('dintres'); + + if (response) { + if (response.timeout || !response.ad || //gmi.test(response.ad)) { + return bidResponses; } - return validBidRequests.map(bid => { - let bidPayload = { - adUnitCode: bid.adUnitCode, - auctionId: bid.auctionId, - bidder: bid.bidder, - bidderRequestId: bid.bidderRequestId, - bidRequestsCount: bid.bidRequestsCount, - requestId: bid.bidId, - sizes: bid.sizes.map(size => ({ - w: size[0], - h: size[1], - })), - transactionId: bid.transactionId, - zoneId: bid.params.zoneId, - }; + // Setting our returned sizes object to default values + let returnedSizes = { + width: 1800, + height: 1000 + }; - let protocol = bid.params.protocol || DEFAULT_PROTOCOL; - let bidHost = bid.params.bidHost || DEFAULT_BID_HOST; - let payload = Object.assign({}, commonPayload, bidPayload); - - return { - method: 'POST', - url: protocol + '://' + bidHost + '/bid', - data: payload, - options: { - contentType: 'application/json', - withCredentials: true - }, - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequest An object with bid request informations - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: (serverResponse, bidRequest) => { - const bidResponses = []; - const response = serverResponse.body; - - if (response) { - if (response.timeout || !response.ad || response.ad.match(//gmi)) { - return bidResponses; - } - - // Setting our returned sizes object to default values - let returnedSizes = { - width: 1800, - height: 1000 + // Verifying Banner sizes + if (bidRequest && bidRequest.data && bidRequest.data.w === 1 && bidRequest.data.h === 1) { + // If banner sizes are 1x1 we set our default size object to 1x1 + returnedSizes = { + width: 1, + height: 1 }; + } - // Verifying Banner sizes - if (bidRequest && bidRequest.data && bidRequest.data.w === 1 && bidRequest.data.h === 1) { - // If banner sizes are 1x1 we set our default size object to 1x1 - returnedSizes = { - width: 1, - height: 1 - }; - } - - const bidResponse = { - requestId: response.requestId || '', - cpm: response.cpm || 0, - width: response.width || returnedSizes.width, - height: response.height || returnedSizes.height, - creativeId: response.creativeId || 1, - dealId: response.dealId || 1, - currency: response.currency || DEFAULT_CURRENCY, - netRevenue: response.netRevenue || true, - ttl: response.ttl || DEFAULT_TTL, - ad: response.ad, - pbav: SUBLIME_VERSION - }; + const bidResponse = { + requestId: response.requestId || '', + cpm: response.cpm || 0, + width: response.width || returnedSizes.width, + height: response.height || returnedSizes.height, + creativeId: response.creativeId || 1, + dealId: response.dealId || 1, + currency: response.currency || DEFAULT_CURRENCY, + netRevenue: response.netRevenue || true, + ttl: response.ttl || DEFAULT_TTL, + ad: response.ad, + pbav: SUBLIME_VERSION + }; - bidResponses.push(bidResponse); - } + sendEvent('bida', true); + bidResponses.push(bidResponse); + } else { + sendEvent('dnobid'); + } - return bidResponses; - }, + return bidResponses; +} + +/** + * Send debug when we timeout + * @param {Object} timeoutData + */ +function onTimeout(timeoutData) { + log('Timeout from adapter', timeoutData); + sendEvent('dbidtimeout', true); +} + +export const spec = { + code: BIDDER_CODE, + aliases: [], + isBidRequestValid: isBidRequestValid, + buildRequests: buildRequests, + interpretResponse: interpretResponse, + onTimeout: onTimeout, }; registerBidder(spec); diff --git a/test/spec/modules/sublimeBidAdapter_spec.js b/test/spec/modules/sublimeBidAdapter_spec.js index 087d5790f4a..8a4388d1424 100644 --- a/test/spec/modules/sublimeBidAdapter_spec.js +++ b/test/spec/modules/sublimeBidAdapter_spec.js @@ -1,10 +1,30 @@ import { expect } from 'chai'; -import { spec } from 'modules/sublimeBidAdapter.js'; +import { spec, sendEvent, log, setState, state } from 'modules/sublimeBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +let utils = require('src/utils'); + describe('Sublime Adapter', function() { const adapter = newBidder(spec); + describe('sendEvent', function() { + let sandbox; + + beforeEach(function () { + sandbox = sinon.sandbox.create(); + }); + + it('should trigger pixel', function () { + sandbox.spy(utils, 'triggerPixel'); + sendEvent('test', true); + expect(utils.triggerPixel.called).to.equal(true); + }); + + afterEach(function () { + sandbox.restore(); + }); + }) + describe('inherited functions', function() { it('exists and is a function', function() { expect(adapter.callBids).to.exist.and.to.be.a('function'); @@ -129,6 +149,7 @@ describe('Sublime Adapter', function() { currency: 'USD', netRevenue: true, ttl: 600, + pbav: '0.5.1', ad: '', }, ]; @@ -170,6 +191,7 @@ describe('Sublime Adapter', function() { netRevenue: true, ttl: 600, ad: '', + pbav: '0.5.1', }; expect(result[0]).to.deep.equal(expectedResponse); @@ -219,6 +241,7 @@ describe('Sublime Adapter', function() { netRevenue: true, ttl: 600, ad: '', + pbav: '0.5.1', }; expect(result[0]).to.deep.equal(expectedResponse); @@ -250,6 +273,10 @@ describe('Sublime Adapter', function() { let expectedResponse = []; expect(result).to.deep.equal(expectedResponse); + + describe('On bid Time out', function () { + spec.onTimeout(result); + }); }); }); }); From 714619bd610d7c249c85204d6b1d787753c62b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20GRAND?= Date: Thu, 2 Apr 2020 13:13:31 +0200 Subject: [PATCH 3/6] Remove pixels on non-event and add onBidWon --- modules/sublimeBidAdapter.js | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index 515eaa3b8c2..728c35214ca 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -38,10 +38,8 @@ export function setState(value) { /** * Send pixel to our debug endpoint * @param {string} eventName - Event name that will be send in the e= query string - * @param {Boolean=} isMandatoryPixel - If set to true, will always send the pixel */ -export function sendEvent(eventName, isMandatoryPixel = false) { - const shoudSendPixel = (isMandatoryPixel || state.debug); +export function sendEvent(eventName) { const ts = Date.now(); const eventObject = { t: ts, @@ -54,14 +52,10 @@ export function sendEvent(eventName, isMandatoryPixel = false) { ver: SUBLIME_VERSION, }; - if (shoudSendPixel) { - log('Sending pixel for event: ' + eventName, eventObject); + log('Sending pixel for event: ' + eventName, eventObject); - const queryString = url.formatQS(eventObject); - utils.triggerPixel('https://' + SUBLIME_ANTENNA + '/?' + queryString); - } else { - log('Not sending pixel for event (use debug: true to send it): ' + eventName, eventObject); - } + const queryString = url.formatQS(eventObject); + utils.triggerPixel('https://' + SUBLIME_ANTENNA + '/?' + queryString); } /** @@ -151,8 +145,6 @@ function interpretResponse(serverResponse, bidRequest) { const bidResponses = []; const response = serverResponse.body; - sendEvent('dintres'); - if (response) { if (response.timeout || !response.ad || //gmi.test(response.ad)) { return bidResponses; @@ -187,15 +179,21 @@ function interpretResponse(serverResponse, bidRequest) { pbav: SUBLIME_VERSION }; - sendEvent('bida', true); bidResponses.push(bidResponse); - } else { - sendEvent('dnobid'); } return bidResponses; } +/** + * Send pixel when bidWon event is triggered + * @param {Object} timeoutData + */ +function onBidWon(bid) { + log('Bid won', bid); + sendEvent('bidwon', true); +} + /** * Send debug when we timeout * @param {Object} timeoutData @@ -211,6 +209,7 @@ export const spec = { isBidRequestValid: isBidRequestValid, buildRequests: buildRequests, interpretResponse: interpretResponse, + onBidWon: onBidWon, onTimeout: onTimeout, }; From 6f0a3f0b30c971206a90748c1811260af8c76ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o?= <51166933+SublimeLeo@users.noreply.github.com> Date: Thu, 2 Apr 2020 17:25:34 +0200 Subject: [PATCH 4/6] Incremente version of sublimeBidAdapter --- modules/sublimeBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index 728c35214ca..20da1497ad5 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -9,7 +9,7 @@ const DEFAULT_CURRENCY = 'EUR'; const DEFAULT_PROTOCOL = 'https'; const DEFAULT_TTL = 600; const SUBLIME_ANTENNA = 'antenna.ayads.co'; -const SUBLIME_VERSION = '0.5.1'; +const SUBLIME_VERSION = '0.5.2'; /** * Debug log message From a4d6563bb8da54c2f8d3b8a7818faa27ad1f4e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20GRAND?= Date: Mon, 6 Apr 2020 14:18:13 +0200 Subject: [PATCH 5/6] Renamed pixel for timeout and introduce gvlid --- modules/sublimeBidAdapter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index 20da1497ad5..2d769059c14 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -4,6 +4,7 @@ import * as utils from '../src/utils.js'; import * as url from '../src/url.js'; const BIDDER_CODE = 'sublime'; +const BIDDER_GVLID = 114; const DEFAULT_BID_HOST = 'pbjs.sskzlabs.com'; const DEFAULT_CURRENCY = 'EUR'; const DEFAULT_PROTOCOL = 'https'; @@ -200,11 +201,12 @@ function onBidWon(bid) { */ function onTimeout(timeoutData) { log('Timeout from adapter', timeoutData); - sendEvent('dbidtimeout', true); + sendEvent('bidtimeout', true); } export const spec = { code: BIDDER_CODE, + gvlid: BIDDER_GVLID, aliases: [], isBidRequestValid: isBidRequestValid, buildRequests: buildRequests, From 6cfafefafffcee0fb96d8eea1de98fdb236c1002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o?= <51166933+SublimeLeo@users.noreply.github.com> Date: Wed, 8 Apr 2020 11:21:49 +0200 Subject: [PATCH 6/6] Remove unnecessary params for sendEvent Co-Authored-By: fgcloutier --- modules/sublimeBidAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index a624d09e67e..5270ab943fd 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -192,7 +192,7 @@ function interpretResponse(serverResponse, bidRequest) { */ function onBidWon(bid) { log('Bid won', bid); - sendEvent('bidwon', true); + sendEvent('bidwon'); } /** @@ -201,7 +201,7 @@ function onBidWon(bid) { */ function onTimeout(timeoutData) { log('Timeout from adapter', timeoutData); - sendEvent('bidtimeout', true); + sendEvent('bidtimeout'); } export const spec = {