Google表格脚本链接在提交表单时发送重复的电子邮件

问题描述 投票:1回答:2

我遇到的问题是我写的脚本在提交表单时发送重复的电子邮件。当我打开电子表格时,脚本也会执行。我只有一个触发器设置为在提交表单时运行脚本,而且我是唯一一个对表单具有编辑权限的人。我尝试完全删除脚本项目并创建一个新项目,但没有解决问题。我不确定我的脚本是否有任何不稳定因素,但这里是:

function sendEmails() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('Raw Data'); // Gets Raw Data Sheet
  var lastRow = sheet.getLastRow(); // Gets last row of sheet everytime the form is submitted
  var lastColumn = sheet.getLastColumn(); // Gets last column of sheet everytime the form is submitted
  var value = sheet.getRange(lastRow,1,lastRow,lastColumn).getValues().toString(); 
  var comments = sheet.getRange(lastRow, 41).getValue().toString(); // Gets additional comments from inspection form submitted
  if (value.indexOf("NOT OK") > -1) {
    MailApp.sendEmail({
    to: "[email protected]",
    subject: 'Machine Issue',
    htmlBody: "An inspection of the xyz machine has returned issues: " + "<br/><br/>"
      + "<b>" + comments + "</b>" + "<br/><br/>" +
      " Click " + '<a href="https:goo.gl/ahGbGu&^"> <b>HERE</b></a>' 
      + " to see the last inspection report.",
    });
  } // Produces email based on defined parameters.
}

我也试过删除触发器并设置一个新的触发器,但也没有用。

google-apps-script google-sheets google-form
2个回答
1
投票

检查执行日志。如果您有多个执行但只有一个Form Responses行,这是表单提交触发器的已知错误。解决它的唯一方法是使用脚本锁。

像这样:

     SpreadsheetApp.flush();
     var lock = LockService.getScriptLock();
  try {
    lock.waitLock(15000); // wait 15 seconds for others' use of the code section and lock to stop and then proceed
     } catch (e) {
        Logger.log('Could not obtain lock after 30 seconds.');
        return HtmlService.createHtmlOutput("<b> Server Busy please try after some time <p>")
        // In case this a server side code called asynchronously you return a error code and display the appropriate message on the client side
        return "Error: Server busy try again later... Sorry :("
     }
START NORMAL CODE HERE

我只有一个脚本,这确实是一个问题,但这是一个非常糟糕的问题,每个表单提交最多六次执行,而scriptlock是锁定它的最整洁的方法。如果您的代码本身花费的时间少于15秒,则会缩短等待时间,以便更多的副本放弃更快。如果使用此方法,您仍会在执行日志中看到额外的副本,但它们只有15秒长。看着他们以这种方式被抓住并杀死是非常令人满意的。


0
投票

这行有一个问题:

var value = sheet.getRange(lastRow,1,lastRow,lastColumn).getValues().toString(); 

让我们说lastRow是20.然后这个代码得到最后一行加上接下来的19行值,大概都是空白的。第三个参数是行数,第四个是列数。

最好将事件对象传递给函数并使用e.values而不必去最后一行。如果您一个接一个地提交多个表单提交,您实际上可能会收到错误的数据。

这条线也有问题:

htmlBody: "An inspection of the xyz machine has returned issues: " + "<br/><br/>"
      + "<b>" + comments + "</b>" + "<br/><br/>" +
      " Click " + '<a href="https:goo.gl/ahGbGu&^"> <b>HERE</b></a>' 
      + " to see the last inspection report.",
    });

应删除htmlBody参数末尾的逗号。

试试这段代码:

function sendEmails(e) {
  var value=e.values.toString();
  var comments=e.values[40]; 
  if (value.indexOf("NOT OK") > -1) {
    var html="An inspection of the xyz machine has returned issues: "; 
    html+="<br/><br/>" + "<b>" + comments + "</b>" + "<br/><br/>" + " Click " 
    html+='<a href="https:goo.gl/ahGbGu&^"> <b>HERE</b></a>' + " to see the last inspection report.";
    MailApp.sendEmail({to: "[email protected]",subject: 'Machine Issue',htmlBody: html});
    //Logger.log(html);
  } 
}

根据@J,我多玩了一点。 G. onFormSubmit触发器返回多个触发器时出现问题。我通过使用以下用于登录onFormSubmit触发器的代码解决了测试的情况。

function testFormSubmission(ev) {
  var lock=LockService.getUserLock();
  try{
    if(ev.values && !ev.values[1]){throw('Spurious Returns Error');}
      if(lock.tryLock(10000)) {
      var ss=SpreadsheetApp.getActive();
      var sh=ss.getSheetByName('LogSheet');
      var tA=[Utilities.formatDate(new Date(), Session.getScriptTimeZone(),"d/M/yyyy HH:mm:ss")];
      tA=tA.concat(ev.values);
      tA.splice(tA.length-1,1,ev.triggerUid,ev.range.rowStart,ev.range.columnEnd,JSON.stringify(ev.values));
      sh.appendRow(tA);
      lock.releaseLock();  
    }
  }
  catch(error){
    console.error(error);
    return;
  }
} 
© www.soinside.com 2019 - 2024. All rights reserved.