google-apps-scriptgoogle-sheetsoauth-2.0authorizationupwork-api

Setting Oauth2 to get access token using spreadsheets


I've been using Spreadsheets and upwork, as I want to integrate between them.

So I'm trying to make authorization for upwork through spreadsheets, using the documentation steps and everything is going fine. But when i authorize my account i see that the response_type is not a token, it's a code.

 function authorize() {
 return OAuth2.createService('upwork')

      // Set the endpoint URLs, which are the same for all Google services.
      .setAuthorizationBaseUrl('https://www.upwork.com/ab/account-security/oauth2/authorize')
      .setTokenUrl('https://www.upwork.com/ab/account-security/oauth2/token')

      // Set the client ID and secret, from the Google Developers Console.
      .setClientId('cleintID')
      .setClientSecret('clientSecret')
      .setRedirectUri('https://script.google.com/macros/d/{Script-ID}/usercallback') 
 
      .setTokenFormat(OAuth2.TOKEN_FORMAT.FORM_URL_ENCODED)
      
      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties())
}

So this is my first question, Is there is a way to set the response_type to token, as i am setting in the picture above the clientID,redirectUri... (I tried setResponseType but it doesn't exist)

although working as it's and using response_type=code, after authorization the a request should be returned to the

function as below function authCallback(request) {
  var driveService = authorize();
  Logger.log(request) //this is always null
  var isAuthorized = driveService.handleCallback(request);
  if (isAuthorized) {
    Logger.log('Yaaay')
    return HtmlService.createHtmlOutput('Success! You can close this tab.');
  } else {
    Logger.log('Naaay')
    return HtmlService.createHtmlOutput('Denied. You can close this tab');
  }
}

authorize() is not called ??

Finally below is the whole code i'm using.

function authorize() {
 return OAuth2.createService('upwork')

      // Set the endpoint URLs, which are the same for all Google services.
      .setAuthorizationBaseUrl('https://www.upwork.com/ab/account-security/oauth2/authorize')
      .setTokenUrl('https://www.upwork.com/ab/account-security/oauth2/token')

      // Set the client ID and secret, from the Google Developers Console.
      .setClientId('cleintID')
      .setClientSecret('clientSecret')
      .setRedirectUri('https://script.google.com/macros/d/{Script-ID}/usercallback') 
 
      .setTokenFormat(OAuth2.TOKEN_FORMAT.FORM_URL_ENCODED)
      
      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties())
}

function redirect() {
  var driveService = authorize();
  if (!driveService.hasAccess()) {
    var authorizationUrl = driveService.getAuthorizationUrl();
    var template = HtmlService.createTemplate(
        '<a href="<?= authorizationUrl ?>" target="_blank">Press here to authroze</a>.');
    template.authorizationUrl = authorizationUrl;
    var page = template.evaluate().setTitle('Authroize');
    SpreadsheetApp.getUi().showSidebar(page);
  }
}

function authCallback(request) {
  var driveService = authorize();
  Logger.log(request)
  var isAuthorized = driveService.handleCallback(request);
  if (isAuthorized) {
    Logger.log('Yaaay')
    return HtmlService.createHtmlOutput('Success! You can close this tab.');
  } else {
    Logger.log('Naaay')
    return HtmlService.createHtmlOutput('Denied. You can close this tab');
  }
}

Update: I found that redirectURI is incorrect format, as google require the URI to be in the form of https://script.google.com/macros/d/{SCRIPT ID}/usercallback, so now the error changes and i got a failure

    Error: Error retrieving token: 404: {"<!DOCTYPE html>\n<html lang":"\"en\">\n<head>\n\n <meta name","":"undefined"," window.performance.mark 

":"undefined"," window.performance.mark(name);\n }\n\n function remove_mark(name) {\n window.performance ":"undefined"," window.performance.clearMarks ":"undefined"," window.performance.clearMarks(name);\n }\n\n function 

create_measure(name, startMark, endMark) {\n window.performance ":"undefined"," window.performance.measure ":"undefined"," window.performance.measure(name, startMark, endMark);\n }\n\n function remove_measure(name) {\n window.performance ":"undefined"," window.performance.clearMeasures ":"undefined"," window.performance.clearMeasures(name);\n }\n</script>\n <link 

rel":"\"stylesheet\" href","amp;site.application":"AccountSecurity","amp;site.version":"ed46c62af44692608c290dd0b498fa933b20c567","amp;site.environment":"prod","amp;server-error.status":"1",

"amp;server-error.label":"404+-+Agate","amp;server-error.traceId":"5c7d08790a6473b1-IAD\" height","l":"'+l:'';j.async","granted_time":1598271686} (line 541, file "Service")

Solution

  • .setTokenUrl('https://www.upwork.com/ab/account-security/oauth2/token')
    

    According to documentation, tokenurl should be

    POST /api/v3/oauth2/token

    Use:

    .setTokenUrl('https://www.upwork.com/api/v3/oauth2/token')
    

    406 is due to incorrect or no Accept headers. This header is set due to

    .setTokenFormat(OAuth2.TOKEN_FORMAT.FORM_URL_ENCODED)
    

    Remove it to use default accept headers:

    //.setTokenFormat(OAuth2.TOKEN_FORMAT.FORM_URL_ENCODED)