使用Apps脚本代码更新(覆盖)一个Apps脚本文件和另一个Apps脚本文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Apps脚本代码更新(覆盖)一个Apps脚本文件和另一个Apps脚本文件相关的知识,希望对你有一定的参考价值。

覆盖文件。覆盖Apps脚本文件。

这不是创建新的Apps脚本文件的问题。那对我没用。我需要更新现有的Apps脚本文件。这个问题与创建新文件类似,但问题不同。更新的语法和更新的要求可能与创建新文件不同,我无法从创建新文件的答案中获得解决方案。我已经看了一个创建新文件的答案,但这还没有回答我的问题。

我尝试使用高级驱动器服务使用其他应用程序脚本文件更新现有的应用程序脚本文件。

function updateMyScript() {
  var targetFileID = 'File ID';

  var dataSource = {
    "files": [
      {
        "id":"739a57da-f77c-4e1a-96df-7d86ef227d62",
        "name":"Code",
        "type":"server_js",
        "source":"function doGet() {\n  return htmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
      },
      {
        "id":"2c7e8b5a-dbc5-4cd2-80e9-77b6291b3167",
        "name":"index",
        "type":"html",
        "source":"\u003chtml\u003e\n  \u003cbody\u003e\n    New message!!\n  \u003c/body\u003e\n\u003c/html\u003e"
      }
    ]
  };

  var filesResource = Drive.Files.get(targetFileID);
  var blob = Utilities.newBlob(JSON.stringify(dataSource), "application/vnd.google-apps.script+json");
  var whatRezult = Drive.Files.update(filesResource, targetFileID, blob, {"convert":"true"});

  Logger.log('whatRezult: ' + whatRezult);
};

id对象中的dataSource属性是项目内部每个特定.gshtml文件的id。我通过将“目标”Apps脚本文件下载到JSON,然后打开JSON文件并复制出文件ID来获取这些ID。所以,我知道那些是正确的。我想用一种方法从代码中检索项目中的单个文件ID。关于创建新的应用程序脚本文件的帖子没有解释如何从项目文件中获取“子”ID。项目文件ID与项目内的每个文件ID不同。 nametype属性是显而易见的。并且只有两种类型的文件,例如,有server_js和“html”类型。看起来像Apps脚本项目文件的内部文件的source可以是字符串文字。因此,您只需键入您想要的替换内容即可。

target ID是自我解释的。

如果有一种方法可以使用高级驱动器服务或UrlFetchApp.fetch()来回答我的问题。我只想使用Apps脚本。所以,我不是在寻找用其他语言编写的解决方案,或者是从Apps Script外部运行的解决方案。

使用上面的代码,我从下一行到最后一行收到错误:

Drive.Files.update(filesResource, targetFileID, blob, {"convert":"true"});

错误是:

该应用程序没有更新Apps脚本所需的范围。

所以,显然,它正在寻找一个可以在某处指示的范围设置。我猜它会进入选项的第四个参数。

答案

你需要要求特殊的Drive-AppsScript scope

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

由于您无法告诉Apps Script为您询问此范围(它通过分析您的代码自动确定其自己的范围)。你需要自己做oAuth舞(例如使用Eric's lib)。但是,既然您也无法设置此令牌,那么您自己检索脚本以在其内置或高级服务调用中使用(不是我知道的),您也必须手动执行UrlFetch调用,并通过您的标题中的“自定义”标记(如“create new script”问题中所示)。

update的UrlFetch调用非常类似于insert。只需将方法更改为PUT并在路径中添加应用程序脚本项目ID即可。

var url = "https://www.googleapis.com/upload/drive/v2/files/" + scriptID;
var requestBody = ...; //the same
var options = {
  "headers": {
     'Authorization': 'Bearer ' +  yourManuallyFetchedToken,
   }, 
  "contentType": "application/vnd.google-apps.script+json",
  "method" : "PUT", //changed here from POST to PUT
  "payload": JSON.stringify(requestBody)
}
另一答案

我已经创建了一个项目的GitHub存储库,该存储库将从源Apps脚本文件更新一个Apps脚本文件(目标)。它完全免费复制和使用。

GitHub Repository - apps-script-update

有关说明,请参阅GitHub存储库中的自述文件

GitHub上的代码使用的是较新的Apps Script API,它与原始答案不同。

另一答案

新的Apps Script API现在允许更新Apps脚本项目。更新的项目可以绑定到文档。 (Sheet,Form,Doc)此代码使用REST API,并使用UrlFetchApp.fetch(url,options)从Apps脚本代码发出PUT请求此代码从Apps脚本文件运行以更新另一个Apps脚本文件。

必须为运行代码的Apps脚本文件启用Apps Script API。 Apps Cloud API已在Google Cloud控制台中启用。从代码编辑器中,选择“资源”和“云平台项目”搜索Apps Script API并启用它。

function updateContent(scriptId,content,theAccessTkn) {
//try{
  var options,payload,response,url;

  if (!content) {
    //Error handling function
    return;
  }

  if (!theAccessTkn) {
    theAccessTkn = ScriptApp.getOAuthToken();
  }

  //https://developers.google.com/apps-script/api/reference/rest/v1/projects/updateContent
  url = "https://script.googleapis.com/v1/projects/" + scriptId + "/content";

  options = {
    "method" : "PUT",
    "muteHttpExceptions": true,
    "headers": {
      'Authorization': 'Bearer ' +  theAccessTkn
     },
    "contentType": "application/json",//If the content type is set then you can stringify the payload
    "payload": JSON.stringify(content)
  };

  response = UrlFetchApp.fetch(url,options);
  response = JSON.parse(response);//Must be parsed even though it shows as coming back as an object

  //Logger.log('typeof response: ' + typeof response)

  //Logger.log('response 29 in file GS_Update: ' + JSON.stringify(response).slice(0,45))

  return response;
//} catch(e) {
  //Logger.log(response)
//}
};

您必须使用正确的范围才能使代码在没有授权错误的情况下运行。

范围可以在appsscript.json文件中设置。要查看appsscript.json文件,必须先单击“查看”菜单,然后选择“显示清单”菜单项。

{
  "timeZone": "America/New_York",
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.projects",
    "https://www.googleapis.com/auth/script.external_request"
  ],
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER"
}

第一次使用Apps Script API时,PUT请求可能不起作用,并且会返回包含指向Google Cloud控制台的链接的错误。这就是为什么从Logger.log('typeof response: ' + typeof response)声明中查看返回响应response = UrlFetchApp.fetch(url,options);很重要的原因。

以上是关于使用Apps脚本代码更新(覆盖)一个Apps脚本文件和另一个Apps脚本文件的主要内容,如果未能解决你的问题,请参考以下文章

例外:未配置访问 - API 更新后使用 Google Apps 脚本的 BigQuery

无法使用 Google Apps 脚本显示授权对话框

无法通过Google Apps脚本显示授权对话框

如何从 Google 电子表格中的 Google Apps 脚本自动更新“站点地图”功能?

使用 Google BigQuery / Apps 脚本为插入 Google 表格的数据添加时间戳

使用 Apps 脚本定义/创建 BigQuery 保存视图的 SQL 查询