Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Analytics Reporting v4 with API key

I need to integrate a very basic report from Google Analytics in the dashboard page of a CMS web application I'm building with asp.net web forms (C#).

I remember I was able to do it on a test made in 2015 with API V3, but now, with V4, I get always an error message that OAuth2 is needed for authentication.

I need to access to a specific analytics account I own, not the account of the user that navigate in the CMS!

So I use the API KEY given by Google API Manager. I have given to that API Key all the permission. The API key is similar to this: "d471c3ce04612f143ff0Be319aac2e17d0159add"

here is the code

using Google.Apis.AnalyticsReporting.v4;
using Google.Apis.Services;
using System;
using Google.Apis.AnalyticsReporting.v4.Data;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.IO;
using Google.Apis.Auth.OAuth2;
using System.Threading;
using Google.Apis.Util.Store;
using System.Web;


public static class GoogleAnalyticsAPI
{


static string vmcApiKey = "<<API-KEY>>";

public static void Test()
{
    AnalyticsReportingService ars = GetService(vmcApiKey);

    // Create the DateRange object.
    DateRange dateRange = new DateRange() { StartDate = "2017-01-01", EndDate = "2017-04-28" };

    // Create the Metrics object.
    Metric sessions = new Metric { Expression = "ga:sessions", Alias = "Sessions" };

    //Create the Dimensions object.
    Dimension browser = new Dimension { Name = "ga:browser" };

    // Create the ReportRequest object.
    // Create the ReportRequest object.
    ReportRequest reportRequest = new ReportRequest
    {
        ViewId = "<<VIEW-ID>>",
        DateRanges = new List<DateRange>() { dateRange },
        Dimensions = new List<Dimension>() { browser },
        Metrics = new List<Metric>() { sessions }
    };

    List<ReportRequest> requests = new List<ReportRequest>();
    requests.Add(reportRequest);

    // Create the GetReportsRequest object.
    GetReportsRequest getReport = new GetReportsRequest() { ReportRequests = requests };

    // Call the batchGet method.
    GetReportsResponse response = ars.Reports.BatchGet(getReport).Execute();
}


public static AnalyticsReportingService GetService(string apiKey)
{
    try
    {
        if(string.IsNullOrEmpty(apiKey))
            throw new ArgumentNullException("api Key");

        return new AnalyticsReportingService(new BaseClientService.Initializer()
        {
            ApiKey = apiKey,
            ApplicationName = "AnalyticsReporting API key example",
        });
    }
    catch(Exception ex)
    {
        throw new Exception("Failed to create new AnalyticsReporting Service", ex);
    }
}

On the last line of Test() method, ars.Reports.BatchGet(getReport).Execute(); I get the error:

Google.Apis.Requests.RequestError Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential.

But again with OAUTH2 authentication I access the user data and is not what I want. I need to access a specific account I own, independently by the user that is browsing the CMS.

like image 322
Giox Avatar asked Dec 24 '22 18:12

Giox


1 Answers

API key is for accessing public data only which means you could only use it with the metadata api.

Google Analytics data is private data owned by a user. Since this is your own data that you are trying to access you should create a service account. Service accounts are preauthorized. Go to Google developer console and create service account credentials. Then take the service account email address and add it as a user at the ACCOUNT level in the admin section of the google analytics website. It MUST be the ACCOUNT level. You have now authorized the service account to access the data of that account.

Service account Auth

// Copyright 2017 DAIMTO :  www.daimto.com
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by DAIMTO-Google-apis-Sample-generator 1.0.0
//     Template File Name:  ServiceAccount.tt
//     Build date: 01/02/2017 22:31:50
//     C# generater version: 1.0.0
//     
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// About 
// 
// Unoffical sample for the AnalyticsReporting v4 API for C#. 
// This sample is designed to be used with the Google .Net client library. (https://github.com/google/google-api-dotnet-client)
// 
// API Description: Accesses Analytics report data.
// API Documentation Link https://developers.google.com/analytics/devguides/reporting/core/v4/
//
// Discovery Doc  https://www.googleapis.com/discovery/v1/apis/AnalyticsReporting/v4/rest
//
//------------------------------------------------------------------------------
// Installation
//
// This sample code uses the Google .Net client library 
//
// NuGet package:
//
// Location: https://www.nuget.org/packages/Google.Apis.AnalyticsReporting.v4/ 
// Install Command: PM>  Install-Package Google.Apis.AnalyticsReporting.v4
//
//------------------------------------------------------------------------------  
using Google.Apis.AnalyticsReporting.v4
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;

namespace GoogleSamplecSharpSample.AnalyticsReportingv4.Auth
{

    public class static ServiceAccountExample
    {

        /// <summary>
        /// Authenticating to Google using a Service account
        /// Documentation: https://developers.google.com/accounts/docs/OAuth2#serviceaccount
        /// </summary>
        /// <param name="serviceAccountEmail">From Google Developer console https://console.developers.google.com</param>
        /// <param name="serviceAccountCredentialFilePath">Location of the .p12 or Json Service account key file downloaded from Google Developer console https://console.developers.google.com</param>
        /// <returns>AnalyticsService used to make requests against the Analytics API</returns>
        public static AnalyticsReportingService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath)
        {
            try
            {
                if (string.IsNullOrEmpty(serviceAccountCredentialFilePath))
                    throw new Exception("Path to the service account credentials file is required.");
                if (!File.Exists(serviceAccountCredentialFilePath))
                    throw new Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath);
                if (string.IsNullOrEmpty(serviceAccountEmail))
                    throw new Exception("ServiceAccountEmail is required.");

                // These are the scopes of permissions you need. It is best to request only what you need and not all of them
                string[] scopes = new string[] { AnalyticsReportingService.Scope.Analytics };             // View your Google Analytics data

                // For Json file
                if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
                {
                    GoogleCredential credential;
                    using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
                    {
                        credential = GoogleCredential.FromStream(stream)
                             .CreateScoped(scopes);
                    }

                    // Create the  Analytics service.
                    return new AnalyticsReportingService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "AnalyticsReporting Service account Authentication Sample",
                    });
                }
                else if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".p12")
                {   // If its a P12 file

                    var certificate = new X509Certificate2(serviceAccountCredentialFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
                    var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
                    {
                        Scopes = scopes
                    }.FromCertificate(certificate));

                    // Create the  AnalyticsReporting service.
                    return new AnalyticsReportingService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "AnalyticsReporting Authentication Sample",
                    });
                }
                else
                {
                    throw new Exception("Unsupported Service accounts credentials.");
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("Create service account AnalyticsReportingService failed" + ex.Message);
                throw new Exception("CreateServiceAccountAnalyticsReportingFailed", ex);
            }
        }
    }
}

Code ripped from my Google-api-Dotnet samples project for Reporting API

Once you have created your service you should be able to use the code on the samples page for C#

I have an old tutorial on Service accounts with V3. Google Analytics Authentication

like image 80
DaImTo Avatar answered Dec 26 '22 21:12

DaImTo