Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

.NET Library for Accessing and Querying Google Analytics V3 via Service Account

0.00/5 (No votes)
30 Jan 2014 2  
Simple Google Analytics Access, with Service Account Credential OAuth2

Introduction

Simply .NET Project for Google Analytics API v3 Usage

Tired of looking for help, things isn't really working for you! get started to analytics quickly from here. Want to work with analytics the way it should be, that's the place for you.

This article will give you a quick jump to analytics and using it with Simple Analytics open source library that provides a framework on top of the .NET Google Analytics API, simplifying the access, retrieval and working with the Reporting API in a simple way

Background

First you need to configure your Google developer account and register a project in the cloud console.

ps. those instructions are using the new console for old console users you'll find same things but some are under different names in the menu

  1. create an account on Google Cloud Console
  2. Create a new Project from the console or select an existing project
  3. Under APIs and Auths : Enable the Analytics API
  4. Go to Credentials Page
    1. Create New Client ID
    2. Select Service Account
    3. you will be prompted to download a Key file store it some where safe as we'll be using it in authentication
    4. A table for service account credentials will be displayed to you containing Client ID, Email address, and public key finger prints
  5. Copy the email address then login in to your Analytics Web Account
    1. Go the Admin Section under it select the profile you want to access and under user accounts paste the email provided to you
    2. It's important to do that on both the profile (site) and the account
  6. Go to git hub and download the Simple Analytics Library
  7. In Visual Studio select the project you want to work on add the Analytics.dll library to it
  8. Run the following command under
Package Manager Console from : Tools -> Library Package Manager -> Package Manager Console

and execute the below command this will install and reference the google analytics API in your project

PM> Install-Package Google.Apis.Analytics.v3 -Pre [PROJECT_NAME] 

ok now you're ready to go

Using the code

Using the library is simple first you need to authenticate your self using the Google Service OAuth2 one line is required, please note that the email below is the email provided to you in the console service account section

Analytics.AnalyticsManager manager = new Analytics.AnalyticsManager(Server.MapPath("~/bin/privatekey.p12"), "YOUR_EMAIL"); 

Now we need to query the profiles you have access to, and set a default Profile to work with you could get the number of the profile from the analytics url it's the number after p

https://www.google.com/analytics/web/?hl=en#management/Settings/a32880022w60002165p61347423/

manager.LoadAnalyticsProfiles();<br />
manager.SetDefaultAnalyticProfile("80425770");

now we set the metrics and dimensions, a complete Reporting API Commands are placed in the project so you could easily set metrics and dimensions

List<Analytics.Data.DataItem> metrics = new List<Analytics.Data.DataItem>();
metrics.Add(Analytics.Data.Visitor.Metrics.visitors);
metrics.Add(Analytics.Data.Session.Metrics.visits);
List<Analytics.Data.DataItem> dimensions = new List<Analytics.Data.DataItem>();
dimensions.Add(Analytics.Data.GeoNetwork.Dimensions.country);
dimensions.Add(Analytics.Data.GeoNetwork.Dimensions.city);  

now you're done get a table with analytics data

System.Data.DataTable table = manager.GetGaDataTable(DateTime.Today.AddDays(-3),DateTime.Today, metrics, dimensions, null, metrics); 

that's it you could easily get any API data by changing/adding the metrics and dimensions properties

Library Implementation

The library implementation has a major class player called AnalyticsManager the analytics manager allows to initiate an authentication through OAuth2 Service Account Authentication

var certificate = new X509Certificate2(certificateKeyPath, "notasecret", X509KeyStorageFlags.Exportable);
string x = certificate.IssuerName.Name;
credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(apiEmail)
    {
                    Scopes = new[] { Google.Apis.Analytics.v3.AnalyticsService.Scope.Analytics }
        }.FromCertificate(certificate));

analyticsService = new Google.Apis.Analytics.v3.AnalyticsService(new BaseClientService.Initializer()
    {
            HttpClientInitializer = credential,
                    ApplicationName = "Jareeda"
        });

a certificate is created from the passed key the notasecret password is the same password for all key files from google nevertheless the signature differs in the key it self so the combination gives different signatures.

a service account credential is initialized and passed to it the Scope "Analytics" that's an enumerator where you could change it to AnalyticsReadOnly, AnalyticsEdit, AnalyticsManageUsers each will give you different access rights, depending on the permissions given from the Analytics Web.

an AnalyticsService object is then created this object will be used for querying along the class afterword

analytics methods require you pass a table_id or a profile_id

public System.Data.DataTable GetGaDataTable(DateTime startDate, DateTime endDate, List<Data.DataItem> metricsList, List<Data.DataItem> dimensionsList, List<Data.DataItem> filtersList, int? maxResults, Google.Apis.Analytics.v3.DataResource.GaResource.GetRequest.OutputEnum? output, Google.Apis.Analytics.v3.DataResource.GaResource.GetRequest.SamplingLevelEnum? samplingLevel, List<Data.DataItem> segmentList, List<Data.DataItem> sortList, int? startIndex, List<Data.DataItem> fieldsList)
        {
            if (DefaultProfile == null)
                throw new Exception("Please set a default profile first using SetDefaultAnalyticProfile method");
            
            Google.Apis.Analytics.v3.Data.GaData gaData = GetGaData("ga:" + DefaultProfile.Id, startDate, endDate, Data.DataItem.GetString(metricsList), Data.DataItem.GetString(dimensionsList), Data.DataItem.GetString(filtersList), maxResults, output, samplingLevel, Data.DataItem.GetString(segmentList), Data.DataItem.GetString(sortList), startIndex, Data.DataItem.GetString(fieldsList));
            System.Data.DataTable table = BuildTableColumns(metricsList, dimensionsList);
            if(gaData != null)
                table = BuildTableRows(gaData, table);
            return table;
        }

in this method I pass the max parameters needed for retrieving GaData from analytics API where the passed DataItem List are the complete Dimensions and Metrics List Organized By Category based on the Google Complete Metrics and Dimensions Reference Guide I have parsed the complete guide and created an XML File for all the dimensions and metrics

<DataCategory Name="Session">
    <ItemType Name="Dimensions" Value="1">
      <DataItem Name="visitLength" APICommand="ga:visitLength" WebViewName="Visit Duration" AppViewName="Session Duration" DataType="STRING" AllowedInSegments="True">The length of a visit to your property measured in seconds and reported in second increments. The value returned is a string.</DataItem>
    </ItemType>
    <ItemType Name="Metrics" Value="2">
      <DataItem Name="visits" APICommand="ga:visits" WebViewName="Visits" AppViewName="Sessions" DataType="INTEGER" AllowedInSegments="True">Counts the total number of sessions.</DataItem>
      <DataItem Name="bounces" APICommand="ga:bounces" WebViewName="Bounces" AppViewName="" DataType="INTEGER" AllowedInSegments="True">The total number of single page (or single engagement hit) sessions for your property.</DataItem>
      <DataItem Name="timeOnSite" APICommand="ga:timeOnSite" WebViewName="Visit Duration" AppViewName="Session Duration" DataType="TIME" AllowedInSegments="True">The total duration of visitor sessions represented in total seconds.</DataItem>
    </ItemType>
    <ItemType Name="Calculated" Value="3">
      <DataItem Name="visitBounceRate" APICommand="ga:visitBounceRate" WebViewName="Bounce Rate" AppViewName="" DataType="PERCENT" AllowedInSegments="False">The percentage of single-page visits (i.e., visits in which the person left your property from the first page). (ga:bounces / ga:visits ) </DataItem>
      <DataItem Name="avgTimeOnSite" APICommand="ga:avgTimeOnSite" WebViewName="Avg. Visit Duration" AppViewName="Avg. Session Duration" DataType="TIME" AllowedInSegments="False">The average duration visitor sessions represented in total seconds. (ga:timeOnSite / ga:visits ) </DataItem>
    </ItemType>
  </DataCategory> 

placed the XML file in the resources of the project and generated Classes based on the Categories containing Classes of Metrics and Dimensions for each that contains DataItem Objects which contains the definition of the complete properties for the commands retrieving properties from the XML Resource File - giving it the flavor of .NET Resources usage.

 

all public variables placed in classes like Session, Visitor etc. have description attribute above taken from the analytics API so you could reference features easily without having to get back to the API that allows you to reference features in code with intellisense on it

List<Analytics.Data.DataItem> metrics = new List<Analytics.Data.DataItem>();
metrics.Add(Analytics.Data.Session.Metrics.visits);
metrics.Add(Analytics.Data.Visitor.Metrics.newVisits);

List<Analytics.Data.DataItem> dimensions = new List<Analytics.Data.DataItem>();
dimensions.Add(Analytics.Data.GeoNetwork.Dimensions.country);
dimensions.Add(Analytics.Data.Time.Dimensions.month); 

there are other 4 Overloaded Methods for the GetGaDataTable mentioned above

 DataTable GetGaDataTable(DateTime startDate, DateTime endDate, List<Data.DataItem> metricsList)
DataTable GetGaDataTable(DateTime startDate, DateTime endDate, List<Data.DataItem> metricsList, List<Data.DataItem> sortList)
DataTable GetGaDataTable(DateTime startDate, DateTime endDate, List<Data.DataItem> metricsList, List<Data.DataItem> dimensionsList, List<Data.DataItem> filtersList, List<Data.DataItem> sortList)
DataTable GetGaDataTable(DateTime startDate, DateTime endDate, List<Data.DataItem> metricsList, List<Data.DataItem> dimensionsList, List<Data.DataItem> filtersList, Google.Apis.Analytics.v3.DataResource.GaResource.GetRequest.SamplingLevelEnum? samplingLevel, List<Data.DataItem> sortList, List<Data.DataItem> fields) 

the returned data table contains not just the data but preserving the data types of the data too, so string, integer, float etc. types are assigned to the columns this means you could bind it directly and start operating on the tables  

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here