Google Calendar API watch event

295 Views Asked by At

I can get a list of events from a public Google Calendar by calling this function on DOMContentLoad:

function fetchCalendar() {
    gapi.load("client", () => {
        gapi.client.init({
            "apiKey": <apiKey>,
            "discoveryDocs": <discoveryDocs>
        }).then(() => {
            return gapi.client.calendar.events.list({
                "calendarId": <calendarId>,
                "timeZone": <timeZone>,
                "singleEvents": true,
                "timeMin": <timeMin>,
                "orderBy": "startTime"
            });
        }).then((response) => {
            for (let i=0; i<response.result.items.length; i++) {
                console.log(response.result.items[i]);
            }
        }).catch((reason) => {
            console.error(reason);
        });
    });
}

I would like to be notified when the content of the given calendar changes (add, remove, edit). So far I have this function, but I get a 401 Invalid Credentials error:

function watchCalendar() {
    gapi.load("client", () => {
        gapi.client.init({
            "apiKey": <apiKey>,
            "discoveryDocs": <discoveryDocs>
        }).then(() => {
            // it seems to fail after this point
            return gapi.client.calendar.events.watch({
                "calendarId": <calendarId>,
                "resource": {
                    "id": "42",
                    "type": "web_hook",
                    "address": "./app.html"
                }
            });
        }).then((response) => {
            // what to do here, if I can solve the error 401?
        }).catch((reason) => {
            console.error(reason);
        });
    });
}

As a workaround I could fetch the calendar at given intervals, but getting notified of changes would be ideal.

1

There are 1 best solutions below

3
Tanaike On

"Events: watch" of Calendar API is required to be requested with the POST method. Ref In this case, the access token is required to be used. In your showing script, only an API key is used. I guessed that this might be the reason for your current issue.

The API key can retrieve public contents like I can get a list of events from a public Google Calendar by calling this function. But, the API key cannot be used for requesting with the POST method.

Pattern 1:

If you want to use your script by retrieving the access token, I thought that "JavaScript quickstart for Calendar API" of the official document might be useful.

The service account might be able to be also used for this situation. Ref

Pattern 2:

If you want to simply test the script using the access token, you can use the following modified script.

gapi.auth.setToken({ access_token: "### your access token ###" });
gapi.client.init({
  discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"]
})
  .then(_ => {
    gapi.client.calendar.events.watch({
      "calendarId": "<calendarId>,",
      "resource": {
        "id": "###",
        "type": "web_hook",
        "address": "./app.html"
      }
    })
      .then((response) => {
        console.log(response)
      }).catch((reason) => {
        console.error(reason);
      });
  });

Note:

  • If you cannot use the access token, your workaround of As a workaround I could fetch the calendar at given intervals, might be useful.

Reference: