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 
    })