I'm working on a project where I have to access a set of Google Calendars using REST and working with Java.
The program, situated on a private non-Google server, periodically (via cron job) connects to the Google account, gets the list of Calendars linked to the account, gets the last month's events of each calendar, and returns an XML file containing all the information. The program should be able to execute and access calendars WITHOUT any user input. For the moment, the project specifies that the Calendar will just be read, not modified (so only GET/LIST calls will be made).
I have looked through the Google documentation and been over the sample codes using client libraries, and almost all examples given require OAuth 2.0 user consent before accessing calendar API. Even the REST API documentation pages require you activate OAuth 2.0 to return requested information (otherwise returning a HTTP 40X error code and JSON file containing error status and message).
How could I connect to the Google Calendar REST API to get the information I need, everything being done via REST calls, and without requiring user consent at the time of execution?
Or am I over-complicating things, and only require the 'Server Key', found in the Resgistered Apps part of the Google Cloud Console?
Or am I requiring to use both OAuth and developer key? (I found someone mention it here under a question with the title : Google Calendar API v3 hardcoded credentials ; however, the question and solution were for PHP, and I don't know if something similar would be possible or necessary in Java).
I hope I have given enough information as to what I'm looking for, and also that this question hasn't been covered so far. I did research it, and didn't find anything close enough to what I was looking for.
I was unable to post more than 2 links (lacking reputation), but did look at the Google Calendar v3 REST API, as well as the page specifying the creation of a JWT.
If you just need to access a particular set of calendars, I would create a service account and share the necessary calendars with that account.
To do so:
Then you should be able to use the following code:
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.json.gson.GsonFactory;
import java.io.File;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import java.util.Arrays;
import com.google.api.services.calendar.Calendar;
GoogleCredential credentials = new GoogleCredential.Builder().setTransport(GoogleNetHttpTransport.newTrustedTransport())
.setJsonFactory(new GsonFactory())
.setServiceAccountId("<service account email address>@developer.gserviceaccount.com")
.setServiceAccountScopes(Arrays.asList("https://www.googleapis.com/auth/calendar.readonly"))
.setServiceAccountPrivateKeyFromP12File(new File("<private key for service account in P12 format>-privatekey.p12"))
.build();
Calendar client = new Calendar.Builder(GoogleNetHttpTransport.newTrustedTransport(), new GsonFactory(), credentials).build();
client.<do calendar stuff>.execute();
If instead you are a domain administrator who needs to access calendars for all Google Apps accounts that are part of your domain without consent from individual users, then instead of step 4 above:
You should now be able to write code like the following:
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.json.gson.GsonFactory;
import java.io.File;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import java.util.Arrays;
import com.google.api.services.calendar.Calendar;
GoogleCredential credentials = new GoogleCredential.Builder().setTransport(GoogleNetHttpTransport.newTrustedTransport())
.setJsonFactory(new GsonFactory())
.setServiceAccountId("<service account email address>@developer.gserviceaccount.com")
.setServiceAccountScopes(Arrays.asList("https://www.googleapis.com/auth/calendar"))
.setServiceAccountPrivateKeyFromP12File(new File("<private key for service account in P12 format>-privatekey.p12"))
.setServiceAccountUser("<domain user whose data you need>@yourdomain.com")
.build();
Calendar client = new Calendar.Builder(GoogleNetHttpTransport.newTrustedTransport(), new GsonFactory(), credentials).build();
client.<do calendar stuff as that user>()
In addition to the steps mentioned in @aeijdenberg's answer, the Service Account now needs to explicitly accept the shared calendar by adding it to its CalendarList via CalendarList.insert. See:
Service Accounts don't accept automatically shared calendars anymore [148804709] https://issuetracker.google.com/issues/148804709
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With