Search code examples
javascripthtmlauthenticationgoogle-apicalendar

Google Calendar API wont authenticate with service account


I'm trying to code a script with the Google calendar API which allows the script to create an event in the calendar when the function gets called. However I have struggle with the code for the authentication since the old sign-in library gets deprecated. My aim is that users who visit my website don't have to sign in with their google account and that I can just use an OAuth2.0 client ID or service account. I think this should be possible. For the moment I only try to list calendar events and ofc trying to authenticate.

This is the error I get: "You have created a new client application that uses libraries for user authentication or authorization that will soon be deprecated. New clients must use the new libraries instead; existing clients must also migrate before these libraries are deprecated. See the Migration Guide for more information."

This is my code:

<!DOCTYPE html>
<html>
  <head>
    <title>Google Calendar API Quickstart</title>
    <meta charset="utf-8" />
  </head>
  <body>
    <p>Google Calendar API Quickstart</p>
    <div id="content"></div>

    <!-- Load the API Client Library -->
    <script src="https://apis.google.com/js/platform.js"></script>
    <script>
      gapi.load("client:auth2", function() {
        gapi.client
          .init({
            apiKey: "<MY-API-KEY",
            discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
            clientId: "<MY-CLIENT-ID>",
            scope: "https://www.googleapis.com/auth/calendar"
          })
          .then(function() {
            gapi.auth2
              .getAuthInstance()
              .signIn({
                prompt: "consent",
                client_id:
                  "MY-CLIENT-ID"
              })
              .then(function() {
                // List events on the calendar
                listEvents();
              });
          });
      });

      function listEvents() {
        gapi.client.calendar.events
          .list({
            calendarId: "primary",
            timeMin: new Date().toISOString(),
            showDeleted: false,
            singleEvents: true,
            maxResults: 10,
            orderBy: "startTime"
          })
          .then(function(response) {
            var events = response.result.items;
            var content = "";

            if (events.length > 0) {
              for (i = 0; i < events.length; i++) {
                var event = events[i];
                var start = event.start.dateTime || event.start.date;
                content +=
                  "<p>" +
                  event.summary +
                  " - " +
                  start +
                  "</p>";
              }
            } else {
              content = "<p>No upcoming events found.</p>";
            }
            document.getElementById("content").innerHTML = content;
          });
      }
    </script>
  </body>
</html>

I didn't found any solutions in the Google API documentation or in the migration guide. So I'm not sure what I should change.


Solution

  • Service account authorization is not supported by client side JavaScript. You would need to switch to a server sided version of it, lets say node.js.

    Once you have done that you need to configure domain wide delegation on your google workspace account, to grant your service account access to delegate on behalf of one of the users on your google workspace domain.

    to be clear service accounts do not work with standard gmail accounts, delegation can only be configured via a google workspace domain account.