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

时间:2019-02-12 17:35:48

标签: google-apps-script google-sheets google-form

我遇到一个问题,即我提交的脚本在提交表单时发送重复的电子邮件。当我只是打开电子表格时,脚本有时也会执行。提交表单时,我只设置了一个触发器来运行脚本,并且我是唯一拥有对工作表进行编辑访问权限的触发器。我尝试完全删除脚本项目并创建一个新项目,但未能解决问题。我不确定我的脚本中是否有任何古怪的东西,但是这里是:

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: "test@test.com",
    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.
}

我还尝试过删除触发器并设置一个新触发器,但该触发器也不起作用。

3 个答案:

答案 0 :(得分:1)

检查执行日志。如果您有多个执行,但是只有一个“表单响应”行,则这是表单提交触发器的一个已知错误。解决该问题的唯一方法是使用脚本锁。

像这样:

     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

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

答案 1 :(得分:1)

我在提交表单时也遇到了多封电子邮件的问题。我注意到我的代码正在为我拥有的每个发送电子邮件功能发送一封电子邮件。就像,它是基于评分电子邮件的,所以我所做的是,我关闭了所有替代功能,因此,它将检查要点,如果不符合要求,则不会发送电子邮件,而是继续下一个功能,直到找到符合要求的功能。

我认为在您的代码中,其阅读两次发送电子邮件,因此他会继续阅读发送的电子邮件,查找需求并发送。然后,它读取下一封发送的电子邮件,再次查找要求并再次发送电子邮件。

就像您下令两次发送电子邮件一样。

答案 2 :(得分: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: "test@test.com",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;
  }
} 
相关问题