bashgoogle-cloud-platformgoogle-analyticsgcloud

How to access the Google Analytics Data API via bash script using gcloud


On a Ubuntu server I want to regularly execute a script which calls the Google Analytics Data API in order to extract the 20 most visited pages of a website.

According to the Google Cloud CLI Documentation i created the following bash script:

#!/bin/bash

# Set environment variables
export KEY_FILE="/home/yesitsme/utilities/scripts/gcloud.json"
export PROPERTY_ID="278767000"

# Authenticate using the service account
gcloud auth activate-service-account --key-file=$KEY_FILE

# Get access token
ACCESS_TOKEN=$(gcloud auth print-access-token)

# Make API request for page views in the last 24 hours
curl -X POST \
  "https://analyticsdata.googleapis.com/v1beta/properties/$PROPERTY_ID:runReport" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "dateRanges": [
          {
            "startDate": "yesterday",
            "endDate": "today"
          }
        ],
        "dimensions": [
          {
            "name": "pagePath"
          }
        ],
        "metrics": [
          {
            "name": "screenPageViews"
          }
        ],
        "limit": 5
      }'

If i execute the gcloud auth command only, i see that the access token gets created successfully.

But when executing the script, i get this output with an error:

Activated service account credentials for: [zwischengas-google-cloud-api@zwischengas.iam.gserviceaccount.com]
{
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
        "domain": "googleapis.com",
        "metadata": {
          "method": "google.analytics.data.v1beta.BetaAnalyticsData.RunReport",
          "service": "analyticsdata.googleapis.com"
        }
      }
    ]
  }
}

So the question is clear: why does my newly created service account have not enough permissions? Any hint?


Solution

  • Thanks to the hint of @DazWilkin i found a working solution. Here is what I have done:

    Here is the full shell script that accesses your Google Analytics:

    #!/bin/bash
    
    # Set variables
    KEY_FILE="/home/myuser/gcloud-service-account-secret.json"
    PROPERTY_ID="27yy67xxx"
    SCOPE="https://www.googleapis.com/auth/analytics.readonly"
    
    # Get an access token
    ACCESS_TOKEN=$(oauth2l fetch --credentials=$KEY_FILE --scope=$SCOPE)
    
    # Check if token retrieval was successful
    if [ -z "$ACCESS_TOKEN" ]; then
      echo "Failed to retrieve access token"
      exit 1
    fi
    
    # Query Google Analytics Data API
    curl -s -X POST \
      "https://analyticsdata.googleapis.com/v1beta/properties/$PROPERTY_ID:runReport" \
      -H "Authorization: Bearer $ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
            "dateRanges": [
              {
                "startDate": "yesterday",
                "endDate": "today"
              }
            ],
            "dimensions": [
              {
                "name": "pagePath"
              }
            ],
            "metrics": [
              {
                "name": "screenPageViews"
              }
            ],
      "dimensionFilter": {
             "orGroup": {
                "expressions": [
                  {
                    "filter": {
                      "fieldName": "pagePath",
                      "stringFilter": {
                        "matchType": "BEGINS_WITH",
                        "value": "/path1_i_want_to_include/"
                      }
                    }
                  },
                  {
                    "filter": {
                      "fieldName": "pagePath",
                      "stringFilter": {
                        "matchType": "BEGINS_WITH",
                        "value": "/path2/i/want/to_include/"
                      }
                    }
                  }
                ]
              }
      },
            
            "limit": 50
          }'
    

    The result is simply a JSON file that you can store on disk and further process with your backend software.