Vico
Vico

Reputation: 1256

Google Calendar Push notification 404 error

I've subscribed to a calendar with the following command:

calendar.events
          .watch({
            calendarId: aCal.id,
            requestBody: {
              id: uuid.v1(),
              type: "web_hook",
              address: 'http://mywebsite.com',
            },
          })
          .catch((e) => e)

Each time I create an event, I receive a notification with "x-goog-resource-id":"unzJsxcVNifZI5ogOmIKRJ3Oiog".

What is this id? Google documentation states it's an "opaque resource id", but when I try to get a calendar with this Id, I get a 404.

This ID is not an event Id, since it's the same for each event I create in single calendar. When I create an event in another calendar, this ID changes. So it could be a calendar Id.

Unfortunately, each get I do with the following request:

calendar.events.list(
      {
        calendarId: calId,
      },
      (err, res) => {
        if (err) reject(err);
    
        resolve(res.data.items);
      }
    );

returns me a 404. Same with the Google API explorer.

What is this ID? How can I know what has changed in the calendar with the Id?

Thanks for your help,

Upvotes: 0

Views: 279

Answers (1)

iansedano
iansedano

Reputation: 6481

A notification won't tell you what has changed, just that there has been a change.

The x-goog-resource-id represents the specific notification channel, not the resource that you are watching.

Since you can set up notifications on many different resources (Acl, CalendarList, Events, and Settings resources), you just have to keep track of the the id of the notification channel and what resource it corresponds to. The notification also conains the x-goog-resource-uri, which should point to the resource that has changed.

Setting up the channel

When you make a "watch" request. I.e. create a new notification channel, to this sample endpoint:

https://www.googleapis.com/calendar/v3/calendars/[email protected]/events/watch

With this body:

{
  "id": "whateverIdyouFeltlikeAdding",
  "type": "web_hook",
  "address": "https://yourwebhookaddress.com"
}

You should get a response like this (the IDs are fake):

{
    "kind" : "api#channel",
    "expiration" : "1617113510000",
    "resourceId" : "2iPJp6kI2131231245543aQ_rIFGwE",
    "id" : "whateverIdyouFeltlikeAdding",
    "resourceUri" : "https://www.googleapis.com/calendar/v3/calendars/[email protected]/events?alt=json"
}

Then you should make a GET request to take a "snapshot" of the calendar at that time.

Receiving a notification and finding out what has changed

When you change an event you should receive a notification with this info (this example is summarized and with fake data):

'x-goog-channel-id': 'whateverIdyouFeltlikeAdding',
'x-goog-message-number': '3313856',
'x-goog-resource-id': '2iPJp6kI2131231245543aQ_rIFGwE',
'x-goog-resource-state': 'exists',
'x-goog-resource-uri': 'https://www.googleapis.com/calendar/v3/calendars/[email protected]/events?alt=json',

Note that the resourceID from the creation of the channel matches the x-goog-resource-id (even though these particular IDs are fake). The x-goog-channel-id also matches the custom id you give on its creation.

To identify the resource that has changed, you need to store these ID from the creation of the channel, you could use x-goog-channel-id or the x-goog-resource-id to compare them to your local store.

You local store might be a simple JSON:

{
    '2iPJp6kI2131231245543aQ_rIFGwE' : '[email protected]'
}

Or you can just parse the x-goog-resource-uri to obtain the calendar ID.

Once you have identified the resource, you would have to make another GET request to compare with your "snapshot". You can use the etag included in the responses to quickly scan which specific resources have changed.

Docs

Upvotes: 1

Related Questions