Google apps script 使用谷歌应用程序脚本Web应用程序轮询谷歌工作表更改的最佳方法?

Google apps script 使用谷歌应用程序脚本Web应用程序轮询谷歌工作表更改的最佳方法?,google-apps-script,Google Apps Script,我正在开发一个google apps脚本web应用程序,让它在google工作表上投票以获取更改/更新。目前,这可以是“内容”,也可以是工作表上次更新的时间。我不能使用GUI /浏览器进行交互,因此考虑运行Web应用程序的命令来自命令行上的卷曲,并将文本内容返回到相同的内容。用户将根据需要重新启动web应用程序,并将其设置为运行@3分钟 我有一个基本的工作程序: 当应用程序启动时,检查/获取原始状态(日期/内容) 运行计数器(每个计数器)和计时器(睡眠),并在每次迭代中检查/获取当前状态(日期/

我正在开发一个google apps脚本web应用程序,让它在google工作表上投票以获取更改/更新。目前,这可以是“内容”,也可以是工作表上次更新的时间。我不能使用GUI /浏览器进行交互,因此考虑运行Web应用程序的命令来自命令行上的卷曲,并将文本内容返回到相同的内容。用户将根据需要重新启动web应用程序,并将其设置为运行@3分钟

我有一个基本的工作程序:

  • 当应用程序启动时,检查/获取原始状态(日期/内容)
  • 运行计数器(每个计数器)和计时器(睡眠),并在每次迭代中检查/获取当前状态(日期/内容)
  • 在每次迭代中,根据当前状态测试原始状态。如果它们不同,则通过ContentService发送文本输出(消息、日期或当前内容)
  • 我发现有三种方法适用于上述基本例程:

    A.以数组形式获取图纸数据范围值(sh.getDataRange().getValues();)

    B.获取DriveApp LastUpdated值(DriveApp.getFileById(fileId.getLastUpdated();)

    C.获取上次修改日期的修订列表(修订=Drive.revisions.list(fileId))

    A运行良好,可以针对电子表格上的特定网格(表格),但对于大型数据集可能会有问题

    function doGet() {
      var ss = SpreadsheetApp.openById(fileId);
      var sh = ss.getSheetByName('SheetName');
      var rng = sh.getDataRange().getValues();
      var msg = '';
    
      for (var i = 0; i < 20; i++) {
        SpreadsheetApp.flush();
        var cur = sh.getDataRange().getValues();
        i = i + 1;
        if (JSON.stringify(rng) !== JSON.stringify(cur)) {
          msg = JSON.stringify(cur);
          return ContentService.createTextOutput(msg);
        }
        Utilities.sleep(10000);
      }
    
      return ContentService.createTextOutput(msg);
    
    }
    
    函数doGet(){
    var ss=SpreadsheetApp.openById(fileId);
    var sh=ss.getSheetByName('SheetName');
    var rng=sh.getDataRange().getValues();
    var msg='';
    对于(变量i=0;i<20;i++){
    SpreadsheetApp.flush();
    var cur=sh.getDataRange().getValues();
    i=i+1;
    if(JSON.stringify(rng)!==JSON.stringify(cur)){
    msg=JSON.stringify(cur);
    返回ContentService.createTextOutput(msg);
    }
    公用事业.睡眠(10 000);
    }
    返回ContentService.createTextOutput(msg);
    }
    
    B,但您似乎必须等待1到5分钟才能报告工作表上的更新。这“可能”是可以的,但对于进行更改的用户来说,速度不够快

    function doGet() {
    
      var lastUpdated = DriveApp.getFileById(fileId).getLastUpdated();
      var ss = SpreadsheetApp.openById(fileId);
      var sh = ss.getSheetByName('Sheet2');
      var rng = sh.getDataRange().getValues();
      var msg = '';
    
      for (var i = 0; i < 20; i++) {
        SpreadsheetApp.flush();
        var curUpdate = DriveApp.getFileById(fileId).getLastUpdated();
        i = i + 1;
        if (lastUpdated.toString() !== curUpdate.toString()) {
          msg = lastUpdated.toString() + "\n" + curUpdate.toString();
          return ContentService.createTextOutput(msg);
        }
        Utilities.sleep(10000);
      }
    
      return ContentService.createTextOutput(msg);
    
    }
    
    函数doGet(){
    var lastUpdated=DriveApp.getFileById(fileId).getLastUpdated();
    var ss=SpreadsheetApp.openById(fileId);
    var sh=ss.getSheetByName('Sheet2');
    var rng=sh.getDataRange().getValues();
    var msg='';
    对于(变量i=0;i<20;i++){
    SpreadsheetApp.flush();
    var curUpdate=DriveApp.getFileById(fileId).getLastUpdated();
    i=i+1;
    if(lastUpdated.toString()!==curUpdate.toString()){
    msg=lastUpdated.toString()+“\n”+curUpdate.toString();
    返回ContentService.createTextOutput(msg);
    }
    公用事业.睡眠(10 000);
    }
    返回ContentService.createTextOutput(msg);
    }
    
    C并几乎立即报告了日期变更。不过,读了a

    函数doGet(){
    var msg='';
    var revisions=Drive.revisions.list(fileId);
    var修订=修订。项目[revisions.items.length-1];
    var日期=新日期(修订版.modifiedDate);
    对于(变量i=0;i<20;i++){
    var currevs=Drive.Revisions.list(fileId);
    var currev=currevs.items[currevs.items.length-1];
    var curdate=新日期(currev.modifiedDate);
    i=i+1;
    if(date.toString()!==curdate.toString()){
    msg=date.toString()+“\n”+curdate.toString();
    返回ContentService.createTextOutput(msg);
    }
    公用事业.睡眠(10 000);
    }
    返回ContentService.createTextOutput(msg);
    }
    
    使用B是有意义的,但我找不到一种方法使getLastupdated的响应更直接,也许C,使用修订是一种方法?我是否错过了一个“转到”方法,或者我的web应用程序例程需要改进

    根据@Diego的建议,我还通过高级驱动器服务尝试了“modifiedDate”。这是一种享受:)

    函数doGet(){
    var lastUpdated=Drive.getFileById(fileId).modifiedDate;
    var msg='';
    对于(变量i=0;i<20;i++){
    var curUpdate=Drive.getFileById(fileId).modifiedDate;
    i=i+1;
    if(lastUpdated.toString()!==curUpdate.toString()){
    msg=lastUpdated.toString()+“\n”+curUpdate.toString();
    返回ContentService.createTextOutput(msg);
    }
    公用事业.睡眠(10 000);
    }
    返回ContentService.createTextOutput(msg);
    }
    
    我发现在文件中使用修改日期与最新版本之间的区别在于,该文件还将报告绑定脚本的更改。修订仅限于电子表格上的更改,不包括脚本更改。这可以在我下面的测试中看到,两者之间有几分钟的差异

    如果要特别将范围限制为仅电子表格更改,则将使用修订报告最准确的值

    function test() {
      const fileId = FILE_ID;
      console.log(getLastRevision(fileId)); // 2021-01-12T15:32:43.175Z
      console.log(getLastUpdated(fileId)); // Tue Jan 12 2021 15:53:53 GMT+0000 (Greenwich Mean Time)
      console.log(getLastUpdatedAdvanced(fileId)); // 2021-01-12T15:53:53.941Z
    }
    
    function getLastRevision(fileId) {
      let response;
      do {
        response = Drive.Revisions.list(fileId, { maxResults: 1000 });
      } while (response.nextPageToken);
      return response.items[response.items.length - 1].modifiedDate;
    }
    
    function getLastUpdated(fileId) {
      return DriveApp.getFileById(fileId).getLastUpdated();
    }
    
    function getLastUpdatedAdvanced(fileId) {
      return Drive.Files.get(fileId).modifiedDate;
    }
    
    我不知道您希望电子表格有多少修订,但使用
    nextPageToken
    非常简单。然而,如果电子表格将有数千次修订,并且您将经常进行轮询,那么它可能不是最有效的方法


    我无法使用
    DriveApp.getFileById(fileId).getLastUpdated()
    复制延迟,但我觉得这并不罕见。您可以改为尝试使用,就像您正在进行修订一样,以获取
    modifiedDate
    。我不希望它返回延迟值。正如您所指出的,这可能是您的最佳选择,因为您不需要担心修订的数量,但请记住,它也反映了非电子表格更新。

    顺便说一句,我不确定您要对循环做什么。您可能对它们有一个合理的需求,但是在这个问题的上下文中,它们似乎是不必要的,并且可能是有害的
    function doGet() {
    
      var lastUpdated = Drive.getFileById(fileId).modifiedDate;
      var msg = '';
    
      for (var i = 0; i < 20; i++) {
        var curUpdate = Drive.getFileById(fileId).modifiedDate;
        i = i + 1;
        if (lastUpdated.toString() !== curUpdate.toString()) {
          msg = lastUpdated.toString() + "\n" + curUpdate.toString();
          return ContentService.createTextOutput(msg);
        }
        Utilities.sleep(10000);
      }
    
      return ContentService.createTextOutput(msg);
    
    }
    
    function test() {
      const fileId = FILE_ID;
      console.log(getLastRevision(fileId)); // 2021-01-12T15:32:43.175Z
      console.log(getLastUpdated(fileId)); // Tue Jan 12 2021 15:53:53 GMT+0000 (Greenwich Mean Time)
      console.log(getLastUpdatedAdvanced(fileId)); // 2021-01-12T15:53:53.941Z
    }
    
    function getLastRevision(fileId) {
      let response;
      do {
        response = Drive.Revisions.list(fileId, { maxResults: 1000 });
      } while (response.nextPageToken);
      return response.items[response.items.length - 1].modifiedDate;
    }
    
    function getLastUpdated(fileId) {
      return DriveApp.getFileById(fileId).getLastUpdated();
    }
    
    function getLastUpdatedAdvanced(fileId) {
      return Drive.Files.get(fileId).modifiedDate;
    }