0
votes

I'm trying to extract some data from Google Analytics API. However i'm getting a 403 error when i run the application saying -Execution of request failed: https://www.google.com/analytics/feeds/data?ids=ga:12345678&dimensions=ga:date&metrics=ga:visits&start-date=2014-02-16&end-date=2014-02-19&sort=ga:day

I'm not sure if something is wrong with the code or the URL?

This line is causing the error:

return service.Query(dataQuery);

This is the error in browser:

The remote server returned an error: (403) Forbidden.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Net.WebException: The remote server returned an error: (403) Forbidden.

Analytics class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Google.GData.Analytics;
using GoogleChartSharp;
using Nop.Admin.Models;

namespace Nop.Web.Models
{
    public static class Analytics
    {    
        private const int IMAGE_WIDTH = 900;
        private const int IMAGE_HEIGHT = 200;
        private const string DATAFEED_URL = "https://www.google.com/analytics/feeds/data?ids=ga:12345678&dimensions=ga:date&metrics=ga:visits&start-date=2014-02-16&end-date=2014-02-19";    
        private const string USERNAME = "[email protected]";
        private const string PASSWORD = "mypassword!";
        private const string PROFILE_ID = "ga:12345678";              

        private static DataFeed AnalyticsVisitorsThisMonth()
        {
            // Google Analytics Service. The name dosnt mather.
            var service = new AnalyticsService("WebSiteAnalytics");

            // Add your credentials
            service.setUserCredentials(USERNAME, PASSWORD);

            // The Data Query (What to fetch from google analytics)
            // Read more about it here: http://code.google.com/intl/sv-SE/apis/analytics/
            var dataQuery = new DataQuery(DATAFEED_URL)
            {
                Ids = PROFILE_ID,
                Metrics = "ga:visits",
                Sort = "ga:day",
                Dimensions = "ga:day",
                GAStartDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("yyyy-MM-dd"),
                GAEndDate = DateTime.Now.ToString("yyyy-MM-dd")
            };

            return service.Query(dataQuery);
        }


        private static int[] FixChartData(List<int> data, out int iMax)
        {
            List<int> chartData = new List<int>();

            iMax = data.Max();
            iMax = (int)(Math.Ceiling(iMax / 10.0d) * 10);

            foreach (var i in data)
            {
                chartData.Add((int)(((double)61 / (double)iMax) * i));
            }

            for (int i = chartData.Count; i < 32; i++)
            {
                chartData.Add(0);
            }
            return chartData.ToArray();
        }


        public static string VisitorsThisMonth()
        {
            // Fetch the datafeed from google analytics
            DataFeed df = AnalyticsVisitorsThisMonth();

            List<int> data = new List<int>();
            int[] chartData;
            int iMax = 1;

            // Create a list of values
            foreach (var ae in df.Entries)
            {
                data.Add(int.Parse(((DataEntry)(ae)).Metrics[0].Value));
            }

            // Fix the data (max value = 61) and add coming days of the month.
            chartData = FixChartData(data, out iMax);

            // Create the chart, here you can laborite yourself
            LineChart chart = new LineChart(IMAGE_WIDTH, IMAGE_HEIGHT, LineChartType.SingleDataSet);
            chart.SetData(chartData.ToArray());
            chart.AddFillArea(new FillArea("ACC3FF", 0));
            chart.SetDatasetColors(new string[] { "000000" });
            chart.SetLegend(new string[] { "Visitors" });

            chart.SetTitle("Visitors this month", "000000", 14);


            ChartAxis leftAxis = new ChartAxis(ChartAxisType.Left);
            leftAxis.SetRange(0, (int)(Math.Ceiling(iMax / 10.0d) * 10));
            chart.AddAxis(leftAxis);

            ChartAxis bottomAxis = new ChartAxis(ChartAxisType.Bottom);
            bottomAxis.SetRange(1, 31);
            chart.AddAxis(bottomAxis);

            return chart.GetUrl();
        }

    }
}

ShopStatisticsController:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Nop.Admin.Models.ShopStatistics;
using Google.GData.Analytics;
using GoogleChartSharp;
using Nop.Web.Models;

namespace Nop.Admin.Controllers
{

    public class ShopStatisticsController : Controller
    {
        //
        // GET: /ShopStatistics/

        public ActionResult Company()
        {
            return View();
        }

    }
}

Company view:

@using Telerik.Web.Mvc.UI
@using GoogleAnalyticsTracker;
@using Google;
@using GoogleAnalyticsTracker.Web.Mvc;
@{
    ViewBag.Title = "Company";
    Layout = "~/Views/Shared/_AdminLayout.cshtml";
}

<h2>Company</h2>


<img src="@Nop.Web.Models.Analytics.VisitorsThisMonth()" alt="Visitors this month" />
2

2 Answers

1
votes

403 means you probably don't have the rights to read the data. If you're sure you're using correct username/password, make sure that the profile ID is also correct.

When you login to analytics, your URL looks something like https://www.google.com/analytics/web/?hl=en-GB#home/aXXXXXXXXwYYYYYYYYpZZZZZZZZ/

Make sure the number you assigned to PROFILE_ID is the number after 'p' ("ga:ZZZZZZZZ" in my case).

If this doesn't help you I'd recommend you switch to OAuth authentication, as the old way you're using is deprecated by Google and is not guaranteed to work.

0
votes

I don't believe that Client Login works with Google analytics you need to use oauth2. The code looks something like this.

UserCredential credential; 
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
          new ClientSecrets { ClientId = "YourClientId", ClientSecret = "YourClientSecret" },
          new[] { AnalyticsService.Scope.AnalyticsReadonly},
          "user",
          CancellationToken.None,
          new FileDataStore("Drive.Auth.Store")).Result; } 

Once you have authentication you need only create the AnaltyicsService all your requests then go though this service.

AnalyticsService service = new AnalyticsService(
                           new BaseClientService.Initializer() {
                           HttpClientInitializer = credential,
                           ApplicationName = "Analytics API sample", });

Google Analtyics C# tutorial