Skip to content
This repository has been archived by the owner on Feb 13, 2021. It is now read-only.

Commit

Permalink
Merge pull request prebid#43 in AOLP_ADS_JS/prebid.js from release/1.…
Browse files Browse the repository at this point in the history
…4.1 to master

* commit '73b5a90bdc80c71baf733e3079f453a8dfca6eb5':
  Updated CHANGELOG
  Updated CHANGELOG
  Fixed unit test fixture for AOL adapter
  Refactoring of unit tests for AOL analytics #2
  Minor refactoring of unit tests for AOL analytics
  CHANGELOG
  Fixed handling of 3rd party pixels in AOL adapter
  Added more unit tests for AOL analytics
  Added unit tests for AOL analytics
  Refactoring of AOL analytics
  • Loading branch information
marian-r committed Oct 26, 2016
2 parents ff495c3 + 73b5a90 commit 76d84ac
Show file tree
Hide file tree
Showing 6 changed files with 1,361 additions and 566 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
AOL Prebid 1.4.1
----------------
Refactoring of AOL analytics.
Fixed reporting of pageId parameter in AOL analytics.
BUGFIX: Fixed retrieving 3rd party pixels from bid response in AOL adapter.


AOL Prebid 1.4.0
----------------
Updated to Prebid 0.13.1
Expand Down
362 changes: 183 additions & 179 deletions src/adapters/analytics/aol.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,201 +28,205 @@ const EVENTS = {
WIN: 2
};

let adUnits = {};

let baseSchemaTemplate = template`${'protocol'}://${'host'}/hbevent/${'tagversion'}/${'network'}/${'placement'}/${'site'}/${'eventid'}/hbeventts=${'hbeventts'};cors=yes`;
let auctionSchemaTemplate = template`;pubadid=${'pubadid'};hbauctionid=${'hbauctionid'};hbwinner=${'hbwinner'};hbprice=${'hbprice'}${'hbcur'}${'pubapi'}`;
let winSchemaTemplate = template`;hbauctioneventts=${'hbauctioneventts'};pubadid=${'pubadid'};hbauctionid=${'hbauctionid'};hbwinner=${'hbwinner'};pubcpm=${'pubcpm'}`;
let bidderSchemaTemplate = template`;hbbidder=${'hbbidder'};hbbid=${'hbbid'};hbstatus=${'hbstatus'};hbtime=${'hbtime'}`;

export default utils.extend(adapter({
url: '',
analyticsType
}), {
url: '',
analyticsType
}), {

enableAnalytics({
options = {
server: null // Internal use only. Use 'region' config option for AOL adapter.
enableAnalytics({
options = {
server: null // Internal use only. Use 'region' config option for AOL adapter.
}
}) {
this.server = options ? options.server : null;
this.adUnits = {};

//first send all events fired before enableAnalytics called
events.getEvents().forEach(event => {
if (!event) {
return;
}
}) {
this.server = options ? options.server : null;

//first send all events fired before enableAnalytics called
events.getEvents().forEach(event => {
if (!event) {
return;
}
this.enqueue(event);
});

events.on(AUCTION_END, args => this.enqueue({ eventType: AUCTION_END, args }));
events.on(BID_WON, args => this.enqueue({ eventType: BID_WON, args }));

this.enableAnalytics = function _enable() {
return utils.logMessage(
`AOL analytics adapter already enabled, unnecessary call to 'enableAnalytics()'.`
);
};
},

//override AnalyticsAdapter functions by supplying custom methods
track({ eventType, args }) {
switch (eventType) {
case AUCTION_END:
let adUnitsConf = $$PREBID_GLOBAL$$.adUnits;
let bidsReceived = $$PREBID_GLOBAL$$._bidsReceived;
let bidsRequested = $$PREBID_GLOBAL$$._bidsRequested;

let bidsReceivedPerBidderPerAdUnit = bidsReceived
.reduce((bidsReceivedPerBidderPerAdUnit, bid) => {
let bidsPerBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let bidsPerBidderPerAdUnit = bidsPerBidder[bid.adUnitCode] || [];
bidsPerBidderPerAdUnit.push(bid);
bidsPerBidder[bid.adUnitCode] = bidsPerBidderPerAdUnit;
bidsReceivedPerBidderPerAdUnit[bid.bidder] = bidsPerBidder;
return bidsReceivedPerBidderPerAdUnit;
}, {});

let bidsToReport = bidsRequested
.map(bidderRequest => bidderRequest.bids
.map(bid => {
let receivedBidsForBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let receivedBidsForBidderForAdUnit = receivedBidsForBidder[bid.placementCode] || [];
// check received bids, or mark bid as timed out if no more received bids
if (receivedBidsForBidderForAdUnit.length > 0) {
return receivedBidsForBidderForAdUnit.shift(); // remove to count timed out bids
} else {
return {
adUnitCode: bid.placementCode,
bidder: bid.bidder,
cpm: 0,
getStatusCode: () => 3, // ERROR_TIMEOUT
timeToRespond: new Date().getTime() - bidderRequest.start
};
}
})
)
.reduce((a, b) => a.concat(b), []);

bidsToReport.forEach(bid => {
const currentAdUnitCode = bid.adUnitCode;
let adUnit = adUnits[currentAdUnitCode];
if (!adUnit) {
adUnit = initAdUnit(currentAdUnitCode);
adUnit = addAolParams(adUnit, adUnitsConf, bidsReceived);
adUnits[currentAdUnitCode] = adUnit;
}
adUnit.winner = (adUnit.winner.cpm < bid.cpm) ? bid : adUnit.winner;
adUnit.bids.push(Object.assign(bid));
});

for (let code in adUnits) {
if (adUnits.hasOwnProperty(code)) {
let adUnit = adUnits[code];
if (adUnit.aolParams) {
let url = this.buildEndpoint(EVENTS.AUCTION, adUnit);
this.reportEvent(url);
}
}
}

break;

case BID_WON:
let bidWon = args;
this.enqueue(event);
});

for (let code in adUnits) {
if (adUnits.hasOwnProperty(code) && bidWon.adUnitCode === code) {
let url = this.buildEndpoint(EVENTS.WIN, adUnits[code]);
this.reportEvent(url);
}
events.on(AUCTION_END, args => this.enqueue({ eventType: AUCTION_END, args }));
events.on(BID_WON, args => this.enqueue({ eventType: BID_WON, args }));

this.enableAnalytics = function _enable() {
return utils.logMessage(
`AOL analytics adapter already enabled, unnecessary call to 'enableAnalytics()'.`
);
};
},

//override AnalyticsAdapter functions by supplying custom methods
track({ eventType, args }) {
switch (eventType) {
case AUCTION_END:
this.reportAuctionEvent({
adUnitsConfig: $$PREBID_GLOBAL$$.adUnits,
bidsReceived: $$PREBID_GLOBAL$$._bidsReceived,
bidsRequested: $$PREBID_GLOBAL$$._bidsRequested
});
break;

case BID_WON:
this.reportWinEvent({ winningBid: args });
break;
}
},

reportAuctionEvent({ adUnitsConfig, bidsRequested, bidsReceived }) {
let bidsReceivedPerBidderPerAdUnit = bidsReceived
.reduce((bidsReceivedPerBidderPerAdUnit, bid) => {
let bidsPerBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let bidsPerBidderPerAdUnit = bidsPerBidder[bid.adUnitCode] || [];
bidsPerBidderPerAdUnit.push(bid);
bidsPerBidder[bid.adUnitCode] = bidsPerBidderPerAdUnit;
bidsReceivedPerBidderPerAdUnit[bid.bidder] = bidsPerBidder;
return bidsReceivedPerBidderPerAdUnit;
}, {});

let bidsToReport = bidsRequested
.map(bidderRequest => bidderRequest.bids
.map(bid => {
let receivedBidsForBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let receivedBidsForBidderForAdUnit = receivedBidsForBidder[bid.placementCode] || [];
// check received bids, or mark bid as timed out if no more received bids
if (receivedBidsForBidderForAdUnit.length > 0) {
return receivedBidsForBidderForAdUnit.shift(); // remove to count timed out bids
} else {
return {
adUnitCode: bid.placementCode,
bidder: bid.bidder,
cpm: 0,
getStatusCode: () => 3, // ERROR_TIMEOUT
timeToRespond: new Date().getTime() - bidderRequest.start
};
}

break;
})
)
.reduce(utils.flatten, []);

let adUnits = this.adUnits;

bidsToReport.forEach(bid => {
const currentAdUnitCode = bid.adUnitCode;
let adUnit = adUnits[currentAdUnitCode];
if (!adUnit) {
adUnit = initAdUnit(currentAdUnitCode);
adUnit = addAolParams(adUnit, adUnitsConfig, bidsReceived);
adUnits[currentAdUnitCode] = adUnit;
}
adUnit.winner = (adUnit.winner.cpm < bid.cpm) ? bid : adUnit.winner;
adUnit.bids.push(Object.assign({}, bid));
});

},

reportEvent(url) {
ajax(url, null, null, { withCredentials: true });
},

getBaseSchema(eventId, adUnit) {
let aolParams = adUnit.aolParams;
return {
protocol: (document.location.protocol === 'https:') ? 'https' : 'http',
host: this.server || serverMap[aolParams.region] || serverMap.us,
tagversion: '3.0',
network: aolParams.network || '',
placement: aolParams.placement,
site: aolParams.pageid || 0,
eventid: eventId,
hbeventts: Math.floor(Date.now() / 1000) // Unix timestamp in seconds.
};
},

getAuctionSchema(adUnit) {
let aolParams = adUnit.aolParams;
return {
pubadid: adUnit.code,
hbauctionid: generateAuctionId(aolParams.placement),
hbwinner: adUnit.winner.bidder ? getBidderId(adUnit.winner.bidder) : 0,
hbprice: adUnit.winner.cpm || 0,
hbcur: aolParams.currencyCode ? `;hbcur=${aolParams.currencyCode}` : '',
pubapi: aolParams.pubapiId ? `;pubapi=${aolParams.pubapiId}` : ''
};
},

getWinSchema(adUnit) {
let auctionParams = adUnit.auctionParams;
return {
pubadid: adUnit.code,
hbauctioneventts: auctionParams.hbauctioneventts,
hbauctionid: auctionParams.hbauctionid,
hbwinner: getBidderId(adUnit.winner.bidder),
pubcpm: adUnit.winner.cpm
};
},

getBidderSchema(bid) {
return {
hbbidder: getBidderId(bid.bidder),
hbbid: bid.cpm || 0,
hbstatus: getStatusCode(bid),
hbtime: bid.timeToRespond || ''
};
},

buildEndpoint(event, adUnit) {
let baseSchema, url;

switch (event) {

case EVENTS.AUCTION:

baseSchema = this.getBaseSchema(EVENTS.AUCTION, adUnit);
let auctionSchema = this.getAuctionSchema(adUnit);
adUnit.auctionParams = {
hbauctioneventts: baseSchema.hbeventts,
hbauctionid: auctionSchema.hbauctionid
};
url = baseSchemaTemplate(baseSchema) + auctionSchemaTemplate(auctionSchema);
adUnit.bids.forEach(bid => {
url = url + bidderSchemaTemplate(this.getBidderSchema(bid));
});
return url;

case EVENTS.WIN:

baseSchema = this.getBaseSchema(EVENTS.WIN, adUnit);
let winSchema = this.getWinSchema(adUnit);
url = baseSchemaTemplate(baseSchema) + winSchemaTemplate(winSchema);
return url;
for (let code in adUnits) {
if (adUnits.hasOwnProperty(code)) {
let adUnit = adUnits[code];
if (adUnit.aolParams) {
this.reportEvent(EVENTS.AUCTION, adUnit);
}
}
}
},

reportWinEvent({ winningBid }) {
let adUnits = this.adUnits;
for (let code in adUnits) {
if (adUnits.hasOwnProperty(code) && winningBid.adUnitCode === code) {
this.reportEvent(EVENTS.WIN, adUnits[code]);
}
}
},

reportEvent(event, adUnit) {
let url = this.buildEventUrl(event, adUnit);
ajax(url, null, null, { withCredentials: true });
},

getBaseSchema(eventId, adUnit) {
let aolParams = adUnit.aolParams;
return {
protocol: (document.location.protocol === 'https:') ? 'https' : 'http',
host: this.server || serverMap[aolParams.region] || serverMap.us,
tagversion: '3.0',
network: aolParams.network || '',
placement: aolParams.placement,
site: aolParams.pageId || 0,
eventid: eventId,
hbeventts: Math.floor(Date.now() / 1000) // Unix timestamp in seconds.
};
},

getAuctionSchema(adUnit) {
let aolParams = adUnit.aolParams;
return {
pubadid: adUnit.code,
hbauctionid: generateAuctionId(aolParams.placement),
hbwinner: adUnit.winner.bidder ? getBidderId(adUnit.winner.bidder) : 0,
hbprice: adUnit.winner.cpm || 0,
hbcur: aolParams.currencyCode ? `;hbcur=${aolParams.currencyCode}` : '',
pubapi: aolParams.pubapiId ? `;pubapi=${aolParams.pubapiId}` : ''
};
},

getWinSchema(adUnit) {
let auctionParams = adUnit.auctionParams;
return {
pubadid: adUnit.code,
hbauctioneventts: auctionParams.hbauctioneventts,
hbauctionid: auctionParams.hbauctionid,
hbwinner: getBidderId(adUnit.winner.bidder),
pubcpm: adUnit.winner.cpm
};
},

getBidderSchema(bid) {
return {
hbbidder: getBidderId(bid.bidder),
hbbid: bid.cpm || 0,
hbstatus: getStatusCode(bid),
hbtime: bid.timeToRespond || ''
};
},

buildEventUrl(event, adUnit) {
let baseSchema, url;

switch (event) {

case EVENTS.AUCTION:

baseSchema = this.getBaseSchema(EVENTS.AUCTION, adUnit);
let auctionSchema = this.getAuctionSchema(adUnit);
adUnit.auctionParams = {
hbauctioneventts: baseSchema.hbeventts,
hbauctionid: auctionSchema.hbauctionid
};
url = baseSchemaTemplate(baseSchema) + auctionSchemaTemplate(auctionSchema);
adUnit.bids.forEach(bid => {
url = url + bidderSchemaTemplate(this.getBidderSchema(bid));
});
return url;

case EVENTS.WIN:

baseSchema = this.getBaseSchema(EVENTS.WIN, adUnit);
let winSchema = this.getWinSchema(adUnit);
url = baseSchemaTemplate(baseSchema) + winSchemaTemplate(winSchema);
return url;

});
}
}

});

function template(strings, ...keys) {
return function(...values) {
Expand Down
Loading

0 comments on commit 76d84ac

Please sign in to comment.