diff --git a/README.md b/README.md index 64c1e06..9c85f98 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Proudly brought to you by [@revolunet](http://twitter.com/revolunet) and [@delta - automatic page tracking - events tracking - e-commerce tracking + - enhanced e-commerce tracking - multiple-domains - ga.js and and analytics.js support - cross-domain support @@ -57,8 +58,11 @@ var app = angular.module('app', ['angular-google-analytics']) // Ignore first page view... helpful when using hashes and whenever your bounce rate looks obscenely low. AnalyticsProvider.ignoreFirstPageLoad(true); - //Enabled eCommerce module for analytics.js - AnalyticsProvider.useECommerce(true); + //Enabled eCommerce module for analytics.js(uses legacy ecommerce plugin) + AnalyticsProvider.useECommerce(true,false); + + //Enabled eCommerce module for analytics.js(uses ec plugin instead of ecommerce plugin) + AnalyticsProvider.useECommerce(true,true); //Enable enhanced link attribution AnalyticsProvider.useEnhancedLinkAttribution(true); @@ -101,6 +105,81 @@ var app = angular.module('app', ['angular-google-analytics']) // - complete transaction Analytics.trackTrans(); + // Enhanced Ecommerce Tracking + + // Product Impression Tracking + Analytics.addImpression(productId, name, list, brand, category, variant, position, price); + Analytics.pageView(); + // example: + Analytics.addImpression('sku-1','Test Product 1','Category List','Brand 1','Category-1','variant-1','1','24990'); + Analytics.addImpression('sku-2','Test Product 2','Category List','Brand 2','Category-1','variant-3','2','2499'); + Analytics.pageView(); + + // Product Click Tracking + Analytics.addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + Analytics.productClick(listName); + // example: + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.productClick('Search Result'); + + // Product Detail Tracking + Analytics.addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + Analytics.trackDetail(); + // example: + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackDetail(); + + // Add to cart Tracking + Analytics.addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + Analytics.trackCart('add'); + // example: + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackCart('add'); + + // Remove from cart Tracking + Analytics.addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + Analytics.trackCart('remove'); + // example: + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackCart('remove'); + + // Checkout Tracking + Analytics.addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + Analytics.trackCheckout(checkoutStep,optionValue); + // example: + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackCheckout(1,'Visa'); + + // Transaction Tracking + Analytics.addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + Analytics.trackTransaction(transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option); + // example: + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2222','1','MEN10','1'); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','1111','1','WOMEN10','1'); + Analytics.trackTransaction('T1234','Online Store - Web','3333','10','200','FLAT10','','',''); + + // Promotion Impressions + Analytics.addPromo(productId, name, creative, position); + Analytics.addPromo(productId, name, creative, position); + Analytics.addPromo(productId, name, creative, position); + Analytics.pageView(); + // Note: Before tracking promotion Click, call pageView otherwise promotion impressions will be treated as promotion clicks + // example: + Analytics.addPromo('PROMO_1234','Summer Sale', 'summer_banner2', 'banner_slot1'); + Analytics.pageView(); + + // Promotion Clicks + Analytics.addPromo(promotionId, promotionName, creative, position); + Analytics.addPromo(promotionId, promotionName, creative, position); + Analytics.addPromo(promotionId, promotionName, creative, position); + Analytics.promoClick(promotionName); + // example: + Analytics.addPromo('PROMO_1234','Summer Sale', 'summer_banner2', 'banner_slot1'); + Analytics.promoClick('Summer Sale'); + // populate a custom dimension Analytics.set('dimension1', 'Paid'); @@ -123,7 +202,9 @@ AnalyticsProvider.useAnalytics(true); // Ignore first page view. AnalyticsProvider.ignoreFirstPageLoad(true); //Enable eCommerce module for analytics.js -AnalyticsProvider.useECommerce(true); +AnalyticsProvider.useECommerce(true,false); +//Enable enhanced eCommerce module for analytics.js +AnalyticsProvider.useECommerce(true,true); //Enable enhanced link attribution module for analytics.js or ga.js AnalyticsProvider.useEnhancedLinkAttribution(true); //Enable analytics.js experiments diff --git a/dist/angular-google-analytics.js b/dist/angular-google-analytics.js index a9f5fa7..1586d80 100644 --- a/dist/angular-google-analytics.js +++ b/dist/angular-google-analytics.js @@ -1,6 +1,6 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.6 - 2014-10-14 + * @version v0.0.7 - 2014-10-20 * @link http://github.com/revolunet/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT @@ -21,6 +21,7 @@ angular.module('angular-google-analytics', []) pageEvent = '$routeChangeSuccess', cookieConfig = 'auto', ecommerce = false, + enhancedEcommerce = false, enhancedLinkAttribution = false, removeRegExp, experimentId, @@ -86,11 +87,13 @@ angular.module('angular-google-analytics', []) return true; }; - this.useECommerce = function (val) { + this.useECommerce = function (val,enhanced) { ecommerce = !!val; + enhancedEcommerce = !!enhanced; return true; }; + this.setRemoveRegExp = function (regex) { if (regex instanceof RegExp) { removeRegExp = regex; @@ -185,7 +188,10 @@ angular.module('angular-google-analytics', []) if ($window.ga) { if (ecommerce) { - $window.ga('require', 'ecommerce', 'ecommerce.js'); + if (!enhancedEcommerce) + $window.ga('require', 'ecommerce', 'ecommerce.js'); + else + $window.ga('require', 'ec', 'ec.js'); } if (enhancedLinkAttribution) { $window.ga('require', 'linkid', 'linkid.js'); @@ -262,7 +268,10 @@ angular.module('angular-google-analytics', []) this._log('_addTrans', arguments); } else if ($window.ga) { if (!ecommerce) { - console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true);'); + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); } else { $window.ga('ecommerce:addTransaction', { id: transactionId, @@ -295,15 +304,22 @@ angular.module('angular-google-analytics', []) $window._gaq.push(['_addItem', transactionId, sku, name, category, price, quantity]); this._log('_addItem', arguments); } else if ($window.ga) { - $window.ga('ecommerce:addItem', { - id: transactionId, - name: name, - sku: sku, - category: category, - price: price, - quantity: quantity - }); - this._log('ecommerce:addItem', arguments); + if (!ecommerce) { + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); + } else { + $window.ga('ecommerce:addItem', { + id: transactionId, + name: name, + sku: sku, + category: category, + price: price, + quantity: quantity + }); + this._log('ecommerce:addItem', arguments); + } } }; @@ -318,10 +334,16 @@ angular.module('angular-google-analytics', []) $window._gaq.push(['_trackTrans']); this._log('_trackTrans', arguments); } else if ($window.ga) { - $window.ga('ecommerce:send'); - this._log('ecommerce:send', arguments); + if (!ecommerce) { + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); + } else { + $window.ga('ecommerce:send'); + this._log('ecommerce:send', arguments); + } } - }; /** @@ -332,11 +354,254 @@ angular.module('angular-google-analytics', []) */ this._clearTrans = function () { if ($window.ga) { - $window.ga('ecommerce:clear'); - this._log('ecommerce:clear', arguments); + if (!ecommerce) { + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); + } else { + $window.ga('ecommerce:clear'); + this._log('ecommerce:clear', arguments); + } } }; + /** + Enhanced Ecommerce + */ + + /** + * Add product data + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#product-data + * @param productId + * @param name + * @param category + * @param brand + * @param variant + * @param price + * @param quantity + * @param coupon + * @param position + */ + this._addProduct = function (productId, name, category, brand, variant, price, quantity, coupon,position) { + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_addProduct', productId, name, category, brand, variant, price, quantity, coupon,position]); + this._log('_addProduct', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:addProduct', { + id: productId, + name: name, + category: category, + brand: brand, + variant: variant, + price: price, + quantity: quantity, + coupon: coupon, + position: position + }); + this._log('ec:addProduct', arguments); + } + } + }; + + /** + * Add Impression data + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#impression-data + * @param id + * @param name + * @param list + * @param brand + * @param category + * @param variant + * @param position + * @param price + */ + this._addImpression = function(id, name, list, brand, category, variant, position, price){ + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_addImpression', id, name, list, brand, category, variant, position, price]); + this._log('_addImpression', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:addImpression', { + id: id, + name: name, + category: category, + brand: brand, + variant: variant, + list: list, + position: position, + price: price + }); + } + this._log('ec:addImpression', arguments); + } + }; + + /** + * Add promo data + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce + * @param productId + * @param name + * @param creative + * @param position + */ + this._addPromo = function (productId, name, creative,position) { + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_addPromo', productId, name, creative, position]); + this._log('_addPromo', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:addPromo', { + id: productId, + name: name, + creative: creative, + position: position + }); + this._log('ec:addPromo', arguments); + } + } + }; + + /** + * get ActionFieldObject + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-data + * @param id + * @param affliation + * @param revenue + * @param tax + * @param shipping + * @param coupon + * @param list + * @param step + * @param option + */ + this._getActionFieldObject = function (id,affiliation,revenue,tax,shipping,coupon,list,step,option) { + var obj = {}; + if (id) obj.id = id; + if (affiliation) obj.affiliation = affiliation; + if (revenue) obj.revenue = revenue; + if (tax) obj.tax = tax; + if (shipping) obj.shipping = shipping; + if (coupon) obj.coupon = coupon; + if (list) obj.list = list; + if (step) obj.step = step; + if (option) obj.option = option; + return obj; + }; + + /** + * Set Action being performed + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-actions + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-types + * @param action + * @param name + * @param obj + */ + this._setAction = function(action,obj){ + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_setAction',action,obj]); + this._log('__setAction', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:setAction',action,obj); + this._log('ec:setAction', arguments); + } + } + }; + + /** + * Track Transaction + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-transactions + * @param transactionId + * @param affiliation + * @param revenue + * @param tax + * @param shipping + * @param coupon + * @param list + * @param step + * @param option + */ + this._trackTransaction = function (transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option) { + this._setAction('purchase',this._getActionFieldObject(transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option)); + this._pageView(); + }; + + /** + * Track Refund + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-refunds + * @param transactionId + * + */ + this._trackRefund = function (transactionId) { + this._setAction('refund',this._getActionFieldObject(transactionId)); + this._pageView(); + }; + + /** + * Track Checkout + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-checkout + * @param step + * @param option + * + */ + this._trackCheckOut = function (step,option) { + this._setAction('checkout',this._getActionFieldObject(null,null,null,null,null,null,null,step,option)); + this._pageView(); + }; + + /** + * Track add/remove to cart + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#add-remove-cart + * @param action + * + */ + this._trackCart = function (action){ + if(['add','remove'].indexOf(action) !== -1){ + this._setAction(action); + this._send('event','UX','click', action + 'to cart'); + } + }; + + /** + * Track promo click + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks + * @param promotionName + * + */ + this._promoClick = function (promotionName){ + this._setAction('promo_click'); + this._send('event','Internal Promotions','click', promotionName); + }; + + /** + * Track product click + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks + * @param promotionName + * + */ + this._productClick = function (listName){ + this._setAction('click',this._getActionFieldObject(null,null,null,null,null,null,listName,null,null)); + this._send('event','UX','click', listName); + }; + /** * Send custom events * https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings#implementation @@ -352,6 +617,9 @@ angular.module('angular-google-analytics', []) } }; + this._pageView = function() { + this._send('pageview'); + }; /** * Set custom dimensions, metrics or experiment * https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets @@ -390,6 +658,7 @@ angular.module('angular-google-analytics', []) cookieConfig: cookieConfig, displayFeatures: displayFeatures, ecommerce: ecommerce, + enhancedEcommerce: enhancedEcommerce, enhancedLinkAttribution: enhancedLinkAttribution, getUrl: getUrl, experimentId: experimentId, @@ -414,9 +683,43 @@ angular.module('angular-google-analytics', []) clearTrans: function () { me._clearTrans(); }, + addProduct: function (productId,name,category,brand,variant,price,quantity,coupon,position){ + me._addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + }, + addPromo: function(productId, name, creative, position){ + me._addPromo(productId, name, creative, position); + }, + addImpression: function(productId, name, list, brand, category, variant, position, price){ + me._addImpression(productId, name, list, brand, category, variant, position, price); + }, + productClick: function(listName){ + me._productClick(listName); + }, + promoClick : function (promotionName){ + me._promoClick(promotionName); + }, + trackDetail: function(){ + me._setAction('detail'); + me._pageView(); + }, + trackCart: function(action){ + me._trackCart(action); + }, + trackCheckout: function(step,option){ + me._trackCheckOut(step,option); + }, + trackTransaction: function(transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option){ + me._trackTransaction(transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option); + }, + setAction: function (action,obj) { + me._setAction(action,obj); + }, send: function (obj) { me._send(obj); }, + pageView: function () { + me._pageView(); + }, set: function (name, value) { me._set(name, value); } diff --git a/dist/angular-google-analytics.min.js b/dist/angular-google-analytics.min.js index 4c73392..c987d84 100644 --- a/dist/angular-google-analytics.min.js +++ b/dist/angular-google-analytics.min.js @@ -1,8 +1,8 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.6 - 2014-10-14 + * @version v0.0.7 - 2014-10-20 * @link http://github.com/revolunet/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT */ -"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var a,b,c,d,e,f,g=!1,h=!0,i="",j=!1,k="$routeChangeSuccess",l="auto",m=!1,n=!1,o=!1,p=!1,q={allowLinker:!0};this._logs=[],this.setAccount=function(b){return a=b,!0},this.trackPages=function(a){return h=a,!0},this.trackPrefix=function(a){return i=a,!0},this.setDomainName=function(a){return c=a,!0},this.useDisplayFeatures=function(a){return b=!!a,!0},this.useAnalytics=function(a){return j=!!a,!0},this.useEnhancedLinkAttribution=function(a){return n=!!a,!0},this.useCrossDomainLinker=function(a){return p=!!a,!0},this.setCrossLinkDomains=function(a){return f=a,!0},this.setPageEvent=function(a){return k=a,!0},this.setCookieConfig=function(a){return l=a,!0},this.useECommerce=function(a){return m=!!a,!0},this.setRemoveRegExp=function(a){return a instanceof RegExp?(d=a,!0):!1},this.setExperimentId=function(a){return e=a,!0},this.ignoreFirstPageLoad=function(a){o=!!a},this.$get=["$document","$rootScope","$location","$window",function(r,s,t,u){function v(){if(a){u._gaq=[],u._gaq.push(["_setAccount",a]),c&&u._gaq.push(["_setDomainName",c]),n&&u._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),h&&!o&&u._gaq.push(d?["_trackPageview",x()]:["_trackPageview"]);var e;e=b?("https:"===document.location.protocol?"https://":"http://")+"stats.g.doubleclick.net/dc.js":("https:"===document.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js",function(){var a=r[0],b=a.createElement("script");b.type="text/javascript",b.async=!0,b.src=e;var c=a.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}(e),g=!0}}function w(){if(!a)return console.warn("No account id set for Analytics.js");if(function(a,b,c,d,e,f,g){a.GoogleAnalyticsObject=e,a[e]=a[e]||function(){(a[e].q=a[e].q||[]).push(arguments)},a[e].l=1*new Date,f=b.createElement(c),g=b.getElementsByTagName(c)[0],f.async=1,f.src=d,g.parentNode.insertBefore(f,g)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),angular.isArray(a)?a.forEach(function(a){u.ga("create",a.tracker,l,{name:a.name})}):p?(u.ga("create",a,l,q),u.ga("require","linker"),f&&u.ga("linker:autoLink",f)):u.ga("create",a,l),b&&u.ga("require","displayfeatures"),h&&!o&&u.ga("send","pageview",x()),u.ga&&(m&&u.ga("require","ecommerce","ecommerce.js"),n&&u.ga("require","linkid","linkid.js"),e)){var c=document.createElement("script"),d=document.getElementsByTagName("script")[0];c.src="//www.google-analytics.com/cx/api.js?experiment="+e,d.parentNode.insertBefore(c,d)}}var x=function(){var a=t.path();return d?a.replace(d,""):a};this._log=function(){this._logs.push(arguments)},this._trackPage=function(b,c){c=c?c:r[0].title,h&&!j&&u._gaq?(u._gaq.push(["_set","title",c]),u._gaq.push(["_trackPageview",i+b]),this._log("_trackPageview",arguments)):h&&j&&u.ga&&(angular.isArray(a)?a.forEach(function(a){u.ga(a.name+".send","pageview",{page:i+b,title:c})}):u.ga("send","pageview",{page:i+b,title:c}),this._log("pageview",arguments))},this._trackEvent=function(a,b,c,d){!j&&u._gaq?(u._gaq.push(["_trackEvent",a,b,c,d]),this._log("trackEvent",arguments)):u.ga&&(u.ga("send","event",a,b,c,d),this._log("event",arguments))},this._addTrans=function(a,b,c,d,e,f,g,h,i){!j&&u._gaq?(u._gaq.push(["_addTrans",a,b,c,d,e,f,g,h]),this._log("_addTrans",arguments)):u.ga&&(m?(u.ga("ecommerce:addTransaction",{id:a,affiliation:b,revenue:c,tax:d,shipping:e,currency:i||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(a,b,c,d,e,f){!j&&u._gaq?(u._gaq.push(["_addItem",a,b,c,d,e,f]),this._log("_addItem",arguments)):u.ga&&(u.ga("ecommerce:addItem",{id:a,name:c,sku:b,category:d,price:e,quantity:f}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!j&&u._gaq?(u._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):u.ga&&(u.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){u.ga&&(u.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(a){u.ga&&(u.ga("send",a),this._log("send",a))},this._set=function(a,b){u.ga&&(u.ga("set",a,b),this._log("set",a,b))},j?w():v();var y=this;return h&&s.$on(k,function(){y._trackPage(x())}),{_logs:y._logs,cookieConfig:l,displayFeatures:b,ecommerce:m,enhancedLinkAttribution:n,getUrl:x,experimentId:e,ignoreFirstPageLoad:o,trackPage:function(a,b){y._trackPage(a,b)},trackEvent:function(a,b,c,d){y._trackEvent(a,b,c,d)},addTrans:function(a,b,c,d,e,f,g,h,i){y._addTrans(a,b,c,d,e,f,g,h,i)},addItem:function(a,b,c,d,e,f){y._addItem(a,b,c,d,e,f)},trackTrans:function(){y._trackTrans()},clearTrans:function(){y._clearTrans()},send:function(a){y._send(a)},set:function(a,b){y._set(a,b)}}}]}); \ No newline at end of file +"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var a,b,c,d,e,f,g=!1,h=!0,i="",j=!1,k="$routeChangeSuccess",l="auto",m=!1,n=!1,o=!1,p=!1,q=!1,r={allowLinker:!0};this._logs=[],this.setAccount=function(b){return a=b,!0},this.trackPages=function(a){return h=a,!0},this.trackPrefix=function(a){return i=a,!0},this.setDomainName=function(a){return c=a,!0},this.useDisplayFeatures=function(a){return b=!!a,!0},this.useAnalytics=function(a){return j=!!a,!0},this.useEnhancedLinkAttribution=function(a){return o=!!a,!0},this.useCrossDomainLinker=function(a){return q=!!a,!0},this.setCrossLinkDomains=function(a){return f=a,!0},this.setPageEvent=function(a){return k=a,!0},this.setCookieConfig=function(a){return l=a,!0},this.useECommerce=function(a,b){return m=!!a,n=!!b,!0},this.setRemoveRegExp=function(a){return a instanceof RegExp?(d=a,!0):!1},this.setExperimentId=function(a){return e=a,!0},this.ignoreFirstPageLoad=function(a){p=!!a},this.$get=["$document","$rootScope","$location","$window",function(s,t,u,v){function w(){if(a){v._gaq=[],v._gaq.push(["_setAccount",a]),c&&v._gaq.push(["_setDomainName",c]),o&&v._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),h&&!p&&v._gaq.push(d?["_trackPageview",y()]:["_trackPageview"]);var e;e=b?("https:"===document.location.protocol?"https://":"http://")+"stats.g.doubleclick.net/dc.js":("https:"===document.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js",function(){var a=s[0],b=a.createElement("script");b.type="text/javascript",b.async=!0,b.src=e;var c=a.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}(e),g=!0}}function x(){if(!a)return console.warn("No account id set for Analytics.js");if(function(a,b,c,d,e,f,g){a.GoogleAnalyticsObject=e,a[e]=a[e]||function(){(a[e].q=a[e].q||[]).push(arguments)},a[e].l=1*new Date,f=b.createElement(c),g=b.getElementsByTagName(c)[0],f.async=1,f.src=d,g.parentNode.insertBefore(f,g)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),angular.isArray(a)?a.forEach(function(a){v.ga("create",a.tracker,l,{name:a.name})}):q?(v.ga("create",a,l,r),v.ga("require","linker"),f&&v.ga("linker:autoLink",f)):v.ga("create",a,l),b&&v.ga("require","displayfeatures"),h&&!p&&v.ga("send","pageview",y()),v.ga&&(m&&(n?v.ga("require","ec","ec.js"):v.ga("require","ecommerce","ecommerce.js")),o&&v.ga("require","linkid","linkid.js"),e)){var c=document.createElement("script"),d=document.getElementsByTagName("script")[0];c.src="//www.google-analytics.com/cx/api.js?experiment="+e,d.parentNode.insertBefore(c,d)}}var y=function(){var a=u.path();return d?a.replace(d,""):a};this._log=function(){this._logs.push(arguments)},this._trackPage=function(b,c){c=c?c:s[0].title,h&&!j&&v._gaq?(v._gaq.push(["_set","title",c]),v._gaq.push(["_trackPageview",i+b]),this._log("_trackPageview",arguments)):h&&j&&v.ga&&(angular.isArray(a)?a.forEach(function(a){v.ga(a.name+".send","pageview",{page:i+b,title:c})}):v.ga("send","pageview",{page:i+b,title:c}),this._log("pageview",arguments))},this._trackEvent=function(a,b,c,d){!j&&v._gaq?(v._gaq.push(["_trackEvent",a,b,c,d]),this._log("trackEvent",arguments)):v.ga&&(v.ga("send","event",a,b,c,d),this._log("event",arguments))},this._addTrans=function(a,b,c,d,e,f,g,h,i){!j&&v._gaq?(v._gaq.push(["_addTrans",a,b,c,d,e,f,g,h]),this._log("_addTrans",arguments)):v.ga&&(m?n?console.warn("Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. Use AnalyticsProvider.setECommerce(true,false);"):(v.ga("ecommerce:addTransaction",{id:a,affiliation:b,revenue:c,tax:d,shipping:e,currency:i||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);"))},this._addItem=function(a,b,c,d,e,f){!j&&v._gaq?(v._gaq.push(["_addItem",a,b,c,d,e,f]),this._log("_addItem",arguments)):v.ga&&(m?n?console.warn("Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. Use AnalyticsProvider.setECommerce(true,false);"):(v.ga("ecommerce:addItem",{id:a,name:c,sku:b,category:d,price:e,quantity:f}),this._log("ecommerce:addItem",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);"))},this._trackTrans=function(){!j&&v._gaq?(v._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):v.ga&&(m?n?console.warn("Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. Use AnalyticsProvider.setECommerce(true,false);"):(v.ga("ecommerce:send"),this._log("ecommerce:send",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);"))},this._clearTrans=function(){v.ga&&(m?n?console.warn("Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. Use AnalyticsProvider.setECommerce(true,false);"):(v.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);"))},this._addProduct=function(a,b,c,d,e,f,g,h,i){!j&&v._gaq?(v._gaq.push(["_addProduct",a,b,c,d,e,f,g,h,i]),this._log("_addProduct",arguments)):v.ga&&(m?n?(v.ga("ec:addProduct",{id:a,name:b,category:c,brand:d,variant:e,price:f,quantity:g,coupon:h,position:i}),this._log("ec:addProduct",arguments)):console.warn("Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);"):console.warn("ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);"))},this._addImpression=function(a,b,c,d,e,f,g,h){!j&&v._gaq?(v._gaq.push(["_addImpression",a,b,c,d,e,f,g,h]),this._log("_addImpression",arguments)):v.ga&&(m?n?v.ga("ec:addImpression",{id:a,name:b,category:e,brand:d,variant:f,list:c,position:g,price:h}):console.warn("Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);"):console.warn("ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);"),this._log("ec:addImpression",arguments))},this._addPromo=function(a,b,c,d){!j&&v._gaq?(v._gaq.push(["_addPromo",a,b,c,d]),this._log("_addPromo",arguments)):v.ga&&(m?n?(v.ga("ec:addPromo",{id:a,name:b,creative:c,position:d}),this._log("ec:addPromo",arguments)):console.warn("Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);"):console.warn("ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);"))},this._getActionFieldObject=function(a,b,c,d,e,f,g,h,i){var j={};return a&&(j.id=a),b&&(j.affiliation=b),c&&(j.revenue=c),d&&(j.tax=d),e&&(j.shipping=e),f&&(j.coupon=f),g&&(j.list=g),h&&(j.step=h),i&&(j.option=i),j},this._setAction=function(a,b){!j&&v._gaq?(v._gaq.push(["_setAction",a,b]),this._log("__setAction",arguments)):v.ga&&(m?n?(v.ga("ec:setAction",a,b),this._log("ec:setAction",arguments)):console.warn("Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);"):console.warn("ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);"))},this._trackTransaction=function(a,b,c,d,e,f,g,h,i){this._setAction("purchase",this._getActionFieldObject(a,b,c,d,e,f,g,h,i)),this._pageView()},this._trackRefund=function(a){this._setAction("refund",this._getActionFieldObject(a)),this._pageView()},this._trackCheckOut=function(a,b){this._setAction("checkout",this._getActionFieldObject(null,null,null,null,null,null,null,a,b)),this._pageView()},this._trackCart=function(a){-1!==["add","remove"].indexOf(a)&&(this._setAction(a),this._send("event","UX","click",a+"to cart"))},this._promoClick=function(a){this._setAction("promo_click"),this._send("event","Internal Promotions","click",a)},this._productClick=function(a){this._setAction("click",this._getActionFieldObject(null,null,null,null,null,null,a,null,null)),this._send("event","UX","click",a)},this._send=function(a){v.ga&&(v.ga("send",a),this._log("send",a))},this._pageView=function(){this._send("pageview")},this._set=function(a,b){v.ga&&(v.ga("set",a,b),this._log("set",a,b))},j?x():w();var z=this;return h&&t.$on(k,function(){z._trackPage(y())}),{_logs:z._logs,cookieConfig:l,displayFeatures:b,ecommerce:m,enhancedEcommerce:n,enhancedLinkAttribution:o,getUrl:y,experimentId:e,ignoreFirstPageLoad:p,trackPage:function(a,b){z._trackPage(a,b)},trackEvent:function(a,b,c,d){z._trackEvent(a,b,c,d)},addTrans:function(a,b,c,d,e,f,g,h,i){z._addTrans(a,b,c,d,e,f,g,h,i)},addItem:function(a,b,c,d,e,f){z._addItem(a,b,c,d,e,f)},trackTrans:function(){z._trackTrans()},clearTrans:function(){z._clearTrans()},addProduct:function(a,b,c,d,e,f,g,h,i){z._addProduct(a,b,c,d,e,f,g,h,i)},addPromo:function(a,b,c,d){z._addPromo(a,b,c,d)},addImpression:function(a,b,c,d,e,f,g,h){z._addImpression(a,b,c,d,e,f,g,h)},productClick:function(a){z._productClick(a)},promoClick:function(a){z._promoClick(a)},trackDetail:function(){z._setAction("detail"),z._pageView()},trackCart:function(a){z._trackCart(a)},trackCheckout:function(a,b){z._trackCheckOut(a,b)},trackTransaction:function(a,b,c,d,e,f,g,h,i){z._trackTransaction(a,b,c,d,e,f,g,h,i)},setAction:function(a,b){z._setAction(a,b)},send:function(a){z._send(a)},pageView:function(){z._pageView()},set:function(a,b){z._set(a,b)}}}]}); \ No newline at end of file diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index 5817096..40c6d4e 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -14,6 +14,7 @@ angular.module('angular-google-analytics', []) pageEvent = '$routeChangeSuccess', cookieConfig = 'auto', ecommerce = false, + enhancedEcommerce = false, enhancedLinkAttribution = false, removeRegExp, experimentId, @@ -79,11 +80,13 @@ angular.module('angular-google-analytics', []) return true; }; - this.useECommerce = function (val) { + this.useECommerce = function (val,enhanced) { ecommerce = !!val; + enhancedEcommerce = !!enhanced; return true; }; + this.setRemoveRegExp = function (regex) { if (regex instanceof RegExp) { removeRegExp = regex; @@ -178,7 +181,10 @@ angular.module('angular-google-analytics', []) if ($window.ga) { if (ecommerce) { - $window.ga('require', 'ecommerce', 'ecommerce.js'); + if (!enhancedEcommerce) + $window.ga('require', 'ecommerce', 'ecommerce.js'); + else + $window.ga('require', 'ec', 'ec.js'); } if (enhancedLinkAttribution) { $window.ga('require', 'linkid', 'linkid.js'); @@ -255,7 +261,10 @@ angular.module('angular-google-analytics', []) this._log('_addTrans', arguments); } else if ($window.ga) { if (!ecommerce) { - console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true);'); + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); } else { $window.ga('ecommerce:addTransaction', { id: transactionId, @@ -288,15 +297,22 @@ angular.module('angular-google-analytics', []) $window._gaq.push(['_addItem', transactionId, sku, name, category, price, quantity]); this._log('_addItem', arguments); } else if ($window.ga) { - $window.ga('ecommerce:addItem', { - id: transactionId, - name: name, - sku: sku, - category: category, - price: price, - quantity: quantity - }); - this._log('ecommerce:addItem', arguments); + if (!ecommerce) { + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); + } else { + $window.ga('ecommerce:addItem', { + id: transactionId, + name: name, + sku: sku, + category: category, + price: price, + quantity: quantity + }); + this._log('ecommerce:addItem', arguments); + } } }; @@ -311,10 +327,16 @@ angular.module('angular-google-analytics', []) $window._gaq.push(['_trackTrans']); this._log('_trackTrans', arguments); } else if ($window.ga) { - $window.ga('ecommerce:send'); - this._log('ecommerce:send', arguments); + if (!ecommerce) { + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); + } else { + $window.ga('ecommerce:send'); + this._log('ecommerce:send', arguments); + } } - }; /** @@ -325,11 +347,254 @@ angular.module('angular-google-analytics', []) */ this._clearTrans = function () { if ($window.ga) { - $window.ga('ecommerce:clear'); - this._log('ecommerce:clear', arguments); + if (!ecommerce) { + console.warn('ecommerce no set. Use AnalyticsProvider.setECommerce(true,false);'); + } else if(enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is enabled. Only one plugin(ecommerce/ec) can be used at a time. ' + + 'Use AnalyticsProvider.setECommerce(true,false);'); + } else { + $window.ga('ecommerce:clear'); + this._log('ecommerce:clear', arguments); + } } }; + /** + Enhanced Ecommerce + */ + + /** + * Add product data + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#product-data + * @param productId + * @param name + * @param category + * @param brand + * @param variant + * @param price + * @param quantity + * @param coupon + * @param position + */ + this._addProduct = function (productId, name, category, brand, variant, price, quantity, coupon,position) { + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_addProduct', productId, name, category, brand, variant, price, quantity, coupon,position]); + this._log('_addProduct', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:addProduct', { + id: productId, + name: name, + category: category, + brand: brand, + variant: variant, + price: price, + quantity: quantity, + coupon: coupon, + position: position + }); + this._log('ec:addProduct', arguments); + } + } + }; + + /** + * Add Impression data + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#impression-data + * @param id + * @param name + * @param list + * @param brand + * @param category + * @param variant + * @param position + * @param price + */ + this._addImpression = function(id, name, list, brand, category, variant, position, price){ + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_addImpression', id, name, list, brand, category, variant, position, price]); + this._log('_addImpression', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:addImpression', { + id: id, + name: name, + category: category, + brand: brand, + variant: variant, + list: list, + position: position, + price: price + }); + } + this._log('ec:addImpression', arguments); + } + }; + + /** + * Add promo data + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce + * @param productId + * @param name + * @param creative + * @param position + */ + this._addPromo = function (productId, name, creative,position) { + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_addPromo', productId, name, creative, position]); + this._log('_addPromo', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:addPromo', { + id: productId, + name: name, + creative: creative, + position: position + }); + this._log('ec:addPromo', arguments); + } + } + }; + + /** + * get ActionFieldObject + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-data + * @param id + * @param affliation + * @param revenue + * @param tax + * @param shipping + * @param coupon + * @param list + * @param step + * @param option + */ + this._getActionFieldObject = function (id,affiliation,revenue,tax,shipping,coupon,list,step,option) { + var obj = {}; + if (id) obj.id = id; + if (affiliation) obj.affiliation = affiliation; + if (revenue) obj.revenue = revenue; + if (tax) obj.tax = tax; + if (shipping) obj.shipping = shipping; + if (coupon) obj.coupon = coupon; + if (list) obj.list = list; + if (step) obj.step = step; + if (option) obj.option = option; + return obj; + }; + + /** + * Set Action being performed + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-actions + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-types + * @param action + * @param name + * @param obj + */ + this._setAction = function(action,obj){ + if (!analyticsJS && $window._gaq) { + $window._gaq.push(['_setAction',action,obj]); + this._log('__setAction', arguments); + } else if ($window.ga) { + if (!ecommerce) { + console.warn('ecommerce not set. Use AnalyticsProvider.setECommerce(true,true);'); + } else if(!enhancedEcommerce ){ + console.warn('Enhanced ecommerce plugin is disabled. Use AnalyticsProvider.setECommerce(true,true);'); + } else { + $window.ga('ec:setAction',action,obj); + this._log('ec:setAction', arguments); + } + } + }; + + /** + * Track Transaction + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-transactions + * @param transactionId + * @param affiliation + * @param revenue + * @param tax + * @param shipping + * @param coupon + * @param list + * @param step + * @param option + */ + this._trackTransaction = function (transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option) { + this._setAction('purchase',this._getActionFieldObject(transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option)); + this._pageView(); + }; + + /** + * Track Refund + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-refunds + * @param transactionId + * + */ + this._trackRefund = function (transactionId) { + this._setAction('refund',this._getActionFieldObject(transactionId)); + this._pageView(); + }; + + /** + * Track Checkout + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-checkout + * @param step + * @param option + * + */ + this._trackCheckOut = function (step,option) { + this._setAction('checkout',this._getActionFieldObject(null,null,null,null,null,null,null,step,option)); + this._pageView(); + }; + + /** + * Track add/remove to cart + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#add-remove-cart + * @param action + * + */ + this._trackCart = function (action){ + if(['add','remove'].indexOf(action) !== -1){ + this._setAction(action); + this._send('event','UX','click', action + 'to cart'); + } + }; + + /** + * Track promo click + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks + * @param promotionName + * + */ + this._promoClick = function (promotionName){ + this._setAction('promo_click'); + this._send('event','Internal Promotions','click', promotionName); + }; + + /** + * Track product click + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks + * @param promotionName + * + */ + this._productClick = function (listName){ + this._setAction('click',this._getActionFieldObject(null,null,null,null,null,null,listName,null,null)); + this._send('event','UX','click', listName); + }; + /** * Send custom events * https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings#implementation @@ -345,6 +610,9 @@ angular.module('angular-google-analytics', []) } }; + this._pageView = function() { + this._send('pageview'); + }; /** * Set custom dimensions, metrics or experiment * https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets @@ -383,6 +651,7 @@ angular.module('angular-google-analytics', []) cookieConfig: cookieConfig, displayFeatures: displayFeatures, ecommerce: ecommerce, + enhancedEcommerce: enhancedEcommerce, enhancedLinkAttribution: enhancedLinkAttribution, getUrl: getUrl, experimentId: experimentId, @@ -407,9 +676,43 @@ angular.module('angular-google-analytics', []) clearTrans: function () { me._clearTrans(); }, + addProduct: function (productId,name,category,brand,variant,price,quantity,coupon,position){ + me._addProduct(productId,name,category,brand,variant,price,quantity,coupon,position); + }, + addPromo: function(productId, name, creative, position){ + me._addPromo(productId, name, creative, position); + }, + addImpression: function(productId, name, list, brand, category, variant, position, price){ + me._addImpression(productId, name, list, brand, category, variant, position, price); + }, + productClick: function(listName){ + me._productClick(listName); + }, + promoClick : function (promotionName){ + me._promoClick(promotionName); + }, + trackDetail: function(){ + me._setAction('detail'); + me._pageView(); + }, + trackCart: function(action){ + me._trackCart(action); + }, + trackCheckout: function(step,option){ + me._trackCheckOut(step,option); + }, + trackTransaction: function(transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option){ + me._trackTransaction(transactionId,affiliation,revenue,tax,shipping,coupon,list,step,option); + }, + setAction: function (action,obj) { + me._setAction(action,obj); + }, send: function (obj) { me._send(obj); }, + pageView: function () { + me._pageView(); + }, set: function (name, value) { me._set(name, value); } diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index d3fcb48..1c3fb8f 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -228,6 +228,149 @@ describe('angular-google-analytics', function(){ }); }); + describe('enhanced e-commerce transactions with analytics.js', function() { + beforeEach(module(function(AnalyticsProvider) { + AnalyticsProvider.useAnalytics(true); + AnalyticsProvider.useECommerce(true,true); + })); + + it('should add product Impression', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addImpression('sku-1','Test Product 1','Category List','Brand 1','Category-1','variant-1','1','24990'); + expect(Analytics._logs.length).toBe(1); + expect(Analytics._logs[0]['0']).toBe('ec:addImpression'); + }); + }); + + it('should add product data', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + expect(Analytics._logs.length).toBe(1); + expect(Analytics._logs[0]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[0]['1'][0]).toBe('sku-2'); + expect(Analytics._logs[0]['1'][1]).toBe('Test Product 2'); + expect(Analytics._logs[0]['1'][2]).toBe('Category-1'); + expect(Analytics._logs[0]['1'][3]).toBe('Brand 2'); + expect(Analytics._logs[0]['1'][4]).toBe('variant-3'); + expect(Analytics._logs[0]['1'][5]).toBe('2499'); + expect(Analytics._logs[0]['1'][6]).toBe('1'); + expect(Analytics._logs[0]['1'][7]).toBe('FLAT10'); + expect(Analytics._logs[0]['1'][8]).toBe('1'); + }); + }); + + it('should add promo data', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addPromo('PROMO_1234','Summer Sale', 'summer_banner2', 'banner_slot1'); + expect(Analytics._logs.length).toBe(1); + expect(Analytics._logs[0]['0']).toBe('ec:addPromo'); + }); + }); + + it('should set Action', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + var dummyAction = 'dummy'; + Analytics.setAction(dummyAction); + expect(Analytics._logs.length).toBe(1); + expect(Analytics._logs[0]['0']).toBe('ec:setAction'); + expect(Analytics._logs[0]['1']['0']).toBe(dummyAction); + }); + }); + + it('should track product click', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + var dummyList = 'dummy list'; + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.productClick(dummyList); + expect(Analytics._logs.length).toBe(3); + expect(Analytics._logs[0]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[1]['0']).toBe('ec:setAction'); + expect(Analytics._logs[1]['1']['0']).toBe('click'); + expect(Analytics._logs[1]['1']['1']['list']).toBe(dummyList); + expect(Analytics._logs[2]['0']).toBe('send'); + }); + }); + it('should track product detail', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackDetail(); + expect(Analytics._logs.length).toBe(3); + expect(Analytics._logs[0]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[1]['0']).toBe('ec:setAction'); + expect(Analytics._logs[1]['1']['0']).toBe('detail'); + expect(Analytics._logs[2]['0']).toBe('send'); + }); + }); + it('should track add to cart event', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackCart('add'); + expect(Analytics._logs.length).toBe(3); + expect(Analytics._logs[0]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[1]['0']).toBe('ec:setAction'); + expect(Analytics._logs[1]['1']['0']).toBe('add'); + expect(Analytics._logs[2]['0']).toBe('send'); + }); + }); + it('should track Remove from cart event', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackCart('remove'); + expect(Analytics._logs.length).toBe(3); + expect(Analytics._logs[0]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[1]['0']).toBe('ec:setAction'); + expect(Analytics._logs[1]['1']['0']).toBe('remove'); + expect(Analytics._logs[2]['0']).toBe('send'); + }); + }); + it('should track checkout', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.trackCheckout(); + expect(Analytics._logs.length).toBe(3); + expect(Analytics._logs[0]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[1]['0']).toBe('ec:setAction'); + expect(Analytics._logs[1]['1']['0']).toBe('checkout'); + expect(Analytics._logs[2]['0']).toBe('send'); + }); + }); + it('should track transaction', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addProduct('sku-2','Test Product 2','Category-1','Brand 2','variant-3','2499','1','FLAT10','1'); + Analytics.addProduct('sku-3','Test Product 3','Category-1','Brand 2','variant-5','299','1','FLAT10','1'); + Analytics.trackTransaction(); + expect(Analytics._logs.length).toBe(4); + expect(Analytics._logs[0]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[1]['0']).toBe('ec:addProduct'); + expect(Analytics._logs[2]['0']).toBe('ec:setAction'); + expect(Analytics._logs[2]['1']['0']).toBe('purchase'); + expect(Analytics._logs[3]['0']).toBe('send'); + }); + }); + it('should track promo click', function() { + inject(function(Analytics) { + expect(Analytics._logs.length).toBe(0); + Analytics.addPromo('PROMO_1234','Summer Sale', 'summer_banner2', 'banner_slot1'); + Analytics.promoClick('Summer Sale'); + expect(Analytics._logs.length).toBe(3); + expect(Analytics._logs[0]['0']).toBe('ec:addPromo'); + expect(Analytics._logs[1]['0']).toBe('ec:setAction'); + expect(Analytics._logs[1]['1']['0']).toBe('promo_click'); + expect(Analytics._logs[2]['0']).toBe('send'); + }); + }); + }); + describe('supports arbitrary page events', function() { beforeEach(module(function(AnalyticsProvider) { AnalyticsProvider.setPageEvent('$stateChangeSuccess');