python data analysis concept

Python for Marketers: Building a Google My Business API application

Update: Since writing this post, Google has removed documentation for Python for this API. My code still works for me, but as this is not a supported language, I’d recommend building in a different language. Read more here.

  • What this is for: Getting reviews from multiple Google My Business locations and converting data into a CSV file
  • Requirements: Python Anaconda distribution, Google My Business account, Google My Business API access, Basic knowledge of API requests and Pandas
  • Concepts covered: Google API Python library, Dataframe filtering
  • Download the entire Python file

For organizations that manage a large number of Google My Business listings, working with review data is a critical to your overall marketing and reputation management strategy.

Around 2017, Google My Business stopped sending email alerts for new reviews if you account had more than 100 locations associated with it. When Google revamped their GMB interface in 2019, they did make available a dashboard to see all of your reviews in one place.

However, depending on how you need your data, you may need something more custom. Enter the Google My Business API.

When I started down the API route, I quickly discovered that there wasn’t as much support or tutorials on building applications with the API, and there were things missing in some of the official documentation out there.

So below is a tutorial on getting started with the Python API for Google My Business. We’ll create a simple request to get review data from multiple locations and load it into a CSV. This tutorial assumes you have a GMB account with multiple locations and familiarity with Pandas dataframes.

Get the API

To get started with the API, you will first need access to the API and then you will need to set up credentials.

  1. Google has instructions on getting access to the Google My Business API. Essentially, you will need to first create a Google Cloud Console account and then fill out a form requesting access to the API.
  2. Once you have been granted access to the API, you will need to follow the instructions to enable the API.
  3. After your API is enabled, log into the Cloud Console and create a New Project. From the menu, select Credentials under APIs & Services.
  4. Click the Create Credentials button and select API key. When configuring the API key, it’s a good idea to establish some restrictions to protect API use.
  5. Next, we’ll need to create an OAuth 2.0 client ID. Select this from the Create Credentials button. For authorized JavaScript origins and authorized redirect URIs, you can set both to http://localhost:8080
  6. After this created, look for a button to download the JSON for your OAuth 2.0 client ID. Click the button and it will download a file called client_secret_######.json. More on this in a bit.

Getting libraries into Anaconda

Next, we’ll need to install some libraries to Python to work with Google’s API.

For this tutorial, I’m using Anaconda distribution, because my ultimate goal is to do some data analysis with the packages that come preinstalled with Anaconda. If you are not using Anaconda, some steps may be a little different depending on your setup.

In order to install a library within Anaconda, you need to open a new Anaconda Prompt. From your Windows menu, open or search for Anaconda Prompt.

Change the directory to your Anaconda environment. In the command prompt, type in (for example)

cd C:\users\username\Anaconda3\

Now, we’ll need to install two API libraries from Google. To install the Google API Python Client, type in your command prompt

conda install -c conda-forge google-api-python-client

This will take a moment to install and will prompt you to confirm the install. After it’s completed, now install the Oauth client library. Type:

conda install -c conda-forge oauth2client

Once you have the libraries installed, you can open your Anaconda navigator to confirm they have been installed successfully by clicking on the Environments tab and searching packages.

Working with the Python file

Next, we’ll start working on making a request. For this tutorial, I’m working in the Spyder IDE.

Google provides some info on getting started with the API with their Python quick start guide. However, we’ll need to make a few modifications.

For the most part, we can copy the script on the Google quick start page, however, there is something missing. You can copy the script and make adjustments as listed below or download the modified PY file.

We will need to import the sys library for the code to function. We’ll also bring in the simplejson library for a later step.

from googleapiclient import sample_tools
from googleapiclient.http import build_http
import sys
import simplejson as json

Next, we’ll need to download the Discovery document. Google has instructions on the Python quick start page, but when you download, save the file as gmb_discovery.json, not myBusiness_discovery.json as the instructions indicate. Save the file to the directory where you have your Python script.

Now, back to the client secrets JSON file we downloaded earlier. Copy this file to the directory that contains your Python script and rename this file client_secrets.json (getting rid of the ID at the end of the name).

Next, we can run the script. Provided your code did not produce any errors, it should open a browser window to authenticate the request. This is a one-time process.

After you return to Spyder, run the script again and you should now see your data in the console.

Next, we’ll add two lines of code to export this data into a JSON file. Modify the last section under the def statement to this:

    # Get the list of locations for the first account in the list
    print("List of Locations for Account " + firstAccount)
    locationsList = service.accounts().locations().list(parent=firstAccount).execute()
    print(json.dumps(locationsList, indent=2))
    with open('gmb_export.json', 'w') as json_file:
        json.dump(locationsList, json_file)

Run the code again, and it will send the data to a JSON file.

Getting Review Data

Now that we’re able to successfully make a simple API call, we can make some more advanced requests like reviews data.

First, we need to import some additional libraries. Add this to your top section:

import pandas as pd
import csv
from pandas.io.json import json_normalize

To get review data, we’ll use the batchGetReviews() method. Based on Google’s documentation, the method requires two parameters, the account and a request body.

We already have the account available, so we just need to add the request body. The body essentially provides the location IDs in an array. In the section where we retrieved a list of locations, we’ll modify the code to our new request.

To get the location IDs for your locations, you can make an accounts.locations.list request via the OAuth Playground.

We’ll create a variable called “body” that will serve as the body of the request. Then we’ll use the batchGetReviews method and pass body as a parameter. This will dump into the JSON file.

    # Get the list of locations for the first account in the list
    print("List of Locations for Account " + firstAccount)
    body = {
        "locationNames": [
                "accounts/XXXXXX/locations/XXXXX",
                "accounts/XXXXXX/locations/XXXXX"
                ]
        }
    locationsList = service.accounts().locations().batchGetReviews(name=firstAccount,body=body).execute()
    print(json.dumps(locationsList, indent=2))

Finally, we’ll convert this JSON data into a CSV..

    with open('gmb_batchreviews.json', 'w') as json_file:
        json.dump(locationsList, json_file)
    #load json object
    with open('gmb_batchreviews.json') as f:
        d = json.load(f)
    #Normalize the nested json file
    df = json_normalize(d['locationReviews'])
    df.to_csv('gmb_batchreviews.csv')
    outfile.close()

Run the script again and it will send the review data for your locations into a CSV file.

Cleaning & filtering the data

The request may return more reviews than you need. For example, we may only want to see reviews from the last 30 days. Using some basic Pandas functions, we can easily filter a dataframe to show only reviews within a specified time frame.

First, go back to the start of your script and we’ll import another library to work with dates and times.

from datetime import datetime, timedelta

Now, go back to the end of your script. First, we’ll import the CSV and drop the index column.

#filter results by time
df2 = pd.read_csv('gmb_batchreviews.csv')
df2 = df2.drop(['Unnamed: 0'], axis=1)

Next, we’ll convert the review date to a date/time format.

df2['review.createTime'] = pd.to_datetime(df2['review.createTime'])
df2 = df2.set_index(['review.createTime'])

Now we’ll set the end range to today and the start date to today minus 30 days. Then we’ll create a new dataframe just showing the

end_range = datetime.now().date()
d = d = datetime.today() - timedelta(days=30)
start_range = d.date()
start_date = str(start_range)
df3 = df2[start_date:]

Alternatively, if you wanted to set a custom range, you could use a date in place of the start_range variable:

df3 = df2['2019-05-01':'2019-06-01']

At this point, our dataframe is filtered by specified date. We can make it a little more user friendly by removing columns we don’t need. We can use the .drop() function to remove these. We can also use .columns to rename our remaining columns.

df3 = df3.drop(columns=['review.name', 'review.reviewId', 'review.reviewer.profilePhotoUrl'])
df3.columns = ['location','comment','reply','reply_date','reviewer','star_rating','date']

If our goal is to make the end product human-readable, we may also want to translate the location ID to a text description.

df3 = df3.replace('accounts/xxxxxxx/locations/xxxxxx','Location Name')

Finally, we’ll export our new dataframe as an XLSX file with the date attached to the file name. We’ll need to convert the end  date to a string to combine it in the first line.

export_name = 'gmb_reviews_export_' + str(end_range) +'.xlsx'
df3.to_excel(export_name, index=False)

The entire Python file is available for download here.

You may also like