如何授权GAS编辑谷歌电子表格的范围



我有一个Powershell脚本,它调用谷歌应用程序脚本函数。

当我运行Powershell脚本时,我可以在GCP项目的错误报告中看到以下错误:

Exception: You do not have permission to call SpreadsheetApp.getActiveSpreadsheet. Required permissions: (https://www.googleapis.com/auth/spreadsheets.currentonly || https://www.googleapis.com/auth/spreadsheets)
at toSpreadsheet (Código:3)
at fromPS (Código:14)

我知道我必须授权作用域,所以我一直试图通过编辑清单文件来做到这一点。

授权范围文件称,

"在授权流程中,Apps Script向用户提供所需作用域的可读描述。例如,如果您的脚本需要对电子表格进行只读访问,则清单可能具有https://www.googleapis.com/auth/spreadsheets.readonly.在授权流程中,具有此范围的脚本要求用户允许此应用程序"查看您的Google电子表格"。">

在我的例子中,我编辑了清单文件appscript.json来添加作用域https://www.googleapis.com/auth/spreadsheets,然后我保存了它,将Google App Script项目发布为API可执行文件,最后我再次运行Powershell代码,但我仍然得到了与上面相同的错误。在所有这些流动过程中,我没有被要求允许任何事情。我无法理解缺少什么授权脚本拥有所需的权限。

我还将电子表格范围添加到了OAuth同意屏幕中,但似乎没有任何区别。我怀疑我应该使用服务帐户来实现这一点,因为我认为没有办法通过OAuth客户端验证,因为我在谷歌上的脚本是从Powershell脚本调用的。我不想相信这一点,因为了解配置OAuth2花了我很多时间:(

一些注意事项:

  1. 当我直接从Google脚本编辑器运行run方法时,Powershell调用的函数运行良好。

  2. 脚本项目部署为API可执行

  3. 谷歌应用程序脚本API在GCP项目中启用

  4. 它与标准GCP项目相关

  5. OAuth凭据是Web应用程序类型

  6. 从Powershell到Google Sheets写入和读取值的脚本运行良好

谷歌脚本:

function toSpreadsheet(text2write)
{ 
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("HIL_APP");
var LastRow = sheet.getLastRow();
for (var i = 1; i < LastRow; i++)
{
sheet.getRange(i+1, 8, 1).setValue(text2write)
}
return "myreturn"
}
function fromPS(params)
{
Logger.log(params) 
var rtn = toSpreadsheet(params)
return rtn
}

清单文件:

{
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets"
],  
"timeZone": "America/Argentina/Buenos_Aires",
"dependencies": {
},
"webapp": {
"access": "ANYONE",
"executeAs": "USER_DEPLOYING"
},
"exceptionLogging": "STACKDRIVER",
"executionApi": {
"access": "MYSELF"
},
"runtimeVersion": "V8"
}

Powershell代码:

function doit{
$json = ".client_id.json"
$jdata = get-content $json | convertfrom-json
<#
$jdata | ForEach-Object {
$_.PSObject.Properties.Value
}
#>
$ClientID = $jdata.web.client_id.ToString()
$ClientSecret = $jdata.web.client_secret.ToString()
$refreshToken = "1//04VvG_FTyDGhiCgYIARAAGAQSNwF-L9IrZ-o1kaZQQccvzL5m4TUTNz6b9Q4KCb16t4cH11gGCshWZWvgaCoMlg73FgpLAGOYTEk" 
$grantType = "refresh_token" 
$requestUri = "https://accounts.google.com/o/oauth2/token" 
$GAuthBody = "refresh_token=$refreshToken&client_id=$ClientID&client_secret=$ClientSecret&grant_type=$grantType" 
$GAuthResponse = Invoke-RestMethod -Method Post -Uri $requestUri -ContentType "application/x-www-form-urlencoded" -Body $GAuthBody

$accessToken = $GAuthResponse.access_token
$headers = @{"Authorization" = "Bearer $accessToken"          
"Content-type" = "application/json"}
$spreadsheetId = "1htbeGlqZ4hojQBWl9fxE4nW_KZI9uVwi0ApzNOIbwnY"
$currentDate = (Get-Date).ToString('MM/dd/yyyy')
$currentTime = (Get-Date).ToString('HH:mm:sstt')
$json = @”
{
"range": "HIL_APP!A1:G1",
"majorDimension": "ROWS",
"values":
[[
"HIL_NAME",
"$env:ComputerName",
"$currentDate",
"$currentTime",
"$env:UserName",
"input from user",
"attempt"
],]
}
“@
$write = Invoke-WebRequest -Uri "https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/HIL_APP!A1:G1:append?valueInputOption=USER_ENTERED" -Method Post -ContentType "application/json" -Body $json  -Headers @{"Authorization"="Bearer $accessToken"}
$read = Invoke-WebRequest -Uri "https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/HIL_APP!A1:G1" -Headers @{"Authorization"="Bearer $accessToken"}
$read
Write-Output "read: " ($read.Content | ConvertFrom-Json)
$scriptId = "1eF7ZaHH-pw2-AjnRVhOgnDxBUpfr0wALk1dVFg7B220bg_KuwVudbALh"          
$json = @"
{
"function": "fromPS",
"parameters": ["myparam"],
"devMode": true
}
"@
$resp = Invoke-WebRequest -Uri "https://script.googleapis.com/v1/scripts/${scriptId}:run" -Method Post -ContentType "application/json" -Body $json -Headers @{"Authorization"="Bearer $accessToken"}
$resp 
Write-Output "script response: " ($resp.Content | ConvertFrom-Json)
}
$error.Clear()
clear
doit

为了使用Apps Script API运行Google Apps Script(GAS(的功能,需要做一些复杂的设置。在这种情况下,我建议测试运行GAS函数,如下所示。这种流动可能过于小心。

流量:

  1. 将云平台项目链接到谷歌应用程序脚本项目。参考
  2. 安装以使用Apps Script API中的scripts.run方法运行GAS函数。参考
  3. 将要运行的脚本放到Google Apps脚本的脚本编辑器中。
    • 在这里,请通过脚本编辑器运行该函数,并确认脚本是否有效。这样就可以避免脚本的问题
  4. 让下面的测试脚本运行。这用于应用程序脚本API的第一次测试。

    function test() {
    return "ok";
    }
    
  5. 放入以下用于检索访问令牌的示例脚本。这是用来测试它的。请在脚本编辑器中运行它,并复制返回的访问令牌。

    function getToken() {
    Logger.log(ScriptApp.getOAuthToken());
    }
    
  6. 测试以使用检索到的访问令牌运行test()的GAS函数。在这种情况下,通过替换$accessToken = $GAuthResponse.access_token来使用powershell的脚本。

    • 发生错误时,请确认应用程序脚本API的设置。在这种情况下,可以说GAS脚本是正确的
    • 如果没有出现错误,请测试以运行您想要运行的函数。在这种情况下,所需的作用域已经包含在访问令牌中。这样就可以避免作用域的问题
  7. 当上述测试完成,并且您使用Apps script API的脚本工作时,请使用作用域检索刷新令牌。范围可以在脚本编辑器中看到。这样,刷新令牌就可以检索到有效的访问令牌。您的脚本可以在本地PC上使用

参考文献:

  • 将云平台项目链接到谷歌应用程序脚本项目
  • 使用应用程序脚本API执行函数

最新更新