1

Ich erstelle einen LED-Grid-Ticker, der auf einer Raspberry Pi ausgeführt wird und Google Analytics-Daten über die Google Analytics API mit Node.js erfasst. Es zählt von mehreren Websites und scrollt die Statistiken über das Raster.Node.js: Google Analytics API: Wie mache ich autorisierte schreibgeschützte Management-API-Anfragen mit einem "Dienstkonto"?

Ich könnte Hilfe verwenden, die Kontoelemente über die Management API, speziell Konto-ID, Eigenschaft IDs und Ansichts-IDs auf manuelle Arbeit zu speichern. Ich bekomme Fehler in diesem Bereich (siehe unten).

Dies schien der Job für eine Service Account. Nachdem ich ein Google Cloud-Projekt here eingerichtet und dann ein Dienstkonto here eingerichtet hatte, fügte ich die E-Mail-Adresse, die in der heruntergeladenen Autorisierung enthalten war, als Property-Benutzer hinzu (Berechtigungen lesen/analysieren), sofern zutreffend in den Google Analytics-Administratoreinstellungen. Damit kann ich erfolgreich Analytics-Daten für eine bekannte Ansicht ID (nachgeschlagen manuell in Google Analytics admin, dargestellt ID auf einer Ansichtseinstellungen Seite), mit diesem abrufen:

'use strict'; 

////////////// 
// includes // 
////////////// 

var google = require('googleapis'); 
var fs = require('fs'); 
var Promise = require('promise'); 

////////////// 
// settings // 
////////////// 

//the service account auth file downloaded from Google Cloud 
var serviceAccountInfoPath = './secrets.json'; 

//view id with 'ga:' prefix 
//I want this to soon be an array of ids looked up by an authenticated API requested 
var viewID = 'ga:999999999'; 

//////// 
// go // 
//////// 

// go get it all 
var go = function() { 
    loadServiceAccountInfo() 
    .then(function(serviceAccountInfo) { 
     return getJwtClient(serviceAccountInfo); 
    }) 
    .then(function(jwtClient) { 
     var client = jwtClient; 
     var analytics = google.analytics('v3'); 
     return getThisYearViewAnalytics(client, analytics, viewID); 
    }) 
    .then(function(result) { 
     console.log('total users: ' + result.totalsForAllResults["ga:users"]); 
     console.log('total sessions: ' + result.totalsForAllResults["ga:pageviews"]); 
     console.log('total pageviews: ' + result.totalsForAllResults["ga:sessions"]); 
    }) 
    .catch(function(error) { 
     console.log("go promise chain failed", error); 
    }); 
}; 

// load the Google service account login details 
var loadServiceAccountInfo = function() { 
    return new Promise(function(resolve, reject) { 
     fs.readFile(serviceAccountInfoPath, 'utf8', function(error, serviceAccountInfoData) { 
      if(error) { 
       console.log('loadServiceAccountInfo failed: ' + error); 
       reject(error); 
      } else { 
       var serviceAccountInfo = JSON.parse(serviceAccountInfoData); 
       resolve(serviceAccountInfo); 
      } 
     }); 
    }); 
}; 

//return a an authenticated Google API client 
var getJwtClient = function(serviceAccountInfo) { 
    return new Promise(function(resolve, reject) { 
     var jwtClient = new google.auth.JWT(serviceAccountInfo.client_email, null, serviceAccountInfo.private_key, ['https://www.googleapis.com/auth/analytics.readonly'], null); 
     jwtClient.authorize(function (error, tokens) { 
      if (error) { 
       console.log('getJwtClient failed: ' + error); 
       reject(error); 
      } else { 
       resolve(jwtClient); 
      } 
     }); 
    }); 
}; 

//this is a test query to get the last year of data for a single view id 
var getThisYearViewAnalytics = function(client, analytics, viewID) { 
    return new Promise(function(resolve, reject) { 
     analytics.data.ga.get({ 
      'auth': client, 
      'ids': viewID, 
      'metrics': 'ga:sessions,ga:pageviews,ga:users', 
      'start-date': '365daysAgo', 
      'end-date': 'today', 
     }, 
     function (error, response) { 
      if (error) { 
       console.log('getThisYearViewAnalytics failed: ' + error); 
       reject(error); 
      } else { 
       resolve(response); 
      } 
     }); 
    }); 
}; 

//ready, set, go! 
go(); 

Das ist eine gute Fortschritte, aber ich anfangen Es treten Authentifizierungsfehler auf, wenn versucht wird, mit ID (s) zu verwenden, die zum Auflisten von Ansichten benötigt werden (was ebenfalls zu denselben Fehlern führt, wenn Sie die Konto-ID kennen).

Ich vermute, dass die Antwort ist, dass ich OAuth verwenden muss, aber wenn ja, wie? Ist ein Dienstkonto keine Option mehr? Ich bin mir nicht sicher, wie ich damit fortfahren würde, wenn das Dienstkonto und das Hardwaregerät nicht mit den üblichen OAuth-Hin-und-Her-Benutzerinteraktionen arbeiten. Vielleicht setze ich gerade etwas falsches im JWT Klienten, der oben benutzt wird?

UDPATE:

Added Informationen für diejenigen, die dies in Zukunft zu lesen: sure Nachdem richtig eingestellt Leseberechtigungen wurden, konnte ich Google Analytics-Konto mit diesem zur Liste:

analytics.management.accounts.list({'auth': client}, function(error, response) { 
    console.log(error); 
    console.log(response); 
}); 

Hinweis: Dies entspricht nicht dem Versprechungsmuster, das ich oben verwendet habe, sondern vermittelt die Idee, wie das Modul node.js googleapis funktioniert.

+1

Wenn Sie den Zugriff auf das Dienstkonto gewährt haben. Haben Sie das auf Kontoebene gemacht? Es sollte kein Problem sein, die Accounts von Management API zu lesen. Versuchen Sie es stattdessen schneller https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtReference/management/accountSummaries/list – DaImTo

+0

auch können Sie die Fehler veröffentlichen. – DaImTo

+0

Aha! Diese sind auf View-Ebene autorisiert. Ich werde innerhalb der nächsten Stunde Fehler testen und posten. Danke für diesen Gedanken! –

Antwort

1

Bei Verwendung eines Dienstkontos mit Google Analytics API. Sie müssen sicherstellen, dass Sie die Berechtigung auf Kontoebene hinzufügen. Ich weiß nicht, warum es die Kontoebene sein muss Ich weiß nur, dass es nicht anders geht.

+0

Das ist richtig. View-Abfragen können mit ansichtsspezifischen Berechtigungen durchgeführt werden (manuelle Eingabe von View-IDs in Skripts erforderlich). Das Abrufen von Kontenlisten, die zu Listen mit Eigenschaften und Ansichten führen, erfordert, dass die Berechtigungen im Konto festgelegt werden, nicht nur in der Ansicht. –

+0

BTW, wenn Sie dieses Projekt veröffentlichen, würde ich gerne den Link – DaImTo

+0

Ich bin glücklich, zu teilen, und werde, nachdem ich [dieses Projekt] (https://github.com/owntheweb/sos-orbiting-Objects) zuerst fertig.Danke für das Erwähnen. –