Скрипт листа Google связан с отправкой дубликатов электронных писем при отправке формы - PullRequest
0 голосов
/ 12 февраля 2019

У меня проблема с тем, что написанный мной скрипт отправляет дубликаты электронных писем при отправке формы.Сценарий также выполняется иногда, когда я просто открываю электронную таблицу.У меня только один триггер, настроенный для запуска скрипта при отправке формы, и я единственный, кто имеет доступ к редактированию листа.Я попытался полностью удалить проект сценария и создать новый, который не решил проблему.Я не уверен, что в моем скрипте есть что-то нехорошее, но вот оно:

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.
}

Я также попытался удалить триггер и настроить новый, который тоже не работал.

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Проверьте ваш журнал казней.Если у вас есть несколько выполнений, но только одна строка ответов формы, это известная ошибка с триггером отправки формы.Единственный способ обойти это - использовать блокировку скрипта.

Примерно так:

     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

У меня есть только один скрипт, где это действительно проблема, но это была действительно ужасная проблема, до шести выполнений на отправку формы, и сценарий блокировкисамый аккуратный способ заблокировать это.Если сам код занимает менее 15 секунд, сократите время ожидания, так что дополнительные копии сдаются быстрее.Если вы используете этот метод, вы все равно увидите дополнительные копии в журнале выполнений, но они будут длиться всего 15 секунд.Очень приятно наблюдать за тем, как их ловят и убивают.

0 голосов
/ 13 февраля 2019

В этой строке есть проблема:

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);
  } 
}

Я немного поиграл с этим, и, согласно @JG, существует проблема с триггерами onFormSubmit, возвращающими несколько триггеров.Я решил ситуацию для моего тестирования, используя следующий код, который я использовал для входа в систему триггеров FormsSubmit.

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;
  }
} 
...