Autorizzazioni API di Google Apps Script per DriveApp.getFileById

Oct 07 2020

Ho un progetto Google Cloud Platform (GCP) che esegue direttamente quasi tutti gli script / funzioni, ma un paio tramite un'API. Tutto è accessibile solo internamente al dominio G Suite e il tipo di applicazione della schermata di consenso OAuth è "Interno".

Ho uno script, che non viene chiamato tramite un'API, ma direttamente su un timer ogni x minuti. Esegue un

DriveApp.getFileByID(pictureID)

Funziona alla grande! Nessun problema.

Ho anche uno script diverso, nello stesso progetto GCP, che invece di essere eseguito attivato da un timer, viene eseguito tramite chiamata tramite un'API. Ecco la riga di codice che lo chiama (non molto importante):

var result = UrlFetchApp.fetch(url, options);

Lo script API funziona alla grande! Fino ad arrivare alle seguenti righe:

      try { var file = DriveApp.getFileById(pictureID); }
      catch (e) {
        Logger.log('e = ' + JSON.stringify(e));
        return;
      }

Il risultato del registro è

e = {"name":"Exception"}

Ho verificato che il pictureID sia lo stesso dello script non API che funziona. Sto facendo un "tentativo" in questo script eseguito dall'API per assicurarmi che il software abbia accesso al file, non per accedervi effettivamente.

Sono abbastanza sicuro che questo sia un problema di autorizzazione. Uso GCP solo da un po 'di tempo, ho una certa esperienza con le autorizzazioni, ma non molto.

Ecco alcuni dettagli sulle autorizzazioni ...

Gli script del progetto Project Properties (File / Project Properties) mostrano che necessita dei seguenti ambiti OAuth:

Secondo la documentazione di Google su https://developers.google.com/apps-script/reference/drive/drive-app#getfilebyidid,

Scripts that use this method require authorization with one or more of the following scopes: 

https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive

Di seguito sono riportati gli ambiti che ho definito ora nella schermata di consenso Oauth di GCP:

Come puoi vedere, ho aggiunto drive, drive.readonly e drive.file (che non sembra essere necessario).

Inoltre, questo particolare file immagine è archiviato nel Google Drive del proprietario del progetto GCP, negli script e nell'amministratore di primo livello del dominio G Suite. Non sarà sempre così, poiché gli utenti condivideranno le immagini dal proprio Google Drive con questo proprietario del software / GCP. Tuttavia, ho la sensazione che anche adesso lo script attivato da un timer funzionerebbe con quei file condivisi dall'utente, ma non lo script chiamato tramite un'API.

Sono abbastanza sicuro che questo sia un problema di autenticazione, ma mi manca qualcosa da qualche parte.

Grazie per l'aiuto!

Aggiornare:

Ecco il codice dallo script che CHIAMA lo script API (modificato per riservatezza), poiché mi chiedo se forse il problema potrebbe non essere dal lato client / chiamante. Forse non ricevo correttamente l'OAuthToken? O il token non ha le autorizzazioni corrette?

  var token = ScriptApp.getOAuthToken();
  
  var header = {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + token,
  };
  
  var parms = [id];
  
  var data = {
    "function": "updateSettings",
    "parameters": parms,
    "devMode": true,
  }
  
  var options = {
    "method":"POST",
    "headers": header,
    "muteHttpExceptions": true,
    "payload": JSON.stringify(data)
  };
  
  // Call the API
  var result = UrlFetchApp.fetch(url, options);

Risposte

Chris Oct 07 2020 at 22:27

L'ho capito dopo aver contattato Google, e purtroppo non ho ricevuto molto aiuto e qualche ora in più di tentativi e ricerche ...

Quello che mi mancava era aggiungere "oathScopes" al file manifest / appsscript.json. Ho giocato con gli ambiti necessari e ho finito con i seguenti due mostrati di seguito. Ho capito la soluzione guardando questa risposta: utilizzando AuthToken ottenuto tramite ScriptApp.getAuthToken () per chiamare le app Web in GAS .

All'interno dell'editor di script, vai a Visualizza / Mostra file manifest.

Ecco come appariva prima:

{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "webapp": {
    "access": "MYSELF",
    "executeAs": "USER_DEPLOYING"
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

ed ecco come appare ora ...

{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "webapp": {
    "access": "MYSELF",
    "executeAs": "USER_DEPLOYING"
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/script.external_request"
    ]
}

Dopo l'aggiunta, ho salvato appsscript.json. Sono quindi andato al mio trigger runOnEdit (lo script chiamante), l'ho rimosso e aggiunto di nuovo. Tuttavia, ciò ha causato un brutto errore dall'aspetto:

Ho cercato e ho trovato questo post: Errore di ricezione durante la creazione di un nuovo trigger su Apps Script . Quindi, ho eseguito il codice nell'editor di script e in effetti è stata visualizzata la schermata di autenticazione. Ho approvato, ho aggiunto di nuovo il trigger e ora tutto funziona alla grande quando si chiama l'API!