Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Calendar incremental sync with initial time_max

I'm trying to sync a google calendar with my rails application. I've been following the documentation provided by Google: Synchronize Resources Efficiently.

My goal is to only sync events one year into the future and split up recurring events into single events so that I don't have to deal with the complexity of recurrence rules and creating child events for recurring parent events.

During the initial sync I set the time_max to be 1 year in the future and during the initial sync I only get recurring events up to one year into the future.

When I perform an incremental sync I pass the sync token and expect to get recurring events limited to within one year of the initial sync's time_max, but this is not what I'm seeing. I am seeing events well past one year (~10 years).

During the incremental sync I'm unable to set a time_max as I get this expected error from Google.

Caught error syncTokenWithRequestRestrictions: Sync token cannot be used with other request restrictions.

Here's the code I use to sync events from google into my application

def sync_from_google
    next_page_token = nil

    begin
      if sync_token.nil? # full sync
        response = @calendar_service.list_events(google_id,
          time_min: Time.now.utc.strftime("%FT%TZ"),
          time_max: 1.year.from_now.utc.strftime("%FT%TZ"),
          single_events: true)
      else # incremental sync
        response = @calendar_service.list_events(google_id,
          sync_token: sync_token,
          page_token: next_page_token,
          single_events: true)
      end

      response.items.each do |gevent|
        GoogleCalendarEvent.create_event(self.id, gevent, nil)
      end
      next_page_token = response.next_page_token

    rescue Google::Apis::ClientError => error
      if error.status_code == 410
        self.unsync
      end
    end while (response.next_sync_token.nil?)

    update_attributes(synced: true, sync_token: response.next_sync_token)
end

Am I being a dummy and missing something obvious?

Should sync_tokens provided by the initial sync store the time range of desired events?

Is there some other way that I can limit the incremental sync's time range?

like image 789
Rich86man Avatar asked Jan 24 '17 20:01

Rich86man


People also ask

What does sync mean on Google Calendar?

When you sync your calendars, new information is usually added to your calendars. This uses your phone's storage so you must have enough storage available to store the updated Google calendars on your device. You can check the storage details on your iOS and Android phones as follows.


1 Answers

I ended up removing the single_events param then manually looping through instances of a recurring event manually with a defined time_min & time_max.

Here's the updated code incase anyone stumbles into this in the future.

def sync_from_google
    next_page_token = nil

    begin
      if sync_token.nil? # full sync
        response = @calendar_service.list_events(google_id,
          time_min: Time.now.utc.strftime("%FT%TZ"),
          time_max: 1.year.from_now.utc.strftime("%FT%TZ"))
      else # incremental sync
        response = @calendar_service.list_events(google_id,
          sync_token: sync_token,
          page_token: next_page_token)
      end

      response.items.each do |gevent|
        if gevent.recurrence
            sync_reccuring_events(gevent)
        else
          GoogleCalendarEvent.create_event(self.id, gevent, nil)
        end
      end
      next_page_token = response.next_page_token

    rescue Google::Apis::ClientError => error
      if error.status_code == 410
        self.unsync
      end
    end while (response.next_sync_token.nil?)

    update_attributes(synced: true, sync_token: response.next_sync_token)
end

and the added method to loop through instances of a recurring event

def sync_reccuring_events(google_event)
    next_page_token = nil

    begin
      response = calendar_service.list_event_instances(google_id,
        google_event.id,
        time_min: Time.now.utc.strftime("%FT%TZ"),
        time_max: 1.year.from_now.utc.strftime("%FT%TZ"),
        page_token: next_page_token)

      response.items.each do |gevent|
          GoogleCalendarEvent.create_event(self.id, gevent, nil)
      end
      next_page_token = response.next_page_token

    end while (next_page_token)
end
like image 71
Rich86man Avatar answered Sep 30 '22 00:09

Rich86man