Google Analytics API Authentication with C# 71


Google Analytics Have you been trying to connect your website or application to the Google Analytics API? Would you like to be able to show your users Google Analytics data for your website?   If you are you trying to work with the Google Analytics API in C# .net I might be able to help.   In this tutorial series, we will be looking into how to connect to Google Analytics API using OAuth2, as well as a service account. I will show you how to get a list of the users Accounts to display to them from the Google Analytics Management API. Using the Meta-data API you will be able to get a full up to date list of the current available metrics and dimensions to display to your users. Finally, we will look at getting data back from Google Analytics by using either the Real-time API or the Core reporting API.

Google Analytics API – Seven part Tutorial Series

  1. Google Analytics API Introduction
  2. Google Analytics API Authentication with C# OAuth2 vs Service Account
  3. Google Analytics Management API with C#Accounts, Web Properties and views(Profiles)
  4. Google Analytics Management API with C# – Advanced
  5. Google Analytics Management API with C# – Upload
  6. Google Analytics Meta-Data API with C# – Showing current dimensions and metrics
  7. Google Analytics Real-Time API with C# – Whats happening now!
  8. Google Analytics Core Reporting API with C#  – Its all about the data baby!

Project Setup

Make sure you create your Microsoft Visual Studio project and have it set to  .NET Framework .net 4.0 or .NET Framework 4.5.

Add the following NuGet Package

Google APIs Client Library for working with Analytics v3.

Supported Platforms:
– .NET Framework 4 and 4.5
– Windows Store apps
– Windows Phone 8 and 8.1
– Portable Class Libraries
To install Google.Apis.Analytics.v3 Client Library, run the following command in the Package Manager Console

PM> Install-Package Google.Apis.Analytics.v3

Usings

Microsoft Visual Studio project  will probably need most of these using’s

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.Apis.Analytics.v3;
using Google.Apis.Auth.OAuth2;
using System.Threading;
using Google.Apis.Util.Store;
using Google.Apis.Services;
using System.Security.Cryptography.X509Certificates;
using System.IO;

[wp_ad_camp_3]

Authenticating Google Analytics API With C#

Authentication is the key to everything here. If you want to be able to access data on Google Analytics from Microsoft Visual Studio using C# in most cases you will need to be authenticated.

The two types of Authentication you can use are:

  • Open Authentication or  OAuth2 – Which is designed to allow you to access other peoples data.   For Example: A user installs your application that will allow them to view their Google Analtyics Data, before your application can view their data the user will be asked to authenticate your application giving your application permission to access their data.
  • Service Account Authentication – Which is designed to allow you to access your own data.   For example: You would like to display a count of the number of page views a page on your website has had.   For this there is no reason to ask permission because you already own this data.

If you are unsure which type of authentication you need to use you can check out my authentication page which gives more detailed explanation into the different types.  I have created a separate tutorial that explains how to create the different credentials.  Decide which type of authentication you need and please read though that tutorial and come back to continue this one.

Types of Authentication

There are two types of Authentication OAuth2 which will allow you to access another users data, and a service account which can be set up to access your own data.   The code for them is slightly different.

OAuth2 Authentication

If you want to be able to access Google Analytics though the API owned by someone else you will need to be authenticated. The code for authentication simply displays a webpage for your user asking them to give you permission to access there data. If the user gives you permission a file is then stored on the machine in the %AppData% directory containing all the information you will need in the future to access there data. For my testing purpose I use Environment. UserName as the name of the user, but if you are doing this web based you could use it as a session var of some kind.

That’s just fine but how does Google know what kind of permission you want to ask the user for? That’s where scopes come in, with scopes you define what permissions you need.

The code below will basically ask for everything, you should only include the scopes you NEED.

Assuming the user clicks Accept and gives you permission you will then have a valid user credential you can build upon. The main problem you may have with this is that it is useing FileDataStore which stores the data in the users %AppData% directory while this is probably fine for an installed application this is probably not the optimal solution for a web application. If you want to store the data in the database you need to create your own implementation of IDataStore. You are in luck I have a working version of that on GitHub.

Service Account Authentication

[wp_ad_camp_1]If you are only accessing your own Google Analytics Account you own this data already, so there is no reason to ask a user for permission to access it. In this instance you should use a Service account. A service account is just like any other user who has been granted access to your Google Analytics data with one exception, its automatic. There will be no prompt for access.

Service Account Setup

Take the service account email address from the Google Developer console, we need to give this email address access to our Google Analytics Data. We do that by adding it as we would any other user in the Admin Section of the Google Analytics Website. Add the service account email address as a user at the account level it must be the account level. This will enable your service account access to the Google Analytics account in question. Did I mention it must be at the ACCOUNT Level?

Service Account Authentication

Now the keyfile that you downloaded from the Google Developer console contains all the information needed by your code to access google. We use the key file to set up our authentication.

Google Analytics Service

Now that you are authenticated its only a matter of passing your credentials to create a new AnalyticsService. The service is where all of the magic is. It is though the service that all of the calls will be made to the Google Analytics API.
Notice how we pass our credential to it.

Public API key

To my knowledge there is only one Public API associated with the Google Analytics APIs that is the MetaData API. The data in the MetaData API is public its free for anyone to access, because of that we don’t need to use OAuth2 or a service account you can create a public API key and create the analyticservice using that

Conclusion

You should now understand how to access the Google Analytics API with an authenticated user. Join me for the next tutorial where we will look at how to get a list of accounts – web properties and profiles for an authenticated Analytics Service.

If you had any problems with this tutorial you can check the a sample project for working with Google Analytics API on GitHub as part of the Google-Dotnet-Samples project. With in that project you will find a helper class for Authentication with Google Analytics. DaimtoAnalyticsAuthenticationHelper.cs

 

Previous Google Analytics API Introduction

Next Google Analytics Management API with C#


About Linda Lawton

My name is Linda Lawton I have more than 20 years experience working as an application developer and a database expert. I have also been working with Google APIs since 2012 and I have been contributing to the Google .Net client library since 2013. In 2013 I became a a Google Developer Experts for Google Analytics.

Leave a Reply to Linda Lawton Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

71 thoughts on “Google Analytics API Authentication with C#

  • Jai Nathani

    Hi Linda,
    Awesome posts you have here. They are really helpful. I just have a question.
    I am working on a website in which I would like to embed the GA charts and display them to the general public. I have been able to embed it and view the chart, however I am unsure as to how to make it public. I do not want the public to have any need to authorize themselves. It should just be come to the website and have a look at the charts. Is this possible?
    Thank you

  • Harel

    Great Tutorials! Kudos!
    Just a small issue I encountered and the relevant solution (Changing this might help other along the way):
    I had a problem when running this code on a server and not on my development machine.
    the solution was in my case to set the keyStorageFlags from X509KeyStorageFlags.Exportable
    to
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable

  • J

    Thanks for writing this walkthrough!

    With the changing state of APIs and Google not providing an official sample (that I could find), I couldn’t find an working sample anywhere. Thanks for this!

  • Murat

    Hi Linda,
    Thanks for writing this walkthrough!
    I have a console application. It takes report with Analytics API.
    I want running specific period on windows server in task schedule, but I didn’t find a solution auto skip OAuth steps.
    what can i do or how can i do

  • Costin

    Hi Linda,

    I’ve been using your code for a while, but I recently got stuck on something.

    I am using OAuth2 Authentication, and I have a CMS with multiple users, each with their own profiles. It happens that our company has a Google account with access to multiple Analytics accounts. For each user who uses the CMS, I connect to the Google Analytics API using a different username, and each user’s token is saved in a database data store. The problem is, if one user disconnects and revokes his token, none of the other users who use the same Google account will be able to access the Analytics API either, which doesn’t make sense.

    And another thing is, if one user authenticates to this Google account and consents to the terms, the subsequent users will still be asked to select the Google account, but will not be asked to consent anything anymore, even though they didn’t send a refresh token in the first place. This behavior is just weird…

  • sandy

    I am following your post and I use service account,and when I test it show that this use didn’t have any account. But in google analytics show that I have one account with property and views.

    My question is I test it on my local computer, is this need on life to test??

    • Linda Lawton

      You missed a section of the Tutorial. A service account is just like any other user it doesn’t have access to anything until you give it access.

      Then go to the Admin section of the Google Analytics Website give the Add the service account email address as a user at the account level it must be the account level. This will enable your service account access to the Google Analytics account in question.

  • sandy

    Hi Lina,

    When I debug it will show “ServiceAccountCredential.cs not found”. why? isn’t this should inside the google api client library??

    if I just go pass this, in the end will return this user don’t have any account, but I do have one account.

    I did all of this test in my local computer, does this will be the matter? should put on life test ?????

    Beg for help!!!!!!!!!!!!

    • Linda Lawton

      That is because you are trying to debug though a dll that’s already built. If you want to debug though the client library you are going to have to download the source code for the client library. Source

  • Seden Akman

    Hi Linda,Thank you very much for this tutorial. It is working perfectly in my localhost, but when I publish it, I get the following error:

    ExceptionType: “System.Security.Cryptography.CryptographicException” Message: “The system cannot find the file specified. ↵” StackTrace: ” at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) ↵ at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) ↵ at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags) ↵ at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags) ↵ at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags) ↵ at Thunder.Main.Default.Authenticate() ↵ at Thunder.Main.Default.GetChartData()”

    The file is there, and I am using a hosting , and I am afraid I don’t have access to IIS. Is there any way I can solve this? Thanks!

    • Linda Lawton

      Make sure the key file is in a place where IIS can access it. For testing purposes put it in the same directory as your project. Name it something weird if you are worried about security.

      • Seden Akman

        Hi Linda, thank you for your answer. The file was in the same directory,and I managed to access the key file adding an application pool tag to my asp.net config, but now this is the error I am getting

        {“Message”:”Access is denied.\r\n”,”StackTrace”:” at System.Security.Cryptography.X509Certificates.X509Store.Add(X509Certificate2 certificate)\r\n at Thunder.Main.Default.Authenticate()\r\n at Thunder.Main.Default.GetChartData()”,”ExceptionType”:”System.Security.Cryptography.CryptographicException”}

        I have trust level full on my web.config, and I reached out to my hosting provider to get access, but they told me i have a problem with my coding, and they’ve given me access.Thank you!

  • Siljith

    Hi Linda,

    Thank you very much for the tutorial. I hope I found a perfect solution I am looking. Unfortunately, I am getting an error while running the sample code you provided. When I run AccountSummaries feed = list.Execute(); I am getting an error “Unexpected character encountered while parsing value: <. Path '', line 0, position 0."
    I've done following
    1. Running application using Service account Authentication after creating my own Service account and adding this email to the google analytics user list with all permission.
    2.I'm refering .p12 file from my local "C " drive as @"C:\Projects\Key\MyWebsite-7f016e7c3562.p12";

    Can you please give some hint why I'm getting this error ?

    Many thanks in advance,
    Siljith

      • Siljith

        Hi Linda,
        Thanks for the reply. I’m using the sample code you provided in GitHub.The changes I made is as follows. I’ve commented Authenticate Oauth2 section and uncommented below given code and changed the service account email and key file path to match my account settings.

        //// Service account Authentication
        //String SERVICE_ACCOUNT_EMAIL = “2046123799103-6v9cj8jbub068jgmss54m9gkuk4q2qu8.apps.googleusercontent.com”;
        //string SERVICE_ACCOUNT_KEYFILE = @”c:\Diamto Test Everything Project-5381f306d5a1.p12″;
        //Service = DaimtoAnalyticsAuthenticationHelper.AuthenticateServiceAccount(SERVICE_ACCOUNT_EMAIL, SERVICE_ACCOUNT_KEYFILE);

        Any suggestion will be greatly appreciated.
        Siljith

  • Seden Akman

    Hi Linda, thank you for your answer. The file was in the same directory,and I managed to access the key file adding an application pool tag to my asp.net config, but now this is the error I am getting

    {“Message”:”Access is denied.\r\n”,”StackTrace”:” at System.Security.Cryptography.X509Certificates.X509Store.Add(X509Certificate2 certificate)\r\n at Thunder.Main.Default.Authenticate()\r\n at Thunder.Main.Default.GetChartData()”,”ExceptionType”:”System.Security.Cryptography.CryptographicException”}

    I have trust level full on my web.config, and I reached out to my hosting provider to get access, but they told me i have a problem with my coding, and they’ve told me I have access, but I am still getting this error.Would love to hear your advice.Thank you!

  • Brian Watkins

    FYI the link you had posted for the Nuget package has a type, you listed

    PM> Install-Package Google.Apis.Analytic.v3

    it should be

    PM> Install-Package Google.Apis.Analytics.v3

    Otherwise, very nice document!

  • Doug

    Linda, first of all: nice work with these tutorials.

    I am experiencing problems to reuse the AccessToken (granted OWin authentication process) in subsequent APIs calls. I opened a thread here (http://stackoverflow.com/questions/31036100/how-can-i-use-asp-net-mvc-owin-accesstoken-in-google-apis-call) but I think that no one will help me with this specific question.

    The problem is that I don´t want to put back the user in the authentication process once he is already authenticated.

    I’ve tried the Google’s example for Web Application (https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth), but the AuthorizationCodeMvcApp always return null in the first attempt (so it redirects back the user to the app’s authentication flow).

    I was wondering if DataStore could help me in some direction… If yes, I don’t know how.

    Thanks in advance.

    Douglas

  • Vijay Sutaria

    Hello Linda,

    Can you please guide me how to user google’s oAuth external token to access google analytic data offline ?

    Thanks in advance

  • Nelssen

    Hello Linda,

    Thanks for the explanation.
    I would like to authenticate and get the ga:visits (now ga:sessions) of my website.
    Do I need to Authenticate?
    I tried your code, but despite of i’m not being able of login I was prompt with a web page.
    Is it possible to Authenticate without getting an web page prompt?

    Thanks in Advance Linda

  • Paritosh

    what is FileDataStore(“Daimto.GoogleAnalytics.Auth.Store”)).Result?

    var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId,
    ClientSecret = clientSecret},
    scopes,
    Environment.UserName,
    CancellationToken.None,
    new FileDataStore(“Daimto.GoogleAnalytics.Auth.Store”)).Result;

    • Linda Lawton Post author

      FileDataStore is a data store that implements “IDataStore”. When used as part of the authentication process it creates and stores a different file for each of the users that authenticate your app. FileDataStore stores in JSON format of the specified object. By default the files are stored in %appdata%.

  • Paritosh

    Google Analytics working properly on my local machine for .Net project but not working properly with hosting with IIS(Hosting environment) for Same project.
    in hosting its unable to open google authentication screen or window(Login).
    Sample Code:

    string[] scopes = new string[] {
    AnalyticsService.Scope.Analytics,
    AnalyticsService.Scope.AnalyticsEdit,
    AnalyticsService.Scope.AnalyticsManageUsers,
    AnalyticsService.Scope.AnalyticsReadonly};
    var clientId = “xxxxxx”;
    var clientSecret = “xxxx”;

    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets
    {
    ClientId = clientId,
    ClientSecret = clientSecret
    },
    scopes,
    Environment.UserName,
    CancellationToken.None,
    new FileDataStore(folder)).Result;

  • Martin

    Hi,

    Awesome post! Very useful.

    Whenever I call the Column.Id it returns something like ga:XXX but no actual values.

    Do you know how I can fix this?

    Thank you

  • James EJ

    Hi Linda

    Thanks for doing this very valuable work. I am trying to access the API via an AnalyticsService using your code, with a .p12 file, however when I actually try and access anything using the AnalyticsService created, the .Execute call just hangs. I can’t get any information about what is happening. I tried the version using the API Key and this actually works perfectly which would seem to indicate my ServiceAccountCredential has something wrong with it. I’ve turned off the local firewall on this machine (I’m testing this on IIS localhost), and still no luck. Could the X509Certificate2 constructor be silently failing to read the file for some reason?

    Thanks
    James

    • Linda Lawton Post author

      Make a dummy request to the api using the client library and credentials will have an access token. This is the only way i have found to fetch an access token for use like this.

  • Gijs Mater

    Hi,

    Is it correct the class GoogleWebAuthorizationBroker wont work in a web aplication after publish? I believe it work perfectly when running localhost but after running it on a IIS server it wont open the google popup bequase its trying to do it on the IIS server.

  • Brad

    Hi Linda

    Thank you so much for these explanations and tutorials. I set this up in a C# console project and it worked wonderfully. However, I have tried to move it to an WCF web service on IIS (running on local machine for the moment) and get a weird issue in the GoogleWebAuthorizationBroker.AuthorizeAsync method. Basically I get a “source not found” window specifying (namley “FileDataStore.cs not found”).
    In the “Source Search Information” it shows a folder that does not exist on my machine (C:\Users\XXXX\Documents\GitHub\google-api-dotnet-client\Src\GoogleApis.DotNet4\Apis\Util\Store\FileDataStore.cs), XXXX replaces user name listed (who likely wrote the some the the Google API reference). I have tried replacing the %appData% location with a physical location and get the same issue.

    Is this possibly a permission issue?

    I noticed you wrote in a comment below to make “IIS has permissions” but I’m still stumped!!

    Cheers
    Brad

    • Linda Lawton Post author

      I think its probably an issue iwth permissions but make sure that you imported the NuGet again to be sure all the dlls are there. Then check out this tutorial

      Something like this: new FileDataStore(@”c:\datastore”,true)

      • Brad

        Hi Linda,
        Appreciate your response. Have re-installed the NuGet and the issue persists :(. I also moved to the Service Account Authentication setup, probably more suitable to my needs, and now get the could not find “ServiceAccountCredential.cs” instead. I noticed in another post you mentioned that there is likely something wrong with the project. If it is possibly a permissions issue, would this need to be configured in IIS or maybe the app.config file?
        Cheers

  • abdel

    Hi,
    Thanks you for your code. I have an asp.net Mvc5 project and I use the authentification by service account but this code doesn’t works => AnalyticsService service = new AnalyticsService(new BaseClientService.Initializer()
    {
    HttpClientInitializer = credential,
    ApplicationName = “Analytics API Sample”,
    });
    Error : Cannot implicitly convert type ‘Google.Apis.Auth.OAuth2.ServiceAccountCredential’ to ‘Google.Apis.Http.IConfigurableHttpClientInitializer’.
    Can you help me?

      • Taufiq

        Hi Linda,

        Thank you for your very informative post. The only trouble I am having at the moment is shared with Abdel’s comment above. I have reread the ‘Service Account’ tutorial but can’t seem to understand why I am getting the “Error : Cannot implicitly convert type ‘Google.Apis.Auth.OAuth2.ServiceAccountCredential’ to ‘Google.Apis.Http.IConfigurableHttpClientInitializer’. Is there something I am missing? I have tried all sorts of different casts to match up the datatypes, but with no avail.

        Any help will go a long way. Thanks!

  • RredCat

    I am trying to use this logic for my asp.net mvc apps and I am in stuck a bit.
    I created OAuth credential added your code to my action with credential and tried to run.
    I get the error:
    Error: redirect_uri_mismatch
    The redirect URI in the request: http://localhost:49200/authorize/ did not match a registered redirect URI.
    Url is strange for me, because I am using another port.

    I feel that I missed something and will be appreciate if anybody shows me the right way to do it.

    I tried different ip address for my keys it doesn’t help.

    • Linda Lawton Post author

      Visual studio debug thing automaticly adds a port on it. Try googling how to get it to stop doing that i cant remember exactly. try and set redirect uri to http://localhost/authorize that might work to.

      If all else fails create a native client Oauth2 and use that for debugging just dont release it to production with that.

  • JR

    Linda – When I run this on my local machine in the IDE it works great. When I push to Azure, it doesn’t work… I’ve debugged the entire service layer solution and found that its at the certificate line that it breaks… Any suggestions?

    var keyFilePath = HttpContext.Current.Server.MapPath(“~/Files/filename.p12”);

    //loading the Key file
    var certificate = new X509Certificate2(keyFilePath, “notasecret”, X509KeyStorageFlags.Exportable);

  • Hadi

    Hi Linda,

    First of all, I would say this is a great tutorial. Thank you for writing this, it helped me a lot when create a web service to get data from google analytics.

    However, I am having a bit issue when running the code on the production site. Based on the error message I got, it says “The underlying connection was closed: An unexpected error occurred on a receive”.

    I’m not sure if this is an issue with the API or the security setting on the production site, since it works properly on other environments such as in my Internal QA, Staging and UAT sites, but not in the production.

    I would like to know if have experienced the same issue when implementing GA API in a web service.

    Or do you have any other tutorial to get GA data using c# webclient instead of using client library ?

    Thank you for you help.

    Regards,

    Hadi

    • Linda Lawton Post author

      I have seen this error a few weeks ago on my development machine. Kaspersky updated something and the built in fire wall was blocking Googles authentication servers. It worked on everyone machine but mine, apparently the sys admin who sits in the office next to me decided my pc world be a great test case for something.

      Turn off the fire wall and anti virus on your server for a minute test that it works. If it does work tell your sys admin, mine is out of the office this week. For the life of me I cant remember what he said he had to disable. Not that i would actually have understood it if he did try and explain it to me. However I can try and ask him next week what it was, i should probably do that so that we can document the issue and note a fix for it.

  • RedEye

    DO NOT USE “STATIC” IN ASP.NET MVC
    w3wp.exe has CPU 100% in mvc, What’s problem? I dont know
    but use the STATIC works fine in the LOCAL SYSTEM(eg Windows Service, Console APP).

    //static ServiceAccountCredential(){
    private ServiceAccountCredential(){
    ,,,,
    var certificate = new X509Certificate2(keyFilePath, “notasecret”, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
    var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
    {
    Scopes = scopes
    }.FromCertificate(certificate));

    return credential;
    }

  • Larss

    Hi Linda, there is very little guidence online so I’m very grateful that you’ve taken the time to write these tutorials. I’m hoping to be able to intergrate CRM data with Google Analytics for a DNN module.
    I suspect things have moved on since 2014 so I’ve been reading various StackOverflow posts for assistance, are there any potential roadblocks ahead following your tutorials or should it all hopefully still work?

    many thanks!