Guía de migración

En esta guía, se proporcionan lineamientos para migrar la API de Core Reporting v3 a la API de Analytics Reporting v4.

Introducción

Si deseas aprovechar las funciones nuevas que se introdujeron en la API de Analytics Reporting v4, migra tu código para usar la API. En esta guía, se muestran las solicitudes en la API de Core Reporting v3 y las solicitudes equivalentes en la API de Analytics Reporting v4 para facilitar la migración.

Migración de Python

Si eres desarrollador de Python, usa la biblioteca auxiliar GAV4 en GitHub para convertir las solicitudes de la API de Google Analytics Core Reporting v3 en solicitudes de la API de Analytics Reporting v4

Extremos

La API de Core Reporting v3 y la API de Analytics Reporting v4 tienen diferentes extremos y métodos HTTP:

Extremo v3

GET https://www.googleapis.com/analytics/v3/data/ga

Extremo v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet

Los siguientes ejemplos comparan una solicitud en v3 con la solicitud equivalente en v4:

v3

Documentación de referencia de la versión 3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
    &start-date=2015-11-01&end-date=2015-11-06 \
    &metrics=ga:users&dimensions=ga:pagePath

v4

Documentación de referencia de la versión 4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    "dateRanges":[
    {
      "startDate":"2015-11-01",
      "endDate":"2015-11-06"
    }],
    "metrics":[
    {
      "expression":"ga:users"
    }],
    "dimensions": [
    {
      "name":"ga:pagePath"
    }]
  }]
}

Bibliotecas cliente y servicio de descubrimiento

Si usas Python, JavaScript o alguna otra biblioteca cliente que se basa en el Servicio de Google Discovery, debes proporcionar la ubicación del documento de descubrimiento para la API de Reporting v4.

Python

from apiclient import discovery

...

# Build the Analytics Reporting API v4 authorized service object.
analyticsReporting = discovery.build(
  'analyticsreporting',
  'v4',
  http=http,
  discoveryServiceUrl='https://analyticsreporting.googleapis.com/$discovery/rest')

JavaScript

gapi.client.load(
  'https://analyticsreporting.googleapis.com/$discovery/rest',
  'v4'
).then(...)

Las bibliotecas cliente de Java y PHP están compiladas con anterioridad, pero puedes usar el servicio de descubrimiento y el generador de API de Google para generarlas.

Solicitudes

En la referencia de la versión 4 de la API, se describe en detalle la estructura del cuerpo de la solicitud. En las siguientes secciones, se describe la migración de parámetros de solicitud de v3 a parámetros de solicitud de v4.

Ver IDs

En la versión 3, un parámetro ids, que acepta un "ID de tabla", tiene el formato ga:XXXX, en el que XXXX es el ID de la vista (perfil). En la versión 4, el ID de vista (perfil) se especifica en el campo viewId del cuerpo de la solicitud.

En los siguientes ejemplos, se comparan el parámetro ids en una solicitud v3 y el campo viewId en una solicitud v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    ...
  }]
}

Intervalos de fechas

La API de Analytics Reporting v4 te permite especificar varios períodos en una sola solicitud. El campo dateRanges toma una lista de objetos DateRange. En la versión 3, se usan los parámetros start-date y end-date para especificar un período en una solicitud.

En los siguientes ejemplos, se comparan los parámetros start-date y end-date en una solicitud v3 y el campo dateRanges en una solicitud v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
    &start-date=2015-11-01&end-date=2015-11-06 \
    ...

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    "dateRanges":[
    {
      "startDate":"2015-11-01",
      "endDate":"2015-11-06"
    }],
    ....
  }]
}

Métricas

El parámetro metrics de la versión 3 corresponde al campo metrics de la versión 4 que toma una lista de objetos Metric.

En los siguientes ejemplos, se comparan los parámetros metrics en una solicitud v3 y el campo metrics en una solicitud v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
    &start-date=2015-11-01&end-date=2015-11-06 \
    &metrics=ga:users,ga:sessions \
    ...

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    "dateRanges":[
    {
      "startDate":"2015-11-01",
      "endDate":"2015-11-06"
    }],
    "metrics":[
    {
      "expression":"ga:users"
    },{
      "expression":"ga:sessions"
    }],
    ...
  }]
}

Dimensiones

El parámetro dimensions de la versión 3 corresponde al campo dimensions de la versión 4 que toma una lista de objetos Dimension.

En los siguientes ejemplos, se comparan los parámetros dimensions en una solicitud v3 y el campo dimensions en una solicitud v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
  &dimensions=ga:country,ga:browser&... \

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "dimensions": [
    {
      "name":"ga:country"
    },{
      "name":"ga:browser"
    }],
    ...
  }]
}

Ordenamiento

El parámetro sort de la versión 3 es equivalente al campo orderBys de la versión 4 que toma una lista de objetos OrderBy.

En la versión 4, para ordenar los resultados por valor de dimensión o métrica, haz lo siguiente:

  • Proporciona su nombre o alias a través del campo fieldName.
  • Especifica el orden de clasificación (ASCENDING o DESCENDING) a través del campo sortOrder.

En los siguientes ejemplos, se comparan el parámetro sort en una solicitud v3 y el campo orderBy en una solicitud v4. Ambos clasifican a los usuarios en orden descendente y las fuentes alfabéticamente:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
  &sort=-ga:users,ga:source

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "orderBys": [
    {
      "fieldName": "ga:users",
      "sortOrder": "DESCENDING"
    },{
      "fieldName": "ga:source"
    }],
  }]
}

Nivel de muestreo

El parámetro samplingLevel de la versión 3 corresponde al campo samplingLevel de la versión 4. En la v3, los valores de samplingLevel aceptados son FASTER, HIGHER_PRECISION y DEFAULT, y, en la v4, los valores de samplingLevel aceptados son SMALL, LARGE y DEFAULT. Ten en cuenta que FASTER en la versión 3 cambió a SMALL en la versión 4 y de HIGHER_PRECISION a LARGE.

En los siguientes ejemplos, se comparan el parámetro samplingLevel en una solicitud v3 y el campo samplingLevel en una solicitud v4:

v3

https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX ...\
samplingLevel=HIGHER_PRECISION

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "samplingLevel": "LARGE"
  }]
}

Segmentos

El parámetro segment de la versión 3 corresponde al campo segments de la versión 4 que toma una lista de objetos Segment.

IDs de segmento

En la versión 4, para solicitar un segmento por ID de segmento, debes crear un objeto Segment y proporcionar su ID a través del campo segmentId.

En los siguientes ejemplos, se compara el parámetro segment en una solicitud v3 y el campo segments en una solicitud v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=gaid::-11

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "viewId": "XXXX",
    "segments": [{
      "segmentId": "gaid::-11"
    }]
  }]
}

Segmentos dinámicos

En la versión 4, para expresar definiciones de segmentos más complicadas, usa el campo segments que incluye un objeto DynamicSegment.

En los siguientes ejemplos, se compara el parámetro segment en una solicitud v3 y el campo segments que contiene un objeto DynamicSegment en una solicitud v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=sessions::condition::ga:medium==referral

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "segments": [{
      "dynamicSegment": {
        "name": "segment_name",
        "sessionSegment": {
          "segmentFilters": [{
            "simpleSegment": {
              "orFiltersForSegment": [{
                "segmentFilterClauses": [{
                  "dimensionFilter": {
                    "dimensionName": "ga:medium",
                    "operator": "EXACT",
                    "expressions": [ "referral" ]
                  }
                }]
              }]
            }
          }]
        }
      }
    }]
  }]
}

Puedes combinar condiciones y secuencias en un segmento:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=users::condition::ga:revenue>10;sequence::ga:deviceCategory==desktop->>ga:deviceCategory==mobile

v4

  "reportRequests": [{
      "dateRanges": [
            { "endDate": "2014-11-30", "startDate": "2014-11-01" }
      ],
      "metrics": [
          {"expression": "ga:pageviews"},
          {"expression": "ga:sessions"}
      ],
      "viewId": "XXXX",
      "dimensions":[{"name":"ga:medium"}, {"name":"ga:segment"}],
      "segments": [{
        "dynamicSegment": {
        "name": "segment_name",
        "userSegment": {
          "segmentFilters": [{
            "simpleSegment": {
              "orFiltersForSegment": [{
                "segmentFilterClauses": [{
                  "metricFilter": {
                    "metricName": "ga:sessions",
                    "operator": "GREATER_THAN",
                    "comparisonValue": "10"
                  }
                }]
              }]
            }
          },
          {
            "sequenceSegment": {
              "segmentSequenceSteps": [{
                "orFiltersForSegment": [{
                  "segmentFilterClauses": [{
                    "dimensionFilter": {
                      "dimensionName": "ga:deviceCategory",
                      "operator": "EXACT",
                      "expressions": ["desktop"]
                    }
                  }]
                }],
                "matchType": "PRECEDES"
              },{
                "orFiltersForSegment": [{
                  "segmentFilterClauses": [{
                    "dimensionFilter": {
                      "dimensionName": "ga:deviceCategory",
                      "operator": "EXACT",
                      "expressions": ["mobile"]
                    }
                  }]
                }]
              }]
            }
          }]
        }
      }
    }]
  }]

Sintaxis de segmentos de la versión 3 en la versión 4

El campo segmentId en la API v4 admite la sintaxis de segmentos en la API v3.

En los siguientes ejemplos, se muestra cómo el parámetro segment en una solicitud de v3 es compatible con el campo segmentId en la solicitud equivalente de v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=sessions::condition::ga:medium==referral

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "viewId": "XXXX",
    "segments": [{
      "segmentId": "sessions::condition::ga:medium==referral"
    }]
  }]
}

Filtros

La v4 usa dimensionFilterClauses para filtrar dimensiones y metricFilterClauses para filtrar métricas. Un dimensionFilterClauses contiene una lista de objetos DimensionFilter y un metricFilterClauses contiene una lista de objetos MetricFilter.

En los siguientes ejemplos, se compara el parámetro filters en una solicitud v3 y el campo dimensionFilterClauses en una solicitud v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
  &start-date=2015-06-01&end-date=2015-07-31&metrics=ga:users& \
  dimensions=ga:browser&filters=ga:browser==Firefox

v4

  "reportRequests": [{
      "dateRanges": [
            { "endDate": "2014-11-30", "startDate": "2014-11-01" }
      ],
      "metrics": [
          {"expression": "ga:pageviews"},
          {"expression": "ga:sessions"}
      ],
      "viewId": "XXXX",
      "dimensions":[{"name":"ga:browser"}, {"name":"ga:country"}],
      "dimensionFilterClauses": [{
           "filters": [{
                "dimension_name": "ga:browser",
                "operator": "EXACT",
                "expressions": ["Firefox"]
            }]
      }]
  }]

Sintaxis de filtros de la versión 3 en la versión 4

Aunque el campo filtersExpression en la versión 4 admite la sintaxis filters en la versión 3, debes usar dimensionFilterClauses y metricFilterClauses para filtrar las dimensiones y las métricas.

En los siguientes ejemplos, se muestra cómo el parámetro filters en una solicitud de v3 es compatible con el campo filtersExpression en la solicitud equivalente de v4:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga%XXXX \
&filters=ga:browser==Firefox

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "filtersExpression": "ga:browser==Firefox"
  }]
}

Filas vacías

El parámetro include-empty-rows de la versión 3 corresponde al campo includeEmptyRows de la versión 4. El valor predeterminado del parámetro de la v3 es true, mientras que en la v4, el valor predeterminado del campo es false. Si no tienes el valor establecido en la v3, deberás establecerlo en true en la v4.

En los siguientes ejemplos, se compara el parámetro include-empty-rows en una solicitud v3 con el campo includeEmptyRows en una solicitud v4:

v3

https://www.googleapis.com/analytics/v3/data/ga? ...\
    &include-empty-rows=true

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "includeEmptyRows": "true",
  }]
}

Paginación

La versión 4 usa los campos pageToken y pageSize para paginar una gran cantidad de resultados. El pageToken se obtiene de la propiedad nextPageToken de un objeto de respuesta.

En los siguientes ejemplos, se comparan los parámetros start-index y max-results en una solicitud de v3 con los campos pageToken y pageSize en una solicitud de v4:

v3

https://www.googleapis.com/analytics/v3/data/ga? ...\
    &start-index=10001&max-results=10000

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    # Taken from `nextPageToken` of a previous response.
    "pageToken": "10000",
    "pageSize": "10000",
  }]
}

Parámetros estándar

La API de Analytics Reporting v4 admite la mayoría de los parámetros de consulta estándar en la API de v3, excepto los parámetros userIp y callback.

En los siguientes ejemplos, se compara el parámetro quotaUser de una solicitud de v3 con el de una solicitud de v4:

Extremo v3

GET https://www.googleapis.com/analytics/v3/data/ga?quotaUser=1X3F2F2

Extremo v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet?quotaUser=1X3F2F2

Respuestas

Debido a que v4 te permite enviar varios objetos ReportRequest en una sola solicitud HTTP, obtienes un array de objetos de informe en la respuesta. Por cada ReportRequest que envíes, obtendrás el Report correspondiente en la respuesta.

informes

Un Informe v4 tiene tres campos de nivel superior: columnHeader, data y nextPageToken.

Debido a que el cuerpo de la respuesta v4 no incluye respuestas a todos los parámetros de consulta como lo hace la respuesta v3, para obtener una respuesta a un parámetro de consulta específico, la aplicación cliente debe agregar ese parámetro a ReportRequest.

Ya abordamos nextPageToken en la sección Paginación, así que primero observemos el objeto columnHeader.

Encabezado de columna

El encabezado de la columna contiene una lista de dimensiones con nombre y un objeto MetricHeader, que contiene una lista de objetos MetricHeaderEntry. Cada objeto MetricHeaderEntry especifica la métrica name y su type (moneda, porcentaje, etcétera) , que te ayuda a formatear la salida.

En los siguientes ejemplos, se compara el campo columnHeaders en una respuesta v3 con el campo columnHeader en una respuesta v4:

v3

"columnHeaders": [
    {
        "name":"ga:source",
        "columnType":"DIMENSION",
        "dataType":"STRING"
    },{
        "name":"ga:city",
        "columnType":"DIMENSION",
        "dataType":"STRING"
    },{
        "name":"ga:sessions",
        "columnType":"METRIC",
        "dataType":"INTEGER"
    },{
        "name":"ga:pageviews",
        "columnType":
        "METRIC",
        "dataType":"INTEGER"
    }
]

v4

"columnHeader": {
    "dimensions": [
        "ga:source",
        "ga:city"
    ],
    "metricHeader": {
        "metricHeaderEntries": [
            {
                "name": "ga:pageviews",
                "type": "INTEGER"
            },
            {
                "name": "ga:sessions",
                "type": "INTEGER"
            }
        ]
    }
},

Filas del informe

La API de Core Reporting v3 muestra los datos del informe en el array de rows, que contiene las dimensiones y métricas solicitadas.

La API de Analytics Reporting v4 muestra los datos del informe en un objeto ReportRow, que contiene un array de dimensiones y un array de objetos DateRangeValues, cada uno de los cuales contiene uno o dos períodos, como se muestra en el siguiente diagrama:

Filas del informe

Filas

v3

"rows": [
    [
        "google",
        "Philadelphia",
        "60",
        "5"
    ],
    [
        "google",
        "Johnstown",
        "21",
        "1"
    ],
    [
        "google",
        "Progress",
        "7",
        "1"
    ]
],

v4

"rows": [
    {
        "dimensions": [
            "google",
            "Philadelphia"
        ],
        "metrics": [
            {
                "values": [
                    "60",
                    "5"
                ]
            }
        ]
    },
    {
        "dimensions": [
            "google",
            "Johnstown"
        ],
        "metrics": [
            {
                "values": [
                    "21",
                    "1"
                ]
            }
        ]
    },
    {
        "dimensions": [
            "google",
            "Progress"
        ],
        "metrics": [
            {
                "values": [
                    "7",
                    "1"
                ]
            }
        ]
    }
],

Muestras de datos

Si se muestrean los resultados, la API de Core Reporting muestra el campo booleano containsSampledData, que se establece en true.

La API de Analytics Reporting v4 no muestra un valor booleano si los datos son muestreados, sino que muestra los campos samplesReadCounts y samplingSpaceSizes. Si los resultados no se muestrean, estos campos no se definirán. En el siguiente ejemplo de Python, se muestra cómo calcular si un informe contiene datos muestreados:

def ContainsSampledData(report):
  """Determines if the report contains sampled data.

   Args:
       report (Report): An Analytics Reporting API v4 response report.

  Returns:
      bool: True if the report contains sampled data.
  """
  report_data = report.get('data', {})
  sample_sizes = report_data.get('samplesReadCounts', [])
  sample_spaces = report_data.get('samplingSpaceSizes', [])
  if sample_sizes and sample_spaces:
    return True
  else:
    return False

A continuación, se muestra un ejemplo de respuesta que contiene datos muestreados de una solicitud con dos períodos. Los resultados se calcularon a partir de casi 500,000 muestras de un tamaño de espacio de muestreo de aproximadamente 15 millones de sesiones:

{
  "reports":
  [
    {
      "columnHeader": {
        ...
      },
      "data": {
        ...
        "samplesReadCounts": [ "499630","499630"],
        "samplingSpaceSizes": ["15328013","15328013"],
      }
    }
  ]
}

Análisis de la respuesta de la versión 4

En el siguiente código de muestra, se analiza y se imprime la respuesta de la API de Analytics Reporting v4:

Python

def printResponse(self, response):
  """Parses and prints the Analytics Reporting API v4 response"""

  for report in response.get('reports', []):
    columnHeader = report.get('columnHeader', {})
    dimensionHeaders = columnHeader.get('dimensions', [])
    metricHeaders = columnHeader.get('metricHeader', {}).get('metricHeaderEntries', [])
    rows = report.get('data', {}).get('rows', [])

    for row in rows:
      dimensions = row.get('dimensions', [])
      dateRangeValues = row.get('metrics', [])

      for header, dimension in zip(dimensionHeaders, dimensions):
        print header + ': ' + dimension

      for i, values in enumerate(dateRangeValues):
        print 'Date range (' + str(i) + ')'
        for metricHeader, value in zip(metricHeaders, values.get('values')):
          print metricHeader.get('name') + ': ' + value

Java

public static void printResponse(GetReportsResponse response) {

  for (Report report: response.getReports()) {
    ColumnHeader header = report.getColumnHeader();
    List<String> dimensionHeaders = header.getDimensions();
    List<MetricHeaderEntry> metricHeaders = header.getMetricHeader().getMetricHeaderEntries();
    List<ReportRow> rows = report.getData().getRows();

    for (ReportRow row: rows) {
      List<String> dimensions = row.getDimensions();
      List<DateRangeValues> metrics = row.getMetrics();
      for (int i = 0; i < dimensionHeaders.size() && i < dimensions.size(); i++) {
        System.out.println(dimensionHeaders.get(i) + ": " + dimensions.get(i));
      }

      for (int j = 0; j < metrics.size(); j++) {
        System.out.print("Date Range (" + j + "): ");
        DateRangeValues values = metrics.get(j);
        for (int k = 0; k < values.size() && k < metricHeaders.size(); k++) {
          System.out.println(metricHeaders.get(k).getName() + ": " + values.get(k));
        }
      }
    }
  }
}

Manejo de errores

Debido a que el formato de respuesta de error en la versión 4 es diferente al de la versión 3, actualiza tu código para manejar las respuestas de error de la versión 4.

En los siguientes ejemplos, se compara una respuesta de error en la v3 y la respuesta de error equivalente en la v4:

v3

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "insufficientPermissions",
    "message": "User does not have sufficient permissions for this profile.",

   }
  ],
  "code": 403,
  "message": "User does not have sufficient permissions for this profile."
 }
}

v4

{
 "error": {
  "code": 403,
  "message": "User does not have sufficient permissions for this profile.",
  "status": "PERMISSION_DENIED",
  "details": [
   {
    "@type": "type.googleapis.com/google.rpc.DebugInfo",
    "detail": "[ORIGINAL ERROR] generic::permission_denied: User does not have sufficient permissions for this profile. [google.rpc.error_details_ext] { message: \"User does not have sufficient permissions for this profile.\" }"
   }
  ]
 }
}