Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google apps script 使用应用程序脚本代码用另一个应用程序脚本文件更新(覆盖)一个应用程序脚本文件_Google Apps Script - Fatal编程技术网

Google apps script 使用应用程序脚本代码用另一个应用程序脚本文件更新(覆盖)一个应用程序脚本文件

Google apps script 使用应用程序脚本代码用另一个应用程序脚本文件更新(覆盖)一个应用程序脚本文件,google-apps-script,Google Apps Script,覆盖文件。覆盖应用程序脚本文件 function updateMyScript() { var targetFileID = 'File ID'; var dataSource = { "files": [ { "id":"739a57da-f77c-4e1a-96df-7d86ef227d62", "name":"Code", "type":"server_js", "source":"functio

覆盖文件。覆盖应用程序脚本文件

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);
};
这不是创建新应用程序脚本文件的问题。那帮不了我。我需要更新现有的应用程序脚本文件。这个问题类似于创建新文件,但不是同一个问题。更新的语法以及更新的要求可能与创建新文件有很大的不同,因此我无法从创建新文件的答案中找到解决方案。我已经看到了创建新文件的答案,但这并没有回答我的问题

我已尝试使用高级驱动器服务用另一个应用程序脚本文件更新现有的应用程序脚本文件

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);
};
dataSource
对象中的
id
属性是项目中每个特定
.gs
html
文件的id。通过将“目标”应用程序脚本文件下载到JSON,然后打开JSON文件并复制文件id,我获得了这些id。所以,我知道这些都是正确的。我想要一种方法,用代码从项目中检索这些单独的文件ID。关于创建新的应用程序脚本文件的帖子没有解释如何从项目文件中获取“子”ID。项目文件ID与项目中的每个文件ID不同。
名称
类型
属性很明显。从示例中可以看出,只有两种类型的文件具有
server\u js
和“html”类型。看起来Apps脚本项目文件的内部文件的
源文件可以是字符串文本。因此,您可以输入任何您想要的替换内容

目标ID
是自解释的

如果有一种方法可以通过高级驱动器服务或
UrlFetchApp.fetch()
实现这一点,这将回答我的问题。我只想使用应用程序脚本。所以,我不是在寻找用其他语言编写的解决方案,也不是在应用程序脚本之外运行的解决方案

使用上述代码,我从下一行到最后一行得到一个错误:

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

应用程序没有更新应用程序脚本所需的作用域


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

您需要请求特殊驱动器应用程序脚本:

因为您无法告诉应用程序脚本为您请求此范围(它通过分析代码自动确定自己的范围)。您需要自己跳oAuth舞(例如使用)。但是,由于您也无法设置您自己检索到的这个令牌,以便脚本在其内置或高级服务调用中使用(据我所知并非如此),因此您也必须手动执行UrlFetch调用,并在标头中传递您的“自定义”令牌(如“”问题中所示)

update
的UrlFetch调用与
insert
调用非常相似。只需将方法更改为
PUT
,并在路径中添加应用程序脚本项目id

var url=”https://www.googleapis.com/upload/drive/v2/files/“+scriptID;
var requestBody=…;//相同
变量选项={
“标题”:{
“授权”:“持票人”+你的手工取票,
}, 
“contentType”:“application/vnd.google apps.script+json”,
“方法”:“PUT”,//此处由POST改为PUT
“有效负载”:JSON.stringify(requestBody)
}

我为一个项目创建了一个GitHub存储库,该项目将从源应用程序脚本文件更新一个应用程序脚本文件(目标)。完全可以免费复制和使用

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


GitHub上的代码正在使用更新的应用程序脚本API,这与原始答案不同。

新的应用程序脚本API现在允许更新应用程序脚本项目。更新的项目可以绑定到文档。(工作表、表单、文档)此代码使用REST API,并使用
UrlFetchApp.fetch(url,选项)
从应用程序脚本文件发出PUT请求,以更新另一个应用程序脚本文件

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);
};
必须为运行代码的应用程序脚本文件启用应用程序脚本API。在谷歌云控制台中启用应用程序脚本API。从代码编辑器中,选择“资源”和“云平台项目”搜索应用程序脚本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"
}

第一次使用应用程序脚本API时,PUT请求可能不起作用,并且将返回一个错误,并带有指向Google云控制台的链接。这就是为什么从
response=UrlFetchApp.fetch(url,选项)中查看返回响应
Logger.log('typeof response:'+typeof response)
声明。

我将此答案标记为正确,并奖励您分数。我已经做了一些工作,并确定请求主体需要在其中包含文件id。我提供了一个包含其他信息的答案。您关于范围、url和方法的信息对于此操作的成功至关重要。因此,它将这很有帮助。要让它真正发挥作用还有很多,但提供所有这些信息将是“非常广泛的”问一个问题。您是否成功更新了现有的应用程序脚本文件,并插入了新文件?例如,您向源代码中添加了一个新的HTML文件。不,我从未从应用程序脚本本身执行过此操作。在node js中,我始终替换所有文件。
drive
范围应包括
drive.readonly
,因此在y中不需要它我们的列表。正在检索文件id