Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle Google Calendar API push notifications?

I can't seem to make sense of this article.

I'm trying to create 2-way syncing of events between my web app and Google Calendar. I've got my events successfully syncing to Google Calendar, but the push notifications Google sends me aren't of any use.

When I create a new event, and then I create a watch:

$channel = new Google_Service_Calendar_Channel();
$channel->setId($watchId);
$channel->setType('web_hook');
$channel->setAddress(URL::route('gapi.watchEvent'));
$channel->setResourceId($seg->gapi_event_id); // does this do anything??
$channel->setToken(json_encode(['segment_id'=>$seg->id]));
$channel->setParams([
    'ttl' => 2628000, // is this respected??
]);

$watchResp = $calendarService->events->watch($googleCalendarId, $channel);

Firstly, does $channel->setResourceId do anything? I want to listen to changes to a specific event, but always seems to give me notifications for the entire calendar.

The headers that Google sends me look like this:

"X-Goog-Channel-Id": "qJSdaxkKKkXXXXXXXXXX",
"X-Goog-Channel-Expiration": "Thu, 10 Sep 2015 01:45:57 GMT",
"X-Goog-Resource-State": "exists",
"X-Goog-Message-Number": "1811101",
"X-Goog-Resource-Id": "wBkuOkYwEhDiXXXXXXXXX",
"X-Goog-Resource-Uri": "https://www.googleapis.com/calendar/v3/calendars/[email protected]/events?alt=json",

The X-Goog-Channel-Id is the watch id that I chose. X-Goog-Resource-Uri appears to just be a link to the calendar. And I don't know what X-Goog-Resource-Id. It doesn't appear to be either my calendar ID or my event ID.

All I want to know is what data changed? How do I extract that information out of the push notification?

I don't care if I have to subscribe to every event my app creates, or just once per calendar.

like image 676
mpen Avatar asked Aug 11 '15 02:08

mpen


1 Answers

When you get a push notification, it contains almost no useful information. You have to make a request back to Google to ask what's changed since your last sync. Read this article for more information.

Basically, you want to use $_SERVER['HTTP_X_GOOG_CHANNEL_ID'] (the watch ID you generated) and/or $_SERVER['HTTP_X_GOOG_RESOURCE_ID'] (the watch ID Google generates) to look up the calendar ID that you created a watch on in your own DB (you'll have to store this when you create the watch).

Once you have the calendar ID, you have to do an events/list request to find out what's changed. They have a PHP example on that page, but you'll have to add in the syncToken which you should also store.

Despite events/watch being under "events", you're really listening to all the events for a calendar, not changes in a specific event (don't be fooled by the PHP API which has a Google_Service_Calendar_Channel::setResourceId option -- it does nothing). Make sure to store the resourceId you get back. You'll need that to stop notifications.

Also, watches expire after some amount of time. And you can't refresh them either. I suggest you stop the old watch a week or two before its about to expire and create a new one. The new one must have a different ID than the old one.

like image 178
mpen Avatar answered Oct 19 '22 13:10

mpen