4

Initial situation:

  • In one of our services, we use a service account to call Google Calendar API.
  • User can share their calendars with this technical account via its technical emailaddress (@.iam.gserviceaccount.com).
  • As calendars are shared, we can query them via API (CalendarList/List: https://developers.google.com/calendar/v3/reference/calendarList/list)
  • All this was working fine for several years without problem.

Current issue:

  • As we have discovered recently, newly shared calendars are not returned via the API call anymore. Calendars shared in the past are still returned (!)
  • We are aware of pageTokens and handle them - this couldn't be a problem. In case of one (test) account only 8 calendars are shared currently and we cannot get more.
  • There is no error/warning during the call on backend side
  • There is no error/warning/quota problem on the Google Developer Console

We haven't received any warning/alert from Google about Calendar API changes or limitations of our account(s). Also I haven't found any publicly known issue/outage about Google Calendar.

What could be the problem?

Should I report it to Google? If yes how exactly? All I could found was a "Google Cloud Platform Free Trial Troubleshooter", where (apart from a suggest to use stackoverflow ;]) all I can do with a "specific question and technical support" is to "start a chat", which leads to an internal Google site (moma). Is there anything else I could try?

Any help would be much appreciated!

UPDATE: There as indirect trace/hint in official documents that Google has changed this behaviour of (automatically) accepting shared Calendars - compare the "Share an existing calendar" section's current and 2019 august version:

UPDATE 2 I have managed to report this issue to Google thanks to @DaImTo (google account required): https://issuetracker.google.com/issues/148804709

The point is the following:

  • "Due to a recent change of behaviour, any account has to explicitly "accept" a Calendar that has been shared with them."
  • Status: Won't Fix (Intended behavior)
gabowsky
  • 572
  • 4
  • 13
  • Please certify this statement "As we have discovered recently, newly shared calendars are not returned via the API call anymore. Calendars shared in the past are still returned " Please explain exactly what your problem is as it is written currently its hard to understand your issue. – Linda Lawton - DaImTo Feb 03 '20 at 11:29
  • 1
    All right, I try to articulate more clearly. Steps to reproduce: 1. User shares his/hers calendar with the email of the service account 2. Executing CalendarList/List, we expect to return all calendars, including the one shared in step 1 Situation is, that the API call returns only "earlier shared" calendars, but not the one we share now. I hope I clarified the bits - if not, please ask specific questions, thank you! – gabowsky Feb 03 '20 at 11:41

3 Answers3

8

There has been a recent change

After you share a calendar with a user / a service account, this user / service account has to "accept" the sharing by adding the shared calendar to his calendar list.

This can either be done (in case of a user) from the UI by clicking "Add this calendar" or programmatically (works both for users and service accounts) with the method CalendarList: insert.

ziganotschka
  • 25,866
  • 2
  • 16
  • 33
  • 1
    Thank you for the tip, i'll check this out, and accept this as solution, if it works. – gabowsky Feb 03 '20 at 13:04
  • I can confirm that something has changed on Google Calendar API's end; and that "accepting" the calendar via CalendarList:insert works. It is very unfortunate, that this is not really suitable solution for our use-case, but that's another story. Thanks once again! – gabowsky Feb 03 '20 at 13:34
  • Would you please link the change log where you are seeing that this was changed? – Linda Lawton - DaImTo Feb 03 '20 at 13:57
  • I am not aware of a change log - we talking here about a very recent change, but I can confirm from my experience with the Calendar API that now the "acceptance" of the calendar became mandatory. – ziganotschka Feb 03 '20 at 14:32
  • @ziganotschka without a change log then its not necessarily a "change" it could be a "bug" These are two very different things. Please post the change log where you read that this is in fact a "change" – Linda Lawton - DaImTo Feb 04 '20 at 08:57
  • Hmm. If I have a service account and a user shared his calendar with the service account, how can I know that this happened so that I can add it to my calendar list? This seems a bit catch-22-ish - I need the calendar to be on my calendar list to get a list of all calendars I have access to, and I need to add the calendar which I have been granted to my calendar list myself, without being notified of it. Is there a good solution here? – JHH Jul 06 '21 at 12:37
2

One more solution to this is

1) Add Calendar to your Google Account

2) Share Calendar with Service Account Email Id

3) Go to settings and Sharing in newly created calendar and find the Calendar Id

4) Follow this Link - https://developers.google.com/calendar/v3/reference/calendarList/insert

This is sample PHP Code for adding existing calendar in Service Account

$calendarListEntry = new Google_Service_Calendar_CalendarListEntry();
$calendarListEntry->setId("calendarId");

$createdCalendarListEntry = $service->calendarList->insert($calendarListEntry);

echo $createdCalendarListEntry->getSummary();

5) Now call Calendar List API and you will find added calendar id in service account calendar List

  • In some application scenarios this makes the calendar list pointless. If you have the calendar ID, you don't really need the calendar list, just use the ID to access the calendar. At least in the case where the list is only used for a user friendly list to look up IDs anyway. – tjmoore Jun 10 '20 at 17:53
1

CalendarList.List Returns the calendars on the user's calendar list.

This is not necessarily all of the calendars a user has access to. A users calendar list appears on the bottom left hand side of the google calendar web app

enter image description here

When a user is granted access to a new calendar they accept access via an email. When they do that the calendar is normally added to their calendarlist.list. This does not happen with a service account because it doesn't have the ability to check an email and accept the invite it just has access.

If you want the calendars added to the service accounts calendarlist then you will need to insert them via the service account. using calendarlist.insert

Im not sure why you think this worked in that past i have been using this api for years and never bothered with using the calenadarlist with service accounts for this very reason.

  1. User shares his/hers calendar with the email of the service account 2. Executing CalendarList/List, we expect to return all calendars, including the one shared in step 1 Situation is, that the API call returns only "earlier shared" calendars, but not the one we share now. I hope I clarified the bits - if not, please ask specific questions, thank you!

There is no method that will return all calendars that a user has access to. TBH the response would be huge consider all of the public calendars out there in the wild they would also be returned.

Tip for using service accounts.

service accounts are not intended for you to be giving out to users to have them grant it access to their calendars. Service accounts are meant for you the developer to have a static calendar that you can use in your application and save data to that.

If you are accessing a users calendar then you should be using Oauth2 and saving the refresh token if you need access to their data when they are offline.

Report issue

There have been a lot of changes recently around service accounts and google calendar i have reported servral issues myself over the last few months issue forum I suggest that you submit this as an issue. Link it here and i will see if i can find my contact on that team to ping about the issue.

Nemesius
  • 179
  • 10
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • 1
    Well, your approach states as if this never worked. I would like to clarify, that this is not the case, this was working fine for years without problem. Something could have changed on Google Calendar API's side, as mentioned by @ziganotschka. Apart from this, thank you for the detailed response! – gabowsky Feb 03 '20 at 13:04
  • I have never seen anything be automatically inserted into calednarlist i would suggest that maybe you have a change in your code that has removed this feature something must have been inserting it for you. Nothing has changed in calendar api that i am aware of. – Linda Lawton - DaImTo Feb 03 '20 at 13:45
  • I can confirm, that "insert" was not necessary until recently - good question when and how was it changed. The only official place I found which reflects/hints that something is changed a Google Calendar "support page" about sharing calendars --> see my update about it. I appreciate your helping intention as well, thank you once again! – gabowsky Feb 04 '20 at 08:48
  • Check update if you decide to report the issue link it to me and i will be happy to ping my contact on the team. – Linda Lawton - DaImTo Feb 04 '20 at 08:55
  • Thanks for the tip for the issue form. I desperately searched for something like this, to report issues officially to Google. Cheers! :) – gabowsky Feb 04 '20 at 09:04
  • 1
    Just to add this certainly did work in the past and project I work on has many customers using this functionality, which worked for several years. We rely on it to provide a UI for users in a service application for users to select calendars shared with the service account. This change breaks the application and users can no longer see shared calendars. To provide another UI to manually add to the calendar list with an ID is not friendly and makes the calendar list pointless anyway as we use it just to get the IDs from a human readable list to store in our own application. – tjmoore Mar 30 '20 at 16:03
  • Adding that as a service application, users are administrators in our case. This relates to a room booking product that needs configuration via a service account to access explicitly shared calendars. Free Google accounts and G-Suite customers. – tjmoore Mar 30 '20 at 16:05
  • Further note. Sign-In and use of refresh tokens is an option we provide but with the number of customers makes us hit the API limits when we provide the sign-in consent project. Service accounts are created by the customer and they share their calendars with it. Customer could create their own sign-in project but this requires validation process with Google if public Google accounts are involved which is a long and complex process. For a service application with no user present, service accounts are the more suitable option. – tjmoore Jun 10 '20 at 18:51