2012-10-19 15 views
15

Zdałem sobie sprawę, że to pytanie zostało wcześniej zadane, ale z niewielką ilością kodu przykładowego, więc proszę ponownie, ale przynajmniej z pewnym ukierunkowaniem.Jak korzystać z konta usługi, aby uzyskać dostęp do interfejsu API Google Analytics w wersji 3 z .NET C#?

Po godzinach poszukiwań przedstawiłem następujące częściowe wdrożenie.

namespace GoogleAnalyticsAPITest.Console 
{ 
    using System.Security.Cryptography.X509Certificates; 
    using DotNetOpenAuth.OAuth2; 
    using Google.Apis.Analytics.v3; 
    using Google.Apis.Analytics.v3.Data; 
    using Google.Apis.Authentication.OAuth2; 
    using Google.Apis.Authentication.OAuth2.DotNetOpenAuth; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      log4net.Config.XmlConfigurator.Configure(); 
      string Scope = Google.Apis.Analytics.v3.AnalyticsService.Scopes.Analytics.ToString().ToLower(); 
      string scopeUrl = "https://www.googleapis.com/auth/" + Scope; 
      const string ServiceAccountId = "nnnnnnnnnnn.apps.googleusercontent.com"; 
      const string ServiceAccountUser = "[email protected]"; 
      AssertionFlowClient client = new AssertionFlowClient(
       GoogleAuthenticationServer.Description, new X509Certificate2(@"7039572692013fc5deada350904f55bad2588a2a-privatekey.p12", "notasecret", X509KeyStorageFlags.Exportable)) 
      { 
       Scope = scopeUrl, 
       ServiceAccountId = ServiceAccountId//,ServiceAccountUser = ServiceAccountUser 
      }; 
      IAuthorizationState state = AssertionFlowClient.GetState(client); 
      AnalyticsService service = new AnalyticsService(authenticator); 
      string profileId = "ga:xxxxxxxx"; 
      string startDate = "2010-10-01"; 
      string endDate = "2010-10-18"; 
      string metrics = "ga:visits"; 
      DataResource.GaResource.GetRequest request = service.Data.Ga.Get(profileId, startDate, endDate, metrics); 
      request.Dimensions = "ga:date"; 
      GaData data = request.Fetch(); 
     } 
    } 
} 

Mam kilka problemów. Wywołanie AssertionFlowClient.GetState(client) prowadzi do "invalid_scope" odpowiedź, jak widać w dzienniku DotNetOpenAuth z

2012-10-19 13: 27: 36272 (GMT-4) [8] Informacje DotNetOpenAuth - DotNetOpenAuth, wersja = 4,0 .0.11165, Kultura = neutralny, PublicKeyToken = 2780ccd10d57b246 (urzędowy) 2012-10-19 13: 27: 36 284 (GMT-4) [8] DEBUG DotNetOpenAuth.Messaging.Channel - Przygotowanie do wysłania komunikatu AssertionFlowMessage (2.0). 19.10.2012 13: 27: 36294 (GMT-4) [8] Informacje DotNetOpenAuth.Messaging.Channel - Gotowe AssertionFlowMessage wychodzący (2,0) wiadomości do https://accounts.google.com/o/oauth2/token: grant_type: zapewnienie assertion_type: http://oauth.net/grant_type/jwt/1.0/bearer zapewnienie: (a wiązka zakodowanych znaków tutaj)

2012-10-19 13: 27: 36,296 (GMT-4) [8] DEBUG DotNetOpenAuth.Messaging.Channel - Wysyłanie żądania AsercjiFlowMessage. 2012-10-19 13: 27: 36 830 (GMT-4) [8] DEBUG DotNetOpenAuth.Http - HTTP POST https://accounts.google.com/o/oauth2/token 2012-10-19 13: 27: 36,954 (GMT-4) [8] ERROR DotNetOpenAuth.Http - WebException z https://accounts.google.com/o/oauth2/token: { "błąd": "invalid_scope" }

próbowałem określając jedną lub obie ServiceAccountId i ServiceAccountUser bez powodzenia.

Po drugie, nawet jeśli otrzymam IAuthorizationState, nie jestem pewien, jak uzyskać IAuthenticator, które można przekazać do konstruktora AnalyticsService.

Poniżej znajduje się plik web.config Używam do włączania rejestrowania DotNetOpenAuth.

<?xml version="1.0"?> 
<configuration> 
    <configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.10.0, Culture=neutral, publicKeyToken=1b44e1d426115821" /> 
    <!--<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false"/>--> 
    <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth"> 
     <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/> 
     <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/> 
     <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/> 
     <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/> 
    </sectionGroup> 
    </configSections> 
    <log4net> 
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 
     <file value="DotNetOpenAuth.log"/> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maxSizeRollBackups value="10"/> 
     <maximumFileSize value="100KB"/> 
     <staticLogFileName value="true"/> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/> 
     </layout> 
    </appender> 
    <appender name="TracePageAppender" type="OpenIdProviderWebForms.Code.TracePageAppender, OpenIdProviderWebForms"> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/> 
     </layout> 
    </appender> 
    <!-- Setup the root category, add the appenders and set the default level --> 
    <root> 
     <level value="ALL"/> 
     <appender-ref ref="RollingFileAppender"/> 
     <appender-ref ref="TracePageAppender"/> 
    </root> 
    <!-- Specify the level for some specific categories --> 
    <logger name="DotNetOpenAuth"> 
     <level value="ALL"/> 
    </logger> 
    </log4net> 
    <dotNetOpenAuth> 
    <!-- This is an optional configuration section where aspects of dotnetopenauth can be customized. --> 
    <!-- For a complete set of configuration options see http://www.dotnetopenauth.net/developers/code-snippets/configuration-options/ --> 
    <!--<messaging clockSkew="00:10:00" lifetime="00:03:00" strict="true">--> 
    <!--<messaging> 
     <untrustedWebRequest timeout="00:00:30" readWriteTimeout="00:00:01.500" maximumBytesToRead="1048576" maximumRedirections="10"> 
     <whitelistHosts> 
      --> 
    <!-- Uncomment to enable communication with localhost (should generally not activate in production!) --> 
    <!-- 
      <add name="localhost"/>    
     </whitelistHosts> 
     </untrustedWebRequest> 
    </messaging>--> 
    <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. --> 
    <reporting enabled="false"/> 
    </dotNetOpenAuth> 
    <appSettings> 
    <!--<add key="log4net.Internal.Debug" value="true" />--> 
    </appSettings> 
    <runtime> 
    </runtime> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
    </startup> 
</configuration> 

Odpowiedz

11

Poniższy kod, poprawione z mojego pierwotnego pytania, bazuje na przykład dostarczonych przez Ian Fraser w:

https://groups.google.com/forum/#!msg/google-search-api-for-shopping/4uUGirzH4Rw/__c0e4hj0ekJ

Jego kod skierowana trzy kwestie:

  1. Wydaje się, jakby AnalyticsService.Scopes.AnalyticsReadonly nie działa, przynajmniej nie dla mnie lub dla sposobu, w jaki to robię.
  2. Z jakiegoś powodu usługa ServiceAccountUser musi zostać przypisana do właściwości ServiceAccountId instancji AssertionFlowClient.
  3. OAuth2Authenticator zapewnia IAuthenticator, którego szukałem.

w projekcie, obejmują odniesienia do:

  • lib \ DotNetOpenAuth.dll
  • lib \ Google.Apis.dll
  • Lib \ Google.Apis.Authentication.OAuth2.dll
  • Services \ AnalyticsService \ Google.Apis.Analytics.v3.dll

-

namespace GoogleAnalyticsAPITest.Console 
{ 
    using System.Security.Cryptography.X509Certificates; 
    using Google.Apis.Analytics.v3; 
    using Google.Apis.Analytics.v3.Data; 
    using Google.Apis.Authentication.OAuth2; 
    using Google.Apis.Authentication.OAuth2.DotNetOpenAuth; 
    using Google.Apis.Util; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      log4net.Config.XmlConfigurator.Configure();    
      const string ServiceAccountId = "nnnnnnnnnnn.apps.googleusercontent.com"; 
      const string ServiceAccountUser = "[email protected]"; 
      AssertionFlowClient client = new AssertionFlowClient(
       GoogleAuthenticationServer.Description, new X509Certificate2(@"value-privatekey.p12", "notasecret", X509KeyStorageFlags.Exportable)) 
      { 
       Scope = AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue(), 
       ServiceAccountId = ServiceAccountUser //Bug, why does ServiceAccountUser have to be assigned to ServiceAccountId 
       //,ServiceAccountUser = ServiceAccountUser 
      }; 
      OAuth2Authenticator<AssertionFlowClient> authenticator = new OAuth2Authenticator<AssertionFlowClient>(client, AssertionFlowClient.GetState);    
      AnalyticsService service = new AnalyticsService(authenticator);    
      string profileId = "ga:64968920"; 
      string startDate = "2010-10-01"; 
      string endDate = "2010-10-31"; 
      string metrics = "ga:visits"; 
      DataResource.GaResource.GetRequest request = service.Data.Ga.Get(profileId, startDate, endDate, metrics); 
      request.Dimensions = "ga:date"; 
      GaData data = request.Fetch();    
     } 

    } 
} 
+0

Wygląda na to, że poprawny zasięg tylko do odczytu to https://www.googleapis.com/auth/analytics.readonly. Różni się to od konwersji wartości wyliczeniowej na łańcuch. Ponadto nie musiałem ustawiać ServiceAccountUser. –

+0

@BenMills możesz wyjaśnić, w jaki sposób jesteś uwierzytelniony? Zgaduję, że mówisz, że ustawiłeś ServiceAccountId na wartość nnnnnnnnnnn.apps.googleusercontent.com, ale nie jestem pewien, co masz na myśli. Zmodyfikowałem kod, aby ustawić zakres na "analytics.readonly", ponieważ jest to prawdopodobnie podstawowy sposób, w jaki ludzie będą go używać. –

+0

Przykro mi, miałeś rację. Ustawiłem ServiceAccountId na [email protected] Nie musiałem w żaden sposób brać pod uwagę nnnnnnnnnnn.apps.googleusercontent.com. –

2

Oto mój przykład pracy zamieszczone tutaj [1]: Automated use of google-api-dotnet-client with OAuth 2.0 I włożył wiele badań nad znalezieniem i składając kod razem nadzieję, że to zaoszczędzić trochę czasu.

+0

jestem z pewnością poświęcisz mnóstwo czasu temu rozwiązaniu. Wygląda na to, że musiałeś przejść na niższy poziom niż interfejs API, którego używam. Jednak twój przykład używa raczej NativeApplicationClient niż AssertionFlowClient. Doceniam opinie. –

1

chodzi Richard Collette odpowiedzi, należy uważać, że za pomocą jego metodę, jeśli chcesz korzystać z Analytics API w trybie tylko do odczytu, poprawny sposób z niego korzystać to:

string Scope = "analytics.readonly" 

i nie

string Scope = AnalyticsService.Scopes.AnalyticsReadOnly.ToString().ToLower() 

ponieważ wydaje się mówić, że jest błąd. W rzeczywistości błąd polega na tym, że metoda .toString() zwraca analyticsreadonly i NOT analytics.readonly, co jest sposobem, który lubi Google. to jest to!

+1

Świetna informacja. Powiedziałbym, że to błąd w enum. Jaki jest sens tych wyliczeń, jeśli nie możesz ich użyć? –

+1

@RichardCollette W przestrzeni nazw Google.Apis.Util dostępna jest metoda rozszerzenia do odzyskiwania wartości ciągu z wyliczenia AnalyticsService.Scopes, AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue(). –

3
string scope = Google.Apis.Util.Utilities.GetStringValue(AnalyticsService.Scopes.AnalyticsReadonly); 
+0

To jest metoda rozszerzenia. Nie musisz tego tak nazywać. Zobacz powyższe rozwiązanie. –

4

byłem sprawdzeniu Analytics API wczoraj i zauważyłem, jak to jest i nieudokumentowane żadnych próbek itp

wszelkie sposoby, jakie stworzył bibliotekę, które można wykorzystać do analityki dostępu łatwo z kilku liniach i dokonać bezpośredniego wiązania z danymi do DataTables na dane zwracane jest open source na github więc nie krępuj się przyczynić :)

https://github.com/rmostafa/DotNetAnalyticsAPI

Wykorzystanie

Analytics.AnalyticsManager manager = new Analytics.AnalyticsManager(Server.MapPath("~/bin/privatekey.p12"), "YOUR_EMAIL"); 
      manager.LoadAnalyticsProfiles(); 


List<Analytics.Data.DataItem> metrics = new List<Analytics.Data.DataItem>(); 
metrics.Add(Analytics.Data.Visitor.Metrics.visitors); 
metrics.Add(Analytics.Data.Session.Metrics.visits); 
List<Analytics.Data.DataItem> dimensions = new List<Analytics.Data.DataItem>(); 
dimensions.Add(Analytics.Data.GeoNetwork.Dimensions.country); 
dimensions.Add(Analytics.Data.GeoNetwork.Dimensions.city); 


System.Data.DataTable table = manager.GetGaDataTable(DateTime.Today.AddDays(-3), DateTime.Today, metrics, dimensions, null, metrics); 

Istnieje bezpośrednie odwzorowanie kodu dla wszystkich Google API polecenia Reporting skategoryzowane w taki sam sposób jak API, więc można nawet bez czytania dokumentacji API w ogóle, ponieważ wszystkie funkcje nie są udokumentowane w atrybutach, jakie pisał kod, który analizowany pełną dokumentację API i zasobami metryk, wymiarów, Obliczone funkcje w XML, że generowany od zajęć fizycznych, które można użyć bezpośrednio jak w przykładzie powyżej, to zabawa się bawić :) cieszyć

https://github.com/rmostafa/DotNetAnalyticsAPI

Powiązane problemy