I'm trying to get my Groovy/Grails application to speak to the Google Calendar API from Java, using a service model. For now I'll be happy with a simple calendar list. No matter what I do though, I end up with:
URI: /test
Class: com.google.api.client.auth.oauth2.TokenResponseException
Message: 400 Bad Request { "error" : "invalid_grant" }
The same user "[email protected]" owns both the calendar and the API Console App. Code as follows:
package quirkplanner
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.http.HttpTransport
import com.google.api.client.json.JsonFactory
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.calendar.Calendar
import com.google.api.services.calendar.model.*;
class TestController {
def servletContext
private static final HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String SERVICE_EMAIL = "[email protected]";
private static final String CLIENT_ID = "12345678901234.apps.googleusercontent.com";
private static final String PATH_TO_CERTIFICATE = "/WEB-INF/abcdefabcdef-privatekey.p12";
private static final String SERVICE_ACCOUNT_USER="[email protected]";
def index() {
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_EMAIL)
.setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/calendar"))
.setServiceAccountPrivateKeyFromP12File(new File(servletContext.getRealPath(PATH_TO_CERTIFICATE)))
.setServiceAccountUser(SERVICE_ACCOUNT_USER)
.build();
Calendar service3 = new Calendar(HTTP_TRANSPORT, JSON_FACTORY, credential);
com.google.api.services.calendar.model.Calendar calendar = service3.calendars().get("primary").execute();
render("ok")
}
}
BuildConfig.groovy Dependencies are:
compile 'com.google.api-client:google-api-client:1.18.0-rc'
compile 'com.google.http-client:google-http-client-jackson2:1.18.0-rc'
And I also have a list of JAR's I'm using. The list it not complete, hence the BuildConfig dependencies. Ideally, I should really choose one or the other...
There are a few things that could try:
setServiceAccountUser(SERVICE_ACCOUNT_USER)
Be sure to use the SERVICE_EMAIL for the
.setServiceAccountId(SERVICE_EMAIL)
as you have correctly done. Google's documentation is not clear on this but using the Service Account ID will not work.
Good Luck!