DriveApp.getFileById的Google Apps脚本API授权 [英] Google Apps Script API Authorizations for DriveApp.getFileById

本文介绍了DriveApp.getFileById的Google Apps脚本API授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Google Cloud Platform Project(GCP),该项目可以直接运行几乎所有脚本/功能,但是可以通过API来运行.一切都只能在G Suite域内部进行访问,并且OAuth同意屏幕的应用程序类型"为内部".

我有一个脚本,该脚本不是通过API调用的,而是每隔x分钟直接在计时器上调用的.它执行

DriveApp.getFileByID(pictureID)

这很好用!没问题.

在同一个GCP项目中,我还有一个不同的脚本,该脚本不是通过计时器触发的,而是通过API调用的.这是调用它的代码行(不是很重要):

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

API脚本运行非常棒!直到到达以下行:

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

日志结果为

e = {"name":"Exception"}

我验证了pictureID与可以正常工作的非API脚本中的相同.我正在尝试尝试"在此API运行脚本中,以确保该软件有权访问该文件,而不是实际访问该文件.

我很确定这是一个授权问题.我现在仅使用GCP已有一段时间,对授权有一定的经验,但经验不足.

以下是有关授权的一些​​详细信息...

项目的脚本项目属性(文件/项目属性)显示,它需要以下OAuth范围:

根据Google在 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

以下是我现在在GCP Oauth同意屏幕上定义的范围:

如您所见,我添加了drive,drive.readonly和& drive.file(实际上并不需要).

最重要的是,这个特定的图像文件存储在GCP项目所有者,G Suite域的脚本和顶级管理员的Google云端硬盘中.情况并非总是如此,因为用户将自己的Google云端硬盘中的图片共享给该软件/GCP所有者.但是,我有一种感觉,即使现在由计时器触发的脚本也可以与这些用户共享的文件一起使用,但不适用于通过API调用的脚本.

我很确定这是一个Auth问题,但是我在某处丢失了一些东西.

谢谢您的帮助!

更新:

这是来自脚本的代码,该代码调用了API脚本(为了保密起见,对其进行了更改),我想知道问题是否可能出在客户端/调用方.也许我没有正确获得OAuthToken?还是令牌没有正确的权限?

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

解决方案

我与Google联系后就发现了这一点,很可惜没有得到太多帮助,还有更多的时间进行尝试和研究...

我所缺少的是添加"oathScopes";到manifest/appsscript.json文件.我试用了所需的示波器,最后得到了以下两个示图.我通过查看以下答案找出了解决方案:使用通过ScriptApp.getAuthToken()获得的AuthToken来调用GAS中的Web应用. /p>

在脚本编辑器中,转到查看/显示清单文件".

这是以前的样子:

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

这就是现在的样子...

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

添加后,我保存了appsscript.json.然后,我转到runOnEdit触发器(调用脚本),将其删除并重新添加.但是,这导致了令人讨厌的外观错误:

我查了一下,发现了这篇文章:在Apps脚本上创建新触发器时收到错误.因此,我在脚本编辑器中运行了代码,实际上它调出了auth屏幕.我批准并重新添加了触发器,现在一切都可以很好地调用API!

I have a Google Cloud Platform Project (GCP) that runs almost all scripts/functions directly, but a couple through an API. Everything is only accessible internally to the G Suite domain, and the OAuth consent screen Application Type is "Internal".

I have a script, which is not called via an API, but directly on a timer every x minutes. It performs a

DriveApp.getFileByID(pictureID)

This works great! No problems.

I also have a different script, in the same GCP Project, which instead of running triggered by a timer, runs by being called through an API. Here is the line of code that calls it (not really important):

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

The API script runs great! Until it gets to the following lines:

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

The result of the log is

e = {"name":"Exception"}

I verified that the pictureID is the same as it is in the non-API script that works. I am doing a "try" in this API-run script to make sure that the software has access to the file, not to actually access it.

I am pretty sure that this is an authorization issue. I've been using GCP only for a little while now, have some experience with authorizations, but not a lot.

Here are some details around the authorizations...

The project's scripts Project Properties (File/Project Properties) shows that it needs the following OAuth Scopes:

According to Google's documentation at 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

Here are the scopes that I've defined now on the GCP Oauth consent screen:

As you can see, I've added drive, drive.readonly, & drive.file (which doesn't really seem to be needed).

On top of it all, this particular image file is stored in the Google Drive of the owner of the GCP Project, scripts, and top-level admin of the G Suite domain. That will not always be the case, as users will be sharing images from their own Google Drive to this software/GCP owner. However, I have a feeling that even now the script triggered by a timer would work with those user-shared files, but not the script called through an API.

I'm pretty sure this is an Auth issue, but I am missing something somewhere.

Thank you for your help!

Update:

Here is the code from the script that CALLS the API script (changed some for confidentiality), as I'm wondering if perhaps the problem may not be on the client/calling side. Perhaps I'm not getting the OAuthToken correctly? Or the token doesn't have the correct permissions?

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

解决方案

I figured it out after contacting Google, and unfortunately not getting much help, and a few more hours of trying and research...

What I was missing was adding "oathScopes" to the manifest/appsscript.json file. I played around with the scopes needed and ended up with the following two shown below. I figured out the solution by looking at this answer: Using AuthToken obtained via ScriptApp.getAuthToken() to call web apps in GAS.

Inside the script editor, go to View/Show manifest file.

Here is what it looked like before:

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

and here is what it looks like now...

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

After adding, I saved appsscript.json. I then went to my runOnEdit trigger (the calling script), removed and re-added it. However, that caused a nasty looking error:

I looked that up, and found this post: Receiving error when creating new trigger on Apps Script. So, I ran the code in the script editor, and indeed it brought up the auth screen. I approved, re-added the trigger, and now everything works great in calling the API!

这篇关于DriveApp.getFileById的Google Apps脚本API授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆