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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With