0

我正在Visual Studio(VB)中编写一个Windows服务应用程序,用于轮询用户Google日历以查看在接下来的5分钟内发生的任何事件。从Windows服务访问Google Calendar API

理想情况下,我希望我的服务生成凭据,但我不认为Windows服务可以弹出浏览器页面来验证某人。目前,我正在从可以弹出浏览器的控制台应用程序生成特定位置的凭据,并让该服务在该位置查找凭据。我想完全摆脱控制台应用程序,但是如果有必要,我将在安装该服务的批处理文件中运行它。

我遇到的最大问题是生成凭证文件(次要问题),更重要的是刷新它,以便它在一小时后不会过期(主要问题)。

这里是我的窗口服务代码(我跑我的控制台应用程序,并允许访问我的日历后,这个工作完全正常的小时):

Dim Scopes As String() = {CalendarService.Scope.CalendarReadonly} 
Dim ApplicationName As String = "Google Calendar API .NET Quickstart" 

Private Sub writeUpdateTimerEvent(source As Object, e As ElapsedEventArgs) 

    Dim credential As UserCredential 

    Try 

     Using stream = New FileStream("FILE PATH TO client_secret.json", FileMode.Open, FileAccess.Read) 

      Dim credPath As String = "FILE PATH TO WHERE MY CONSOLE APP IS STORING THE CREDENTIALS FILE" 
      credPath = Path.Combine(credPath, ".credentials/calendar-dotnet-quickstart.json") 

      credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result 

      If credential Is Nothing Then 
       credential.RefreshTokenAsync(CancellationToken.None) 
      End If 

     End Using 

     ' Create Google Calendar API service. 
     Dim service = New CalendarService(New BaseClientService.Initializer() With { 
      .HttpClientInitializer = credential, 
      .ApplicationName = ApplicationName 
     }) 

     ' Define parameters of request. 
     Dim request As EventsResource.ListRequest = service.Events.List("primary") 
     request.TimeMin = DateTime.Now 
     request.TimeMax = DateTime.Now.AddMinutes(5) 
     request.ShowDeleted = False 
     request.SingleEvents = True 
     request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime 

     ' List events. 
     Dim eventsString As String = "" 
     Dim events As Events = request.Execute() 

     If events.Items IsNot Nothing AndAlso events.Items.Count > 0 Then 
      'This is where I do my operations on events occuring in the next 5 minutes 
      EventLog1.WriteEntry("Event occuring within 5 minutes") 
     Else 
      EventLog1.WriteEntry("No event occuring within 5 minutes") 
     End If 
    Catch ex As Exception 
     EventLog1.WriteEntry("error grabbing events." & Environment.NewLine & ex.message) 
    End Try 
End Sub 

这里是我的控制台应用程序代码(几乎相同如上所示):

Module Module1 

Dim Scopes As String() = {CalendarService.Scope.CalendarReadonly} 
Dim ApplicationName As String = "Google Calendar API .NET Quickstart" 

Sub Main() 
    Dim credential As UserCredential 

    Using stream = New FileStream("client_secret.json", FileMode.Open, FileAccess.Read) 
     Dim credPath As String = "SAME FILE PATH AS IN MY SERVICE" 
     credPath = Path.Combine(credPath, ".credentials/calendar-dotnet-quickstart.json") 

     credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result 
     Console.WriteLine(Convert.ToString("Credential file saved to: ") & credPath) 
    End Using 

    ' Create Google Calendar API service. 
    Dim service = New CalendarService(New BaseClientService.Initializer() With { 
      .HttpClientInitializer = credential, 
      .ApplicationName = ApplicationName 
     }) 

    ' Define parameters of request. 
    Dim request As EventsResource.ListRequest = service.Events.List("primary") 
    request.TimeMin = DateTime.Now 
    request.ShowDeleted = False 
    request.SingleEvents = True 
    request.MaxResults = 10 
    request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime 

    ' List events. 
    Dim events As Events = request.Execute() 
    Console.WriteLine("Upcoming events:") 
    If events.Items IsNot Nothing AndAlso events.Items.Count > 0 Then 
     For Each eventItem As Object In events.Items 
      Dim [when] As String = eventItem.Start.DateTime.ToString() 
      If [String].IsNullOrEmpty([when]) Then 
       [when] = eventItem.Start.[Date] 
      End If 
      Console.WriteLine("{0} ({1})", eventItem.Summary, [when]) 
     Next 
     Console.WriteLine("You may now close this window.") 
     System.Environment.Exit(0) 
    Else 
     Console.WriteLine("No upcoming events found.") 
    End If 
    Console.Read() 

End Sub 

End Module 
+0

不确定这是否有帮助,但是您是否检查了[.NET Quickstart](https://developers.google.com/google-apps/calendar/quickstart/dotnet)? – noogui

+0

.NET Quickstart之后是我到了这一步,我的代码基本上是直接从该指南,从CSharp转换到VB。 – JonW

+0

我相信你应该使用服务帐户。 https://developers.google.com/identity/protocols/OAuth2#serviceaccount –

回答

0

使用服务帐户而不是用户帐户立即工作。无需处理生成凭证或刷新令牌。

Dim serviceAccountEmail As [String] = ConfigurationManager.AppSettings("ServiceAcct") 

Dim certificate = New X509Certificate2("key.p12", "notasecret", X509KeyStorageFlags.Exportable) 


Dim credential1 As New ServiceAccountCredential(New ServiceAccountCredential.Initializer(serviceAccountEmail) With { 
     .Scopes = Scopes 
    }.FromCertificate(certificate)) 


Dim service = New CalendarService(New BaseClientService.Initializer() With { 
     .HttpClientInitializer = credential1, 
     .ApplicationName = ApplicationName 
    })