Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Last active April 30, 2024 14:24
Show Gist options
  • Save tanaikech/d9674f0ead7e3320c5e3184f5d1b05cc to your computer and use it in GitHub Desktop.
Save tanaikech/d9674f0ead7e3320c5e3184f5d1b05cc to your computer and use it in GitHub Desktop.
Retrieving Access Token From OneDrive using Google Apps Script

Retrieving Access Token From OneDrive using Google Apps Script

Overview

This GAS sample is for retrieving access token to use OneDrive APIs using Google Apps Script.

In this script, the authorization code is automatically retrieved.

Demo

Usage

In order to use this, both accounts of Google and OneDrive (MSN) are required.

Google side

  1. Copy and paste the sample script to your script editor. You can use the standalone script for this.
  2. Deploy Web Apps.
    • On the Script Editor
      • File
      • -> Manage Versions
      • -> Save New Version
      • Publish
      • -> Deploy as Web App
      • -> At Execute the app as, select "your account"
      • -> At Who has access to the app, select "Only myself"
      • -> Click "Deploy"
      • -> Copy URL of "latest code" (This is important!)
      • -> Click "OK"
  3. URL of "latest code" is https://script.google.com/macros/s/###/dev. So please modify this URL. Replace from "dev" to "usercallback" for the URL. And copy this modified URL.
    • From : https://script.google.com/macros/s/###/dev
    • To : https://script.google.com/macros/s/###/usercallback

OneDrive side

  1. Log in to Microsoft Azure portal.
  2. Search "Azure Active Directory" at the top of text input box. And open "Azure Active Directory".
  3. Click "App registrations" at the left side bar.
    • In my environment, when I used Chrome as the browser, no response occurred. So in that case, I used Microsoft Edge.
  4. Click "New registration"
    1. app name: "sample app name"
    2. Supported account types: "Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)"
    3. Redirect URI (optional): Web
      • URL: https://script.google.com/macros/s/###/usercallback
    4. Click "Register"
  5. Copy "Application (client) ID".
  6. Click "Certificates & secrets" at the left side bar.
    1. Click "New client secrets".
    2. After input the description and select "expire", click "Add" button.
    3. Copy the created secret value.

By above operation, the preparation is done.

Ref

Launch Script: Google side

In order to run the script, please launch as follows.

  1. Input "Application (client) ID" and "Created secret value" from OneDrive to clientId and clientSecret in the function setProp() of the sample script of Google Apps Script.
  2. Run setProp().

As a next step, launch as follows.

  • On the Script Editor
    • Publish
    • -> Deploy as Web App
    • -> Click Test web app for your latest code..

By this, the script is run.

Note

Refresh token can be retrieved by including offline_access in the Scope.

Script

This is Google Apps Script.

function setProp() {
  PropertiesService.getScriptProperties().setProperties({
    clientId: "### application ID ###",
    clientSecret: "### application secret ###",
    scope: "offline_access files.readwrite.all" // This is sample. So please modify for your environment.
  });
}

function doGet() {
  var prop = PropertiesService.getScriptProperties().getProperties();
  var url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
  var param = {
    response_type: "code",
    client_id: prop.clientId,
    redirect_uri: getCallbackURL(),
    state: ScriptApp.newStateToken()
      .withMethod("callback")
      .withTimeout(300)
      .createToken(),
    scope: prop.scope
  };
  var params = [];
  for (var name in param) {
    params.push(name + "=" + encodeURIComponent(param[name]));
  }
  var html =
    '<input type="button" value="auth" onclick="window.open(\'' +
    url +
    "?" +
    params.join("&") +
    "', 'Authorization', 'width=500,height=600');\">";
  return HtmlService.createHtmlOutput(html);
}

function getCallbackURL() {
  var url = ScriptApp.getService().getUrl();
  if (url.indexOf("/exec") >= 0) {
    url = url.slice(0, -4) + "usercallback";
  }
  url = url.slice(0, -3) + "usercallback";
  PropertiesService.getScriptProperties().setProperties({
    redirect_uri: url
  });
  return url;
}

function callback(e) {
  var credentials = fetchAccessToken(e.parameter.code);
  return HtmlService.createHtmlOutput(JSON.stringify(credentials, null, "  "));
}

function fetchAccessToken(code) {
  var prop = PropertiesService.getScriptProperties().getProperties();
  var payload = {
    code: code,
    client_id: prop.clientId,
    client_secret: prop.clientSecret,
    redirect_uri: prop.redirect_uri,
    grant_type: "authorization_code"
  };
  var res = UrlFetchApp.fetch(
    "https://login.microsoftonline.com/common/oauth2/v2.0/token",
    {
      method: "POST",
      payload: payload,
      muteHttpExceptions: true
    }
  );
  return JSON.parse(res.getContentText());
}

Note:

  • At January 3, 2019, I could know that the flow for retrieving the client ID and secret had been changed by an email. By this, I could update this. The sample script is not changed.
  • At August 19, 2020, it could confirm that above sample script worked. In the current stage, it seems that the specification of this is not changed.
@phuongpham
Copy link

works great! Thanks

@felipe-negri
Copy link

felipe-negri commented Aug 13, 2019

I have this error my account its a user personal account, can you help me ? https://1drv.ms/u/s!AvmBjBDFCJP9ibNuV0BKx7H-EjTc-Q?e=VIubfa

@tanaikech
Copy link
Author

Unfortunately, I couldn't understand about your issue from your comment. I apologize for this.

@felipe-negri
Copy link

I get the message in English version https://1drv.ms/u/s!AvmBjBDFCJP9ibNxj69pgWmsfvPqcw

@DK013
Copy link

DK013 commented Apr 13, 2020

I'm getting this error from onedrive login page while authenticating : Image Link

@chrislawes79
Copy link

Hi. Please forgive my noobiness but how do we access OneDrive with returning JSON (from above code)?

@Tallesecs
Copy link

How can i get the refresh_token? thanks in advance

@dyros26
Copy link

dyros26 commented Aug 18, 2020

i followed all of this but im having an error

{ "error": "invalid_request", "error_description": "AADSTS900144: The request body must contain the following parameter: 'code'.\r\nTrace ID: 6c1740b9-27a2-4c9d-a8a3-e57db5990d00\r\nCorrelation ID: 6269f75e-9b9b-4fbc-bc66-2741cacdf6ea\r\nTimestamp: 2020-08-18 08:29:58Z", "error_codes": [ 900144 ], "timestamp": "2020-08-18 08:29:58Z", "trace_id": "6c1740b9-27a2-4c9d-a8a3-e57db5990d00", "correlation_id": "6269f75e-9b9b-4fbc-bc66-2741cacdf6ea", "error_uri": "https://login.microsoftonline.com/error?code=900144" }

@sweatysock
Copy link

Many many thanks for publishing this and for making it so easy to understand.

I have read a lot of articles about OAuth2 but this simple clear example is by far the best I have seen. No jargon, just clean simple code that works along with a simple video loop of it running. I used this as a guide to build my solution in nodejs and it works perfectly.

Again, many thanks for doing this. Well done.

@Jyrko
Copy link

Jyrko commented Oct 18, 2022

It still works

@Ruslancic
Copy link

Yeah, still works! But for personal accounts, u need to adjust the endponts! Btw, thx for nice solution!

@maxsalibe
Copy link

Stuck here: Message: AADSTS700016: Application with identifier 'undefined' was not found in the directory 'A... S.A.'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.
Any suggestions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment