New Science
New Science

Reputation: 1

Building drive app from apps script - Whats wrong in the below code

Below is the code taken from Arun Nagarajan's Example: I am tried the same code to check.. But Its not installing properly. (I removed my redirect url, client id and secret in the below). Please tell me what wrong in the below code.

var AUTHORIZE_URL = 'https://accounts.google.com/o/oauth2/auth';
var TOKEN_URL = 'https://accounts.google.com/o/oauth2/token';
var REDIRECT_URL =             'exec';
var tokenPropertyName = 'GOOGLE_OAUTH_TOKEN';

var CLIENT_ID = '';
var CLIENT_SECRET = '';

function doGet(e) {
var HTMLToOutput;

if(e.parameters.state){
var state = JSON.parse(e.parameters.state);
if(state.action === 'çreate'){
var meetingURL = createMeetingNotes();
HTMLToOutput = '<html><h1>Meeting notes document created!</h1><a href="'+meetingURL+'">    <click here to open</a></html>';
}
else if (state.ids){
var doc = DocsList.getFileById(state.ids[0]);
var url = doc.getContentAsString();
HTMLToOutput = '"<html><a href="' +url+'"</a></html>"';
}
else {
zipAndSend(state.ecportIds.Session.getEffectUser().getEmail());
HTMLToOutput = '"<html><h1>Email sent. Check your Inbox.</h1></html>"';
}
}
else if(e.parameters.code){
getAndStoreAccessToken(e.parameters.code);
HTMLToOutput = '<html><h1>App is installed. You can close this window now or navigate to your </h1><a href="https://drive.google.com/">Google Drive</a></html>';
}
else {
HTMLToOutput = '<html><h1>Install this App into your google drive </h1><a href="' + getURLForAuthorization() + '">Click here to start install</a></html>';
}

return HtmlService.createHtmlOutput(HTMLToOutput);

}

function getURLForAuthorization() {
return  AUTHORIZE_URL + '?response_type=code&client_id=' + CLIENT_ID + '&redirect_uri='     + REDIRECT_URL + '&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.install+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email';
}

function getAndStoreAccessToken(code) {
var parameters = { method : 'post',
                  payload : 'client_id='+ CLIENT_ID + '&client_secret=' + CLIENT_SECRET + '&grant_type=authorization.code&redirect_uri=' + REDIRECT_URL};
var response = UrlFetchApp.fetch(TOKEN_URL.parameters).getContentText();
var tokenResponse = JSON.parse(response);
UserProperties.getProperty(tokenPropertyName, tokenResponse.access_token);
}

function getUrlFetchOptions() {
return {'contentType' : 'application/json',
        'headers' : {'Authorization': 'Bearer ' +         UserProperties.getProperty(tokenPropertyName),
                     'Accept' : 'application/json'}};           

}

function IsTokenValid() {
return UserProperties.getProperty(tokenPropertyName);
}

The error showing is: Bad request:undefined

I think the error is inside the function called : getAndStoreAccessToken.

var parameters = { method : 'post',
payload : 'client_id='+ CLIENT_ID + '&client_secret=' + CLIENT_SECRET + '&grant_type=authorization.code&redirect_uri=' + REDIRECT_URL};

Please tell me the correct url format for payload.

Upvotes: 0

Views: 388

Answers (2)

Arun Nagarajan
Arun Nagarajan

Reputation: 5645

The error seems in this line -

var response = UrlFetchApp.fetch(TOKEN_URL.parameters).getContentText();

I think you want TOKEN_URL , parameters (note the comma)

Upvotes: 1

Scott S.
Scott S.

Reputation: 97

First, if you are trying to access Google Drive from within google apps script, what is the purpose of the authorization? Google drive is available w/o authorization. Are you trying to make your application utilize the gDrive of other users (or on behalf of other users)?

Second, instead of manually performing the authorization, which is very hard to troubleshoot, you can take advantage of Class OAuthConfig which simplifies the authorization/request process. The only disadvantage is that OAuthConfig currently uses OAuth1.0 (which is currently deprecated). Although it's particular use is Fusion Tables, and not drive, this library makes great use of OAuthConfig and .fetch and I have used it to model my own OAuth functions. My example below works great. The googleAuth() function sets up the authorization and then the rest of the application can make authorized requests using UrlFetchApp.fetch(url,options) while google does all the authorization stuff in the background.

function googleAuth(oAuthFields) {
      var oAuthConfig = UrlFetchApp.addOAuthService(oAuthFields.service);
      oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/"+
                 "OAuthGetRequestToken?scope=" + oAuthFields.scope);
      oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
      oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
      oAuthConfig.setConsumerKey(oAuthFields.clientId);
      oAuthConfig.setConsumerSecret(oAuthFields.clientSecret);
      return {oAuthServiceName:oAuthFields.service, oAuthUseToken:"always"};
}
function fusionRequest(methodType, sql, oAuthFields, contentType) {
  var fetchArgs = OAL.googleAuth(oAuthFields);
  var fetchUrl = oAuthFields.queryUrl;
  fetchArgs.method = methodType;
  if( methodType == 'GET' ) {
    fetchUrl += '?sql=' + sql;
    fetchArgs.payload = null;
  } else{
    fetchArgs.payload = 'sql='+sql;
  }
  if(contentType != null) fetchArgs.contentType = contentType;
  Logger.log(UrlFetchApp.getRequest(oAuthFields.queryUrl, fetchArgs));
  var fetchResult = UrlFetchApp.fetch(oAuthFields.queryUrl, fetchArgs);

  if( methodType == 'GET' ) return JSON.parse(fetchResult.getContentText());
  else return fetchResult.getContentText();

}

Upvotes: 0

Related Questions