2012-06-30 111 views
2

我一直在閱讀Google Calendar API和google-api-ruby-client庫的文檔,但我在理解它們時遇到了很多麻煩。如何在Google Calendar API中使用google-api-ruby-client?

我有一個Rails應用程序,其前端允許用戶創建名爲Events的對象,並將它們保存在我的服務器上的數據庫中。我想要的是,在將這些事件保存在數據庫中後,我想調用Google Calendar API在Google日曆上創建事件(該服務器已創建,並且只有服務器纔有權修改該日曆)。

我有很多問題搞清楚如何使用紅寶石庫進行API驗證。使用OAuth2對我來說沒有任何意義,因爲我不需要授權任何用戶,因爲我對他們的數據不感興趣。我查看了服務帳戶(http://code.google.com/p/google-api-ruby-client/wiki/ServiceAccounts),但看起來Google帳戶不受服務帳戶支持。

任何人有任何想法?這是我與(使用服務帳戶)的實驗代碼:

@client = Google::APIClient.new(:key => 'my_api_key') 
path_to_key_file = '/somepath/aaaaaa-privatekey.p12' 
passphrase = 'my_pass_phrase' 
key = Google::APIClient::PKCS12.load_key(path_to_key_file, passphrase) 
asserter = Google::APIClient::JWTAsserter.new(
     '[email protected]', 
     'https://www.googleapis.com/auth/calendar', 
     key) 
# To request an access token, call authorize: 
@client.authorization = asserter.authorize() 

calendar = @client.discovered_api('calendar', 'v3') 

event = { 
    'summary' => 'Appointment', 
    'location' => 'Somewhere', 
    'start' => { 
     'dateTime' => '2012-06-03T10:00:00.000-07:00' 
    }, 
    'end' => { 
     'dateTime' => '2012-06-03T10:25:00.000-07:00' 
    }, 
    'attendees' => [ 
     { 
      'email' => 'attendeeEmail' 
     }, 
     #... 
     ] 
    } 

result = @client.execute!(:api_method => calendar.events.insert, 
          :parameters => {'calendarId' => 'primary'}, 
          :body => JSON.dump(event), 
          :headers => {'Content-Type' => 'application/json'}) 

那麼當然我收到此錯誤信息:谷歌:: APIClient :: ClientError(用戶必須對谷歌日曆簽署了),因爲服務帳戶不支持Google日曆。

回答

1

我認爲你仍然需要一個真正的谷歌用戶來承載日曆實例。但是,一旦你有了以你的身份創建的日曆,你可以與服務帳戶分享。在日曆的共享設置中,只需使用服務帳戶的電子郵件地址(我的服務帳戶以@ developer.gserviceaccount.com結尾)。利用正確的共享權限,您的服務帳戶可以創建/更改事件信息,而不會混淆您的特定身份。從那裏,您可以與更多的人(或公衆)分享日曆,以便消費鏡像事件。

我遇到的另一個問題是,似乎您只能在每個到期期間授權()服務帳戶一次。您必須保存您獲得的令牌並在接下來的一小時內重新使用它,然後獲取新令牌。

0

我也遇到了麻煩,最後得到了處理它。底線是Google Calendar API v3需要OAuth,您需要通過Google Developer Console設置應用/項目,然後請求目標Google帳戶的OAuth權限。授予授權後,您需要保存刷新令牌並在後續調用中使用它以獲取新的訪問令牌(即過期!)。我在這裏寫了一篇詳細的博客文章:http://www.geekytidbits.com/google-calendar-api-from-ruby/,這是我的示例腳本,應該有助於您理解流程:

#gem install 'google-api-client' 

require 'google/api_client' 

#Setup auth client 
client_secrets = Google::APIClient::ClientSecrets.load #client_secrets.json must be present in current directory! 
auth_client = client_secrets.to_authorization 
auth_client.update!(
    :scope => 'https://www.googleapis.com/auth/calendar', 
    :access_type => "offline", #will make refresh_token available 
    :approval_prompt =>'force', 
    :redirect_uri => 'http://www.myauthorizedredirecturl.com' 
) 

refresh_token_available = File.exist?('refresh_token.txt') 

if !refresh_token_available 
#OAuth URL - this is the url that will prompt a Google Account owner to give access to this app. 
puts "Navigate browser to: '#{auth_client.authorization_uri.to_s}' and copy/paste auth code after redirect." 

#Once the authorization_uri (above) is followed and authorization is given, a redirect will be made 
#to http://www.myauthorizedredirecturl.com (defined above) and include the auth code in the request url. 
print "Auth code: " 
auth_client.code = gets 
else 
#If authorization has already been given and refresh token saved previously, simply set the refresh code here. 
auth_client.refresh_token = File.read('refresh_token.txt') 
end 

#Now, get our access token which is what we will need to work with the API. 
auth_client.fetch_access_token! 

if !refresh_token_available 
    #Save refresh_token for next time 
    #Note: auth_client.refresh_token is only available the first time after OAuth permission is granted. 
    #If you need it again, the Google Account owner would have deauthorize your app and you would have to request access again. 
    #Therefore, it is important that the refresh token is saved after authenticating the first time! 
    File.open('refresh_token.txt', 'w') { |file| file.write(auth_client.refresh_token) } 
    refresh_token_available = true 
end 

api_client = Google::APIClient.new 
cal = api_client.discovered_api('calendar', 'v3') 

#Get Event List 
puts "Getting list of events..." 
list = api_client.execute(:api_method => cal.events.list, 
    :authorization => auth_client, 
    :parameters => { 
     'maxResults' => 20, 
     'timeMin' => '2014-06-18T03:12:24-00:00', 
     'q' => 'Meeting', 
     'calendarId' => 'primary'}) 

puts "Fetched #{list.data.items.count} events..." 

#Update Event 
puts "Updating first event from list..." 
update_event = list.data.items[0] 
update_event.description = "Updated Description here" 
result = api_client.execute(:api_method => cal.events.update, 
    :authorization => auth_client, 
    :parameters => { 'calendarId' => 'primary', 'eventId' => update_event.id}, 
    :headers => {'Content-Type' => 'application/json'}, 
    :body_object => update_event) 
puts "Done with update." 

#Add New Event 
puts "Inserting new event..." 
new_event = cal.events.insert.request_schema.new 
new_event.start = { 'date' => '2015-01-01' } #All day event 
new_event.end = { 'date' => '2015-01-01' } 
new_event.description = "Description here" 
new_event.summary = "Summary here" 
result = api_client.execute(:api_method => cal.events.insert, 
    :authorization => auth_client, 
    :parameters => { 'calendarId' => 'primary'}, 
    :headers => {'Content-Type' => 'application/json'}, 
    :body_object => new_event) 
puts "Done with insert."