diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index af5228b8b92..644a7d24e16 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -458,47 +458,35 @@ function updateRpaCookie() { return decodedRpaCookie; } -const gamEventFunctions = { - 'slotOnload': (auctionId, bid) => { - cache.auctions[auctionId].gamHasRendered[bid.adUnit.adUnitCode] = true; - }, - 'slotRenderEnded': (auctionId, bid, event) => { - if (event.isEmpty) { - cache.auctions[auctionId].gamHasRendered[bid.adUnit.adUnitCode] = true; - } - bid.adUnit.gam = utils.pick(event, [ - // these come in as `null` from Gpt, which when stringified does not get removed - // so set explicitly to undefined when not a number - 'advertiserId', advertiserId => utils.isNumber(advertiserId) ? advertiserId : undefined, - 'creativeId', creativeId => utils.isNumber(creativeId) ? creativeId : undefined, - 'lineItemId', lineItemId => utils.isNumber(lineItemId) ? lineItemId : undefined, - 'adSlot', () => event.slot.getAdUnitPath(), - 'isSlotEmpty', () => event.isEmpty || undefined - ]); - } -} - function subscribeToGamSlots() { - ['slotOnload', 'slotRenderEnded'].forEach(eventName => { - window.googletag.pubads().addEventListener(eventName, event => { - const isMatchingAdSlot = utils.isAdUnitCodeMatchingSlot(event.slot); - // loop through auctions and adUnits and mark the info - Object.keys(cache.auctions).forEach(auctionId => { - (Object.keys(cache.auctions[auctionId].bids) || []).forEach(bidId => { - let bid = cache.auctions[auctionId].bids[bidId]; - // if this slot matches this bids adUnit, add the adUnit info - if (isMatchingAdSlot(bid.adUnit.adUnitCode)) { - // mark this adUnit as having been rendered by gam - gamEventFunctions[eventName](auctionId, bid, event); - } - }); - // Now if all adUnits have gam rendered, send the payload - if (rubiConf.waitForGamSlots && !cache.auctions[auctionId].sent && Object.keys(cache.auctions[auctionId].gamHasRendered).every(adUnitCode => cache.auctions[auctionId].gamHasRendered[adUnitCode])) { - clearTimeout(cache.timeouts[auctionId]); - delete cache.timeouts[auctionId]; - sendMessage.call(rubiconAdapter, auctionId); + window.googletag.pubads().addEventListener('slotRenderEnded', event => { + const isMatchingAdSlot = utils.isAdUnitCodeMatchingSlot(event.slot); + // loop through auctions and adUnits and mark the info + Object.keys(cache.auctions).forEach(auctionId => { + (Object.keys(cache.auctions[auctionId].bids) || []).forEach(bidId => { + let bid = cache.auctions[auctionId].bids[bidId]; + // if this slot matches this bids adUnit, add the adUnit info + if (isMatchingAdSlot(bid.adUnit.adUnitCode)) { + // mark this adUnit as having been rendered by gam + cache.auctions[auctionId].gamHasRendered[bid.adUnit.adUnitCode] = true; + + bid.adUnit.gam = utils.pick(event, [ + // these come in as `null` from Gpt, which when stringified does not get removed + // so set explicitly to undefined when not a number + 'advertiserId', advertiserId => utils.isNumber(advertiserId) ? advertiserId : undefined, + 'creativeId', creativeId => utils.isNumber(creativeId) ? creativeId : undefined, + 'lineItemId', lineItemId => utils.isNumber(lineItemId) ? lineItemId : undefined, + 'adSlot', () => event.slot.getAdUnitPath(), + 'isSlotEmpty', () => event.isEmpty || undefined + ]); } }); + // Now if all adUnits have gam rendered, send the payload + if (rubiConf.waitForGamSlots && !cache.auctions[auctionId].sent && Object.keys(cache.auctions[auctionId].gamHasRendered).every(adUnitCode => cache.auctions[auctionId].gamHasRendered[adUnitCode])) { + clearTimeout(cache.timeouts[auctionId]); + delete cache.timeouts[auctionId]; + sendMessage.call(rubiconAdapter, auctionId); + } }); }); } @@ -576,6 +564,13 @@ let rubiconAdapter = Object.assign({}, baseAdapter, { if (!cache.gpt.registered && utils.isGptPubadsDefined()) { subscribeToGamSlots(); cache.gpt.registered = true; + } else if (!cache.gpt.registered) { + cache.gpt.registered = true; + let googletag = window.googletag || {}; + googletag.cmd = googletag.cmd || []; + googletag.cmd.push(function() { + subscribeToGamSlots(); + }); } break; case BID_REQUESTED: diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 4bb2f6e217c..d8eb4fb0bdc 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -1361,7 +1361,6 @@ describe('rubicon analytics adapter', function () { describe('with googletag enabled', function () { let gptSlot0, gptSlot1; let gptSlotRenderEnded0, gptSlotRenderEnded1; - let gptslotOnload0, gptslotOnload1; beforeEach(function () { mockGpt.enable(); gptSlot0 = mockGpt.makeSlot({code: '/19968336/header-bid-tag-0'}); @@ -1375,16 +1374,6 @@ describe('rubicon analytics adapter', function () { lineItemId: 3333 } }; - gptslotOnload0 = { - eventName: 'slotOnload', - params: { - slot: gptSlot0, - isEmpty: false, - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333 - } - }; gptSlot1 = mockGpt.makeSlot({code: '/19968336/header-bid-tag1'}); gptSlotRenderEnded1 = { @@ -1397,16 +1386,6 @@ describe('rubicon analytics adapter', function () { lineItemId: 6666 } }; - gptslotOnload1 = { - eventName: 'slotOnload', - params: { - slot: gptSlot1, - isEmpty: false, - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333 - } - }; }); afterEach(function () { @@ -1536,12 +1515,6 @@ describe('rubicon analytics adapter', function () { mockGpt.emitEvent(gptSlotRenderEnded0.eventName, gptSlotRenderEnded0.params); mockGpt.emitEvent(gptSlotRenderEnded1.eventName, gptSlotRenderEnded1.params); - expect(server.requests.length).to.equal(0); - - // now emit slotOnload and it should send - mockGpt.emitEvent(gptslotOnload0.eventName, gptslotOnload0.params); - mockGpt.emitEvent(gptslotOnload1.eventName, gptslotOnload1.params); - expect(server.requests.length).to.equal(1); let request = server.requests[0]; let message = JSON.parse(request.requestBody);