从Windows服务访问Google Calendar API
问题描述:
我正在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
答
使用服务帐户而不是用户帐户立即工作。无需处理生成凭证或刷新令牌。
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
})
不确定这是否有帮助,但是您是否检查了[.NET Quickstart](https://developers.google.com/google-apps/calendar/quickstart/dotnet)? – noogui
.NET Quickstart之后是我到了这一步,我的代码基本上是直接从该指南,从CSharp转换到VB。 – JonW
我相信你应该使用服务帐户。 https://developers.google.com/identity/protocols/OAuth2#serviceaccount –