<?xml version="1.0" encoding="utf-8" ?>
<rss version="0.91">
<!-- RSS generated automatically on Friday 18 May 2012, 2:13 -->
	<channel>
		<title>TechPad</title>
		<description>Web analytics implementation hacks for ecommerce and content sites</description>
		<link>http://techpad.co.uk/?utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Main_feed</link>
		<language>en-gb</language>
			<item>
				<title><![CDATA[A quick guide to R and Google Analytics]]></title>
				<description><![CDATA[A beginner's guide to getting started with the R Statistical Computing programming language for Google Analytics data analysis.

<div><p>R is a programming language designed for statistical analysis and graphical data visualisation. It's a command line language, similar in many ways to Python, but can also be used from graphical applications, too.&nbsp;</p><p>R is becoming popular with analysts who want to do a bit more with the data they export from Google Analytics. While the learning curve is initially a bit steep, there's an R package for Google Analytics which can make working with, and visualising, API data a little less challenging.</p><p>I've recently been dabbling with R and Google Analytics and thought I'd share some pointers on how to get started with some simple projects.&nbsp;</p><h2>1. Install R and R-XML</h2><p>Besides R itself, the R for Google Analytics code also uses a couple of extra extensions for fetching the data from the webservice and for parsing the resulting XML.&nbsp;</p><p>I'm a Linux user and on Ubuntu/Debian you can install these by entering: sudo apt-get install r-base r-cran-xml libcurl4-gnutls-dev libxml2-dev</p><h2>2. Start R and install RCurl and XML</h2><p>To install the required RCurl package you need to start R by opening a terminal and typing R then entering a command to download the package from one of the&nbsp;<a target="_blank" mce_href="http://www.r-project.org/" href="http://www.r-project.org/">CRAN mirrors</a>. These are much like the CPAN mirrors used in Perl, but contain R packages rather than Perl packages.</p><p>The&nbsp;<a target="_blank" mce_href="http://code.google.com/p/r-google-analytics/" href="http://code.google.com/p/r-google-analytics/">Google Analytics R documentation</a>&nbsp;and code comments suggest using the www.omegahat.com mirror, however, this domain appears to no longer be in use, so I went for Imperial College's CRAN mirror, which is at http://cran.ma.imperial.ac.uk.</p><p>You can download RCurl from your chosen mirror by entering the following command in the R command line interface: install.packages("RCurl", repos = "http://cran.ma.imperial.ac.uk")</p><p>Once you've done that, issue the command below to install the XML libraries in R: install.packages("XML", repos = "http://www.omegahat.org/R")</p><h2>3. Install R Google Analytics</h2><p>There's a pre-built package for using R with Google Analytics, but it's not in Cran, so you'll need to download it the&nbsp;<a href="http://code.google.com/p/r-google-analytics/downloads/detail?name=RGoogleAnalytics_1.1.tar.gz">RGoogleAnalytics code libraries</a>&nbsp;from Google Code.</p><p>To install RGoogleAnalytics start R (just type R in a terminal) and then enter this command (with the location and file name replaced with where ever you've put the RGoogleAnalytics tarball): install.packages("/home/matt/Downloads/RGoogleAnalytics_1.1.tar.gz",repos=NULL,type="source")&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="266" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f5682610a881.jpg">&nbsp;</p><h2>4. Install RStudio</h2><p>Next, I'd recommend installing RStudio, a very powerful graphical client available for R, which is free and open source and available for Linux, Mac and Windows. You can<a href="http://www.rstudio.org/download/desktop">download it</a>&nbsp;from www.rstudio.org as a package for your OS.&nbsp;</p><p>Not only does it provide simple access to the command line, but it will also display any visualisations generated within the application itself, which is nice. The full&nbsp;<a href="http://www.rstudio.org/docs/">documentation for RStudio</a>&nbsp;will tell you more.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="280" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f5685dc8a6b2.jpg"></p><h2>5. Load the RGoogleAnalytics library&nbsp;</h2><p>If you wish to install any additional packages, click the Packages tab in the lower right hand corner of the RStudio GUI and RStudio will automatically install the selected package and its dependencies with a single click. This makes extending R really, really easy. In order to use one of the packages, you need to tick the checkbox so the libraries are loaded.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="345" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f5687c58f593.jpg">&nbsp;</p><p>When you load the RGoogleAnalytics library, you should see it fire up the dependencies in the console window.</p><p>&gt; library("RGoogleAnalytics")<br>Loading required package: RCurl<br>Loading required package: bitops<br>Loading required package: XML</p><h2>6. Connect to the Google Analytics Core Reporting API</h2><p>Using the source editor window at the top right of RStudio write a few lines of code to start up RGoogleAnalytics in R, pass your login credentials to the Google Analytics Core Reporting API and fetch your profile data.&nbsp;</p><p>ga &lt;- RGoogleAnalytics()<br>ga$SetCredentials("you@yourdomain.com", "qkjshdjkdsksk")<br>profiles &lt;- ga$GetProfileData()<br></p><p><img alt="" border="" hspace="" vspace="" width="426" height="114" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f57c48d9bfcb.jpg">&nbsp;</p><p>Highlight the text you've written and then click the "Run" button to execute this chunk of code - you should see some results in the Workspace window pane. &nbsp;</p><p>Click the "Profiles" option and you should get a pop-up window containing all of the profiles for your ID and all of the table IDs for your GA tables. You'll need to grab one of the table IDs to use to query GA.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="233" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f57c6957c5ef.jpg"></p><h2>7. Running basic GA queries</h2><p>Once you have an open connection to GA, you can now compose a Google Analytics API query to pass to the Core Reporting API using the QueryBuilder() function. Here's a basic example to fetch visitors and pageviews for a given date period.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="226" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f57c80730ba2.jpg">&nbsp;</p><p>When the query runs you should see it pause for a second while it queries the Google Analytics servers and then display the results in the console window on the bottom left had corner of RStudio.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="209" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f57c8e778042.jpg"></p><p>While handy, at the moment, this isn't anything you couldn't achieve either via the Data Feed Query Explorer or via the Core Reporting API in any other language that takes your fancy.&nbsp;</p><h2>8. Plotting data</h2><p>R has tons of features for quickly plotting data and applying statistical calculations to data sets. Basic plots are achieved using the plot() function while trend lines can be added using lines(). You can do this on your GA data with:</p><p>require(stats)<br>plot(ga.data$data)<br>lines(lowess(ga.data$data))<br></p><p><img alt="" border="" hspace="" vspace="" width="426" height="240" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f57cc7d9a04a.jpg">&nbsp;</p><p>This is only really scratching the surface and the quick plot I did obviously isn't ideal for this data set, but hopefully it's enough to give you a rough idea of how it's done. &nbsp;</p><p>If I get a spare moment, I'll do a follow-up to explain how you can do more useful stuff with R, as soon as I figure it out myself!</p></div>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=220&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_220]]></link>
			</item>
			<item>
				<title><![CDATA[How to improve your Google Merchant Center feed quality]]></title>
				<description><![CDATA[Keeping your Google Merchant Center feeds low on errors and warnings will keep the traffic and revenue coming in. Here are some pointers on how to improve feed quality. 

<p>Google Merchant Centre (formerly Google Base) feeds are XML or text files which contain data on the products sold in your e-commerce platform and they power both Google Shopping and the product extensions in Google Adwords. </p><p>

Google sets strict criteria on data quality and error limits and if you don't monitor these you risk having your feed penalised and some or all of your products de-listed.</p><p>

In September 2011, Google started gradually enforcing new <a target="_blank" mce_href="http://merchant-center-announcements.blogspot.com/2011/09/we-have-gradually-begun-enforcing.html" href="http://merchant-center-announcements.blogspot.com/2011/09/we-have-gradually-begun-enforcing.html">feed specification requirements </a>and if you didn't update your feed then it's possible you may have experienced a traffic and revenue drop from this source.</p><p> 

Among the new additions were the requirement to provide data on product availability, the Google Product Category and images. </p><p>If you sell clothes and shoes there are <a target="_blank" mce_href="http://merchant-center-announcements.blogspot.com/2011/07/weve-made-changes-to-google-product.html" href="http://merchant-center-announcements.blogspot.com/2011/07/weve-made-changes-to-google-product.html">additional things</a> you need to provide too.</p><h2>

Step 1: Examine the Dashboard</h2><p>Login to the Google Merchant Centre and open the <a target="_blank" mce_href="http://www.google.co.uk/merchants/merchantdashboard" href="http://www.google.co.uk/merchants/merchantdashboard">Dashboard</a> for the site you want to examine.

</p><p>The Dashboard shows some charts outlining the number of products that are active, awaiting review, disapproved or expiring for the Product Search and Product Ads; the number of search clicks; a summary of data quality and the total number of items inserted. 

</p><p><img mce_src="/custom/images/medium/4f5614b429bf4.jpg" height="265" width="426" src="/custom/images/medium/4f5614b429bf4.jpg">&nbsp;</p><p>We're concerned with three main things: the number of items inserted, the overall data quality and the number of errors in the data feeds. The more effort you put into the data quality and errors, the more products you'll get listed.

</p><p><b>Step 2: Submit a test feed</b></p><h2>Step 2: Submit a test feed</h2><p>While the standard Google Merchant Center web interface will show you errors and warnings, it won't show them all on one page and there's no immediate option to download them all in an easily digested spreadsheet. 

</p><p><img mce_src="/custom/images/medium/4f5606839aef7.jpg" height="221" width="426" src="/custom/images/medium/4f5606839aef7.jpg">&nbsp;</p><p>Therefore, the first step I'd suggest is to download your existing feed from the Data feeds page and rename it under a new name in order to create a <a target="_blank" mce_href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=1188998" href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=1188998">test data feed</a>. 

</p><p>On the Data feeds page click "New Test Data Feed" and upload the copy of the feed you downloaded to create a new test data feed which will allow you to check your changes and download all errors and warnings in a CSV file. </p><p><img mce_src="/custom/images/medium/4f5606826079e.jpg" height="335" width="426" src="/custom/images/medium/4f5606826079e.jpg">&nbsp;</p><p>

After a few minutes, if you click the list of errors on the Data feeds &gt; Status section, you should find an option to "Download full report". Click the link and you should receive a huge CSV file to open in Excel allowing you to search for errors and warnings. 

</p><p><img mce_src="/custom/images/medium/4f5606848285f.jpg" height="303" width="426" src="/custom/images/medium/4f5606848285f.jpg">&nbsp;</p><p>&nbsp;</p><h2>Step 3: Examine data quality&nbsp;&nbsp;</h2><p>The next step is to look at your <a target="_blank" mce_href="http://www.google.co.uk/merchants/qualityfeedback" href="http://www.google.co.uk/merchants/qualityfeedback">data quality</a>, which covers things like missing or invalid product identifiers, or long titles. 

The issues Google discovers in your feed will be separated into Critical Errors and Suggested Optimisations. </p><p>Critical Errors are obviously really bad and you must fix them quickly to prevent your feed being suspended. 

</p><p><img mce_src="/custom/images/medium/4f5614b2effc0.jpg" height="314" width="426" src="/custom/images/medium/4f5614b2effc0.jpg">&nbsp;</p><p>Typical reasons for critical errors are products that have been added without the required product identifier or GTIN, which is usually a product code or barcode. 

</p><p>Rather unhelpfully, Google doesn't inform you by email when it discovers such issues, so you'll need to check the Data quality report regularly. </p><p>It's also worth setting up an alert in Google Analytics to inform you of traffic drops from this source. 

If you click the "<a target="_blank" mce_href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=160161" href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=160161">How to fix</a>" links, you'll find details on how you can resolve the problem. </p><p>You'll need to work through the errors one by one, examine your feed data for similar issues, and then upload it to assess what's left to fix.</p><h2>Step 4: Examine data feed errors</h2><p>Data feed errors are the next issue to tackle. You can examine these by viewing the reports at Data feeds &gt; Status &gt; View errors. </p><p>If you need to download a copy of your XML feed to examine, you can use the link on this page and then open it up in a text editor. 

</p><p>You can also find individual errors by using Ctrl + F within the full report you downloaded in Step 2 and searching for "error". 

</p><p>The item errors report on the web interface will show any products that have errors and have been de-listed. None of these will be shown on Google Shopping or Google Ads, so you'll want to rectify these first. 

</p><p>Typical reasons for errors are "non-unique items", which are usually different products with the same product code; image URLs which contain unusual characters such as square brackets, or items with product descriptions that contain too much text.</p><h2>Step 5: Testing your changes&nbsp;</h2><p>Once you've edited your product content to resolve the issues the Google Merchant Center has flagged, you'll need to use your e-commerce platform to regenerate the feed.</p><p> 

Once you've done this, go to Data feeds &gt; Daily upload and click the "Update and fetch now" button. </p><p>After a few minutes, you should see the new data appearing in your Status report and you'll be able to work out what work is left to complete.</p><h2>Solving common errors</h2><p>Any products in your feed that throw an error won't be displayed in Google Product Search or Product Ads, so fixing these should be your top priority. 

</p><p><b>"Item too big"
</b></p><p>The <a target="_blank" mce_href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=1139283" href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=1139283">item is too big</a> error is caused by product descriptions which are over 10KB in size. Flash or JavaScript code, or just shedloads of text can push you over this limit, so you'll simply need to cut the length of the copy in the description field to fix it. 

</p><p><b>"Invalid URL in attribute"</b></p><p>
The <a target="_blank" mce_href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=160038" href="http://support.google.com/merchants/bin/answer.py?hl=en-GB&amp;answer=160038">Invalid URL in attribute</a> error is triggered by dodgy URLs and filenames present in the Google Merchant Centre feed. Typical causes for this are spaces in URLs that haven't been escaped with "%20", the presence of backslashes instead of forward slashes, the use of relative URLs (ie. file.html) and missing http:// at the start of the URL. </p><p>

<b>"Duplicate item"</b></p><p>Duplicate item errors are usually caused by product administrators inadvertently using the same product code for multiple SKUs. This is easily fixed by identifying the duplicates and adding the correct product codes, or the additional EAN/GTIN for the SKUs.</p><p><b>"Missing required attribute: title"</b></p><p>Oh dear, one of your staff has added a product without a page title, which isn't very clever, but thankfully it is easily fixed.</p><p><b>Solving common warnings
</b></p><p>Warnings won't prevent products from being listed, but they do affect your overall feed quality, so might feasibly have an impact upon ranking. It makes sense to improve these where you can.</p><p> 

<b>"Invalid UPC value"
</b></p><p>The Universal Product Code (UPC) is a US barcode based on 12 numerical digits. Check that yours meets these criteria if you're supplying one. Make sure there are no non-numerical characters present. All barcodes passed to Google get validated, and it will throw an error if it finds an invalid code, which means the product won't be displayed.</p><p><b>"Invalid string value in attribute: description"
</b></p><p>The description field in the feed contains the product copy for the item you're promoting. The usual reason for the "invalid string value" error is that the description is completely missing, or contains an invalid character. If the description is completely missing you'll also get another warning for "Missing recommended attribute: description".

</p><p><b>"Missing recommended attribute: google_product_category"
</b></p><p>The <a target="_blank" mce_href="http://support.google.com/merchants/bin/answer.py?hl=en&amp;answer=160081" href="http://support.google.com/merchants/bin/answer.py?hl=en&amp;answer=160081">Google Product Category</a> is a string which tells Google Shopping how to categorise the item. It's typically something like "Media &gt; DVDs &amp; Videos" and is based on Google's taxonomy, not yours. 

</p><p>However, although it's wise to add it to every item you list it's only essential for feeds in the UK, US, Germany, Japan and France which sell products in <a target="_blank" mce_href="http://merchant-center-announcements.blogspot.com/" href="http://merchant-center-announcements.blogspot.com/">certain categories listed here</a>. 

</p><p><b>"Missing recommended attribute: product_type"
</b></p><p>Unlike the google_product_category, the product_type field is based on your site's taxonomy for the given item. You'd usually use this in conjunction with google_product_category to place the item in Google's taxonomy, and then provide additional <a target="_blank" mce_href="http://support.google.com/merchants/bin/answer.py?hl=en&amp;answer=160081" href="http://support.google.com/merchants/bin/answer.py?hl=en&amp;answer=160081">breadcrumb information</a> to further categorise the product. 

</p><p><b>"Missing recommended attribute: image_link"
</b></p><p>The image link is a recommended field to provide, so you'll need to source an image and include the URL in your feed to get rid of this notice.</p><p><img alt="" title="undefined" align="" border="" height="310" hspace="" vspace="" width="426" src="http://techpad.co.uk/custom/images/medium/4f563f048a067.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p><h2>7 helpful tips for troubleshooting feeds</h2><p>1. Check the Google Merchant Center Dashboard regularly to ensure your feeds are working optimally. Google won't tell you when your products or feed gets de-listed and you'll lose money if you don't check regularly. 

</p><p>2. Keep a close eye on the <a target="_blank" mce_href="http://merchant-center-announcements.blogspot.com/" href="http://merchant-center-announcements.blogspot.com/">Google Merchant Center Announcements blog</a>. This is where you'll find more information on forthcoming changes to feed requirements and how they might affect you. </p><p>

3. Track the revenue you're getting from Google Merchant Centre feeds using Google Analytics campaign tracking parameters in your URLs. You can create dashboards (above), custom reports, advanced segments and alerts to help you can an eye on things. 

</p><p>4. If you need help diagnosing problems with your feed, check out the <a target="_blank" mce_href="http://groups.google.com/a/googleproductforums.com/forum/#!forum/merchant-center" href="http://groups.google.com/a/googleproductforums.com/forum/#!forum/merchant-center">Google Merchant Center forums</a> at Google Groups. 

</p><p>5. The errors and warnings which apply to you will depend on what you sell, and in which countries you operate. You'll need to check the guidelines at <a target="_blank" mce_href="http://support.google.com/merchants/?hl=en-GB" href="http://support.google.com/merchants/?hl=en-GB">Google Merchant Center Help</a> to find out which ones matter to you. 

</p><p>6. You can find GTINs that Google recognises by searching for the product in Google Shopping and clicking the "Compare Prices" button which usually appears on the first result. Scroll to the bottom and you should find the EAN you need.</p><p>7. Dodgy GTINs are among the trickiest issues to solve and your item will be rejected if you supply an invalid code. Fortunately, you can validate them yourself directly within your platform using <a target="_blank" href="https://github.com/charithe/gtin-validator/blob/master/gtin_validator.py">code like this</a>.&nbsp;</p><p>8. Provide as much detail as possible and make sure content editors always maintain high standards of data quality. Miss out your EANs, for example, and you'll get far less exposure. &nbsp;</p><p><b>Why bother?</b>&nbsp;</p><p>Here's what can happen to your performance if you optimise properly! A 200%+ performance boost. Simply fixing the errors and warnings and improving taxonomy helps increase the clicks.&nbsp;</p><p>We're now seeing a huge increase in revenues from this channel which is making a massive financial contribution. &nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="106" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f5f463c7008c.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=219&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_219]]></link>
			</item>
			<item>
				<title><![CDATA[Using Google Analytics ecommerce data for ABC/Pareto analysis]]></title>
				<description><![CDATA[Performing an ABC or Pareto analysis on your e-commerce sales can shed light on several interesting things about your business.

<p>Vilfredo Pareto's eponymous Pareto principle is a rule of thumb applied to many things in business, one of which is that 80% of revenue will come from 20% of your product range.&nbsp;</p><p>Knowing which 20% of your products are having the greatest impact on your revenues can help you reduce the revenue you lose to stock outs and help you optimise your product sales for the slower turning lines.</p><p>It's not directly possible to do a Pareto analysis in Google Analytics, but you can use the Google Analytics Data Feed Query Explorer to extract your annual sales data and pull it into Excel for further analysis.&nbsp;</p><p><b>Step 1: Fetching the data</b>&nbsp;</p><p>Log into the Data Feed Query Explorer and create a query to fetch the product name and item revenue for every product you've sold over the past 12 months, and order the results by descending item revenue.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="355" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f4d42a434cc5.jpg">&nbsp;&nbsp;</p><p>You can save time by <a href="http://techpad.co.uk/custom/images/medium/4f4d42a434cc5.jpg">clicking here</a> and then authenticating your Google Analytics account. If you highlight the data produced with your cursor, you can just copy and paste it from the Data Feed Query Explorer straight into Excel.&nbsp;</p><p><b>Step 2: Sorting the data</b></p><p>Now that we've got our revenue data for all of the products we've sold over the past year, we need to count the number of products and split them into three classes, A (the top 20% of sales), B (the next 75% of sales) and C (the bottom 5% of sales).&nbsp;I'd recommend placing each class on its own sheet so you can go over them more easily. &nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="272" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f4d4709a5c32.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p><p>You should find that approximately 80% of your revenue comes from the top 20% of products sold (it was 75% in the case of my site), while the other two classes (80% of your stock) make up the remaining 20% of your revenue.&nbsp;&nbsp;</p><p><b>Step 3: Analysing the class data</b></p><p><b></b>The products in class A are the ones that are currently of the greatest importance to your revenue.&nbsp;These are the ones you need to keep a really close eye on in terms of your&nbsp;<a mce_href="http://techpad.co.uk/content.php?sid=209" href="http://techpad.co.uk/content.php?sid=209">inventory control</a>&nbsp;as&nbsp;<a mce_href="http://techpad.co.uk/content.php?sid=183" href="http://techpad.co.uk/content.php?sid=183">stock outs will lose you sales</a>.&nbsp;</p><p>However, if anything, the really interesting stuff lies within the B and C classes. If you spot products in here that you'd expect ought to really be fast-moving products that shift in large quantities worthy of class A, then you've spotted a potential problem.&nbsp;Are they priced too high? What's stopping your customers purchasing them as often as you'd expect?&nbsp;</p><p>If everything is definitely in order regarding pricing and other on-site issues, then perhaps you could reduce your inventory levels of these slower moving items, make them special order items or get them drop-shipped to free up working capital?&nbsp;</p><p>The other really useful information lies in what you can't see. Google Analytics will obviously only tell you about the products you <i>have</i> sold. </p><p>If you compare the total number of products you've exported to the actual number of products in your range you may spot a number of products that haven't sold at all - so called class D items. In this case, there's something very wrong and you definitely ought to consider clearing these, unless they're simply range completers.</p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=218&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_218]]></link>
			</item>
			<item>
				<title><![CDATA[Building analytics tools with the Google Core Reporting API part II]]></title>
				<description><![CDATA[This quick guide explains how you can create a flexible table structure for displaying data exported from the Google Analytics Core Reporting API. 

<p>In part one of this series of blog posts on the Google Analytics Core Reporting API - <a mce_href="http://techpad.co.uk/content.php?sid=198" href="http://techpad.co.uk/content.php?sid=198">Building analytics tools with the Google Core Reporting API part I</a> -&nbsp; I explained how to perform authentication with OAuth 2.0 and how to access data objects.&nbsp;</p><p>The next step is to display your data. </p><p>However, if you're creating different queries to run which have varying numbers and types of metric and dimension selected, you need a flexible way of formatting data without the need to code a new table each time you modify your API query. </p><p>The Smarty templating engine for PHP is ideal for this.&nbsp;</p><p><b>Step 1: Install Smarty and set it up</b></p><p>Firstly you'll need to install Smarty and get it set up so you can use it within your Core Reporting API application. You can download it from www.smarty.net and check the excellent Smarty Crash Course for some tips on set-up and basic usage.&nbsp;</p><p>Once you've set it up, you'll want to assign a title variable to pass to Smarty: $smarty-&gt;assign('title','Data for ');</p><p><img alt="" title="undefined" align="" border="" height="283" hspace="" vspace="" width="426" src="http://techpad.co.uk/custom/images/medium/4f5867f97ecaf.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p><p>Then you need to get the column headers, which are your metrics and dimensions, and add them to an array to pass to Smarty so we can use them as the table headers: $smarty-&gt;assign('headers',$data['columnHeaders']);</p><p>The rest of the data can be passed to Smarty as $data: $smarty-&gt;assign('data',$data); and then you can send it all to the display template with $smarty-&gt;display('../templates/table.tpl');</p><p><b>Step 2: Create your flexible table template</b></p><p>In order to get your content to display clearly, with the right column headings and the right number of columns, we need a flexible structure that works for any combination of metrics and dimensions.&nbsp;</p><p>Create the basic table structure using the standard  tags and then create a loop construct within your first set of  table row tags to add the headings based on the selected dimensions and metrics. &nbsp;</p><p><img alt="" title="undefined" mce_src="/custom/images/medium/4f576f0bd7556.jpg" align="" border="" height="254" hspace="" vspace="" width="426" src="/custom/images/medium/4f576f0bd7556.jpg"></p><p>The next step is to loop through the actual data. I used a foreach to loop over all of the results and display them in the appropriate table cells.&nbsp;</p><p>There are some tweaks that are worth making to make the data more presentable. </p><p>I used the Smarty cycle value to add a class "on" or "off" to each table row and then added CSS to change the colour to create a zebra-table effect of alternating row colours.&nbsp;</p><p><img mce_src="/custom/images/medium/4f586f47e3780.jpg" height="360" width="426" src="/custom/images/medium/4f586f47e3780.jpg">&nbsp;</p><p>I also used is_numeric and stristr to check to see whether the value was a string or an integer and rounded the values that had lots of trailing decimal places, and truncated long strings, such as URLs, to make the data a bit cleaner. </p><p>Add some CSS to style it up and you've got a quick and easy way to 
display lots of data from the Core Reporting API, without the need to 
edit anything other than your original query. &nbsp; <br></p><p><img alt="" title="undefined" align="" border="" height="148" hspace="" vspace="" width="426" src="http://techpad.co.uk/custom/images/medium/4f586826099b2.jpg" onmouseover="undefined" onmouseout="undefined"></p><p>Next time I'll explain how you can use refresh tokens to create applications that can run without user interaction. &nbsp;</p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=213&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_213]]></link>
			</item>
			<item>
				<title><![CDATA[Turn Google Analytics into an inventory profiling system]]></title>
				<description><![CDATA[Want to get inventory profiling data on your stock into Google Analytics so you can analyse it? Here's how I did it with a server-side event tracking hack.

<p>Stock management tends to be quite basic for those of us using standard e-commerce platforms without expensive warehouse integration systems.</p>

<p>It relies upon two key bits of data held in the e-commerce platform's database: the current stock holding for each product, and the low-stock level for each product.</p>

<p>When an item is sold, the stock holding goes down according to the number of units sold. Each product is then re-ordered when its stock level reaches its low-stock level or re-order point (ROP).</p> 

<p>The stock holding level is manually increased when the ordered goods arrive from the supplier and stock levels are replenished to the maximum stock level.</p>

<p>This technique works but its success is dependent upon a number of things, and there are various business considerations to take into consideration to ensure it works optimally.</p><p>Here's a textbook representation of what happens to stock levels. &nbsp;&nbsp;</p><p><img alt="" title="undefined" align="" border="" height="314" hspace="" vspace="" width="426" src="http://techpad.co.uk/custom/images/medium/4f23d7f84669b.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p>

<h3>The problem?</h3>
<p>Well, two main things can go wrong. </p><p>You can run out of stock because your stock holding isn't large enough to meet the demand, or you can have a low-stock level which is too low, which means you run out of stock while waiting for the goods you've re-ordered to arrive.</p>

<p>These things need checking continually, because demand for products can rise (and fall), causing you to run out of popular products (or have a surplus of slow sellers you need to turn).</p>

<p>I've explained before how I have used Google Analytics to <a mce_href="http://techpad.co.uk/content.php?sid=183" href="http://techpad.co.uk/content.php?sid=183">identify the revenue you lose to stock-outs</a>, and it's well worth implementing this if you suspect stock control needs improving.</p>

<p>However, looking at stock-outs only gives you part of the picture. </p><p>What you really want to see, is how close you get to your buffer inventory, how much stock you have, what the demand is like, and how much working capital you have tied up in your stock in relation to sales.</p>

<p>Most e-commerce platforms don't tell you this, and our systems don't report it, so I spent a day devising a hack to obtain the data and pull it into Google Analytics for monitoring, reporting and analysis.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="232" align="" title="undefined" src="/custom/images/medium/4f7dbb0c9bc4d.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p><h3>What will this hack provide?</h3><div><ul><li>Timelines showing how your total inventory level and value changes over time.</li><li>Timelines showing how many categories, subcategories, products and SKUs you have.</li><li>Timelines showing how many stocked and drop-shipped SKUs you have.</li><li>Timelines showing how many customers and newsletter subscribers you have.</li><li>Detailed data on the number of subcategories, products and SKUs per category.</li><li>The value and inventory size of each category on your site.</li><li>The total inventory, buffer inventory and inventory value for every product on your site.</li><li>Plus any other timeline-based daily metrics you fancy injecting into GA.&nbsp;</li></ul></div>

<h3>Step 1: Setting up server-side analytics</h3>
<p>In order to obtain data on these things you need to query the database at a particular time each day and send the data to Google Analytics.</p><p> However, that's not feasible using the standard client-side tracking code - you need to do it on the server-side from a command-line application. <br></p><p>To achieve this I developed a command-line application in PHP which runs on the PHP-CLI and queries a SQL database to obtain the metrics required.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="163" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f24246c4df4b.jpg" onmouseover="undefined" onmouseout="undefined"></p><p>It then injects them into Google Analytics using the excellent&nbsp;<a mce_href="http://techpad.co.uk/content.php?sid=205" href="http://techpad.co.uk/content.php?sid=205">PHP-GA</a> class. If you've not used this before you can get some general usage tips from my post on the hack I made&nbsp;for testing a <a mce_href="http://techpad.co.uk/content.php?sid=205" href="http://techpad.co.uk/content.php?sid=205">cookie-less Google Analytics implementation</a>.</p><p>Using a command-line application with server-side analytics allows you to run the code from a server and can <a mce_href="http://techpad.co.uk/content.php?sid=195" href="http://techpad.co.uk/content.php?sid=195">bypass the 10 event limit</a> imposed for the client side GATC.&nbsp;</p><p>You could also use <a mce_href="http://techpad.co.uk/content.php?sid=186" href="http://techpad.co.uk/content.php?sid=186">SSGA server-side Google Analytics</a> if you prefer, but it's not been updated for a while and, annoyingly, it encodes spaces in event category, action and label strings.&nbsp;</p><p><span class="Apple-style-span" style="font-size: 14px; font-weight: bold; ">Step 2: Obtaining aggregate daily totals</span></p>
<p>The first thing I wanted to obtain was aggregate daily totals on various metrics to give an overview on the inventory not provided by our e-commerce platform. </p><p>This includes metrics like the daily levels for: total categories, total products, total SKUs, total stocked SKUs, total drop-shipped SKUs, total inventory units and total inventory value. <br></p>

<p>I wrote a PHP class containing a series of functions which ran SQL queries against the e-commerce platform's database and returned the required data in variables I could pass to GA and echo to the command line output.</p><p>If anything, this was the most complicated bit, due to the nature of some of the joins required to query the database. These will obviously vary according to your platform, so I've skipped them out here. &nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="274" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f2424e54203a.jpg" onmouseover="undefined" onmouseout="undefined"></p><h3>Step 3: Configuring your events</h3><p>Once I had the metrics, I then used server-side event tracking to add the data to GA to a separate profile - the latter point is important, for reasons I'll explain in a minute.</p><p>Here's the format I used for the PHP-GA events to ensure data is placed in the correct place in GA for easy analysis.&nbsp;These events place all data in an event category called 'Aggregate daily totals'. Drilling-down to action and label levels gives you access to the rest of your data.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="257" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f23e5f9b889d.jpg">&nbsp;</p><p><b>Categories</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Category','12',12).<br><b>Goal:</b>&nbsp;Monitors the total number of categories over time.<br></p><p><b>Products</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Products','1234',1234).<br><b>Goal:</b>&nbsp;Monitors the total number of products over time.<br></p><p><b>SKUs (stocked)</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','SKUs (stocked)','12345',12345).<br><b>Goal:</b>&nbsp;Monitors the total number of SKUs stocked over time.<br></p><p><b>SKUs (direct)</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','SKUs (direct)','1234',1234).<br><b>Goal:</b>&nbsp;Monitors the total number of drop-shipped SKUs over time.<br></p><p><b>SKUs (out of stock)</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','SKUs (out of stock)','123',123).<br><b>Goal:</b>&nbsp;Monitors the total number of out of stock SKUs over time.<br></p><p><b>Inventory units</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Inventory units','1234567',1234567).<br><b>Goal:</b>&nbsp;Monitors the total number of units of stock held over time.<br></p><p><b>Inventory value</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Inventory value','8787878',8787878).<br><b>Goal:</b>&nbsp;Monitors the total value of units of stock held over time.<br></p><p><b>Customers</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Customers','1234567',1234567).<br><b>Goal:</b>&nbsp;Monitors the total number of customers over time.<br></p><p><b>Newsletter subscribers</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Newsletter subscribers','123456',123456).<br><b>Goal:</b>&nbsp;Monitors the total number of newsletter subscribers over time.</p><p>Here's an example of the code required to create the new session in PHP-GA and to send the event tracking data. Again, there's more information and sample code in <a href="http://techpad.co.uk/content.php?sid=205">my other post on PHP-GA</a>.&nbsp;</p><p>Providing you're sending fewer than 499 events in a single PHP-GA session, you should be able to use a single&nbsp;$tracker-&gt;trackPageview($page,$session,$visitor);&nbsp;call. </p><p>Send more and you risk hitting the 500 hit limit for a session, and you'll need to split events over multiple sessions in the same script.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="282" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f22bdb9368f4.jpg" onmouseover="undefined" onmouseout="undefined"></p><p>Echoing the output of the application to the terminal is useful during testing because it allows you to see that the data are being obtained correctly and gives you the opportunity to look for PHP-GA's errors, since PHP-CLI applications don't run through Apache and errors, warnings and notices don't appear in its error logs.</p><p>Once you've sent some test data, you should see it appearing in the GA web interface within about 10 minutes. </p><p>It's then possible to look at the charts produced showing the daily 
event values to see how they change over time. Some of the other totals obviously won't be usable, but that's easily fixed by creating custom reports.</p><h3>Step 4: Analysing inventory by category</h3>

<p>Now that I had an overview of the entire inventory, the next thing I wanted to examine was the inventory at a product level.&nbsp;</p>

<p>The data should be useful for finding out which categories were underperforming and should show what return we were getting from the stock held, when you compare sales revenue to inventory.</p>

<p>How many products and SKUs were in each category? How much stock were we holding? How much working capital was tied up in stock? What return did we get from our inventory for the category?</p>

<p>If we had £2000 of working capital tied up in our stocks of purple mohair ties but monthly sales were only £100, did we really need so much stock? Would it be better to drop-ship these instead?</p><p>Extracting these data is achieved in similar ways, but obviously involves a bit of looping and for my e-commerce platform some of the database queries involved some complicated joins and concatenation.</p><p>However, the principle is easy. First you need to get your list of categories, then for each category you need to obtain the total number of products, SKUs, inventory held and its value. Here's an example of the event tracking code used.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="135" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f243efb86545.jpg"></p><p><b>Subcategories in category</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Subcategories in category','Tablet PCs',3).<br><b>Goal:</b>&nbsp;Monitors the total number of subcategories in a category over time.<br></p><p><b>Products in category</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Products in category','Tablet PCs',123).<br><b>Goal:</b>&nbsp;Monitors the total number of products in a category over time.</p>

<p><b>SKUs in category</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','SKUs in category','Tablet PCs',3234).<br><b>Goal:</b>&nbsp;Monitors the total number of SKUs in a category over time.<br></p><p><b>Inventory units in category</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Inventory units in category','Tablet PCs',39393).<br><b>Goal:</b>&nbsp;Monitors the total number of units of stock in a category over time.</p><p><b>Inventory value in category</b><br><b>Event format:</b>&nbsp;_trackEvent('Aggregate daily totals','Inventory value in category','Tablet PCs',123456).<br><b>Goal:</b>&nbsp;Monitors the total value of stock in a category over time.</p><p>If you have lots of data to send, consider using sleep(1) to pause for a second between the POSTing of data to prevent hammering the GA servers with a shed-load (that's English for a lot) of traffic all at once.&nbsp;</p><p>You'll also need to ensure you use PHP-GA to create a new session for each set of related events you send, otherwise you'll hit the 500 hits per session limit and execution of the script will stop.&nbsp;</p><p>It's worth making sure that error messages are set to display to standard out because you may get "MySQL has gone away" timeout messages if your data takes a long time to crunch. Opening a new connection for each chunk of data should solve this. &nbsp;</p><h3>Step 5: Sending product-level data</h3><p>Now that we've done with collecting the aggregate data and the category-level data, it's time to do the bulkier task of obtaining the product-level data which provides your actual inventory profile timelines.&nbsp;</p><p>The principle for this bit is the same as for the category-level data. You run a SELECT query against your database to get a full list of your SKUs and return the product name, SKU code, cost price, quantity of stock being held and then create a while loop.&nbsp;</p><p>Within the while loop you need to create a new PHP-GA session for each SKU returned and then send four events containing the data we want to send to Google Analytics. </p><p>It's vital to create a new session for each one, because you'll otherwise hit the 500 hit limit in no time. You'll also want to use a sleep() function to minimise the speed at which data is sent to Google's servers.</p><p>Since we're adding a bit more data to these, and allowing more drilling-down, these data are going in separate event categories.&nbsp;</p><p><b>Inventory units<br>Event format:</b>&nbsp;_trackEvent('Inventory units','Apple Macbook Pro 15','AMBP15',5).<br><b>Goal:</b>&nbsp;Monitors the total holding of a SKU over time.</p><p><b>Inventory value</b><br><b>Event format:</b>&nbsp;_trackEvent('Inventory value','Apple Macbook Pro 15','AMBP15',4500).<br><b>Goal:</b>&nbsp;Monitors the total value of SKU inventory over time.<br></p><p><b>Re-order level</b><br><b>Event format:</b>&nbsp;_trackEvent('Re-order level','Apple Macbook Pro 15','AMBP15',1).<br><b>Goal:</b>&nbsp;Monitors the re-order or low-stock level over time.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="285" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f23db975d440.jpg" onmouseover="undefined" onmouseout="undefined"></p><h3>Step 6: Automating data collection</h3><p>In order for the data to be accurate you need to ensure that the queries are only run once per day.&nbsp;</p>

<p>I configured a cron job to run my script as a scheduled task on my Linux server every night at one minute past midnight with this command: 01 00 * * * php /var/www/stockprofiler/profiler.php</p>

<p>Every morning when I check GA, I have fresh data from the previous day. I don't need to touch the code again - it just keeps sending me new data on the inventory just as the client-side code does.&nbsp;</p><h3>Step 6: Accessing your inventory data</h3><p>Once you've followed the above steps, you'll be able to access the data in your new profile via the following event categories.&nbsp;You can drill-down among them to see aggregate totals for each day, category or product.</p><p><img alt="" title="undefined" align="" border="" height="218" hspace="" vspace="" width="426" src="http://techpad.co.uk/custom/images/medium/4f23d6b27eac4.jpg">&nbsp;</p><p>Don't forget that because we're sending daily totals to GA, the only field that will really make sense if the event value and the timeline for the metric. </p><p>The total event value metrics will be calculated based on the combined sum of daily events, so won't mean much.&nbsp;It's best to create some custom reports.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="202" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f24495c94cc9.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p><h3>Handy tips</h3><ul><li>Put this data in a <a href="http://support.google.com/googleanalytics/bin/answer.py?hl=en&amp;answer=55486">separate Google Analytics profile</a> to prevent the large quantity of hit level data sent pushing you over your data limit. It would be nice to have the data in the same account as your web data, as you'd then be able to compare web metrics to inventory metrics, but there are risks to that if you have a large site.</li></ul><ul><li>Don't send more than 10 million bits of hit level data per month, otherwise you'll hit Google Analytics'&nbsp;<a mce_href="http://support.google.com/googleanalytics/bin/answer.py?hl=en&amp;answer=1070981" href="http://support.google.com/googleanalytics/bin/answer.py?hl=en&amp;answer=1070981">data limit</a>. If you have a big product range, calculate the number of events your script will be firing to determine whether this could be an issue.</li></ul><ul><li>Don't exceed more than 1 million hits per day, otherwise your data will only be refreshed once a day, and you'll exceed your monthly data limit.</li></ul><div><img alt="" title="undefined" align="" border="" height="263" hspace="" vspace="" width="426" src="http://techpad.co.uk/custom/images/medium/4f22d44a24837.jpg">&nbsp;&nbsp;</div><ul><li>Use the new real time reports in Google Analytics 5 to get an idea of the amount of data being sent and the rate, and to check that everything is working as intended during testing.</li></ul><ul><li>If you're using this hack with Google Analytics Premium there is no data limit, so theoretically you could use this with quite a big product inventory.&nbsp;</li></ul><ul><li>Don't send more than 500 bits of hit level data in a single session. If you're looping over data, use PHP-GA to start a new session in each loop, which will increase the number of sessions and prevents you hitting the <a href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html">500 hit limit</a>.&nbsp;</li></ul><ul><li>Use a <a href="http://php.net/manual/en/function.sleep.php">sleep() function</a> to pause the sending of session data by your script for a second to prevent it hammering the GA servers.&nbsp;</li></ul><ul><li>Make sure your <a href="http://en.wikipedia.org/wiki/Cron">cron job</a> only fires once a day, as most of these are daily totals which will be ruined if you inadvertently send the data multiple times.</li></ul><ul><li>Create custom reports to make the data more meaningful, since some of the metrics won't apply with this hack.&nbsp;</li></ul>


]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=209&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_209]]></link>
			</item>
			<item>
				<title><![CDATA[Monitoring operations error rates and financial losses in Google Analytics]]></title>
				<description><![CDATA[To help drive improvements in operations service quality and reduce financial losses, you'll need to know how many damages and faulty items are being replaced free of charge and how many customers are suffering from orders with missing items or picking errors. Thankfully, it's quite easy to track this in Google Analytics using a fairly simple back-end hack. 

<div>This little hack allows you to create a dashboard in Google Analytics which shows how many items you've given away free of charge to customers in the event of service quality failures, such as warehouse picking errors, transit damages and goods that have failed under warranty.</div><div>&nbsp;</div><div>Not only will you be able to see the financial costs of this, you'll also be able to look for trends, and examine the underlying data to reveal useful facts, like which products are most frequently being picked incorrectly or which products most often arrive smashed.&nbsp;</div><div>&nbsp;</div><div>If your ecommerce platform is already set-up with Google Analytics ecommerce tracking on the back-end, to allow you to record ecommerce data for orders taken by telephone, setting this up and creating the dashboards should take you less than an hour. &nbsp;</div><div><h3>Adding the data to Google Analytics</h3></div><div>Assuming you've already got a system in place which allows you to take orders on the back-end of your ecommerce platform, the first step is to add a simple select menu to your back-end which records the reason why you're providing a given product as a free of charge replacement.&nbsp;</div><div>&nbsp;</div><div>The option values here are going to become the event tracking actions in Google Analytics, so you'll want to choose them carefully. I went with the following options. </div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="100" align="" title="undefined" mce_src="/custom/images/medium/4f1878a550a1c.jpg" src="/custom/images/medium/4f1878a550a1c.jpg" onmouseover="undefined" onmouseout="undefined"></div><div>&nbsp;</div><div>When the form is submitted, you'll need to write a little snippet of server-side code to grab the selected value from the menu and get the name of the product and its value. Since I'm sending the data to Google Analytics using the ecommerce tracking methods, I already had access to these data.&nbsp;</div><div>&nbsp;</div><div>In your tracking code, you now need to grab that information and use your server-side language to write a single line of code into your Google Analytics tracking tag which is based on this format (but with variable data populating the event action, event label and event value fields).&nbsp;</div><div>&nbsp;&nbsp;</div><code>_gaq.push(['_trackEvent','Free replacement','Damaged item','iPad 2', 429]);</code><div>&nbsp;</div><div>In the above code I've used "Free replacement" as the event category, added the value from the select menu in the event action, the product name in the event label and the rounded value of the product in the event value field. The latter bit is important, since you can't use floats in the event value field. </div><div>&nbsp;</div><div>That's basically all you need to do in order to get the data you need into Google Analytics! Dead easy.</div><div><h3>Creating the dashboards</h3></div><div>To access the data easily it makes sense to take advantage of the excellent new dashboard features in Google Analytics. I used the widget feature to create two widgets for each event action (ie. Damaged item, Picking error, Faulty under warranty etc).</div><div>&nbsp;</div><div>One of the widgets you create needs to record the Total Events metric and should filter to only show the Event Category which is an exact match for the Event Action you added to your code (ie. Damaged item). I also created an additional widget to provide an overall count of total replacements which filtered by the Event Category "Free replacements".</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="246" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f1878a6c3dbb.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</div><div>&nbsp;</div><div>Once you've worked through all of your event actions and created a widget to report the total events for each one, the next step is to create widgets for the total value. These will give you a rounded approximation of the total value you've spent on replacing the items free of charge due to your various service failings.</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="243" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f18889635526.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</div><div>&nbsp;</div><div>Again, just work through each of the event actions that you had in your original code and you should end up with about 12 widgets, which also happens to be the maximum number you can store on a given dashboard in GA 5.&nbsp;</div><div><div><h3>Using the data</h3></div></div><div>One other potentially useful dashboard to create would be a report showing which products are arriving broken, failing under warranty or being picked incorrectly. </div><div>&nbsp;</div><div>To create this, you'd be best using the Table option on the widget tool and opting to display the event label and adding your desired filter, which should then generate a list of products for the given event action.</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="293" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f1878a41415a.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</div><div>&nbsp;</div><div>Now all that remains is to get your staff to use the field, wait for the data to flow in, and then give the warehouse staff a ticking off when the error rate rockets or buy them a case of beer when things improve markedly.</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="303" align="" title="undefined" src="/custom/images/medium/4f3a11b9431d1.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</div><div>&nbsp;</div><div>At the moment, you can't export the dashboard to PDF, mail them as scheduled reports or do much else, but they're nonetheless pretty handy for keeping an eye on financial losses and can help drive improvements if you utilise the data well.&nbsp;</div>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=208&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_208]]></link>
			</item>
			<item>
				<title><![CDATA[Developing a cookie-less Google Analytics implementation]]></title>
				<description><![CDATA[Unless you've been buried under a rock for the past year, you'll know that it will soon be a legal requirement to get website visitors to opt-in to be tracked using cookie-based analytics. 

<p>Google and the other analytics solution providers have been pretty quiet on the subject of the new <a mce_href="http://techpad.co.uk/content.php?sid=174" href="http://techpad.co.uk/content.php?sid=174">EU cookie legislation</a>. </p><p><a mce_href="http://techpad.co.uk/content.php?sid=199" href="http://techpad.co.uk/content.php?sid=199">Avinash Kaushik has confirmed</a> that analytics providers have been discussing the legislation, but hasn't said whether they have a solution to the problem, and if they do, what it will entail.&nbsp;</p><p>If you're affected, your options are to get users to opt-in to being tracked using cookies (in which case you can kiss goodbye to 90% of your web analytics data and rely on sampling), do nothing in the likely event that the ICO don't bother to prosecute you simply for using GA, or switch to a server-side tracking system which doesn't rely on cookies.&nbsp;</p><p>While I'm aware of other cookie-less tracking systems, I haven't used any since the pre-GA/Webtrends days.&nbsp;</p><p> Personally, I'd be extremely surprised if they came anywhere close to the functionality of Google Analytics, and like many other people in the industry, I've got data in the tool that I want to keep and features I rely upon for my work. </p><p>GA does what I need it to do, and it's tightly integrated into my sites so I can capture additional data to help me make the right decisions.&nbsp;</p><p>If browser manufacturers aren't going to step-in to allow this issue to be handled on the browser side, the best solution for me seems to be the development of a <a mce_href="http://techpad.co.uk/content.php?sid=186" href="http://techpad.co.uk/content.php?sid=186">server-side Google Analytics</a> tracking system. </p><p>That could be one that has official backing, or one that's been built from scratch to help overcome the legislation in a legal and responsible manner.</p><p><img alt="" title="undefined" mce_src="/custom/images/medium/4ccbfacb53be3.jpg" height="285" hspace="" border="" vspace="" width="426" align="" src="/custom/images/medium/4ccbfacb53be3.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p><p><span class="Apple-style-span" style="font-size: 14px; font-weight: bold; ">Server-side Google Analytics?</span></p><p><b></b>The current Google Analytics tracking solution is a client-side system and the JavaScript code is executed by the browser. </p><p>Tracking data is sent to GA via GIF image requests generated by the code, with certain items of data, such as timestamps and unique identification hashes, being stored in a number of first-party cookies in the visitor's browser.</p><p>Google does not yet provide a cookie-less or server-side alternative to this client-side tracking system, although its mobile tracking code comes close. </p><p>I'd be really surprised if its engineers weren't working behind the scenes on a server-side API. Indeed, the client-side code probably already interfaces with something a server-side solution could connect to as well.</p><p>Thankfully, given the lack of an authorised API, there are at least two fairly robust solutions which achieve the same thing: Server-Side Google Analytics (SSGA) and PHP-GA.&nbsp;</p><p>These are both PHP classes which pass similar data back to the GA server by faking the GIF requests, which trick Google Analytics into thinking the data is coming from a client-side tracking tag. </p><p>While some things don't work, and while some actions are harder to track and require more coding effort, they're both actually quite decent and it is possible to get quite a bit of the core tracking data into GA without relying on cookies.</p><h3>Server-side GA isn't cookie-less by default...</h3><p>You can use either SSGA or PHP-GA for this.&nbsp;Both work in very similar ways. </p><p>I've used SSGA on a couple of projects and it works really well, but unlike PHP-GA it hasn't been under active development for quite a while (since April 2009) and it supports fewer features.&nbsp;</p><p>PHP-GA is more modern (it's written in fully namespaced OOP PHP), it supports pretty much all of the main features (including new ones like trackSocial) and is probably the best choice of the two.</p><p>It is server-side, rather than client-side, so the code is hidden from source code viewers and is triggered by PHP on your server, however, it <i>can</i> use cookies for some features. They're just created by PHP, rather than by JavaScript.</p><p>It hasn't been designed to be a cookie-free alternative to GA. It's been designed to replicate the functionality of Google Analytics ga.js JavaScript tracking code in PHP.&nbsp;As a result, if you use it as-is, it could create cookies. Most of the main features don't use cookies, though.</p><h3>Example 1: Basic page tracking</h3><p>For really basic pageview tracking you can use the code below. Don't forget to replace your own UA profile ID, otherwise you'll fill my test account with your data!</p><p><img alt="" title="undefined" height="" hspace="" border="" vspace="" width="" align="" src="http://techpad.co.uk/custom/images/medium/4f048a0359093.jpg" onmouseover="undefined" onmouseout="undefined"></p><p>This example simply adds the user IP address (required by GA but not shown or accessible) the user agent (ie. Windows Vista, Internet Explorer 6) and the details on the page title and file accessed. (Use REMOTE_ADDR, not REMOTE_ADDRESS, as I stupidly did!)</p><p>You can pass additional data to GA using the Visitor() function, which I'll explain in more detail later. This code doesn't set any cookies whatsover and will provide only basic tracking.&nbsp;</p><h3>Example 2: Event tracking</h3><p>Event tracking, probably the best overall feature of Google Analytics, is also very easy to achieve and again doesn't use any cookies. </p><p>You simply call the GoogleAnalytics\Event() function and then pass it the required data using setCategory(), setAction(), setLabel() and setValue() - even the <a mce_href="http://techpad.co.uk/content.php?sid=187" href="http://techpad.co.uk/content.php?sid=187">new opt_noninteraction feature</a> is supported via setNoninteraction().</p><p>The data can then be passed to the tracker using trackEvent(). Interestingly, the client-side version of GA prevents you from sending more than 10 events at once, but <a mce_href="http://techpad.co.uk/content.php?sid=195" href="http://techpad.co.uk/content.php?sid=195">you can send 20 or more simultaneously</a> with both PHP-GA and SSGA. &nbsp;</p><p><img alt="" title="undefined" height="223" hspace="" border="" vspace="" width="426" align="" src="http://techpad.co.uk/custom/images/medium/4f04a74fe8f69.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p><h3>Example 3: Ecommerce tracking</h3><p>Ecommerce tracking works much like the client-side equivalent. First you need to populate the order ID with a random number which is used as the transaction ID. Then you call Item() and set the orderId, the SKU, the name, quantity and price.</p><p>You can then create the transaction, pass the items, the basket total and any details you have on the customer location and shipping charges and it populates the ecommerce tracking data in exactly the same way as the client-side version. Again, no cookies are used.</p><p><img alt="" title="undefined" height="367" hspace="" border="" vspace="" width="426" align="" src="http://techpad.co.uk/custom/images/medium/4f04af649cb6c.jpg" onmouseover="undefined" onmouseout="undefined"></p><h3>Other features</h3><p>There are many more things you can do with PHP-GA, including passing additional visitor data (such as screen resolution, Flash version, Java enabled etc), setting custom variables (with cookies), and using trackSocial.&nbsp;&nbsp;&nbsp;</p><p>This only really scratches the surface of testing what you could do with PHP-GA without the need to use cookies, and what you'd probably need to do to get close to the full features sans cookies.</p><p>Granted, it falls short of client-side GA if you don't use cookies, but it provides the basics of page tracking and ecommerce tracking which could be enough to get by if the worst does happen.&nbsp;</p><p>Sadly, it isn't capable of recognising repeat visitors, presumably because GA only uses the ID stored in the __utma cookie, and not a combination of other visitor features. &nbsp;</p><p>It's not going to solve every problem, but it could record most activities without cookies and it's&nbsp;certainly going to be a lot better than having 90% of your data missing. Obviously it needs more work, though...&nbsp;</p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=205&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_205]]></link>
			</item>
			<item>
				<title><![CDATA[Basic ecommerce brand reporting with the Data Feed Query Explorer]]></title>
				<description><![CDATA[The ecommerce reporting tools of Google Analytics are a little bit too limited at the moment, but you can still extract the data you need using the Data Feed Query Explorer.

<p>If you're an ecommerce retailer you are obviously going to benefit from being able to examine sales of your products by category (ie. laptops) and by brand (ie. Apple).</p>

<p>However, at the moment, it's currently not very easy to produce reports within Google Analytics to allow you to analyse these data because GA's custom report and dashboard tools lack dimensions for ecommerce data. </p>

<p>Thankfully, you can access these data using the <a target="_blank" href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html">Google Analytics Data Feed Query Explorer</a>, or via the underlying <a href="http://techpad.co.uk/content.php?sid=198">Google Analytics Core Reporting API</a> itself.</p>

<p>The Google Analytics Data Feed Query Explorer's web interface provides a much greater range of dimensions and metrics than the standard web front-end to GA, so it's a very powerful tool and you don't need to do any coding to use it. </p>

<h3>Brand performance reporting</h3>
<p>Let's say for example that you want to find out how well your individual Apple products have been selling over the past month.</p>

<p>You simply need to log into the Data Feed Query Explorer, select the desired account and profile and customise the following settings, or <a mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AProductName&amp;metrics=ga%253AitemQuantity%252Cga%253ArevenuePerItem%252Cga%253AitemRevenue%252Cga%253AitemsPerPurchase&amp;filters=ga%253AproductName%253D~Apple&amp;sort=ga%253AitemRevenue&amp;start-date=2011-12-16&amp;end-date=2011-12-30&amp;max-results=50" target="_blank" href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AProductName&amp;metrics=ga%253AitemQuantity%252Cga%253ArevenuePerItem%252Cga%253AitemRevenue%252Cga%253AitemsPerPurchase&amp;filters=ga%253AproductName%253D~Apple&amp;sort=ga%253AitemRevenue&amp;start-date=2011-12-16&amp;end-date=2011-12-30&amp;max-results=50">click here</a> to add them automatically:</p>

<p>
<b>dimensions =</b> ga:ProductName<br>
<b>metrics = </b> ga:itemQuantity,ga:revenuePerItem,ga:itemRevenue<br>
<b>filters = </b>ga:productName=~Apple<br>
<b>sort = </b>-ga:itemRevenue<br>
</p>

<p>If you want to automate your report, pull it out via the <a href="http://techpad.co.uk/content.php?sid=198">Google Analytics Core Reporting API</a>, or pull it into a spreadsheet using a tool like AutomateAnalytics or NextAnalytics, you need to use a URL which looks something like this:</p>

<p><code>https://www.google.com/analytics/feeds/data?ids=ga%3A1234567&amp;dimensions=ga%3AproductName&amp;metrics=ga%3AitemQuantity%2Cga%3ArevenuePerItem%2Cga%3AitemRevenue%2Cga%3AitemsPerPurchase&amp;filters=ga%3AproductName%3D~Apple*&amp;sort=-ga%3AItemRevenue&amp;start-date=2011-12-01&amp;end-date=2011-12-30&amp;max-results=500</code></p>

<p>You'll just need to create a separate report for each of the brands you want to monitor by changing the value you pass to the productName filter.</p>

<h3>Category performance reporting</h3>
<p>Measuring category performance is a bit easier, because it's more feasible to merge data on multiple categories into a single report, so if you want to compare sales of laptops to tablets and mobiles, it's all possible from one query.</p>

<p>You need to customise the following settings, or <a mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AProductName&amp;metrics=ga%253AitemQuantity%252Cga%253ArevenuePerItem%252Cga%253AitemRevenue%252Cga%253AitemsPerPurchase&amp;filters=ga%253AproductCategory%253D~laptops%257Ctablets%257Cmobiles%257Cnetbooks&amp;sort=ga%253AitemRevenue&amp;start-date=2011-12-16&amp;end-date=2011-12-30&amp;max-results=50" target="_blank" href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AProductName&amp;metrics=ga%253AitemQuantity%252Cga%253ArevenuePerItem%252Cga%253AitemRevenue%252Cga%253AitemsPerPurchase&amp;filters=ga%253AproductCategory%253D~laptops%257Ctablets%257Cmobiles%257Cnetbooks&amp;sort=ga%253AitemRevenue&amp;start-date=2011-12-16&amp;end-date=2011-12-30&amp;max-results=50">click here</a> to add them automatically:</p>

<p>
<b>dimensions =</b> ga:ProductName<br>
<b>metrics = </b> ga:itemQuantity,ga:revenuePerItem,ga:itemRevenue<br>
<b>filters = </b>ga:productCategory=~laptops|tablets|mobiles|netbooks<br>
<b>sort = </b>-ga:itemRevenue<br>
</p>

<p>This will create a single report containing data on laptops, tablets, mobiles and netbooks, so you can see which categories are driving the most revenue.</p>



<h3>Basic report extraction</h3>
<p>If you want to pull this custom report data out of the Data Feed Query Explorer's underlying API, you don't necessarily have to do any programming to extract it.</p>

<p>There are several plugins available for pulling data out of the API and into Excel or Google Docs, including:</p>

<ul>
  <li><a mce_href="http://www.nextanalytics.com/index.php" target="_blank" href="http://www.nextanalytics.com/index.php">Next Analytics</a> ($199)</li>
  <li><a mce_href="http://www.gadatagrabbertool.com/" target="_blank" href="http://www.gadatagrabbertool.com/">GA Data Grabber</a> ($299)</li>
  <li><a mce_href="http://www.analyticscanvas.com/" target="_blank" href="http://www.analyticscanvas.com/">Analytics Canvas</a> ($49 per month)</li> 
  <li><a mce_href="http://excellentanalytics.com/" target="_blank" href="http://excellentanalytics.com/">Excellent Analytics</a> (free)</li>
</ul>

<p>Using the tool of your choice, you can replicate the API queries above and get the data pulled into an Excel spreadsheet for further analysis.</p>
]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=202&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_202]]></link>
			</item>
			<item>
				<title><![CDATA[Avinash clarifies on GA's EU cookie law solution]]></title>
				<description><![CDATA[Pretty much all of the analytics platform providers have remained tight-lipped on the forthcoming EU cookie legislation, but chances are they're probably all busy behind the scenes working on a solution for those of us who are affected.

<p>The Google Analytics team has also remained quiet on the matter, leaving most of us to think that we'll need to implement a solution like the ICO's, which led to a 90% drop in the amount of data they were able to collect for analysis.</p><p>I recently asked a question on the GA team's <a href="http://analytics.blogspot.com/2011/12/web-analytics-tv-23-holiday-episode.html" target="_blank" mce_href="http://analytics.blogspot.com/2011/12/web-analytics-tv-23-holiday-episode.html">Web Analytics TV</a> series, which is hosted by Google Analytics Evangelist <a href="http://www.kaushik.net/avinash/" target="_blank" mce_href="http://www.kaushik.net/avinash/">Avinash Kaushik</a> and <a href="https://plus.google.com/u/0/112976464453422312311/posts#112976464453422312311/posts" target="_blank" mce_href="https://plus.google.com/u/0/112976464453422312311/posts#112976464453422312311/posts">Nick Mihailovski</a> from the GA team, which has been answered in the latest episode. </p><p>I asked "It's now a legal requirement in the EU to get permission before
 sending cookies. Google Analytics without accurate ecommerce tracking 
would be useless. Does Google have plans for a server-side working 
around, since PHP APIs for POSTing data already exist." <br></p>

<iframe src="http://www.youtube.com/embed/4sa7eWQy5r4" allowfullscreen="" frameborder="0" height="230" width="430"></iframe>
<br>
<p>Avinash replied: "This is a good question, Matt. Along with other companies, like Microsoft and Yahoo, and Omniture and Webtrends, the team at Google is working with the various entities in the EU to figure out what the implications are. </p><p>"Because some clarity is missing as to what applies in individual countries across the entire EU. At the moment that process has not concluded, but when the process is concluded we will post guidelines on the Analytics blog, analytics.blogspot.com. So stay tuned there.&nbsp;</p><p>"I did want to emphasise that the word 'workaround' is very sensitive in this scenario, so hopefully there are no 'workarounds'. Google as well as all the other companies are going to follow the laws that are applicable in the individual countries. </p><p>"But as to what they are, and what the implications are, we'll post them on our blog. As will our peer companies in the industry, so watch out for that."</p><p>I'm really pleased with this, so thanks to Avinash and Nick for responding. Hopefully it might mean that the EU cookie law is going to be a little less painful than we were originally anticipating.&nbsp; </p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=199&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_199]]></link>
			</item>
			<item>
				<title><![CDATA[Building analytics tools with the Google Core Reporting API part I]]></title>
				<description><![CDATA[The Google Analytics Export API is being deprecated and replaced with the new JSON and OAuth based Google Core Reporting API. Here's what you need to know to get started in using it for Google Analytics application development. 

<p>The Google Core Reporting 3.0 deprecates some of Google's older APIs, such as the Google Analytics Export API and the Google Analytics Management API and works completely differently to before.</p>

<p>It's now REST-based and provides outputted data in JavaScript Object Notation format, or JSON, rather than the old-style XML, which Google reckons means the output is 10 times smaller - making it much faster.</p>

<h3>1. Set up your OAuth credentials</h3>
<p>The Core Reporting API now uses Open Authentication 2.0, or OAuth 2.0, and requires that you register your application before use.</p>

<p>Once set up, your application will need to request an access token from Google which it needs to use in the URL it sends to the relevant API in order to obtain data. No token means no data, so this is a crucial step.</p>

<p>On the plus side, all of the Google APIs have standardised on this, so you only need to learn how to do OAuth once, and it's much more secure.</p>

<p>You'll need to go to the <a mce_href="https://code.google.com/apis/console/" target="_blank" href="https://code.google.com/apis/console/">Google APIs Console</a> and register to get hold of your client ID, client secret and API key. You'll also need to define the URI for your callback page.</p>

<p>Importantly, the URIs (you can provide one per line) all need to be fully qualified domain names pointing at the file with the OAuth code in it. You can now also use a localhost server for this, which makes development easier.</p>

<p>The token is returned as a GET parameter, so your OAuth code needs to grab that and append it to the REST request string. </p>

<h3>2. Set up your server for Curl</h3>
<p>Since you now need to connect using OAuth 2.0, you'll need additional software to handle this as the connection requires the Curl extension for PHP.</p>

<p>On Debian-based servers you can install the dependencies by entering <code>sudo apt-get install php5-curl curl</code> and then re-starting Apache to load the module with <code>sudo service apache2 restart</code>.</p>

<p>You can test your configuration by checking out the latest copy of the Google API PHP Client from the Google Code Subversion repository. <u>Don't</u> download the tarball, as it's currently missing the vital apiAnalyticsService.php file!</p>

<p>You can grab a copy of the latest google-api-php-client by entering: <code>svn checkout http://google-api-php-client.googlecode.com/svn/trunk/ google-api-php-client-read-only</code></p>

<p>If you've downloaded the google-api-php-client from SVN (you won't find this in the tarball at the moment) you should find a directory of <code>examples/analytics/</code>, which includes a file called simple.php. </p>

<p>Put the google-api-php-client on your server, edit the example file using the credentials you added to the Google APIs Console, make sure you've referenced the simple.php as your callback in the APIs Console and open in your browser.</p> 

<p>You should see a screen like the one below, which is requesting permission to connect via OAuth.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="197" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4ef1b16fe495e.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p>

<p>If everything works, you should see a sample application. You might have some server alterations to make if you're using security features such as open_basedir restriction which can block access to certain required functions depending on the directory in which you installed your test code.</p>

<p>You might also need to set the include path for the library directory. You can find out whether this is required by opening a terminal and entering <code>tail -f /var/log/apache2/error.log</code> and re-loading the page.</p> 

<p>There are <a mce_href="http://code.google.com/p/google-api-php-client/wiki/GettingStarted" target="_blank" href="http://code.google.com/p/google-api-php-client/wiki/GettingStarted">instructions here</a> on how to fix your include path so you don't need to include the client libraries in every application on your server.</p>

<p>Or, you can download a copy of the demo file I created here, which includes a modification to the include path to make it work on an Ubuntu server.</p>

<h3>3. Accessing the Google Analytics Core Reporting API</h3>

<p>Inside the <code>/examples/analytics/simple.php</code> file you'll find some example functions which allow you to access a list of web properties (that's the list of sites you have in your account), a list of accounts, a list of all the advanced segments you've created and their settings and a list of all your goals.</p>

<p>The data are returned as PHP arrays, which means they're easy to manipulate from the server side, or directly within a templating engine like Smarty, if you use one. This is much better than the old method of using multiple APIs and the data are easier to handle.</p>

<p>You can access your web properties array by using the following code:<br>
<code>$props = $service-&gt;management_webproperties-&gt;listManagementWebproperties("~all");</code></p>

<p>You can access your accounts array by using the following code:<br>
<code>$accounts = $service-&gt;management_accounts-&gt;listManagementAccounts();</code></p>

<p>You can access your advanced segments array by using the following code:<br>
<code>$segments = $service-&gt;management_segments-&gt;listManagementSegments();</code></p>

<p>You can access your advanced segments array by using the following code:<br>
<code>$goals = $service-&gt;management_goals-&gt;listManagementGoals("~all", "~all", "~all");</code></p>

<h3>4. Obtaining your profile ID</h3>
<p>When it comes to running Google Analytics queries against your data, things get a little challenging. Not because it's difficult, but because for some inexplicable reason, Google requires you to use what it describes in the code comments as the "analytics profile ID". </p>

<p>Now, if you examine the output from the management functions, which return the data on the web properties, accounts, segments and goals, you'll see that they reference <code>id</code>, <code>accountId</code> and <code>internalWebPropertyId</code>. None of these work.</p>

<p>In fact, the ID you need isn't even available in the API data. To obtain it you currently have to go to the Google Analytics interface and look at the URL of the page when logged into the desired account. In version 5 of GA, you'll find the required code after the "p".</p><p><b>Update: </b>I (cleverly) managed to miss a function tucked away in the API which does indeed allow you to obtain this ID computationally, so I take back my criticism! You need to use the code:&nbsp;</p><p><code>$profiles = $service-&gt;management_profiles-&gt;listManagementProfiles("~all", "~all");</code>&nbsp;</p>

<h3>4. Running API queries on your GA data</h3>
<p>Queries are running using the <code>get()</code> function which is part of the ga method in the apiAnalyticsService.php class.</p>

<p>This is called using the following code:<br><code>
$data = $service-&gt;data_ga-&gt;get($ids,$start_date,$end_date,$metrics,$optParams);</code></p>

<p>The <code>get()</code> function requires five things:<br><br>
<code>$ids</code> contains the ID of the profile you extracted from the URL of your account (ie ga:123456789<br>
<code>$start_date</code> is a date in YYYY-MM-DD format<br>
<code>$end_date</code> is a date in YYYY-MM-DD format<br>
<code>$metrics</code> is a comma-separated list of metrics (ie ga:visits,ga:pageviews)<br>
<code>$optParams</code> is an array, which I'll explain below<br>
</p>

<p>The <code>$optParams</code> array has six possible keys:<br><br>
<code>'max-results' =&gt;</code> is an integer containing the maximum number of results to return<br>
<code>'sort' =&gt;</code> is a comma-separated list of dimensions or metrics to sort by<br>
<code>'dimensions' =&gt;</code> is a comma-separated list of dimensions to use<br>
<code>'start-index' =&gt;</code> is an integer used to index the first item returned, which is used for paginating large data sets<br>
<code>'segment' =&gt;</code> is the analytics advanced segment to apply to the data<br>
<code>'filters' =&gt;</code> is a comma-separated list of metric or dimension filters to apply<br>
</p>

<p>
<code>
  $optParams = array('dimensions' =&gt; $dimensions, 
                     'filters' =&gt; $filters,
                     'segment' =&gt; $segment,
                     'sort' =&gt; $sort,
                     'max-results' =&gt; $maxresults,
                     'start-index' =&gt; $startindex);
</code>
</p>

<p>Here's a simple example which retrieves visits and pageviews by browser:<br><br>
<code>
$ids = "ga:123456789";<br>
$start_date = "2011-01-01";<br>
$end_date = "2011-11-30";<br>
$metrics = "ga:visits,ga:pageviews";<br>
$dimensions = "ga:browser";<br>
$optParams = array('dimensions' =&gt; $dimensions);<br>
$data = $service-&gt;data_ga-&gt;get($ids,$start_date,$end_date,$metrics,$optParams);<br>
</code>
</p>

<h3>5. Sorting data</h3>
<p>To sort data you need to add the <code>sort</code> key to the <code>$optParams</code> array and provide one or more dimensions or metrics to sort by.</p>

<p>To sort by ascending pageviews, for example, you'd add <code>'sort' =&gt; 'ga:pageviews'</code> to the array. This would return data with the lowest number of pageviews first.</p>

<p>To achieve a descending sort, in which data is returned from the highest to lowest numbers, you prefix the <code>ga:</code> part with a hyphen. For example, <code>'sort' =&gt; '-ga:pageviews'</code>.</p>

<p>You can combine multiple sort dimensions or metrics by separating them with commas like this: <code>-ga:pageviews,-ga:visits</code> and put them in different orders to give certain items precedence.</p>

<h3>6. Filtering data</h3>
<p>Adding filters is much like adding dimensions, in that you just provide a comma-separated list of filters with your chosen operators or regular expressions and add them to the <code>$optParams</code> array using the key <code>'filters' =&gt; $filters</code>, with the filters in <code>$filters</code>.</p>

<p>Filters are divided into metric filters and dimension filters, as they achieve slightly different things. The metric filters work against integer values to handle things like less than and greater than, while the dimension filters work against strings using regular expressions and operators which identify a substring.</p>

<h3>Metric filters</h3>
<table width="100%">
  <tbody><tr>
    <td><b>Metric operator</b></td>
    <td><b>Metric operator description</b></td>
  </tr>
  
  <tr>
    <td>==</td>
    <td>Metric equals</td>    
  </tr>
  
  <tr>
    <td>!=</td>
    <td>Metric does not equal</td>    
  </tr>
  
  <tr>
    <td>&gt;=</td>
    <td>Metric is greater than or equal to</td>    
  </tr>  
 
   <tr>
    <td>&lt;=</td>
    <td>Metric is less than or equal to</td>    
  </tr>  
  
  <tr>
    <td>&gt;</td>
    <td>Metric is greater than</td>    
  </tr>    

  <tr>
    <td>&lt;</td>
    <td>Metric is less than</td>    
  </tr>  
  
</tbody></table>


<p>You can use a single filter or use a combination of filters using either AND or OR logic. Separating filters with a comma counts as an OR statement, so the filter <code>ga:pageviews&gt;=100,ga:visits&gt;=10</code> will return all pages which have more than 100 page views or more than 10 visits.</p>

<p>For the AND operator you use a semicolon instead of a comma. So <code>ga:pageviews&gt;=100;ga:visits&gt;=10</code> will return all pages which have more than 100 page views AND more than 10 visits.</p>

<p>If you attempt to combine AND and OR in a single filter, OR will always take precedence.</p>

<p>The operators for selecting dimension based filters work in much the same way, but you can't currently combine AND dimension and metric filters in a single filter. </p>

<h3>Dimension filters</h3>
<table width="100%">
  <tbody><tr>
    <td><b>Dimension operator</b></td>
    <td><b>Dimension operator description</b></td>
  </tr>
  
  <tr>
    <td>==bla</td>
    <td>Dimension matches</td>    
  </tr>
  
  <tr>
    <td>!=bla</td>
    <td>Dimensions does not match</td>    
  </tr>
  
  <tr>
    <td>=@bla</td>
    <td>Dimension contains substring</td>    
  </tr>  
 
   <tr>
    <td>!@bla</td>
    <td>Dimension doesn't contain substring</td>    
  </tr>  
  
  <tr>
    <td>=~</td>
    <td>Dimension matches regular expression</td>    
  </tr>    

  <tr>
    <td>!~</td>
    <td>Dimension doesn't match regular expression</td>    
  </tr>  
  
</tbody></table>

<p>So, for example, if you want to modify your <code>$optParams</code> array to include a filter to select all pages on your site which have had more than 1000 visits during a given period, but exclude that to only the posts containing the word "analytics" in the title, your filter might look like this:</p>

<p><code>$filters = "ga:visits&gt;=10;ga:pageTitle=@analytics";</code></p>

<p>I'll cover more in the next part of this series.</p>


<h3>6. Using advanced segments</h3>
<p>One of the really nifty things you can do in GA is use existing advanced segments you've created using the web interface.</p>

<p>You can get segment ID data by running this command: <code>$segments = $service-&gt;management_segments-&gt;listManagementSegments();</code>.</p>

<p>The data returns a combination of your own custom segments, and the many advanced segments Google Analytics provides by default, such as New Visitor and Returning Visitor.</p>

<p>Helpfully, the array of data also includes a definition of the segment so you can see how to set up similar ones yourself via the API. Here's some example output for the default Paid Search Traffic segment.</p>

<p>
<code>
[3] =&gt; Array<br>
(<br>
[id] =&gt; -4<br>
[kind] =&gt; analytics#segment<br>
[selfLink] =&gt; https://www.googleapis.com/analytics/v3/management/segments/gaid::-4<br>
[segmentId] =&gt; gaid::-4<br>
[name] =&gt; Paid Search Traffic<br>
[definition] =&gt; ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==ppc<br>
)<br>
</code>
</p>

<p>You can select a specific segment by id, passing the value <code>gaid::-4</code> to the <code>$segments</code> value of the <code>$optParams</code> array. Or, you can create your own segment dynamically.</p>

<p>What do dynamic segments achieve? Well, pretty much the same thing as filters. However, unlike filters you can boolean OR operators with both dimensions and metrics. Unless you need to do that, you may as well just use filters.</p>
]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=198&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_198]]></link>
			</item>
			<item>
				<title><![CDATA[Bypassing the Google Analytics 10 event limit]]></title>
				<description><![CDATA[There's an undocumented feature in the Google Analytics tracking code which prevents you from sending more than 10 events over a five second period. This is a workaround to bypass it...

<p>One of the slightly annoying things about the otherwise largely brilliant Google Analytics JavaScript tracking code is that it doesn't provide an error messages when things go wrong. </p><p>Miss a quote off, or do something which GA doesn't allow, and you don't get any error messages, which makes debugging a little challenging. </p><p>I've recently been working on a large analytics implementation in which I'm creating a module for an ecommerce platform which handles all of the Google Analytics events, custom variables and ecommerce tracking.&nbsp;</p><p>This code sends a load of ecommerce data, a couple of custom variables and about 14 separate events, which I'm using as a way to extend the functionality of GA, by recording additional useful things, like purchase latency, cohorts and customer lifecycle data.&nbsp;</p><p><b>Debugging Google Analytics tracking code issues</b>&nbsp;&nbsp;</p><p>All was going well until I spotted that not all of the expected data were appearing in GA.&nbsp;</p><p>I'd been debugging the UTM GIF requests with the Firebug Firefox extension, so could see from the UTM GIF request data that the custom variables, ecommerce tracking data and 10 of the events were being added to GIF requests, but four of the events weren't.&nbsp;</p><p>Code wise, everything looked OK, so I figured this must be a limit, something which the analysts from Guava kindly confirmed. &nbsp;</p><p>According to <a mce_href="http://www.google.com/support/forum/p/Google+Analytics/thread?tid=623faee59487408e&amp;hl=en" target="_blank" href="http://www.google.com/support/forum/p/Google+Analytics/thread?tid=623faee59487408e&amp;hl=en">this thread</a> on the Google Analytics support forums, there is indeed an undocumented feature in the tracking code which prevents you from sending more than 10 events at once.</p><p>Apparently, the code uses something called the Token Bucket algorithm to limit the rate at which event data are accepted by the service to prevent it from being flooded with events.&nbsp;</p><p>Basically, you get a token when you connect and you can send up to 10 events with that token. A new one won't be issued for another five seconds, so if you want to send more than 10 events in a short space of time you're stuffed. &nbsp;</p><p><b>The workaround...</b></p><p>I've been using the <a href="http://techpad.co.uk/content.php?sid=186">PHP class SSGA</a> quite a bit recently to send GA data from server-side code without it being displayed in the JavaScript tracking tag, and was keen to see whether it might be the solution.&nbsp;</p><p>It was! I've successfully sent up to 20 events in a single page load, and I am guessing that it might even handle more, should you need it. </p><p>I am guessing that there's something in the GATC which handles the Token Bucket algorithm that's missing when you pass the data directly to GA using a server-side POST.&nbsp;</p><p><b>Client side version?</b></p><p>If you want to do something similar in the client-side GATC, it's still possible. Eduardo Cereto <a href="http://stackoverflow.com/questions/9339326/consecutive-ga-hits-being-dropped/9340290#9340290">wrote some very clever code</a> in JavaScript which can handle this.&nbsp;</p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=195&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_195]]></link>
			</item>
			<item>
				<title><![CDATA[Cohort analysis in Google Analytics]]></title>
				<description><![CDATA[You can find out lots about your customer behaviour by doing a cohort analysis in Google Analytics, using a simple event tracking hack. 

<p>A while ago I read an interesting post from <a target="_blank" mce_href="http://danhilltech.tumblr.com/post/12509218078/startups-hacking-a-cohort-analysis-with-google" href="http://danhilltech.tumblr.com/post/12509218078/startups-hacking-a-cohort-analysis-with-google">Dan Hill</a> which explained how he's added functionality to his Google Analytics tracking to allow him to perform a simple cohort analysis.&nbsp;</p><p>Dan's technique is designed for content sites, so it runs some queries on logged-in users to find out when they signed up and uses Ruby on Rails to add the data to two custom variables for the join month and join year using the visit level scope.</p><p>He then uses the advanced segments in the Google Analytics interface to create custom segments for each cohort, say "November 2011 signups", and then selects a cohort to see how it differs in its conversion rates for his goals.&nbsp;</p><p>That's a neat way of achieving it, but with only five <a mce_href="http://techpad.co.uk/content.php?sid=165" href="http://techpad.co.uk/content.php?sid=165">custom variables</a> available in the free version of GA, their use needs careful monitoring and most of mine are already full. So I've come up with a similar solution which uses event tracking instead.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="231" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f02e02a88780.jpg" onmouseover="return true;undefined" onmouseout="return true;undefined">&nbsp;</p><p><b>Using event tracking for cohort analysis</b></p><p>While <a target="_blank" mce_href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html" href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html">event tracking</a> probably wasn't designed to do stuff like this, I find it lends itself well to this kind of hack. </p><p>Essentially, you can use GA's event tracking feature like a database with four fields (category, action, label and value) and it will neatly store your data, crunch your numbers and allow you to segment against it.&nbsp;</p><p>You'd have your work cut out to produce a similar application so easily if you weren't using Google Analytics, particularly for the data charting. Plus, it's all in one place for analysis with the rest of your data, which makes it really powerful.&nbsp;</p><p>However, event tracking isn't perfect and if you use it in this way you'll need to think ahead about how the data will be displayed in GA. </p><p>It used to be the case that setting events affected your bounce rate, but the new <a mce_href="http://techpad.co.uk/content.php?sid=187" href="http://techpad.co.uk/content.php?sid=187">opt_noninteraction</a> value now overcomes this. To me, the greatest annoyance is the fact that, for no apparent reason, the value field needs to be an integer (ie. 1) and not a float (ie. 1.4). </p><p>This means you'll need to use rounding to ensure any values passed are integers, which makes the event value and average value metrics approximate.</p><p>On the plus side, if your events are purchase related, you'll still get e-commerce data for each event, so you can still get at the data, just not quite so neatly.&nbsp; <br></p><p><b>How it's done</b></p><p>I work on e-commerce sites, so I'm running my event tracking code only when a purchase is made. I trigger the code to run only on the payment confirmation page and run a quick SQL query using PHP to get the date of the user's first order.&nbsp;</p><p>I then apply that date to a PHP function which re-formats the date to provide three different values: the cohort year (ie. 2011), the cohort month (ie. 09) and the cohort quarter (ie. Q3).&nbsp;</p><p>I then send these values to my Google Analytics tracking code and assign them to three different _trackEvent calls, one for "Monthly cohorts", one for "Annual cohorts" and one for "Quarterly cohorts". </p><p>It's vital that when using this technique that you don't try to send more than 10 events at once - since Google Analytics has an undocumented feature in place to prevent the server getting flooded with event tracking data. </p><p>If this is an issue for you, you might like to know I've <a mce_href="http://techpad.co.uk/content.php?sid=195" href="http://techpad.co.uk/content.php?sid=195">developed a workaround for this</a>.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="169" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4f02e0287bc4f.jpg" onmouseover="return true;undefined" onmouseout="return true;undefined">&nbsp;</p><p><b>Accessing the data</b></p><p>As with all event tracking data, you'll find this (in version 5 of GA) under Content &gt; Events &gt; Overview &gt; Cohort analysis.&nbsp; </p><p><img mce_src="/custom/images/medium/4ef9c06ba88a4.jpg" height="113" width="426" src="/custom/images/medium/4ef9c06ba88a4.jpg"></p><p>When you've had this up and running for a few months you'll develop a good picture of what your customer base looks like, which will give you the potential for more insight.&nbsp;</p><p>Chart your cohorts over a period of months to see how many of the customers have returned, then see if you can use lifecycle marketing techniques to target certain cohorts and get them to return.&nbsp;</p><p><b>Update:</b> If you want to try the alternative way of doing this, using custom variables, then do make sure you check out Jonathan Balogh's <a href="http://jonathonbalogh.com/2012/04/01/how-to-do-cohort-analysis-in-google-analytics/">excellent detailed guide</a>.&nbsp;</p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=192&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_192]]></link>
			</item>
			<item>
				<title><![CDATA[Using Google Analytics for complaints analysis]]></title>
				<description><![CDATA[My employer's e-commerce platform doesn't track complaints from customers, or the products which are arriving damaged or being returned regularly, so I built a little application to capture and analyse the data in Google Analytics. 

<div>I'm not sure what proportion of online retailers analyse complaints from customers regarding issues with service quality, products or couriers, but I wouldn't imagine it's a high number - at least not for the smaller retailers.&nbsp;</div><div><br></div><div>Our existing e-commerce platform didn't allow us to measure this, so we had to rely on the call centre staff to tell us when they perceived a problem with our service, couriers or a product.&nbsp;</div><div><br></div><div>However, they couldn't reliable tell us whether courier complaints had risen, whether certain items were arriving damaged, being returned under warranty frequently or myriad other things.&nbsp;</div><div><br></div><div>All of these issues ultimately affect customer perception of service quality, so if you can measure them and spot issues before they get out of hand you'll increase profitability and keep customers happier.&nbsp;</div><div>&nbsp;</div><div>I decided to build a module for our e-commerce platform to allow us to log the data and feed it all into Google Analytics for easier analysis, and let us utilise GA's nifty alerts feature to inform us whenever a problem arose. </div><div>&nbsp;</div><div><b>How it works</b></div><div>When a customer calls our contact centre and has a complaint, the staff member selects the customer's name, order number and product (if any) and ticks some checkboxes which contain data that allows us to categorise the type of complaint. There's also a text field there so they can add call notes. &nbsp;</div><div>&nbsp;</div><div>When the form is submitted, the data are stored in the site's database and the checkbox fields are parsed to allow the complaint to be categorised by type, which allows us to see in the backend whether we've had a lot of courier issues on a particular day, or whatever. </div><div>&nbsp;</div><div>The data are also linked to the customer's profile on the platform, so if they call back we can see what they complained about and why. &nbsp;</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="274" align="" title="undefined" mce_src="/custom/images/medium/4ece3ad2b1e40.jpg" src="/custom/images/medium/4ece3ad2b1e40.jpg" onmouseover="undefined" onmouseout="undefined"></div><div>&nbsp;</div><div>To get the data into Google Analytics, I added the site's tracking code to the backend via a special module I've written to record various administrative tasks on the site. </div><div>&nbsp;</div><div>Again, this parses the data in the checkboxes and assigns it to a PHP array containing all of the data on the complaint type, category and product name. </div><div>&nbsp;</div><div>The analytics module then grabs this array and writes a number of _trackEvent lines into the tracking code, which sends the data to GA.</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="219" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4ece3ea124496.jpg" onmouseover="undefined" onmouseout="undefined"></div><div>Within GA, I grouped the complaints in an event tracking category called 'Complaints' and recorded the type of complaint (Warehouse, Courier, Website or Product) and the nature of the complaint (Wrong items sent, Courier delivered late etc), allowing us to get an overall view of what complaints we were receiving.&nbsp;</div><div>&nbsp;</div><div>The pie chart option in GA is particularly handy here, because you can see at a glance what the nature of complaints look like. This is fake data - our customer service is better than this!&nbsp;</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="251" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4ece3ad088df5.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</div><div>&nbsp;</div><div>For products, I took a different approach and also added the product name. This allows us to see for individual products which ones are arriving broken, have dodgy content on the site, are developing faults under warranty or are being picked incorrectly by the warehouse.&nbsp;</div><div>&nbsp;</div><div><img alt="" border="" hspace="" vspace="" width="426" height="246" align="" title="undefined" src="/custom/images/medium/4ece483d0be63.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</div><div>&nbsp;</div><div>We haven't introduced it yet, but providing the call centre team makes good use of it, it should work really well. The next step is to configure alerts in Google Analytics for different complaints so we can alert staff when, for example, we see an unusually high number of breakages for a given item, or a courier starts to drop the ball with its service. &nbsp;</div><div>&nbsp;</div><div>&nbsp;</div><div>&nbsp;</div>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=191&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_191]]></link>
			</item>
			<item>
				<title><![CDATA[Tracking on-site campaigns with Google Analytics]]></title>
				<description><![CDATA[Google Analytics doesn't have a built-in method for monitoring the performance of on-site campaigns, which is a bit of a drawback, but thankfully it's one that can be overcome with a bit of hacking... 

<p>Given that Google Analytics provides some really nice tools for <a target="_blank" mce_href="http://techpad.co.uk/content.php?sid=100" href="http://techpad.co.uk/content.php?sid=100">tracking external campaigns</a>, it's always struck me as a strange omission that there's no out-of-the-box alternative for the tracking of internal campaigns.&nbsp;</p><p>Maybe internal campaign tracking tools will be the next in the long line of new features the GA team seem to be giving us nearly every month?</p><p>It goes without saying (but I'll say it anyway, given some of the dodgy advice going around) that using the utm_campaign tracking parameters to track internal campaigns is a really bad idea, because when a user clicks an internal link that's been tagged in this way it overwrites their original source, ruining the historical GA data.&nbsp;</p><p>There's also a risk that the additional campaign parameters appended to your URLs might create duplicate content issues. The Google SERPS are full of examples of this. Google probably ignores these but the same might not apply to other search engines.&nbsp;</p><h3>Advertising metrics</h3><p>If you think about it, internal campaigns are effectively on-site advertising so I reckon they should really be measured using the same kind of metrics and KPIs we use to monitor the performance of paid search marketing.&nbsp;</p><p>What GA really needs, but currently lacks, is a simple solution for monitoring internal campaigns so marketers can see the total impressions served, the click-through rate, the coversion rate, the revenue per click, total campaign revenue, average order value and numerous other metrics.&nbsp;</p><p>Having the ability to see all of these would mean we're better able to optimise our on-site marketing. </p><p>However, it's really not that easy to do this without writing some code to extend the default tracking and send the data to GA, and (arguably) writing some additional code to export the data out of GA for external analysis.&nbsp;</p><h3>What should we be aiming to measure?</h3><p><b>Total impressions</b><br>In order to measure the click-through rate (CTR) of our internal campaigns, we're going to need to measure how many times it's been shown to visitors by recording each time an ad is displayed.</p><p><b>Click-through rate</b><br>To determine how well our ads are enticing customers to click we're going to need to measure the gross clicks for each ad unit and then calculate the click-through rate for the individual ad shown.&nbsp;</p><p><b>Transactions</b><br>To allow us to see how many transactions an ad has resulted in, we're going to need to record all transactions which resulted from an ad click or which should be attributed to the ad.&nbsp;</p><p><b>Campaign revenue</b><br>We'll also need to know how much revenue the campaign creative drove in total. That needs to be based around similar criteria to those we set for the transactions measurement.&nbsp;</p><p><b>Average order value</b><br>What was the average order value across all of the transactions for this creative? We can work this out from the total value of the transactions and the total number of transactions.&nbsp;</p><p><b>Conversion rate</b><br>To get our conversion rate, showing us the effectiveness of the ad in converting people who clicked it into purchasers, we'd simply need to know the number of unique clicks and the number of transactions.&nbsp;&nbsp; </p><h3>How can we measure it?</h3><p>In terms of implementing a system to record all the required data in Google Analytics we've really got three main options: <a mce_href="http://techpad.co.uk/content.php?sid=107" href="http://techpad.co.uk/content.php?sid=107">virtual pageviews</a>, site search and event tracking.</p><p>Virtual pageviews would also allow us to capture some of the data, but they're a bit limited for stuff like this. <br></p><p>Justin Cutroni's <a mce_href="http://cutroni.com/blog/2010/03/30/tracking-internal-campaigns-with-google-analytics/" href="http://cutroni.com/blog/2010/03/30/tracking-internal-campaigns-with-google-analytics/">site search method</a> is another option. This works by adding an additional custom parameter to each campaign URL and then parsing this data out in a separate profile using Google Analytics' built-in site search feature.&nbsp;</p><p>However, event tracking allows you to capture pretty much everything in the list above but in a much neater way than the other two methods. </p><p>It can be used to track the impressions on the ads, the clicks and the resulting purchases and their values. </p><p>It's also easily built into your e-commerce platform, so you can set-up a permanent tracking implementation without the need to configure anything in your GA account. It's the hands down winner for implementing this, in my opinion. </p><p>Let's assume we're using a slider promotion on our home page and want to set up event tracking to record all of these data. How could we set that up?<br></p><h3>Step 1: Recording ad impressions</h3><p>In order to calculate the number of impressions served, we need to add event tracking to the JavaScript code which displays each frame of our promotional slider. </p><p>We want to record an event in Google Analytics each time the campaign slide is shown on the page so we can record the total number of impressions for each slide in our slider widget. </p><p>It used to be the case that using event tracking for such passive events would cause a non-bounce, thereby affecting the site-wide bounce rate and messing up your data. </p><p>However, a new _trackEvent parameter called opt_noninteraction now makes it feasible to do <a target="_blank" mce_href="http://techpad.co.uk/content.php?sid=187" href="http://techpad.co.uk/content.php?sid=187">passive event tracking without affecting bounce rate</a>. </p><p>Each time a new slide is displayed you need to fire some code like this: _gaq.push(['_trackEvent','Campaign impressions','Home page slider','Summer sale','',true]);</p><p>Here we're creating an event category called 'Campaign impressions' for all of our impressions data, adding an action called 'Home page slider', setting the label to the name of the slide 'Summer sale', passing a null value, and importantly, setting the non-interaction value to true.&nbsp;</p><p>This will record all of the impressions served on the slider as a whole, and the Summer sale slider specifically, from which we'll be able to calculate a number of other metrics. &nbsp;</p><p>There is a risk to this, though. You're only able to record 500 bits of hit-level data per session, and it's feasible that if you use this heavily, you could reach the limit, and lose important bits of transactional information. Consider the risks before implementing it, or consider sending the data to a separate tracker. &nbsp;</p><h3>Step 2: Recording ad clicks</h3><p>Recording ad clicks is pretty straightforward, since we can just attach our code to an onclick handler in the href for the campaign.&nbsp;For example, onclick="_gaq.push(['_trackEvent','Campaign clicks','Home page slider','Summer sale','',false]);"&nbsp;</p><p>Besides the event which records the original click on the event, I'd also recommend firing a _setCustomVar() function with a session level scope. </p><p>If a user clicks on the 'Summer sale' slide of the 'Home page slider' we'll be able to see whether they purchased as a result of the click, allowing us to get a conversion rate for each slide.&nbsp;</p><h3>Step 3: Calculating the metrics from the data<br></h3><p><b>Total impressions: </b>The total impressions for each slide in a slider will be available from Content &gt; Event tracking &gt; Categories &gt; Slider name &gt; Slide name. You'll be able to use the date selector tool to find the number of impressions for a given period for your reporting.</p><p><b>Total clicks:&nbsp;</b>We can find the total number of clicks for a slide by going to Content &gt; Event tracking &gt; Categories &gt; Campaign clicks &gt; Slider name &gt; Slide name. &nbsp;&nbsp;</p><p><b>Click-through rate: </b>To calculate the CTR for the slide, divide the total impressions by the total clicks.&nbsp;</p><p><b>Campaign revenue: </b>Go to Content &gt; Event tracking &gt; Categories &gt; Campaign clicks &gt; Slider name &gt; Slide name and look in the e-commerce tab under revenue.&nbsp;</p><p><b>Average order value: </b>You'll find the average order value for a given slide at Content &gt; Event tracking &gt; Categories &gt; Campaign clicks &gt; Slider name &gt; Slide name under Average Value. &nbsp;&nbsp;</p><p><b>Conversion rate: </b>Divide the total clicks by 100 then multiply the value by the total number of transactions to get the conversion rate for the individual slide.&nbsp;&nbsp;</p><h3>How can we further improve performance?</h3><p>Now you've got access to these important metrics, you'll be able to look at the performance of your promotional sliders and slides and see which ones work, and which ones don't. </p><p>You can then start tweaking them to see if you can improve their performance. &nbsp;</p><p>A/B testing or multivariate testing is a really obvious way of trying out different variants, and if you integrate Google Website Optimizer with Google Analytics, you can also take advantage of segmentation to look for trends beyond the bottom line.&nbsp;</p><p>If you know that customers from a certain segment are more likely to respond to a different creative, then you'll need to try and target that at them.</p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=189&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_189]]></link>
			</item>
			<item>
				<title><![CDATA[Using Google Analytics for recommendation algorithms]]></title>
				<description><![CDATA[Back in June I explained how you could replicate Amazon's product recommendation tool using some simple Google Analytics hacks. Here's a bit more information on how you can turn this into a working application. 

<p>As I explained in my earlier post "<a href="http://techpad.co.uk/content.php?sid=168" mce_href="http://techpad.co.uk/content.php?sid=168">What do customers ultimately buy after viewing this item?</a>", it's possible to use Google Analytics to manually determine what products customers purchase when they view a particular page.&nbsp;</p><p>That's relatively straightforward for individual products and gives you some insight into which products you ought to be promoting as cross-sells and up-sells on particular pages.&nbsp; </p><p>However, you need to automate the process using the <a href="http://code.google.com/apis/analytics/docs/gdata/home.html" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/home.html">Google Analytics Data Export API</a> in order to make it really useful. </p><h3>Using the Data Export API </h3><p>The Data Export API currently provides read-only access to authenticated users, allowing you to query your Google Analytics data in much the same way as you would through the graphical web interface.&nbsp;</p><p>The Data Export API queries are based around often complex URLs containing the desired query parameters, so there's a URL structure to determine for each request. </p><p>Helpfully, there's a useful tool available in Google's Data Export Labs called the <a href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html">Data Feed Query Explorer</a> which simplifies the process of fine-tuning your API query URL so you can use it in your application.</p><p>There's also an <a href="http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDataFeed.html" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDataFeed.html">excellent guide</a> you'll want to refer to. <br></p><p><img src="http://techpad.co.uk/custom/images/medium/4ea2e4b4956b1.jpg" height="324" width="426"> <br></p><p>I'd recommend using the graphical interface to GA first of all and then trying to replicate your query via the Data Feed Query Explorer to help make the URL, and check that it works as intended. It really makes life a lot easier when you're working with the API. <br></p><h3>Some examples to try</h3><p>There are loads of different ways in which you could use this data in product or content recommendations. </p><p>These are just the basic ones I can think of, but if you start using it with event tracking or custom variables there's even more potential for getting even more detailed data out of GA to help you with recommendations. </p><p><b>1. People who view this page ultimately purchase</b></p><p>The classic Amazon-style product recommendation which tells you what customers ultimately purchase after viewing a given page is quite easy to achieve via the API. </p><p><img src="/custom/images/medium/4ea2e4154e223.jpg" mce_src="/custom/images/medium/4ea2e4154e223.jpg" height="245" width="426">&nbsp;</p><p>The only dynamic data you need to pass to GA is the relative URL of the page (as it will be shown in GA) and the date range you want to select data for. You can restrict the number of results returned to speed things up. <a href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;segment=dynamic%253A%253Aga%253ApagePath%253D%253D%252Fyourpage.html&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;segment=dynamic%253A%253Aga%253ApagePath%253D%253D%252Fyourpage.html&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50">Try it here</a>. <br></p><p>https://www.google.com/analytics/feeds/data?ids=ga%3A<b>123456789</b>&amp;dimensions=ga%3AproductName%2Cga%3AproductSku&amp;metrics=ga%3AuniquePurchases&amp;segment=dynamic%3A%3Aga%3ApagePath%3D%3D%2F<b>yourpage.html</b>&amp;sort=-ga%3AuniquePurchases&amp;start-date=<b>2011-10-08</b>&amp;end-date=<b>2011-10-22</b>&amp;max-results=<b>50</b></p><p><b>2. People who bought this product also purchased </b></p><p>Unlike some of the server-side recommendation engines, which look at purchases made by customers from historic data, this one only uses items from the same transaction, because GA doesn't link transactions to individual customers across multiple visits. </p><p>It's therefore only any good for providing basic cross-sell recommendations. </p><p>If you want to do a more sophisticated cross-sell, based on products other owners own, you'll need to export the data and link them to the customer ID and do the analysis and recommendation outside the GA API. </p><p><img src="/custom/images/medium/4ea6b2e894633.jpg" mce_src="/custom/images/medium/4ea6b2e894633.jpg" height="307" width="426">&nbsp;</p><p>You need to select the ga:productName dimension, the ga:uniquePurchases metric, and the dynamic segment dynamic::ga:productSku=~ and then order by descending uniquePurchases using -ga:uniquePurchases. </p><p>You'll also want to add the filter ga:productSku!=YOURSKU so the recommendations exclude the SKU you passed to the API. <a href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;segment=dynamic%253A%253Aga%253AproductSku%253D%253DYOURSKU&amp;filters=ga%253AproductSku%21%253DOFFER6434&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;segment=dynamic%253A%253Aga%253AproductSku%253D%253DYOURSKU&amp;filters=ga%253AproductSku!%253DOFFER6434&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50">Here's a live example. </a><br></p><p>https://www.google.com/analytics/feeds/data?ids=ga%3A3<b>1234567</b>&amp;dimensions=ga%3AproductName%2Cga%3AproductSku&amp;metrics=ga%3AuniquePurchases&amp;segment=dynamic%3A%3Aga%3AproductSku%3D%3D<b>YOURSKU</b>&amp;filters=ga%3AproductSku!%3D<b>YOURSKU</b>&amp;sort=-ga%3AuniquePurchases&amp;start-date=<b>2011-10-11</b>&amp;end-date=<b>2011-10-25</b>&amp;max-results=<b>50</b></p><p><b>3. Best-selling products this period</b></p><p>Want to show your customers a dynamically-generated list of your best selling products this week, today or this month? This is also quite easy to achieve. </p><p><img src="/custom/images/medium/4ea2dc1376671.jpg" mce_src="/custom/images/medium/4ea2dc1376671.jpg" height="247" width="426">&nbsp;</p><p>You need to provide the ga:productName and ga:productSku dimensions, the ga:uniquePurchases metric and then sort by descending number of purchases by using the parameter -ga:uniquePurchases. </p><p>You can set the start-date and end-date to whatever period you want your best sellers to cover, ie this week, this month, today, this year. <a href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50">Here's an example</a>. </p><p>https://www.google.com/analytics/feeds/data?ids=ga%3A<b>1234567</b>&amp;dimensions=ga%3AproductName%2Cga%3AproductSku&amp;metrics=ga%3AuniquePurchases&amp;sort=-ga%3AuniquePurchases&amp;start-date=<b>2011-10-11</b>&amp;end-date=<b>2011-10-25</b>&amp;max-results=<b>50</b><br></p><p><b>4. Best-selling products for visitors from this referring URL</b></p><p>If you sell a diverse range of products and receive reasonable levels of traffic from niche sources only interested in certain product ranges, you might want to target them with the most relevant offers. </p><p>For example, if you sell mountain bikes, skis and surfboards and want the visitors 
coming from the surfing sites to see recommendations only for surfing stuff, you could target them based on their referring URL.</p><p><img src="/custom/images/medium/4ea6bbab81bee.jpg" mce_src="/custom/images/medium/4ea6bbab81bee.jpg" height="305" width="426">&nbsp;</p><p>To do this you'd simply add the name of the referring site to a dynamic segment and get back a list of products most visitors from this source have purchased. </p><p>You could also combine a list of related sites using regular expressions, so all of the surfing URLs result in the same recommendations. <a href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;segment=dynamic%253A%253Aga%253Asource%253D%2540somesite.com&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;segment=dynamic%253A%253Aga%253Asource%253D%2540somesite.com&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50">Here's an example</a>. <br></p><p>https://www.google.com/analytics/feeds/data?ids=ga%3A<b>1234567</b>&amp;dimensions=ga%3AproductName%2Cga%3AproductSku&amp;metrics=ga%3AuniquePurchases&amp;segment=dynamic%3A%3Aga%3Asource%3D%40<b>somesite.com</b>&amp;sort=-ga%3AuniquePurchases&amp;start-date=<b>2011-10-11</b>&amp;end-date=<b>2011-10-25</b>&amp;max-results=<b>50</b><br></p><p><b>5. People who arrive via this keyphrase ultimately purchase</b></p><p>This
 one works in much the same way, but instead of using a page path you 
use the keyword phrase the user arrived with, ie "lenovo laptop". </p><p>This one might be 
scuppered by Google's recent introduction of SSL searching by default, 
as that now strips off the keywords from the URL when the user is 
logged-in to their Google account, but it should still work for quite a lot of searches.<br></p><p>However, although it seems trivial, to get more accurate results you're going to need some fancier querying. </p><p><img src="/custom/images/medium/4ea6bda143814.jpg" mce_src="/custom/images/medium/4ea6bda143814.jpg" height="304" width="426">&nbsp;</p><p>You'll need to parse out the referring keywords from your search URL, use explode() to break up the keywords and then add them to a filter. </p><p>I've used the filter ga:keyword=@lenovo,ga:keyword=@laptop to do this. The comma between the first and second filters acts as an OR. There's more about this in the <a href="http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDataFeed.html" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDataFeed.html">data feed guide</a>. Here's a <a href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;filters=ga%253Akeyword%253D%2540lenovo%252Cga%253Akeyword%253D%2540laptop&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50" target="_blank" mce_href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html?dimensions=ga%253AproductName%252Cga%253AproductSku&amp;metrics=ga%253AuniquePurchases&amp;filters=ga%253Akeyword%253D%2540lenovo%252Cga%253Akeyword%253D%2540laptop&amp;sort=-ga%253AuniquePurchases&amp;start-date=2011-10-11&amp;end-date=2011-10-25&amp;max-results=50">live example</a>.<br></p>https://www.google.com/analytics/feeds/data?ids=ga%3A<b>1234567</b>&amp;dimensions=ga%3AproductName%2Cga%3AproductSku&amp;metrics=ga%3AuniquePurchases&amp;filters=ga%3Akeyword%3D%40<b>lenovo</b>%2Cga%3Akeyword%3D%40<b>laptop</b>&amp;sort=-ga%3AuniquePurchases&amp;start-date=<b>2011-10-11</b>&amp;end-date=<b>2011-10-25</b>&amp;max-results=<b>50</b><h3>Automating it...</h3><p>Obviously these are just a starting point. </p><p>You can apply the same techniques to getting recommendations for other articles readers may want to read based on the page views of other users; the typical products users purchase after making an internal search, or countless other things. </p><p>To automate these queries and turn them into a working recommendation engine, you'll need to do a bit of server-side coding and make sure you take advantage of caching. </p><p>The queries take a second or two to execute so you'll want to make sure they only get executed every now and then, with the result being cached and subsequent recommendations made from the cached data to improve performance.</p><p>If you can't be bothered with any of this, check out <a href="http://www.liftsuggest.com/" target="_blank" mce_href="http://www.liftsuggest.com/">LiftSuggest</a>, a product recommendation engine designed specifically for doing this using the GA API. There are both free and paid versions. <br></p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=188&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_188]]></link>
			</item>
			<item>
				<title><![CDATA[Using opt_noninteraction event tracking in Google Analytics]]></title>
				<description><![CDATA[A new parameter in Google Analytics' _trackEvent event tracking function means it's now possible to avoid the non-bounce side effect. 

<div>One of the minor annoyances of the more sophisticated uses of event tracking (passive events) in Google Analytics is that triggering an event affects bounce rate, skewing the real data.&nbsp;</div><div><br></div><div>Ordinarily, when you're using event tracking to capture data via an onclick this wouldn't be a problem.&nbsp;</div><div><br></div><div>If a user lands on a page and then clicks, for example, a tab to which you've added event tracking, the interaction would be considered a non-bounce, even if the user doesn't visit another page.&nbsp;</div><div><br></div><div>The thinking is, the user has interacted in a way which is analagous to a page view, so you shouldn't see their visit as a bounce.&nbsp;</div><div><br></div><div>However, under the more fancy uses of event tracking, such as when event tracking data is written directly to the Google Analytics tracking code (GATC) at page load, the entire page view would be recorded as a non-bounce, which will have an effect upon the site average and skews the data for that page.</div><div>&nbsp;</div><div><b>Avoiding the non-bounce effect</b>&nbsp;</div><div>Why would you even want to do such a thing, I hear you ponder?</div><div><br></div><div>Well, passive event tracking is a really simple way of extending the functionality of GA and allows you to record shedloads of data not recorded in the default version. Like <a href="http://econsultancy.com/uk/blog/7860-monitoring-purchase-latency-in-google-analytics" target="_blank" mce_href="http://econsultancy.com/uk/blog/7860-monitoring-purchase-latency-in-google-analytics">purchase latency</a>, <a href="http://techpad.co.uk/content.php?sid=186" mce_href="http://techpad.co.uk/content.php?sid=186">profit or margin</a>, for example.&nbsp;</div><div><br></div><div>With the exception of <a href="http://techpad.co.uk/content.php?sid=166" mce_href="http://techpad.co.uk/content.php?sid=166">custom variables</a>, event tracking is one of the coolest things in GA, from an implementation perspective. Indeed, it's been said that if you're not using event tracking you're not really using GA at all.&nbsp;</div><div><br></div><div>On October 17 2011, Google quietly pushed an improvement to the ga.js file that powers GA, which allows you to use events in this way without any adverse affects upon your bounce rate.&nbsp;</div><div><br></div><div>(You've got to love the way Google giveth (multi-channel funnels, improved event tracking, flow analysis) and then taketh away (stripping the q parameter from SSL searches).&nbsp;</div><div><br></div><div>What this all means, is that there's no a fifth parameter for the _trackEvent() function which opens up a whole new way of using event tracking, without it buggering up your bounce rate data.&nbsp;</div><div>&nbsp;</div><div><b>Introducing opt_noninteraction</b>&nbsp;</div><div>The old function _trackEvent(category, action, opt_label, opt_value) required a category and action but made the label field optional and required that the value was a number without a decimal point.&nbsp;</div><div><br></div><div>The updated function is now _trackEvent(category, action, opt_label, opt_value, opt_noninteraction).&nbsp;</div><div><br></div><div>The opt_noninteraction bit, is a Boolean operator (that is, either true or false).&nbsp;</div><div><br></div><div>If you leave it off (which will be the case for any _trackEvent() stuff you already had set-up prior to the change, it defaults to false and the interaction will affect the bounce rate.&nbsp;</div><div><br></div><div>However, if you add the value 'true', the event hit won't be used in bounce rate calculations.&nbsp;</div><div><br></div><div>If you've got functions already in place in which you're using only one of the optional values (ie opt_label or opt_value), you'll need to pass a null value '' so that GA knows the order of the parameters.&nbsp;</div><div><br></div><div>For example, one of the things I measure using event tracking is the interaction of customers with pages on which the product is <a href="http://techpad.co.uk/content.php?sid=183" mce_href="http://techpad.co.uk/content.php?sid=183">out of stock</a>.&nbsp;</div><div><br></div><div>This works well, but the bounce rate data for that product gets skewed, but adding an additional field to the end fixes the problem.&nbsp;</div><div><br></div><div>_gaq.push(['_trackEvent','Out of stock items','Apple iPad 2','SKU73893','439',true]);</div><div><br></div><div>Using it without the "true", defaults to recording the event as a non-bounce.&nbsp;</div><div><br></div><div>_gaq.push(['_trackEvent','Out of stock items','Apple iPad 2','SKU73893','439']);</div><div>&nbsp;</div><div>If you are not providing the optional value, then you need to change the format and use a null/space rather than a pair of single quotes. <br></div><div>&nbsp;</div><div><div>_gaq.push(['_trackEvent','Out of stock items','Apple iPad 2','SKU73893', ,true]);</div><div>&nbsp;</div><div>Presumably this is because GA wants you to pass the value as an integer/null and not as an empty string, so this won't work. </div><div>&nbsp;</div><div><div>_gaq.push(['_trackEvent','Out of stock items','Apple iPad 2','SKU73893', '',true]);</div></div></div><div>&nbsp;</div><div><b>Other uses</b>&nbsp;</div><div>One other really neat way to use event tracking using the opt_noninteraction true setting would be to use it to record when content is displayed, such as promotional images or ad impressions.&nbsp;</div><div><br></div><div>If you've got a promotional switcher on your home page highlighting some of your new products, you could use jQuery to fire the _trackEvent() function each time a new slide is displayed.&nbsp;</div><div><br></div><div>You'll then be able to use GA to segment those customers who've been shown a particular promo image, allowing you to determine the conversion rate of individual ads.&nbsp;</div>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=187&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_187]]></link>
			</item>
			<item>
				<title><![CDATA[Server-side tracking with Google Analytics]]></title>
				<description><![CDATA[There have been a few times recently when I've needed a server-side method for sending tracking data to Google Analytics. Here's how it's done.

<p>Google Analytics does not yet provide a server-side API for sending data to the GA servers. The current solution uses JavaScript and a GIF to send data from the client side and can't be easily or reliably triggered from the server-side.&nbsp;</p><p>Using the client-side method, the data is sent in the clear to Google so inquisitive developers can look at the JavaScript code or the GIF query string to see what data you're sending.&nbsp;</p><p>I'm a big fan of using event tracking to extend the functionality of GA and find it a really useful tool for recording useful e-commerce metrics such as <a target="_blank" mce_href="http://www.jimnovo.com/Customer-Latency.htm" href="http://www.jimnovo.com/Customer-Latency.htm">purchase latency</a>, which GA doesn't record by default. (Check out my <a target="_blank" mce_href="http://econsultancy.com/uk/blog/7860-monitoring-purchase-latency-in-google-analytics" href="http://econsultancy.com/uk/blog/7860-monitoring-purchase-latency-in-google-analytics">post for Econsultancy</a>&nbsp;on such "passive events", which explains how that's done.)<br></p><p><img mce_src="/custom/images/medium/4e3d8a8e23875.jpg" height="294" width="426" src="/custom/images/medium/4e3d8a8e23875.jpg"> </p><p>I also wanted to take advantage of passive non-interactive event tracking to record some other business critical metrics, such as item profit, item margin, basket profit and basket margin so they could be integrated into my reporting and analysis directly through the GA interface. </p><p>However, I don't really want customers or competitors finding profit or margin data in the JavaScript code or GIF data. </p><p>I've therefore been looking for an effective server-side solution for sending event tracking data to the Google Analytics server without the need to use either JavaScript or the GIF - and now I've found one.&nbsp;</p><p><img mce_src="/custom/images/medium/4e9ffe78c8a22.jpg" height="299" width="426" src="/custom/images/medium/4e9ffe78c8a22.jpg">&nbsp;</p><h3>Server-Side Google Analytics </h3><p>The <a target="_blank" mce_href="http://code.google.com/p/serversidegoogleanalytics/" href="http://code.google.com/p/serversidegoogleanalytics/">Server-Side Google Analytics</a> class (SSGA for short) is an open source PHP class available from Google Code which aims to tackle precisely the problem I've been facing (and a few others I'll outline later).</p><p>The Server Side Google Analytics (SSGA) class relies on the Zend framework's HTTP client to send data to the GA servers, which means you'll either need to install Zend on your server or include a local copy and manually set its include_path. If you don't mind getting your hands dirty you could replacing this dependency with cURL instead, but Zend HTTP works well enough.&nbsp; </p><p>Like the current JavaScript and mobile server-side code, SSGA works by constructing a query string containing the various name=value pairs, but rather than loading a GIF it uses the Zend HTTP client to make the request from the server side. </p><p>This means that data can be sent to GA without the need to load up either the JavaScript tag, GIF or cookies keeping the data away from prying eyes. It also means you can use the class in situations where there's no physical page view, such as via a cron job or other server-side process.&nbsp;</p><p>&nbsp;<img mce_src="/custom/images/medium/4e9ffba58378b.jpg" height="313" width="426" src="/custom/images/medium/4e9ffba58378b.jpg"></p><h3>How it works</h3><p>All you need to do is include the SSGA class, pass your account ID (ie UA-1234567-8) to the setAccountId() function, pass your hostname to setHostName and include a page title and page name for setPageTitle() and setPageView(). These last two can be fictitious if you like, as this then won't skew your existing data. </p><p>For each event you want to record you need to provide four values to the setEvent() function, and then use createEvent() to send the data. </p><p>The values passed to setEvent() are the same category, action, label and value used by the client-side _trackEvent function and the data you pass to them needs to be in a similar format.&nbsp;</p><p>Unlike the client-side API, SSGA converts spaces in the category, action or label to + so you'll want to bear this in mind when categorising your event tracking data. Like the client-side API, the value needs to be an integer, not a float, so don't you'll need to use round() or ceil() to get rid of the decimal point.&nbsp;</p><p>Once the code is executed, you should see your event tracking data appearing in Google Analytics under Content &gt; Event tracking &gt; Categories, usually after an hour or so.&nbsp; </p><p><img mce_src="/custom/images/medium/4ea00196dd67d.jpg" height="298" width="426" src="/custom/images/medium/4ea00196dd67d.jpg">&nbsp;</p><p>I've used this method to record the item profit and item margin of each item purchased, the basket margin and basket profit, and other metrics such as the overall product rating and the number and percentage of negative reviews. </p><p>However, there are many ways in which you could use the same or similar techniques. You could use it to enhance mobile tracking (in which the current server-side solution doesn't provide functionality for event tracking or other sophisticated features), record cron-based scripts, track redirects or use this as a back-up in the event of the EU cookie directive preventing you recording e-commerce tracking data.</p><p>Using SSGA also helps overcome the Token Bucket algorithm limitation of event tracking, which prevents more than 10 events being sent for a given token. &nbsp;</p><h3>3 key reasons why server-side GA is useful</h3><p>1. You can send more confidential data, such as profit and margin, to the GA servers without it being seen in your source code. </p><p>2. You can send additional data, bypassing things such as the 10 events per token limit. </p><p>3. You can send data when cookies and JavaScript are disabled, making it useful for mobile sites and for those affected by forthcoming EU cookie legislation.&nbsp;</p>

<p><i>If server-side Google Analytics are your cup of tea, you might also be interested in this more recent guide to using the related PHP-GA PHP class to hack a <a href="http://techpad.co.uk/content.php?sid=205">cookie-less GA implementation</a>.</i></p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=186&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_186]]></link>
			</item>
			<item>
				<title><![CDATA[Using Google Analytics to track revenue lost to poor stock control]]></title>
				<description><![CDATA[Keeping track of stock levels can be a challenge if your stock control is not automated, particularly when you stock thousands of products or SKUs.

<p>When it's left for humans to manually handle stock levels, products will inevitably fall out of stock at times and you'll lose sales when customers land on pages in which the virtual shelves are bare.</p>

<p>If you're using paid search to acquire customers, you're also throwing money away and the customers are much more likely to bounce when they land on a page containing products they can't purchase.&nbsp;</p><p><img alt="" border="" hspace="" vspace="" width="426" height="197" align="" title="undefined" mce_src="/custom/images/medium/4e7f393760694.jpg" src="/custom/images/medium/4e7f393760694.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p>



<p>I'm told that not many companies measure this and unfortunately Google Analytics doesn't measure this sort of thing by default. However it's quite easy to add this functionality yourself via a relatively straightforward hack.</p>

<p>You'll need to do a spot of coding, but the results are really useful and it's a quick and easy job for the average developer. I implemented this on three e-commerce sites in just a few hours.</p>

<p>Once it's up and running, you'll be able to see which products have fallen out of stock, examine the products that you regularly run out of, and also see which ones are being seen the most by your customers - indicating the greatest loss of revenue.</p>

<p>You could set up automated reporting so the data gets emailed to you every day or week, allowing you to beat your stock control manager with a stick for dropping the ball and losing you sales.</p><p>With a bit more effort you can also create some code which allows you to record the actual value of sales you lost because you sold out of certain items, which can be a really useful KPI to help drive improvements in stock management.&nbsp;</p>




<h3>Step 1: Querying the database</h3>
<p>First, you'll need to create a database query to determine whether the item on your product page has fallen out of stock. </p>

<p>Everyone's database will be different, but basically, you need to run the query and then get a true or false value indicating whether the product is in-stock or out-of-stock.</p>

<p>Your query might look a bit like this: <code>SELECT stock_level, product_name, sku, price FROM products WHERE id = '1234'</code></p>

<p>If your query returns zero, indicating that the product is out of stock, you'll need to get the product name, SKU and price and write the information to the Google Analytics tracking code (GATC). </p>




<h3>Step 2: Modify your GATC</h3>
<p>Precisely how you need to modify your GATC will really depend on how much you've already pimped up your Google Analytics implementation.</p> 

<p>On the average site in which you're just using the default tag the Google Analytics Tracking Code (GATC) will just be included in the bottom of the page.</p>

<p>For more sophisticated sites, the GATC will be being created dynamically and the server will be writing in additional data into extra variables depending on the page being viewed. </p>

<p>Within your GATC, you'll need to write the following trackEvent code and push it to the Google Analytics server. It will add the data to a category called "Out of stock items", along with the product name, the SKU and the price. </p>

<p><code>_gaq.push(['_trackEvent','Out of stock items','Apple iPad 2','2528',399]);</code></p>

<p>Oddly, Google Analytics won't allow you to use a decimal point in a value passed in the trackEvent, so you'll need to round up the price of the product to the nearest whole number.</p><p> You can do this easily using a ceil() type function in your server-side language or the database query itself.</p>





<h3>Step 3: Accessing the raw data</h3>
<p>Every time a page is viewed, the server will check to see whether it's in stock. If it's out of stock a line will be written to the GATC which sends the additional data to Google. </p>

<p>This obviously works most reliably when you have a single product or SKU per page. You could use it with multiple SKUs per page, but the data might not be so clear and it's going to be trickier to interpret.</p>

<p>To access the data, using the older version of Google Analytics go to Content &gt; Event Tracking &gt; Categories &gt; Out of stock items.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="287" align="" title="undefined" src="http://techpad.co.uk/custom/images/medium/4e7f386825966.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p> 

<p>The basic report will show you Total Events (the number of times a page with an out of stock product has been viewed), Unique Events (the number of times those pages have been viewed by unique users), Event Value (the price of each product viewed multiplied by the number of page views) and the Average Value (the average value of each product viewed).</p>




<h3>Step 4: Calculating the approximate total value of lost sales</h3>
<p>The quick and dirty way to calculate the total value of sales lost due to running out of stocks of the products you sell is fairly easy to do.&nbsp;</p><p>Take the total event value, say £1,234,567 and divide it by 100 and then multiply the value by your overall site average conversion rate, say 5%, to get the total estimated value of lost sales, which is £61,728.35.</p> 

<p>This really only works accurately on sites in which there's a single product/SKU per page, and doesn't take into account differing conversion rates for different products, but it's interesting nonetheless.</p><h3>Step 5: Calculating the precise value of total lost sales</h3><p>If you want greater precision, you'll need to use the actual conversion rate for each product, and not the overall site average conversion rate. </p><p>This is because many products differ greatly in their conversion rates. Those items which are on sale might be selling quickly with high conversion rates, while other items might be less keenly priced and sell more slowly. </p><p>Complicated products which require lots of prior research also tend to have lower conversion rates than cheaper commodity items.&nbsp;</p><p>For example, let's say we're looking at an iPod Touch, which has an average value on our site of £184. 744 visitors viewed it over our selected period, and it was out of stock several times for quite long periods, resulting in total event value of £175,904.&nbsp;</p><p>The product has a 2.3% conversion rate, so we can therefore see that by running out we lost around £4045.79.</p><p><img alt="" border="" hspace="" vspace="" width="426" height="236" align="" title="undefined" mce_src="/custom/images/medium/4e7f393848157.jpg" src="/custom/images/medium/4e7f393848157.jpg" onmouseover="undefined" onmouseout="undefined">&nbsp;</p>

<p>&nbsp;Click the product name in the Content &gt; Event Tracking &gt; Categories &gt; Events tab and you should see a report which shows how many times over your selected time period your chosen product has fallen out of stock.</p><p>We can also see from the individual product's charts that it was in stock for several weeks, then sold out, then came back in and sold out after a few days, and did the same thing several times.&nbsp;</p>

<p>If a product is falling out of stock regularly, customer demand might be exceeding your supply, which suggest you need to increase your stock levels, which should allow you to sell more. You definitely shouldn't be running out of stocks of your best selling lines.&nbsp;</p><p>&nbsp;</p><h3>Step 6: Automating it</h3><p>If you're happy with an approximation, you can set up Google Analytics to send you an automated report every day or week to let you know which products are out of stock, and to report the total value of lost sales. You'll need to manually calculate the estimated revenue loss by using your average conversion rate.&nbsp;</p><p>If you want to get more detailed results, you'll need to write an application using a server side language, such as PHP, which queries the Google Analytics server to retrieve the data via the API, and then uses the conversion rate for each product to determine the actual value of lost sales. </p><p>That's a bit of a time consuming task and too lengthy to explain here, but it's probably worthwhile if you've got stock control issues that need to be monitored carefully.&nbsp;</p><h3>KPIs</h3><p>There are a few KPIs I've found useful to report with this data:</p><p>1. Total visits encountering stock-outs</p><p>2. Total revenue lost per visit due to stock-outs</p><p>3. Percentage of visits encountering stock-outs</p><p>4. Total revenue lost&nbsp;</p><p>&nbsp;</p><h3>Caveats</h3>
<p>1. Of course, this will only work when products that are out of stock are viewed. If you've got some obscure products that have fallen out of stock without being noticed, and their product pages don't get viewed for a while, there's going to be a delay in spotting the trend via GA.</p><p>2. It's a hack and GA wasn't designed to do this, and when you view the data in GA it doesn't mean that much, particularly when you view the colour coding when different time periods are compared.&nbsp;</p><p>3. Using a site-wide average conversion rate is risky and only gives a rough approximation. To get detailed figures you'll need to use the individual product conversion rates, which requires much more effort. </p><p>4. This won't tell you when a product is going to sell out, or make any predictions on how you need to adjust stock levels. If you want to do that you'll need to build the functionality into your ecommerce platform. &nbsp;</p>

]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=183&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_183]]></link>
			</item>
			<item>
				<title><![CDATA[Proof that the EU cookie law will stuff up analytics]]></title>
				<description><![CDATA[Fascinating data obtained under the Freedom of Information Act has shown that the ICO has just a 10% conversion rate on getting users to opt-in to receiving cookies.

<p>Like most people who use web analytics software in their work, I've been closely following the <a href="/content.php?sid=160" mce_href="http://techpad.co.uk/content.php?sid=160">EU cookie directive</a> and have been keeping a close eye on what others have been doing to implement cookie opt-ins. </p><p>Unsurprisingly, one of the first to implement an opt-in was the ICO itself - a whole three days before it became law. </p><p>It added a box to the top of its site which informed the user that parts of the site used cookies and that it wished to track users with Google Analytics. </p><p>It then asked them to check a box to opt-in to providing their consent to do so.&nbsp;</p><p><b>Freedom of information</b> <br></p><p>In a very clever move, web analyst <a href="https://twitter.com/#%21/brockvicky" target="_blank" mce_href="https://twitter.com/#!/brockvicky">Vicky Brock</a> contacted the ICO and requested data on their site visits before and after they implemented a cookie opt-in system at the top of every page using the Freedom of Information Act. </p><p>The <a href="https://spreadsheets.google.com/spreadsheet/ccc?key=0AqwDz7xD-hGHdG9GY2E3ZEUxWEtQdFNMdmUwM3dibWc&amp;hl=en_US&amp;authkey=CJOXocQN&amp;ndplr=1#gid=0" target="_blank" mce_href="https://spreadsheets.google.com/spreadsheet/ccc?key=0AqwDz7xD-hGHdG9GY2E3ZEUxWEtQdFNMdmUwM3dibWc&amp;hl=en_US&amp;authkey=CJOXocQN&amp;ndplr=1#gid=0">data she obtained</a> are fascinating. </p><p>They show that only <a href="http://www.flickr.com/photos/vickyb/5859873790/in/photostream/" target="_blank" mce_href="http://www.flickr.com/photos/vickyb/5859873790/in/photostream/">around 10% of site users</a> provided their consent to the ICO to allow it to use cookies.&nbsp;</p><p>It's a worrying indication of where we're heading, but it's not altogether surprising. <br></p><p><b>Opt-in versus opt-out</b></p><p>Rather than the current situation in which users <i>opt-out</i> of being tracked, such as by blocking cookies, using existing global cookie opt-outs provided by web analytics firms, or by using the 'do not track' feature of their browser, we're being forced to get users to <i>opt-in</i>.&nbsp;</p><p>However, benign and anonymous the tracking may be, I can't really imagine that too many people are going to opt-in to providing their consent to being watched - particularly given some of the sensationalist stuff printed in the mainstream press about both cookies and web tracking. </p><p>After all, tracking provides little value to the customer, so why should they bother? Indeed, asking customers if we can track them might even turn some of them off, maybe even acting as something which drives abandonment or reduces purchase conversion rates.<br></p><p>That 10% figure the ICO recorded might well prove to be better than many other sites manage. <br></p><p>Once analysts were concerned mainly with monitoring the conversion rates
 of getting users to complete purchases or sign up to email newsletters,
 now it seems we might also need to start considering the conversion 
rate of how many customers allow us to track them.&nbsp;</p><p>Perhaps not the sort of conversion rate optimisation many would prefer to be doing... <br></p><p><b>What's the solution?</b><br></p><p>Given the incredibly small number of sites who appear to have implemented an opt-in system so far (I reckon I've seen less than half a dozen sites attempting to fully comply with the new regulations), there's no definitive answer on which solution works best. Indeed, before the data Vicky obtained, we were all completely in the dark.</p><p>Personally, I can't really see conventional cookie-based web analytics tools continuing to provide much value to those operating within the EU unless they change. </p><p>If we really are going to be forced into getting permission from our users in order to track them and manage our sites efficiently then maybe we really need to move away from cookies.&nbsp; </p><p>I know that I'd struggle to do my job if I only had access to data on 10% of my customers' behaviours, so unless the web analytics providers help us out by implementing an alternative solution, I think many of us are going to have some challenges ahead to face.</p><p>I'm already working on an in-house server-side solution which will handle much of our e-commerce analytics, but when it lacks cookies it really only scratches the surface of what's already possible and commonplace with tools like Google Analytics and Site Catalyst. </p><p>However, it's certainly going to be a lot more useful than incomplete data covering maybe 10% of our customers. It's an unfortunate position to be in, when the EU could have simply laid down the law in other ways, such as allowing users to opt-out via their browser.</p><p>If you're interested in this do check out <a href="http://www.advanced-web-metrics.com/blog/2011/05/20/google-analytics-and-the-new-eu-privacy-law/" target="_blank" mce_href="http://www.advanced-web-metrics.com/blog/2011/05/20/google-analytics-and-the-new-eu-privacy-law/">this excellent post</a> on Brian Clifton's site.&nbsp; <br></p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=174&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_174]]></link>
			</item>
			<item>
				<title><![CDATA[Track QR codes with Google Analytics]]></title>
				<description><![CDATA[Want to create QR codes to use in your marketing and track their performance in Google Analytics? Here's how it's done.

<p>QR or Quick Response codes are really catching on these days. These odd-looking 2D barcodes resemble a load of pixelated nonsense but they can contain up to 4296 characters of text and URLs.&nbsp;</p><p>Since QR codes are readable by both dedicated QR code readers and the barcode 
scanners available freely for most smartphones, including iPhone and 
Android devices, they're fast becoming popular.&nbsp; </p><p>Already used in industry, they're now catching on with marketers who want to give users easy access to URLs via their customers' smartphones. </p><p>Thankfully, QR codes are fairly easy to generate and you can even track their usage in Google Analytics. <br></p><p><b>Step 1: Generating a trackable URL<br></b></p><p>Since we're including a URL in our QR code, we want to be able to easily track how many people have visited our site as a result of following this specific code. </p><p>We can do that very easily with Google Analytics' campaign tracking parameters.There's a detailed guide to using <a href="http://techpad.co.uk/content.php?sid=100" mce_href="http://techpad.co.uk/content.php?sid=100">campaign tracking</a> here.</p><p>All you need to do is take your existing URL, append some tracking parameters so the visits are automatically labeled and segmented in Google Analytics. </p><p>Take your original URL and add a value for utm_medium, utm_source and utm_campaign using values that have been URL encoded. </p><p>If you've got no ? in the URL, add the first tracking parameter with a ? and add ampersands for the subsequent ones. For example, http://yoursitenamegoeshere.com would become http://yoursitenamegoeshere.com?utm_medium=QR+code&amp;utm_source=Billboard&amp;utm_campaign=Product+launch </p><p>If a ? is already present then just append the tracking with ampersands. For example, http://yoursitenamegoeshere.com/page.php?id=1234 would become http://yoursitenamegoeshere.com/page.php?id=1234&amp;utm_medium=QR+code&amp;utm_source=Billboard&amp;utm_campaign=Product+launch </p><p><b>Step 2: Shorten the URL</b></p><p>Since there's a limit to the number of characters you can fit in a QR code, it makes sense to use a URL shortening service to turn your lengthy trackable URL into a shortened version. </p><p>If you're manually generating your QR code you can simply enter your trackable URL into a URL shortening service such as bit.ly or goo.gl and it will make it into a much shorter version. </p><p>When the user clicks the URL they'll hit the URL shortening service which then redirects them to your longer URL with the tracking appended to the end. </p><p><img src="/custom/images/medium/4dfe05ec01bc7.jpg" mce_src="/custom/images/medium/4dfe05ec01bc7.jpg" height="338" width="426">&nbsp;</p><p><b>Step 3: Generate a QR code<br></b></p><p>Now you've got your URL, you need to convert it into a QR code. You can do this very easily, and automatically, using the <a href="http://code.google.com/apis/chart/image/docs/gallery/qr_codes.html" target="_blank" mce_href="http://code.google.com/apis/chart/image/docs/gallery/qr_codes.html">Google QR code API</a> or you can use my <a href="http://techpad.co.uk/custom/tools/qr_code_generator.php" mce_href="http://techpad.co.uk/custom/tools/qr_code_generator.php">QR Code Generator</a> which will also add the Google Analytics tracking parameters of your choice and shorten the URL for you.</p><p>If you want to use the API, as I am doing with my QR Code Generator, you'll need a little PHP function to handle the data and get the URL of the QR code image.&nbsp;</p><p>function generateQrCode($text,$size){<br>&nbsp; $url = "http://chart.apis.google.com/chart?cht=qr&amp;chs="</p><p>&nbsp;&nbsp; . $size . "x" . $size . "&amp;chl=" . urlencode($text) . "&amp;chld=H|0";<br>&nbsp; return $url;<br>} </p><p>Combine your string of text and the URL into the $text variable, define a size (say 400) and the function will pass this to the Google API and return the URL of your QR code.&nbsp; <br></p><p>The text you pass to the API needs to be UTF-8 and URL encoded. There's a 2K limit on the URL, which is another reason why it makes sense to use a URL shortener. </p><p><img src="/custom/images/medium/4dfe05818cfb4.jpg" mce_src="/custom/images/medium/4dfe05818cfb4.jpg" height="426" width="426">&nbsp;</p><p><b>Step 4: Test the QR code</b></p><p>Once you've put it all together you should have a QR code containing your string of text and the shortened URL. </p><p>Use the barcode scanner on your smartphone (the Android Barcode Scanner is great), point it at the screen and it should recognise the code and display the text and URL on the screen of your phone.&nbsp;</p><p>Click the shortened URL and it should redirect you to your target site, complete with the Google Analytics tracking codes appended to the end of the URL.&nbsp; </p><p><b>Step 5: Track the QR code in Google Analytics</b></p><p>When a user clicks the link in your QR code to follow it to the target site they'll first hit the shortened URL, which will subsequently redirect to your longer URL featuring the Google Analytics tracking parameters.&nbsp;</p><p>Your Google Analytics tracking code will automatically detect the presence of these in the URL of the landing page and will pass them back to your GA profile. </p><p>When you next visit your account profile, look under Traffic Sources &gt; Campaigns and you should see your QR Code campaign listed. </p><p><img src="/custom/images/medium/4dfe06c549712.jpg" mce_src="/custom/images/medium/4dfe06c549712.jpg" height="337" width="426">&nbsp;</p><p><b>Or...</b></p><p>Simply use my <a href="/custom/tools/qr_code_generator.php" mce_href="http://techpad.co.uk/custom/tools/qr_code_generator.php">QR Code Generator</a> which takes care of the URL shortening and adds the tracking parameters of your choice.&nbsp; <br></p>]]></description>
				<link><![CDATA[http://techpad.co.uk/content.php?sid=172&amp;utm_source=TechPad_website&amp;utm_medium=RSS&amp;utm_campaign=Item_172]]></link>
			</item>
	</channel>
</rss>

