מדריך להעברת נתונים (מיגרציה) [ אפשר להוסיף "(מיגרציה)" אם ברור שמדובר על מעבר למוצר חדש או לגרסה חדשה של מוצר ]

המדריך הזה להעביר הנחיות ל-Core Reporting API גרסה 3 אל Analytics Reporting API גרסה 4.

מבוא

כדי לנצל את היתרונות של תכונות החדשות שהושקו ב-Analytics Reporting API v4, צריך להעביר את הקוד כדי להשתמש ב-API. במדריך הזה מוצגות בקשות ב-Core Reporting API v3 ובבקשות המקבילות בגרסה 4 של Analytics Reporting API כדי להקל על ההעברה.

העברה של Python

אם אתם מפתחי Python, השתמשו בספריית העזרה של GAV4 ב-GitHub כדי להמיר בקשות גרסה 3 של Google Analytics Core API API לבקשות של Analytics Reporting API גרסה 4

נקודות קצה

ל-Core Reporting API גרסה 3 ול-Analytics Reporting API v4 יש נקודות קצה ושיטות HTTP שונות:

נקודת קצה v3

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

נקודת קצה v4

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

הדוגמאות הבאות משווים בין בקשה בגרסה 3 לבין הבקשה המקבילה בגרסה 4:

גרסה 3

מסמכי עזר לגרסה 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

גרסה 4

מסמכי עזר לגרסה 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"
    }]
  }]
}

ספריות ושירות לקוחות

אם אתם משתמשים ב-Python, JavaScript או ספריית לקוח אחרת שמסתמכות על Google Discovery Service, עליכם לספק את המיקום של מסמך הגילוי עבור גרסה 4 של Reporting API.

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(...)

ספריות הלקוח של Java ו-PHP מוגדרות מראש, אבל אפשר להשתמש בשירות הגילוי ובמחולל Google APIs כדי ליצור אותן.

בקשות

הפניה ל-API v4 מתארת בפירוט את המבנה של גוף הבקשה. בקטעים הבאים מתוארים ההעברה של פרמטרים של בקשות בגרסה 3 לפרמטרים של בקשות בגרסה 4.

הצגת המזהים

בגרסה 3, פרמטר ids, שמקבל ""טבלה של מזהה&quot, הוא בפורמט ga:XXXX, שבו XXXX הוא מזהה התצוגה המפורטת (הפרופיל). בגרסה 4, מזהה תצוגה (פרופיל) מצוין בשדה viewId בגוף הבקשה.

הדוגמאות הבאות משווים בין הפרמטר ids בבקשת v3 לבין השדה viewId בבקשת v4:

גרסה 3

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

גרסה 4

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

טווחי תאריכים

בגרסה 4 של Analytics Reporting API תוכלו לציין כמה טווחי תאריכים בבקשה אחת. בשדה dateRanges מופיעה רשימה של אובייקטים של DateRange. בגרסה 3, אתם משתמשים בפרמטרים start-date ו-end-date כדי לציין טווח תאריכים בבקשה.

הדוגמאות הבאות משווים בין הפרמטרים start-date ו-end-date בבקשת v3 ובשדה dateRanges בבקשת v4:

גרסה 3

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

גרסה 4

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

מדדים

הפרמטר v3 metrics מייצג את השדה v4 metrics, שמקבל רשימה של אובייקטים מסוג Metric.

הדוגמאות הבאות משווים בין הפרמטרים של metrics בבקשת v3 לבין השדה metrics בבקשת v4:

גרסה 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,ga:sessions \
    ...

גרסה 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"
    },{
      "expression":"ga:sessions"
    }],
    ...
  }]
}

מידות

הפרמטר v3 dimensions תואם לשדה v4 dimensions שמקבל רשימה של אובייקטים .

הדוגמאות הבאות משווים בין הפרמטרים של dimensions בבקשת v3 לבין השדה dimensions בבקשת v4:

גרסה 3

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

גרסה 4

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

עוד כלים

הפרמטר v3 sort זהה לשדה v4orderBys, שמכיל רשימה של אובייקטים של OrderBy.

בגרסה 4, כדי למיין את התוצאות לפי ערך של מאפיין או מדד:

  • מזינים את השם או הכינוי שלו דרך השדה fieldName.
  • מציינים את סדר המיון (ASCENDING או DESCENDING) בשדה sortOrder.

הדוגמאות הבאות משווים את הפרמטר sort בבקשת v3 לבין השדה orderBy בבקשת v4. שתיהן ממוינות את המשתמשים בסדר יורד לפי מקורות בסדר אלפביתי:

גרסה 3

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

גרסה 4

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

רמת דגימה

הפרמטר v3 samplingLevel תואם לשדה v4 samplingLevel. בגרסה 3, ערכי samplingLevel הקבילים הם FASTER, HIGHER_PRECISION ו-DEFAULT. ובגרסה 4, הערכים המותרים של samplingLevel הם SMALL, LARGE ו-DEFAULT. חשוב לזכור שהעדכון של FASTER בגרסה 3 השתנה לגרסה SMALL בגרסה 4, HIGHER_PRECISION לגרסה LARGE.

הדוגמאות הבאות משווים את הפרמטר samplingLevel בבקשת v3 לבין השדה samplingLevel בבקשת v4:

גרסה 3

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

גרסה 4

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

פלחים

הפרמטר v3 segment מתאים לשדה v4 segments שמכיל רשימה של אובייקטים פילוח.

מזהי פלחים

בגרסה 4, כדי לבקש פלח לפי מזהה הפלח, צריך ליצור אובייקט פלח ולספק את המזהה שלו באמצעות השדה SegmentId.

הדוגמאות הבאות משווים את הפרמטר segment בבקשת v3 לבין השדה segments בבקשת v4:

גרסה 3

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

גרסה 4

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

פלחים דינמיים

בגרסה 4, כדי לבטא הגדרות מורכבות יותר של פלחים, השתמשו בשדה segments שכולל אובייקט DynamicSegment.

הדוגמאות הבאות משווים את הפרמטר segment בבקשת v3 לבין השדה segments שמכיל אובייקט DynamicSegment בבקשת v4:

גרסה 3

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

גרסה 4

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" ]
                  }
                }]
              }]
            }
          }]
        }
      }
    }]
  }]
}

אפשר לשלב תנאים ורצפים בפלח:

גרסה 3

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

גרסה 4

  "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"]
                    }
                  }]
                }]
              }]
            }
          }]
        }
      }
    }]
  }]

תחביר של פלחים v3

השדה SegmentId ב-v4 API תומך בתחביר הפילוח ב-v3 API.

הדוגמאות הבאות מראות כיצד הפרמטר segment בבקשת v3 נתמך על ידי השדה segmentId בבקשה המקבילה בגרסה 4:

גרסה 3

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

גרסה 4

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

מסננים

גרסה 4 משתמשת במסננים dimensionFilterClauses כדי לסנן מאפיינים ובטבלה metricFilterClauses אפשר לסנן מדדים. dimensionFilterClauses מכיל רשימה של אובייקטים מסוג dimensionFilter. בנוסף, פרמטר metricFilterClauses מכיל רשימה של אובייקטים MetricFilter.

הדוגמאות הבאות משווים את הפרמטר filters בבקשת v3 לבין השדה dimensionFilterClauses בבקשת v4:

גרסה 3

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

גרסה 4

  "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"]
            }]
      }]
  }]

תחביר של מסנני v3

אף על פי שהשדה filtersExpression ב-v4 תומך בתחביר filters בגרסה 3, השתמשו ב-dimensionFilterClauses וב-metricFilterClauses כדי לסנן את המאפיינים והמדדים.

הדוגמאות הבאות מראות כיצד הפרמטר filters בבקשת v3 נתמך על ידי השדה filtersExpression בבקשה המקבילה בגרסה 4:

גרסה 3

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

גרסה 4

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

שורות ריקות

הפרמטר v3include-empty-rows תואם לשדה 'includeEmptyRows' בגרסה 4. כברירת מחדל, הפרמטר v3 מקבל את הערך true, ואילו בגרסה 4 שדה ברירת המחדל הוא false. אם לא הוגדר ערך בגרסה 3, עליכם להגדיר את הערך ל-true ב-v4.

הדוגמאות הבאות משווים את הפרמטר include-empty-rows בבקשת v3 לשדה includeEmptyRows בבקשת v4:

גרסה 3

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

גרסה 4

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

עימוד

כדי להשתמש בעימוד בין מספר גדול של תוצאות, המערכת משתמשת בגרסה pageToken ובשדה pageSize. ה-pageToken מתקבל מהנכס nextPageToken של אובייקט תגובה.

הדוגמאות הבאות משווים בין הפרמטרים start-index ו-max-results בבקשת v3 לבין השדות pageToken ו-pageSize בבקשת v4:

גרסה 3

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

גרסה 4

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

פרמטרים רגילים

ב-Analytics Reporting API v4 יש תמיכה לרוב הפרמטרים הרגילים של השאילתה ב-v3 API, חוץ מהפרמטרים userIp ו-callback.

הדוגמאות הבאות משווים את הפרמטר quotaUser בבקשת v3 לזה שמופיע בבקשת v4:

נקודת קצה v3

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

נקודת קצה v4

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

תגובות

מאחר שגרסה 4 מאפשרת לשלוח כמה אובייקטים של ReportRequest בבקשת HTTP אחת, תקבלו מערך של אובייקטים של דוחות בתגובה. עם כל ReportRequest נשלח, תקבלו דוח תואם בתגובה.

דוחות

דוח v4 כולל שלושה שדות ברמה העליונה: columnHeader, data ו-nextPageToken.

מכיוון שגוף התגובה v4 לא כולל תגובות לכל הפרמטרים של השאילתה כמו בתגובת גרסה 3, כדי לקבל תשובה לפרמטר של שאילתה ספציפית, אפליקציית הלקוח צריכה להוסיף את הפרמטר הזה ל-ReportRequest.

כבר התייחסנו אל nextPageToken בקטע העימוד, ועכשיו אנחנו צריכים לבדוק את האובייקט columnHeader.

כותרת עמודה

כותרת העמודה כוללת רשימה של מאפיינים (dimensions) ואובייקט MetricHeader, שמכיל רשימה של אובייקטים של MetricHeaderEntry. כל אובייקט MetricHeaderEntry מציין את המדד name ואת type שלו (מטבע, אחוז וכו') , שעוזר לעצב את הפלט.

הדוגמאות הבאות משווים את השדה columnHeaders בתגובת v3 לשדה columnHeader בתגובת v4:

גרסה 3

"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"
    }
]

גרסה 4

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

שורות דיווח

גרסה 3 של ה-Core Reporting API מחזירה את נתוני הדוח במערך rows, שמכיל את המאפיינים והמדדים המבוקשים.

גרסה 4 של Analytics Reporting API מחזירה את נתוני הדוח באובייקט ReportRow, שמכיל מערך של מאפיינים ומערך של DateRangeValues, שכל אחד מהם מכיל טווח תאריכים אחד או שניים, כפי שמתואר בתרשים הבא:

שורות דיווח

Rows

גרסה 3

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

גרסה 4

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

הנתונים שנדגמו

אם התוצאות הן דגימה, Core Reporting API v3 מחזיר את השדה הבוליאני containsSampledData, שמוגדר ל-true.

גרסה 4 של Analytics Reporting API לא מחזירה בוליאני אם הנתונים נדגמים. במקום זאת, ה-API מחזיר את השדות samplesReadCounts ואת השדות samplingSpaceSizes. אם התוצאות לא נדגמו, השדות האלה לא יוגדרו. הדוגמה הבאה ב-Python מראה איך לחשב אם דוח מכיל נתונים שנדגמו:

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

לפניכם דוגמה לתגובה שמכילה נתונים לדוגמה מבקשה שכוללת שני טווחי תאריכים. התוצאות חושבו כמעט מ-500 אלף דוגמאות לגודל דגימה של כ-15 מיליון ביקורים:

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

מנתח את התגובה v4

הקוד לדוגמה הבא מנתח ומדפיס את התגובה Analytics Reporting API 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));
        }
      }
    }
  }
}

טיפול בשגיאות

מאחר שהפורמט של תגובת השגיאה בגרסה 4 שונה מהפורמט בגרסה 3, צריך לעדכן את הקוד כדי לטפל בתגובות השגיאה 4.

הדוגמאות הבאות משווים בין תגובת שגיאה בגרסה 3 לבין התגובה המקבילה לשגיאה בגרסה 4:

גרסה 3

{
 "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."
 }
}

גרסה 4

{
 "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.\" }"
   }
  ]
 }
}