diff --git a/README.md b/README.md index 666f99bd..fbb18752 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ You can find a detailed explanations on the [Prebid Universal Creative](http://p ucTagData.hbPb = "%%PATTERN:hb_pb%%"; ucTagData.hbFormat = "%%PATTERN:hb_format%%"; ucTagData.adId = "%%PATTERN:hb_adid%%"; + // if you're using GAM and want to track outbound clicks on native ads you can add this line + ucTagData.clickUrlUnesc = "%%CLICK_URL_UNESC%%"; ucTagData.requestAllAssets = true; try { diff --git a/src/nativeAssetManager.js b/src/nativeAssetManager.js index ee8abbfb..82f48611 100644 --- a/src/nativeAssetManager.js +++ b/src/nativeAssetManager.js @@ -59,7 +59,21 @@ const assetTypeMapping = { const DEFAULT_CACHE_HOST = 'prebid.adnxs.com'; const DEFAULT_CACHE_PATH = '/pbc/v1/cache'; -export function newNativeAssetManager(win, pubUrl) { +const CLICK_URL_UNESC = `%%CLICK_URL_UNESC%%`; + +let clickUrlUnesc = ''; + +export function newNativeAssetManager(win, nativeTag) { + const { pubUrl } = nativeTag; + + + // clickUrlUnesc contains the url to track clicks in GAM. we check if it + // has been transformed, by GAM, in an URL. + // if CLICK_URL_UNESC is the string "%%CLICK_URL_UNESC%%", we're not in GAM. + if (nativeTag.clickUrlUnesc && nativeTag.clickUrlUnesc !== CLICK_URL_UNESC) { + clickUrlUnesc = nativeTag.clickUrlUnesc; + } + const sendMessage = prebidMessenger(pubUrl, win); let callback; let errorCountEscapeHatch = 0; @@ -289,6 +303,9 @@ export function newNativeAssetManager(win, pubUrl) { } if (data.message === 'assetResponse') { + // add GAM %%CLICK_URL_UNESC%% to the data object to be eventually used in renderers + data.clickUrlUnesc = clickUrlUnesc; + const body = win.document.body.innerHTML; const head = win.document.head.innerHTML; @@ -375,6 +392,10 @@ export function newNativeAssetManager(win, pubUrl) { } } } + + //substitute CLICK_URL_UNESC with actual value + html = html.replaceAll(CLICK_URL_UNESC, bid.clickUrlUnesc || ""); + win.document.body.innerHTML += html; callback && callback(); win.removeEventListener('message', replaceAssets); diff --git a/src/nativeRenderManager.js b/src/nativeRenderManager.js index 619d89cb..c273d9af 100644 --- a/src/nativeRenderManager.js +++ b/src/nativeRenderManager.js @@ -51,7 +51,7 @@ export function newNativeRenderManager(win) { let renderNativeAd = function(doc, nativeTag) { window.pbNativeData = nativeTag; sendMessage = prebidMessenger(nativeTag.pubUrl, win); - const nativeAssetManager = newNativeAssetManager(window, nativeTag.pubUrl); + const nativeAssetManager = newNativeAssetManager(window, nativeTag); if (nativeTag.hasOwnProperty('adId')) { diff --git a/test/spec/nativeAssetManager_spec.js b/test/spec/nativeAssetManager_spec.js index 31897a64..49319898 100644 --- a/test/spec/nativeAssetManager_spec.js +++ b/test/spec/nativeAssetManager_spec.js @@ -40,11 +40,16 @@ const mockDocument = { }; // creates mock postmessage response from prebid's native.js:getAssetMessage -function createResponder(assets,url,template) { +function createResponder(assets,url,template, clickUrlUnesc = '') { return function(type, listener) { if (type !== 'message') { return; } - const data = { message: 'assetResponse', adId: AD_ID, assets, adTemplate:template, rendererUrl:url }; + const data = { + message: 'assetResponse', + adId: AD_ID, assets, + adTemplate:template, + rendererUrl:url, + }; listener({ data: JSON.stringify(data), origin: ORIGIN}); }; } @@ -86,8 +91,11 @@ function generateRenderer(assets) { describe('nativeAssetManager', () => { let win; - function makeManager() { - return newNativeAssetManager(win, ORIGIN); + function makeManager(args) { + return newNativeAssetManager(win, { + pubUrl: ORIGIN, + ...args + }); } beforeEach(() => { @@ -578,4 +586,64 @@ describe('nativeAssetManager', () => { expect(win.document.body.style.width).to.equal('600px'); }); }); + + describe('GAM macro %%CLICK_URL_UNESC%%', () => { + it("should remove %%CLICK_URL_UNESC%% if there's no variable set", () => { + const html = ``; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : AD_ID, + adTemplate : '
##hb_native_body##<\/p>\r\n \t
##hb_native_body##<\/p>\r\n \t