title: How do I access a Google Spreadsheet from App Engine using a Service Account?
body: <p>I have an application on Google App Engine (hosted on appspot.com) which is going to be used by a few users to grab some stuff off the internet, save it in the Datastore and then write it to a Google Spreadsheet. I'm looking to use a Service Account to access the spreadsheet but I run into a 400 OK { "error" : "invalid_grant" } problem when I try to do anything, regardless of whether I try to create a file using the Drive API or access an existing file using Spreadsheets API.</p>
  
  <p>I've turned on both Drive API and Drive SDK in the APIs Console and generated a P12 key. This is my method for building a <code>GoogleCredential</code>:</p>
  
  <pre class="lang-java prettyprint-override"><code>private GoogleCredential getGoogleCredential() throws IOException, GeneralSecurityException {
      GoogleCredential credential = new GoogleCredential.Builder()
      .setTransport(TRANSPORT)
      .setJsonFactory(FACTORY)
      .setServiceAccountId("1511XXX90247.apps.googleusercontent.com")
      .setServiceAccountScopes(scopes)
      .setServiceAccountPrivateKeyFromP12File(
              new File("05a605b0fXXXd2a6be864be15d81a2bd629d3bd6-privatekey.p12"))
      .setServiceAccountUser("XXX@gmail.com") // My personal e-mail address which I used to create the project
      .build();
      return credential;
  }
  </code></pre>
  
  <p>The ServiceAccountID comes from the APIs Console. I've tried using <code>1511XXX90247@developer.gserviceaccount.com</code> as my ServiceAccountUser as well as <code>myappname@appspot.gserviceaccount.com</code>. The scopes I'm using are as follows:</p>
  
  <pre><code>https://spreadsheets.google.com/feeds
  https://docs.google.com/feeds
  https://www.googleapis.com/auth/drive
  https://www.googleapis.com/auth/drive.file
  </code></pre>
  
  <p>Here is the code that fails when I try to use Spreadsheets API:</p>
  
  <pre class="lang-java prettyprint-override"><code>        SpreadsheetService service = new SpreadsheetService("name of my app");
          service.setOAuth2Credentials(getGoogleCredential());
          FeedURLFactory factory = FeedURLFactory.getDefault();
          SpreadsheetQuery query = new SpreadsheetQuery(factory.getSpreadsheetsFeedUrl());
          query.setTitleQuery("test");
          SpreadsheetFeed feed = service.query(query, SpreadsheetFeed.class);
  </code></pre>
  
  <p>The code fails when the service tries execute the query.</p>
  
  <p>Here's the Drive code I tried that also fails:</p>
  
  <pre class="lang-java prettyprint-override"><code>        Drive drive = new Drive.Builder(TRANSPORT, FACTORY,
                   getGoogleCredential()).build();
          com.google.api.services.drive.model.File file = new com.google.api.services.drive.model.File();
          file.setTitle("test");       
          file.setMimeType("application/vnd.google-apps.spreadsheet");
          drive.files().insert(file).execute(); // This is where the code fails
  </code></pre>
  
  <p>No matter what I try, I always seem to end up with the same ìnvalid grant` error. Here's a partial stacktrace:</p>
  
  <pre class="lang-java prettyprint-override"><code>com.google.gdata.util.AuthenticationException: Failed to refresh access token: 400 OK { "error" : "invalid_grant" } 
  at com.google.gdata.client.GoogleAuthTokenFactory$OAuth2Token.refreshToken(GoogleAuthTokenFactory.java:260) 
  at com.google.gdata.client.GoogleAuthTokenFactory.handleSessionExpiredException(GoogleAuthTokenFactory.java:702) 
  at com.google.gdata.client.GoogleService.handleSessionExpiredException(GoogleService.java:738)    at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:680) 
  at com.google.gdata.client.Service.query(Service.java:1237) 
  at com.google.gdata.client.Service.query(Service.java:1178) 
  at spam.gwt.scraper.server.spreadsheets.APIConnector.doGet(APIConnector.java:66)
  </code></pre>
  
  <p>I've tried to look for answers everywhere, including but not limited to the <a href="https://developers.google.com/google-apps/spreadsheets/" rel="nofollow noreferrer">Google Developers Spreadsheets Guide</a>, this <a href="https://stackoverflow.com/questions/13229294/how-do-i-create-a-google-spreadsheet-with-a-service-account-and-share-to-other-g">Service Account-related Stack Overflow question</a> and this <a href="https://stackoverflow.com/questions/13597074/exporting-data-to-google-spreadsheet-from-google-app-engine-java-version">Google App Engine-specific Stack Overflow question</a>. What with the developments (eg. Docs -> Drive) it's hard to find up-to-date info, never mind info that pertains specifically to GAE.</p>