Tuesday, 3 December 2013

Working with Google Analytics Core Reporting API

Ref URL
   
https://code.google.com/p/google-api-java-client/source/browse/?repo=samples
https://developers.google.com/analytics/devguides/reporting/core/v3/

First

1. Configure Website with Google Analytics
2. Configure Google Cloud Console and Register Application
3. Used Google APIs Client Library for Java
4. Import required jar files and implemented Java Code in IDE(Netbeans)

Steps

1. Create a website configured with Google Analytics (http://www.google.com/analytics)
        - Get the .js snippet and copy that code in the pages that have to be tracked
       
2. Create a project and application in 'Google Cloud Console' (https://cloud.google.com/console)
        - Create a project, where project id is auto generated.
        - Inside project -> APIs & auth -> Registered apps, Register an application
        - Inside Registered Application -> OAuth 2.0 Client ID, you will get '.json file', 'Client Id' and 
           'Client Secret', which looks like;
            .json file - Click on Download JSON, which gives required credential file which is used in our code
                Client Id - 559413053225-u9ehiskrqlpc1mh253klsom4sujbn3.apps.googleusercontent.com
                Client Secret - kfwsd_GrOkhxQNt_MXfEoLvM
       
3. Code is mentioned below, by executing which provides Dimensions and Metrics.

Note - Download required jar files from Client Library

/** Working Code **/

package googleanalytics;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.DataStoreFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.analytics.Analytics;
import com.google.api.services.analytics.AnalyticsScopes;
import com.google.api.services.analytics.model.Accounts;
import com.google.api.services.analytics.model.GaData;
import com.google.api.services.analytics.model.GaData.ColumnHeaders;
import com.google.api.services.analytics.model.Profiles;
import com.google.api.services.analytics.model.Webproperties;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.List;

public class HelloAnalyticsApiSample {

  /**
   * Be sure to specify the name of your application. If the application name is {@code null} or
   * blank, the application will log a warning.
   */
  private static final String APPLICATION_NAME = "blogapp";

  /** 'analytics_sample' is the Directory to store user credentials and 'user.home' is the path **/
  private static final java.io.File DATA_STORE_DIR =
      new java.io.File(System.getProperty("user.home"), "analytics_sample");
 
  /**
   * Globally shared instance across your application.
   */
  private static FileDataStoreFactory dataStoreFactory;

  /** Global instance of the HTTP transport. */
  private static HttpTransport httpTransport;

  /** Global instance of the JSON factory. */
  private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

  /**
   * Main demo. This first initializes an analytics service object. It then uses the Google
   * Analytics Management API to get the first profile ID for the authorized user. It then uses the
   * Core Reporting API to search terms. Finally the results are printed
   * to the screen. If an API error occurs, it is printed here.
   *
   */
  public static void main(String[] args) {
    try {     
      httpTransport = GoogleNetHttpTransport.newTrustedTransport();
      System.out.println("main call httpTransport :: "+httpTransport);
      dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
      System.out.println("main call dataStoreFactory :: "+dataStoreFactory);
      Analytics analytics = initializeAnalytics();     
      String profileId = getFirstProfileId(analytics);
      System.out.println("analytics details :: "+analytics);
      System.out.println("profileId is ::"+profileId);
      if (profileId == null) {
        System.err.println("No profiles found.");
      } else {
        GaData gaData = executeDataQuery(analytics, profileId);
        printGaData(gaData);
      }
    } catch (GoogleJsonResponseException e) {
      System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
          + e.getDetails().getMessage());
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
 
  /**
   * Performs all necessary setup steps for running requests against the API.
   *
   * @return An initialized Analytics service object.
   *
   * @throws Exception if an issue occurs with OAuth2Native authorize.
   */
  private static Analytics initializeAnalytics() throws Exception {
    // Authorization.
    System.out.println("inside initializeAnalytics method ");
    Credential credential = authorize();
    System.out.println("Credentials details :: "+ credential);

    // Set up and return Google Analytics API client.
    return new Analytics.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(
        APPLICATION_NAME).build();
  }

  /** Authorizes the installed application to access user's protected data. */
  private static Credential authorize() throws Exception {
    // load client secrets
    System.out.println("inside Credential authorize method");
    // client_secrets.json is the file which consists of client_id and client_secret which is used for access
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(
            HelloAnalyticsApiSample.class.getResourceAsStream("client_secrets.json")));   
    if (clientSecrets.getDetails().getClientId().startsWith("Enter")
        || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
      System.out.println(
          "Enter Client ID and Secret from https://code.google.com/apis/console/?api=analytics "
          + "into Google Analytics/Source Packages/google analytics/client_secrets.json");
      System.exit(1);
    }   
    // set up authorization code flow
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        httpTransport, JSON_FACTORY, clientSecrets,
        Collections.singleton(AnalyticsScopes.ANALYTICS_READONLY)).setDataStoreFactory(
        dataStoreFactory).build();
    // authorize
    System.out.println("End Credential authorize method");
    return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");   
  }

   /**
   * Returns the first profile id by traversing the Google Analytics Management API. This makes 3
   * queries, first to the accounts collection, then to the web properties collection, and finally
   * to the profiles collection. In each request the first ID of the first entity is retrieved and
   * used in the query for the next collection in the hierarchy.
   *
   * @param analytics the analytics service object used to access the API.
   * @return the profile ID of the user's first account, web property, and profile.
   * @throws IOException if the API encounters an error.
   */
  private static String getFirstProfileId(Analytics analytics) throws IOException {
    String profileId = null;

    // Query accounts collection.
    Accounts accounts = analytics.management().accounts().list().execute();

    if (accounts.getItems().isEmpty()) {
      System.err.println("No accounts found");
    } else {
      String firstAccountId = accounts.getItems().get(0).getId();

      // Query webproperties collection.
      Webproperties webproperties =
          analytics.management().webproperties().list(firstAccountId).execute();

      if (webproperties.getItems().isEmpty()) {
        System.err.println("No Webproperties found");
      } else {
        String firstWebpropertyId = webproperties.getItems().get(0).getId();

        // Query profiles collection.
        Profiles profiles =
            analytics.management().profiles().list(firstAccountId, firstWebpropertyId).execute();

        if (profiles.getItems().isEmpty()) {
          System.err.println("No profiles found");
        } else {
          profileId = profiles.getItems().get(0).getId();
        }
      }
    }
    return profileId;
  }

  /**
   * Returns the top 25 organic search keywords and traffic source by visits. The Core Reporting API
   * is used to retrieve this data.
   *
   * @param analytics the analytics service object used to access the API.
   * @param profileId the profile ID from which to retrieve data.
   * @return the response from the API.
   * @throws IOException tf an API error occured.
   */
  private static GaData executeDataQuery(Analytics analytics, String profileId) throws IOException {
    System.out.println("inside executeDataQuery");
    return analytics.data().ga().get("ga:" + profileId, // Table Id. ga: + profile id.
        "2013-11-25", // Start date.
        "2013-11-25", // End date.
        "ga:visits,ga:newVisits,ga:avgPageLoadTime") // Metrics.
        .setDimensions("ga:pagePath,ga:pageTitle")
        .setSort("-ga:newVisits,ga:source")
        .setFilters("ga:medium==organic")
        .setMaxResults(25)
        .execute();
  }

  /**
   * Prints the output from the Core Reporting API. The profile name is printed along with each
   * column name and all the data in the rows.
   *
   * @param results data returned from the Core Reporting API.
   */
  private static void printGaData(GaData results) {
    System.out.println("printing results for profile: " + results.getProfileInfo().getProfileName());

    if (results.getRows() == null || results.getRows().isEmpty()) {
      System.out.println("No results Found.");
    } else {

      // Print column headers.
      for (ColumnHeaders header : results.getColumnHeaders()) {
        System.out.printf("%30s", header.getName());
      }
      System.out.println();

      // Print actual data.
      //System.out.println("Get Rows Name"+results.getRows());
      for (List<String> row : results.getRows()) {
        for (String column : row) {
          System.out.printf("%30s", column);
        }
        System.out.println();
      }

      System.out.println();
    }
  }
}

1 comment:

  1. Nice and good article. It is very useful for me to learn and understand easily. Thanks for sharing your valuable information and time. Please keep updating mulesoft Online Training

    ReplyDelete