Autoryzacje Google Apps Script API dla DriveApp.getFileById

Oct 07 2020

Mam projekt Google Cloud Platform (GCP), który uruchamia prawie wszystkie skrypty / funkcje bezpośrednio, ale kilka za pośrednictwem interfejsu API. Wszystko jest dostępne tylko wewnętrznie w domenie G Suite, a typ aplikacji ekranu akceptacji OAuth to „Wewnętrzna”.

Mam skrypt, który nie jest wywoływany przez API, ale bezpośrednio na zegarze co x minut. Wykonuje

DriveApp.getFileByID(pictureID)

To działa świetnie! Bez problemów.

Mam też inny skrypt, w tym samym projekcie GCP, który zamiast uruchamiać się przez licznik czasu, działa poprzez wywołanie przez API. Oto wiersz kodu, który go wywołuje (nie jest to naprawdę ważne):

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

Skrypt API działa świetnie! Dopóki nie dotrze do następujących wierszy:

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

Wynik dziennika to

e = {"name":"Exception"}

Sprawdziłem, czy pictureID jest taki sam, jak w skrypcie innym niż API, który działa. Robię próbę w tym skrypcie uruchamiającym API, aby upewnić się, że oprogramowanie ma dostęp do pliku, a nie po to, aby uzyskać do niego dostęp.

Jestem prawie pewien, że jest to kwestia autoryzacji. Używam GCP od jakiegoś czasu, mam pewne doświadczenie z autoryzacjami, ale nie za dużo.

Oto kilka szczegółów dotyczących zezwoleń ...

Ze skryptów projektu Project Properties (File / Project Properties) wynika, że ​​wymaga on następujących zakresów protokołu OAuth:

Zgodnie z dokumentacją Google pod adresem 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

Oto zakresy, które zdefiniowałem teraz na ekranie zgody GCP Oauth:

Jak widać, dodałem drive, drive.readonly i drive.file (co nie wydaje się być potrzebne).

Co więcej, ten konkretny plik obrazu jest przechowywany na Dysku Google właściciela projektu GCP, skryptów i administratora najwyższego poziomu domeny G Suite. Nie zawsze tak będzie, ponieważ użytkownicy będą udostępniać obrazy z własnego Dysku Google właścicielowi tego oprogramowania / GCP. Jednak mam wrażenie, że nawet teraz skrypt wyzwalany przez licznik czasu działałby z plikami udostępnionymi przez użytkownika, ale nie ze skryptem wywoływanym przez API.

Jestem prawie pewien, że jest to problem z uwierzytelnianiem, ale gdzieś mi czegoś brakuje.

Dziękuję za pomoc!

Aktualizacja:

Oto kod ze skryptu, który WYWOŁUJE skrypt API (zmieniony częściowo ze względu na poufność), ponieważ zastanawiam się, czy być może problem nie leży po stronie klienta / wywołującego. Być może nie otrzymuję prawidłowo OAuthToken? Lub token nie ma odpowiednich uprawnień?

  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);

Odpowiedzi

Chris Oct 07 2020 at 22:27

Zrozumiałem to po skontaktowaniu się z Google i niestety nie otrzymałem dużej pomocy i kilka godzin prób i badań ...

Brakowało mi dodania „oathScopes” do pliku manifestu / appsscript.json. Bawiłem się potrzebnymi lunetami i skończyło się na dwóch poniższych pokazanych poniżej. Znalazłem rozwiązanie, patrząc na tę odpowiedź: Używanie AuthToken uzyskanego za pośrednictwem ScriptApp.getAuthToken () do wywoływania aplikacji internetowych w GAS .

W edytorze skryptów przejdź do Wyświetl / Pokaż plik manifestu.

Oto jak to wyglądało wcześniej:

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

a oto jak to wygląda teraz ...

{
  "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"
    ]
}

Po dodaniu zapisałem appsscript.json. Następnie przeszedłem do mojego wyzwalacza runOnEdit (skryptu wywołującego), usunąłem go i ponownie dodałem. Jednak spowodowało to nieprzyjemnie wyglądający błąd:

Sprawdziłem to i znalazłem ten post: Błąd odbierania podczas tworzenia nowego wyzwalacza w Apps Script . Więc uruchomiłem kod w edytorze skryptów i rzeczywiście przywołał ekran autoryzacji. Zatwierdziłem, ponownie dodałem wyzwalacz i teraz wszystko działa świetnie w wywoływaniu API!