How to Get Google Metrics from the Google Analytics Platform Using Node.js
Published: 2022-10-27 09:07:07

Assume you've published an app on Google Play and a growing number of people have downloaded it. Eventually, you'll want to know how many total, active installs and other metrics, such as daily, weekly, and monthly active users, your app has.

In this tutorial, I'll show you how to use node.js to get Google metrics/analytics data for your app.

But first, you must do the following;
1. <a href="https://console.cloud.google.com/project">Select or create a Google Cloud Project</a> (Your app must be connected on Google Cloud Platform).
2. <a href="https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com">Have Google Analytics Data API enabled.</a>
3. <a href="https://cloud.google.com/docs/authentication/getting-started">Set up authentication with a service account</a> so you can access the API from your local workstation.

First and foremost, you must install the **@google-analytics/data** google client node library with the following command under the root directory of your node project.

```
npm i @google-analytics/data
```
Next, import the Google Analytics Data API client library at the start of your javascript file as follows;

```javascript
const { BetaAnalyticsDataClient } = 
require('@google-analytics/data');
```
The next step is to call the ``BetaAnalyticsDataClient`` constructor and pass Google credentials, specifically the file path containing Google credentials (This is typically stored in json format and is obtained from step 3 of the aforementioned prerequisites);
```javascript

const analyticsDataClient = new BetaAnalyticsDataClient(
          {
            keyFilename: 'pathtoGooglecredentialsfile',
          }
);
```
Another value you must obtain before fetching Google metrics with this API is the Google Analytics 4 ``property ID``. How to get Google Analytics 4 Property ID?  👉 <a href="https://developers.google.com/analytics/devguides/reporting/data/v1/property-id">Link</a>

Next, let's look at the method that we shall use in fetching analytics;

```javascript
 // get activeUsers, active1DayUsers, active7DayUsers, active28DayUsers, newUsers, totalUsers etc.

getAnalyticsData = async(startDate = '', endDate = '') => {
        
try{
            
 let dateRange = {
        startDate: startDate ? startDate : '30daysAgo',
        endDate: endDate ? endDate : 'yesterday'
     }
            
const [response] = 
await analyticsDataClient.runReport({
     property: `properties/${propertyId}`,
     dateRanges: [dateRange],
     dimensions: [{ name: 'platform' }],
 
     metrics: [
      { name: 'activeUsers' },
      { name: 'active1DayUsers'},
      { name: 'active7DayUsers' },
      { name: 'active28DayUsers' },
      { name: 'newUsers' },
      { name: 'totalUsers' }, 
      { name: 'crashAffectedUsers' },
      { name: 'averageSessionDuration' },
       ],
            });
            
let report = {};

 response.rows.forEach(row => {
                
report.activeUsers = this.numberWithCommas(row.metricValues[0].value);
report.active1DayUsers = this.numberWithCommas(row.metricValues[1].value);
report.active7DayUsers = this.numberWithCommas(row.metricValues[2].value);
report.active28DayUsers = this.numberWithCommas(row.metricValues[3].value);
report.newUsers = this.numberWithCommas(row.metricValues[4].value);
 report.totalUsers = this.numberWithCommas(row.metricValues[5].value);
report.crashAffectedUsers = this.numberWithCommas(row.metricValues[6].value);

let engagementDuration = parseFloat(row.metricValues[7].value);
engagementDuration = engagementDuration >= 3600 
 ? `${(engagementDuration/3600).toFixed(2)} hrs`  :
  engagementDuration < 3600 
  ? `${(engagementDuration/60).toFixed(2)} mins` :                              `${engagementDuration.toFixed(2)} secs`
report.userEngagementDuration = engagementDuration;
                
});
            
  return report;

}
 catch(err){
  throw err;
 }
}
```
``getAnalyticsData`` is a custom method in the above code that retrieves analytics such as ``activeUsers``, ``active1DayUsers``, ``active7DayUsers``, ``active28DayUsers``, ``newUsers``, ``totalUsers``, ``crashAffectedUsers``, and ``averageSessionDuration``.

It takes in 2 optional parameters i.e startDate and endDate. If not supplied, startDate is '30daysAgo' while endDate is yesterday. On the instance for google analytics client, there is a method called runReport which takes in an object of keys, property (where you supply you Google Analytics property ID),dateRange, dimensions and then metrics.

Furthermore, I have a method called ``numberWithCommas`` that formats the metrics values with a thousand separator, as shown below;
```javascript

 // formats a number with thousand separator 
    numberWithCommas = (x) => {
        try{
            return x.toString()
          .replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
        }catch(err){
            throw err;
        }
    }


```
If you want to get``DAU`` (Daily Active Users), ``WAU`` (Weekly Active Users), and ``MAU`` (Monthly Active Users), follow the same steps as above, but change the dimensions to **date** instead of `platform`, and the respect values for the key names for DAU, WAU, and MAU are `dauPerMau`, `dauPerWau`, and `wauPerMau`.



**_The Entire Code_**
```javascript
const { BetaAnalyticsDataClient } = require('@google-analytics/data');
let credentialsJsonPath =  env.GOOGLE_ANALYTICS.PRIVATE_KEY_PATH; 

const analyticsDataClient = new BetaAnalyticsDataClient({
    keyFilename: process.env.GOOGLE_PRIVATE_KEY_PATH
});
const propertyId = env.GOOGLE_ANALYTICS.PROPERTY_ID;

let googleAnalyticsApi = class {

getAnalyticsData = async(startDate = '', endDate = '') => {
        
try{
            
 let dateRange = {
        startDate: startDate ? startDate : '30daysAgo',
        endDate: endDate ? endDate : 'yesterday'
     }
            
const [response] = 
await analyticsDataClient.runReport({
     property: `properties/${propertyId}`,
     dateRanges: [dateRange],
     dimensions: [{ name: 'platform' }],
 
     metrics: [
      { name: 'activeUsers' },
      { name: 'active1DayUsers'},
      { name: 'active7DayUsers' },
      { name: 'active28DayUsers' },
      { name: 'newUsers' },
      { name: 'totalUsers' }, 
      { name: 'crashAffectedUsers' },
      { name: 'averageSessionDuration' },
       ],
            });
            
let report = {};

 response.rows.forEach(row => {
                
report.activeUsers = this.numberWithCommas(row.metricValues[0].value);
report.active1DayUsers = this.numberWithCommas(row.metricValues[1].value);
report.active7DayUsers = this.numberWithCommas(row.metricValues[2].value);
report.active28DayUsers = this.numberWithCommas(row.metricValues[3].value);
report.newUsers = this.numberWithCommas(row.metricValues[4].value);
 report.totalUsers = this.numberWithCommas(row.metricValues[5].value);
report.crashAffectedUsers = this.numberWithCommas(row.metricValues[6].value);

let engagementDuration = parseFloat(row.metricValues[7].value);
engagementDuration = engagementDuration >= 3600 
 ? `${(engagementDuration/3600).toFixed(2)} hrs`  :
  engagementDuration < 3600 
  ? `${(engagementDuration/60).toFixed(2)} mins` :                              `${engagementDuration.toFixed(2)} secs`
report.userEngagementDuration = engagementDuration;
                
});
            
   return report;

  } 
  catch(err){
    throw err;
  }
}

 // formats a number with thousand separator 
    numberWithCommas = (x) => {
        try{
         return x.toString()
         .replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
        }catch(err){
            throw err;
        }
    }


}
```

So that's how you get Google metrics from Google Analytics, and thank you for reading.