Search code examples
pythongoogle-apigoogle-analytics-apigoogle-api-python-client

ga:browserVersion segment filter is giving out HttpError:400 for using 'not' to exclude a user segment. I am using Google Analytics Reporting API V4


I have been writing a Python script to pull GA data for a particular View for YTD. I had a bot traffic between this period which was filtered out in the view but there is still a good chunk of that traffic in April '22. I want to use a segment filter with ga:browserVersion and exclude that traffic. Unfortunately, I am getting the following error:

<HttpError 400 when requesting https://analyticsreporting.googleapis.com/v4/reports:batchGet?alt=json returned "Invalid JSON payload received. Unknown name "not" at 'report_requests[0].segments[0].dynamic_segment.user_segment.segment_filters[0].simple_segment.or_filters_for_segment.segment_filter_clauses[0].dimension_filter': Cannot find field.", 'description': 'Invalid JSON payload received. Unknown name "not" at 'report_requests[0].segments[0].dynamic_segment.user_segment.segment_filters[0].simple_segment.or_filters_for_segment.segment_filter_clauses[0].dimension_filter': Cannot find field.'>

Below is the associated code:

def get_report(analytics, start_date, end_date_delta, pageToken = None):
  """Queries the Analytics Reporting API V4.

  Args:
    analytics: An authorized Analytics Reporting API V4 service object.
  Returns:
    The Analytics Reporting API V4 response.
  """
  return analytics.reports().batchGet(
      body={
        'reportRequests': [
        {
          'viewId': VIEW_ID,
          'pageSize': 10000,
          'pageToken': pageToken,
          'dateRanges': [{'startDate': start_date.strftime("%Y-%m-%d") , 'endDate': (start_date+end_date_delta).strftime("%Y-%m-%d")}],           
           'metrics': [{'expression': 'ga:pageviews'}, {'expression': 'ga:sessions'}, {'expression': 'ga:pageviewsPerSession'}, {'expression': 'ga:totalEvents'}, {'expression': 'ga:uniqueEvents'}, {'expression': 'ga:timeOnPage'}, {'expression': 'ga:users'}, {'expression': 'ga:newUsers'}],
           'dimensions': [{'name':'ga:date'}, {'name':'ga:sourceMedium'}, {'name':'ga:pageTitle'}, {'name':'ga:eventLabel'}, {'name':'ga:eventCategory'}, {'name':'ga:adContent'}, {'name':'ga:segment'}, {'name':'ga:campaign'}, {'name':'ga:dimension8'} ],
           'segments':[{
                'dynamicSegment':
      {
        'name': 'Apr Bot Traffic',
        'userSegment':
        {
          'segmentFilters':[
          {
            'simpleSegment':
            {
              'orFiltersForSegment':
              {
                'segmentFilterClauses': [
                {
                  'dimensionFilter':
                  {
                    'dimensionName':'ga:browserVersion',
                    'not':True,
                    'operator':'EXACT',
                    'expressions':'80.0.3987.163'
                  }
                }]
              }
            }
          }]
        }
      }
      }]
      }]
      }
  ).execute()

Solution

  • It looks as if the SegmentDimensionFilter doesn't support the not field, only the DimensionFilter does.

    You can use a not field in the SegmentFilter clause, though, which should have the same effect in this case.