tks
tks

Reputation: 753

Invalid json error when trying to query google calendar api with access token from Ruby on Rails application

I am trying to set up my Rails application to connect to the google calendar api. I am following the Oauth2 documentation here:

http://code.google.com/apis/accounts/docs/OAuth2.html#SS

and the instructions for creating a single event on a user's private calendar here:

http://code.google.com/apis/calendar/data/2.0/developers_guide_protocol.html#CreatingSingle

I have been able to generate the Oauth2 access and refresh tokens using the server side strategy, but whenever I query the api I get the following error:

{"apiVersion":"2.6","error":{"code":400,"message":"Invalid JSON","errors": [{"domain":"GData","code":"invalidJson","internalReason":"Invalid JSON"}]}}

(This is the same error given in this thread http://groups.google.com/group/google-calendar-help-dataapi/browse_thread/thread/2171226629b28c3b except I am passing GData-Version: 2 into the http post header, so the apiVersion is different )

The json I am using is the example event data given in the protocol document in the second reference link above. As far as I can tell this is generally happening after the second time I query the api after getting the 302 redirect. Would greatly appreciate it if someone would explain what this error means and how to get around it. I'm including the relevent code from my app below:

EventController.rb

event_hash = { :data => {
                 :title => "Tennis with Beth",
                 :details => "Meet for a quick lesson.",
                 :transparency => "opaque",
                 :status => "confirmed",
                 :location => "Rolling Lawn Courts",
                 :when => [{
                   :start => "2012-04-17T15:00:00.000Z",
                   :end => "2012-04-17T17:00:00.000Z"
                   }]
                }
              }

event_data = event_hash.to_json

auth_string = "Bearer " + google_oauth2_credential.access_token # gets access token for user
header_hash = { 'Content-Type' => 'application/json', 'Authorization' => auth_string, 'GData-Version' => '2' }

response = post_to_https('https://www.google.com/calendar/feeds/default/private/full', event_data, header_hash) # note see ApplicationController paste below to see the post_to_https method

if response.code == '302'
  uri_string = response.response['Location']
  response = post_to_https(uri_string, event_data, header_hash)
  render :text => "302 " + response.body
else
    render :text => "not 302 " + response.body)
end

ApplicationController.rb

def post_to_https(url_string, params_hash, header_hash = {})
  uri = URI.parse(url_string)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  request = Net::HTTP::Post.new(uri.request_uri)
  request.set_form_data(params_hash)

  unless header_hash.empty?
    header_hash.each { |key, value| request[key] = value }
  end
  return http.request(request)
end

Upvotes: 1

Views: 1267

Answers (1)

Vic Fryzel
Vic Fryzel

Reputation: 2395

Most of the problems you're discussing here should not occur if you use the latest version of the API and the Ruby client library, as documented here:

http://code.google.com/apis/calendar/v3/using.html#setup

page_token = nil
result = result = client.execute(:api_method => service.events.list,
                                 :parameters => {'calendarId' => 'primary'})
while true
  events = result.data.items
  events.each do |e|
    print e.summary + "\n"
  end
  if !(page_token = result.data.next_page_token)
    break
  end
  result = result = client.execute(:api_method => service.events.list,
                                   :parameters => {'calendarId' => 'primary', 'pageToken' => page_token})
end

Upvotes: 1

Related Questions