Search code examples
c#.netgoogle-apigoogle-analytics-api

Use Google Analytics API to show information in C#


I have been looking for a good solution all day, but Google evolves so fast that I can't find something working. What I want to do is that, I have a Web app that has an admin section where user need to be logged in to see the information. In this section I want to show some data from GA, like pageviews for some specific urls. Since it's not the user information that I'm showing but the google analytics'user I want to connect passing information (username/password or APIKey) but I can't find out how. All the sample I found use OAuth2 (witch, if I understand, will ask the visitor to log in using google).

What I found so far :

Maybe I'm just tired and that tomorrow it will be easy to find a solution but right now I need help!

Thanks


Solution

  • I did a lot of search and finally either looking up code from multiple places and then wrapping my own interface around it i came up with the following solution. Not sure if people paste their whole code here, but i guess why not save everyone else time :)

    Pre-requisites, you will need to install Google.GData.Client and google.gdata.analytics package/dll.

    This is the main class that does the work.

    namespace Utilities.Google
    {
        public class Analytics
        {
            private readonly String ClientUserName;
            private readonly String ClientPassword;
            private readonly String TableID;
            private AnalyticsService analyticsService;
    
            public Analytics(string user, string password, string table)
            {
                this.ClientUserName = user;
                this.ClientPassword = password;
                this.TableID = table;
    
                // Configure GA API.
                analyticsService = new AnalyticsService("gaExportAPI_acctSample_v2.0");
                // Client Login Authorization.
                analyticsService.setUserCredentials(ClientUserName, ClientPassword);
            }
    
            /// <summary>
            /// Get the page views for a particular page path
            /// </summary>
            /// <param name="pagePath"></param>
            /// <param name="startDate"></param>
            /// <param name="endDate"></param>
            /// <param name="isPathAbsolute">make this false if the pagePath is a regular expression</param>
            /// <returns></returns>
            public int GetPageViewsForPagePath(string pagePath, DateTime startDate, DateTime endDate, bool isPathAbsolute = true)
            {
                int output = 0;
    
                // GA Data Feed query uri.
                String baseUrl = "https://www.google.com/analytics/feeds/data";
    
                DataQuery query = new DataQuery(baseUrl);
                query.Ids = TableID;
                //query.Dimensions = "ga:source,ga:medium";
                query.Metrics = "ga:pageviews";
                //query.Segment = "gaid::-11";
                var filterPrefix = isPathAbsolute ? "ga:pagepath==" : "ga:pagepath=~";
                query.Filters = filterPrefix + pagePath;
                //query.Sort = "-ga:visits";
                //query.NumberToRetrieve = 5;
                query.GAStartDate = startDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
                query.GAEndDate = endDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
                Uri url = query.Uri;
                DataFeed feed = analyticsService.Query(query);
                output = Int32.Parse(feed.Aggregates.Metrics[0].Value);
    
                return output;
            }
    
            public Dictionary<string, int> PageViewCounts(string pagePathRegEx, DateTime startDate, DateTime endDate)
            {
                // GA Data Feed query uri.
                String baseUrl = "https://www.google.com/analytics/feeds/data";
    
                DataQuery query = new DataQuery(baseUrl);
                query.Ids = TableID;
                query.Dimensions = "ga:pagePath";
                query.Metrics = "ga:pageviews";
                //query.Segment = "gaid::-11";
                var filterPrefix = "ga:pagepath=~";
                query.Filters = filterPrefix + pagePathRegEx;
                //query.Sort = "-ga:visits";
                //query.NumberToRetrieve = 5;
                query.GAStartDate = startDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
                query.GAEndDate = endDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
                Uri url = query.Uri;
                DataFeed feed = analyticsService.Query(query);
    
                var returnDictionary = new Dictionary<string, int>();
                foreach (var entry in feed.Entries)
                    returnDictionary.Add(((DataEntry)entry).Dimensions[0].Value, Int32.Parse(((DataEntry)entry).Metrics[0].Value));
    
                return returnDictionary;
            }
        }
    }
    

    And this is the interface and implementation that i use to wrap it up with.

    namespace Utilities
    {
        public interface IPageViewCounter
        {
            int GetPageViewCount(string relativeUrl, DateTime startDate, DateTime endDate, bool isPathAbsolute = true);
            Dictionary<string, int> PageViewCounts(string pagePathRegEx, DateTime startDate, DateTime endDate);
        }
    
        public class GooglePageViewCounter : IPageViewCounter
        {
            private string GoogleUserName
            {
                get
                {
                    return ConfigurationManager.AppSettings["googleUserName"];
                }
            }
    
            private string GooglePassword
            {
                get
                {
                    return ConfigurationManager.AppSettings["googlePassword"];
                }
            }
    
            private string GoogleAnalyticsTableName
            {
                get
                {
                    return ConfigurationManager.AppSettings["googleAnalyticsTableName"];
                }
            }
    
            private Analytics analytics;
    
            public GooglePageViewCounter()
            {
                analytics = new Analytics(GoogleUserName, GooglePassword, GoogleAnalyticsTableName);
            }
    
            #region IPageViewCounter Members
    
            public int GetPageViewCount(string relativeUrl, DateTime startDate, DateTime endDate, bool isPathAbsolute = true)
            {
                int output = 0;
                try
                {
                    output = analytics.GetPageViewsForPagePath(relativeUrl, startDate, endDate, isPathAbsolute);
                }
                catch (Exception ex)
                {
                    Logger.Error(ex);
                }
    
                return output;
            }
    
            public Dictionary<string, int> PageViewCounts(string pagePathRegEx, DateTime startDate, DateTime endDate)
            {
                var input = analytics.PageViewCounts(pagePathRegEx, startDate, endDate);
                var output = new Dictionary<string, int>();
    
                foreach (var item in input)
                {
                    if (item.Key.Contains('&'))
                    {
                        string[] key = item.Key.Split(new char[] { '?', '&' });
                        string newKey = key[0] + "?" + key.FirstOrDefault(k => k.StartsWith("p="));
    
                        if (output.ContainsKey(newKey))
                            output[newKey] += item.Value;
                        else
                            output[newKey] = item.Value;
                    }
                    else
                        output.Add(item.Key, item.Value);
                }
                return output;
            }
    
            #endregion
        }
    }
    

    And now the rest is the obvious stuff - you will have to add the web.config values to your application config or webconfig and call IPageViewCounter.GetPageViewCount