Read Google Analytics reports using C# console app

Read Google Analytics reports using C# console app

💡
Starting July 1, 2023 Universal Analytics is no longer supported by Google Analytics. For reading GA4 reports please refer https://kumarvikram.com/get-ga4-report-net/

I was recently given a task to build an app to read Google Analytics data from a C# console app and the app can be scheduled to run every day.
I was successful in creating and POC and demonstrate it. Today I will be sharing the step by step guideline of how I did this. It was my first experience of interacting with Google Analytics .net API.

The whole process can be categorized into two main activities

Setup required credentials in Google Developer Console
  1. Login to Google Developer console with your Google account
  2. Create a new project. It will take couple of seconds. The notification icon at top will tell you when it is ready.
  3. Go to your project dashboard and then select “Go to APIs overview”
  4. Click “ENABLE APIS AND SERVICES”. It will take you to API library page.
  5. Search for “analytics” and choose “Google Analytics Reporting API” from results.
  6. Click “Enable” on API page.
  7. It will prompt you to setup credentials in order to use this API.
  8. Select required options to create appropriate credentials. As we are going to access information from a console application and later it has to be scheduled as a job, we have selected the option “Other non-UI…”
  9. Create service account. “Service account has capability to interact with Google services without requiring user consent, so ideal choice to use with console application”. Note down the Service Account Id, we would need to authorize this user in our Google Analytics panel.
  10. Clicking on “Continue” will download the key file in JSON format and show the confirmation prompt.
  11. Authorize this newly created service account in Google Analytics.
    Go to Admin section of your application in Google Analytics. Select the appropriate view and “User Management” option.

    Add service account ID email

    Add appropriate permission. Here I just want to give access of reading and analyzing reports.
    Click “Add” and you are done.
Building the console application and read reports
  1. Create a C# console app in Visual Studio. I have named it as “GAReportExtractor”.
  2. Install Google.Apis.AnalyticsReporting.v4 nuget package. It will install the nuget package with all dependencies.
  3. Copy key file generated at step 10 to project folder. Go to file properties and set “Copy to Output Directory”
    property to “Copy always”. Missing this step will not copy the key file to bin folder and you will get file not found error on execution.
  4. Get View Id from Google Analytics dashboard by choosing View Setting.
  5. Store key file name and View Id in App.config so that it can be updated as per the environment without requiring any code change.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="KeyFileName" value="Your key file name here"/>
        <add key="ViewId" value="Your ViewId here"/>
      </appSettings>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
        </startup>
    </configuration>
    
  6. Create ReportManager.cs to separate the logic of API initialization and call.
    using Google.Apis.AnalyticsReporting.v4;
    using Google.Apis.AnalyticsReporting.v4.Data;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Services;
    using System.Configuration;
    using System.IO;
    
    namespace GAReportExtractor.App
    {
        public class ReportManager
        {
            /// <summary>
            /// Intializes and returns Analytics Reporting Service Instance using the parameters stored in key file
            /// </summary>
            /// <param name="keyFileName"></param>
            /// <returns></returns>
            private static AnalyticsReportingService GetAnalyticsReportingServiceInstance(string keyFileName)
            {
                string[] scopes = { AnalyticsReportingService.Scope.AnalyticsReadonly }; //Read-only access to Google Analytics
                GoogleCredential credential;
                using (var stream = new FileStream(keyFileName, FileMode.Open, FileAccess.Read))
                {
                    credential = GoogleCredential.FromStream(stream).CreateScoped(scopes);
                }
                // Create the  Analytics service.
                return new AnalyticsReportingService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "GA Reporting data extraction example",
                });
            }
    
            /// <summary>
            /// Fetches all required reports from Google Analytics
            /// </summary>
            /// <param name="reportRequests"></param>
            /// <returns></returns>
            public static GetReportsResponse GetReport(GetReportsRequest getReportsRequest)
            {
                var analyticsService = GetAnalyticsReportingServiceInstance(ConfigurationManager.AppSettings["KeyFileName"]);
                return analyticsService.Reports.BatchGet(getReportsRequest).Execute();
            }
        }
    }
    
  7. Program.cs, the final piece of code where we are combining it all together and executing to get the appropriate report.
    using Google.Apis.AnalyticsReporting.v4.Data;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    
    namespace GAReportExtractor.App
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    #region Prepare Report Request object 
                    // Create the DateRange object. Here we want data from last week.
                    var dateRange = new DateRange
                    {
                        StartDate = DateTime.UtcNow.AddDays(-7).ToString("yyyy-MM-dd"),
                        EndDate = DateTime.UtcNow.ToString("yyyy-MM-dd")
                    };
                    // Create the Metrics and dimensions object.
                    var metrics = new List<Metric> { new Metric { Expression = "ga:sessions", Alias = "Sessions" } };
                    var dimensions = new List<Dimension> { new Dimension { Name = "ga:pageTitle" } };
    
                    //Get required View Id from configuration
                    var ViewId = ConfigurationManager.AppSettings["ViewId"];
    
                    // Create the Request object.
                    var reportRequest = new ReportRequest
                    {
                        DateRanges = new List<DateRange> { dateRange },
                        Metrics = metrics,
                        Dimensions = dimensions,
                        ViewId = ViewId
                    };
                    var getReportsRequest = new GetReportsRequest();
                    getReportsRequest.ReportRequests = new List<ReportRequest> { reportRequest };
                    #endregion
                    
                    //Invoke Google Analytics API call and get report
                    var response = ReportManager.GetReport(getReportsRequest);
    
                    //Print report data to console
                    PrintReport(response);
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    Console.ReadLine();
                }
            }
            private static void PrintReport(GetReportsResponse response)
            {
                foreach (var report in response.Reports)
                {
                    var rows = report.Data.Rows;
                    ColumnHeader header = report.ColumnHeader;
                    var dimensionHeaders = header.Dimensions;
                    var metricHeaders = header.MetricHeader.MetricHeaderEntries;
                    if (!rows.Any())
                    {
                        Console.WriteLine("No data found!");
                        return;
                    }
                    else
                    {
                        foreach (var row in rows)
                        {
                            var dimensions = row.Dimensions;
                            var metrics = row.Metrics;
                            for (int i = 0; i < dimensionHeaders.Count && i < dimensions.Count; i++)
                            {
                                Console.WriteLine(dimensionHeaders[i] + ": " + dimensions[i]);
                            }
                            for (int j = 0; j < metrics.Count; j++)
                            {
                                DateRangeValues values = metrics[j];
                                for (int k = 0; k < values.Values.Count && k < metricHeaders.Count; k++)
                                {
                                    Console.WriteLine(metricHeaders[k].Name + ": " + values.Values[k]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
  8. And we are done! Here we are trying to get all user sessions and the related page titles during last seven days. You can adjust the time range or change the required metrics and dimensions as per your requirement. For more information on metrics and dimensions, see Dimensions & Metrics Explorer.

Thanks for reading. Hope it could be of any help to you.

Download Sample Code used in this post