多次执行Google Script,即使使用Lock on form提交触发器也是如此

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

我很难理解为什么每次提交表单时这个脚本同时执行2,3,甚至4次。我已经添加了LockService,但虽然它有时会阻止发送多封电子邮件,但似乎并不能阻止同时执行。

其他一切工作正常 - 我只是不希望每次失败的执行,因为这些也会因脚本超时而中断后续的合法触发器执行。

我必须从工作表执行,因为我正在调用基于表单响应检索到工作表的数据。工作表未共享,并且没有“孤立”触发器。我删除/重新创建了触发器,甚至重新创建了工作表和脚本,但仍然获得了额外的执行。

在此先感谢您的任何建议!

function zoneRepEmail(e) {

  var lock = LockService.getScriptLock();
  lock.waitLock(30000);  // wait 30 seconds before conceding defeat.
  // got the lock, you may now proceed
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('SupervisorApprovals');
  var lookupRow = e.range.getRow(); 
  var rowRange = sheet.getRange(1,1,sheet.getLastRow(),37);
  
  var appEmailSentLog = rowRange.getCell(lookupRow,36);
  var repEmailSentLog = rowRange.getCell(lookupRow,37); 
   Logger.log(appEmailSentLog);
  
  var form = FormApp.openById('1efkzyAgHf3PjEnPXSXP4P5mTCnII_BQaf5jf2Apr8gM');
   
  var startRow = 3;
  var headers = sheet.getRange(2, 1, 1, sheet.getLastColumn()).getValues()[0];
 
  var timestampColumn = sheet.getRange('K'+lookupRow);
  var dateColumns = sheet.getRangeList(['X'+lookupRow, 'Y'+lookupRow]);
  var pctColumns = sheet.getRange('Z'+lookupRow);
  var phoneColumns = sheet.getRangeList(['P'+lookupRow,'Q'+lookupRow,'U'+lookupRow]);
  var dataRange = sheet.getRange(lookupRow,1,sheet.getLastRow(),37);
  var data = dataRange.getValues();
    
    
  for (var i = 0; i < data.length; ++i){
      var row = data[i]; 
      var timestamp = e.namedValues["Timestamp"];
      var columnOfEditUrl = 46;
      var email_address = "[email protected]";
      var columnOfHomeUnit = 44;
      var columnOfAppId = 45;
      var columnOfZoneRep = 47;
      var columnOfZoneRepEmail = 48;
      var colEmplLName = 2;
      var emplLName = sheet.getRange(lookupRow, 12).getValue();
      var colEmplFName = 3;
      var emplFName = sheet.getRange(lookupRow, 13).getValue();
      var emplMName = sheet.getRange(lookupRow, 14).getValue();
      var locDisp = sheet.getRange(lookupRow, 15).getValue();
      var empPhone = row[15];
      var emplAltPhone = row[16];
      var emplEmail = row[17];
      var emplClass = row[18];
      var emplSup = row[19];
      var supPhone = row[20];
      var supEmail = row[21];
      var trainPosition = row[22];
      var firstAssign = row[23];
      var lastAssign = row[24];
      var tbPercent = row[25];
      var trainIMT = row[26];
      var imtName = row[27];
      var reqTraining = row[28];
      var trainNeeded = row[29];
      var appComments = row[30];
      var homeUnit = row[31];
      var appId = row[1];
      var zoneRep = row[33];
      var zoneRepEmail = sheet.getRange(lookupRow, 35).getValue();
      var appStatus = row[6];
      var statusReason = row[7];
      var statusComment = row[8];
      
    timestampColumn.setNumberFormat("mm/dd/yyyy hh:mm:ss");
    pctColumns.setNumberFormat("###%");
    dateColumns.setNumberFormat("mm/dd/yyyy");
    phoneColumns.setNumberFormat("###-###-####");
    
      var emailTo = emplEmail;
      var message = "The following application to the Rocky Mountain Area Priority Trainee Program has been "+appStatus+" for "+emplFName+" "+emplMName+" "+emplLName+". Please carefully review all details in the application and update your zone sheet accordingly."+"\n"+"If corrections are required, please contact the applicant directly."+"\n"+"A status email has been forwarded to the applicant and supervisor listed."+"\n"+"\n"+"--------------------------------------------------------------"+"\n"+"\n"+"Applicant Name: "+emplFName+" "+emplMName+" "+emplLName+"\n"+"Application Reference ID: "+appId+"\n"+"Dispatch: "+locDisp+"\n"+"Employee Phone: "+empPhone+"\n"+"Employee Alternate Phone: "+emplAltPhone+"\n"+"Employee Email: "+emplEmail+"\n"+"Home Unit ID: "+homeUnit+"\n"+"Employment Class: "+emplClass+"\n"+"\n"+"Supervisor Name: "+emplSup+"\n"+"Supervisor Phone: "+supPhone+"\n"+"Supervisor Email: "+supEmail+"\n"+"\n"+"Trainee Position: "+trainPosition+"\n"+"Taskbook Percentage Complete: "+tbPercent+"\n"+"Taskbook First Assignment: "+firstAssign+"\n"+"\n"+"IMT Trainee: "+trainIMT+"\n"+"Assigned to IMT: "+imtName+"\n"+"\n"+"All Required Training Completed?: "+reqTraining+"\n"+"Training Still Needed for Position: "+trainNeeded+"\n"+"\n"+"Comments: "+appComments+"\n"+"\n"+"Application Status: "+appStatus+"\n"+"Reason for Denial (if applicable): "+statusReason+"\n"+"Supervisor Comments: "+statusComment;
      var appMessage = "The following application to the Rocky Mountain Area Priority Trainee Program has been "+appStatus+" for "+emplFName+" "+emplMName+" "+emplLName+". The application has been forwarded to the Zone Training Representative for processing."+"\n"+"\n"+"--------------------------------------------------------------"+"\n"+"\n"+"Applicant Name: "+emplFName+" "+emplMName+" "+emplLName+"\n"+"Application Reference ID: "+appId+"\n"+"Dispatch: "+locDisp+"\n"+"Employee Phone: "+empPhone+"\n"+"Employee Alternate Phone: "+emplAltPhone+"\n"+"Employee Email: "+emplEmail+"\n"+"Home Unit ID: "+homeUnit+"\n"+"Employment Class: "+emplClass+"\n"+"\n"+"Supervisor Name: "+emplSup+"\n"+"Supervisor Phone: "+supPhone+"\n"+"Supervisor Email: "+supEmail+"\n"+"\n"+"Trainee Position: "+trainPosition+"\n"+"Taskbook Percentage Complete: "+tbPercent+"\n"+"Taskbook First Assignment: "+firstAssign+"\n"+"\n"+"IMT Trainee: "+trainIMT+"\n"+"Assigned to IMT: "+imtName+"\n"+"\n"+"All Required Training Completed?: "+reqTraining+"\n"+"Training Still Needed for Position: "+trainNeeded+"\n"+"\n"+"Comments: "+appComments+"\n"+"\n"+"Application Status: "+appStatus+"\n"+"Reason for Denial (if applicable): "+statusReason+"\n"+"Supervisor Comments: "+statusComment;
      var subject = appStatus+": PT App for "+emplFName+" "+emplMName+" "+emplLName+" // "+trainPosition+" // "+timestamp;

       
    Utilities.sleep(5000);//allow all column formats to be applied, then proceed.
    
 if (repEmailSentLog.isBlank()){
   GmailApp.sendEmail(zoneRepEmail, subject, message,{noReply:true});
    repEmailSentLog.setValue('EmailSent');
 }
    if (appEmailSentLog.isBlank()){
      GmailApp.sendEmail(emplEmail, subject, appMessage,{cc:supEmail,noReply:true});
    appEmailSentLog.setValue('EmailSent');
    }
    
  }
   lock.releaseLock(); Utilities.sleep(10000);
}
google-apps-script google-sheets google-form
1个回答
1
投票

我肯定会删除该行:

Utilities.sleep(10000);

没有理由等待。

如果您想避免由Apps Script限制引起的速率限制错误,那么在for循环内调用服务,只有在出现错误时才会等待。这样,代码不会等待,如果它不需要,只在需要时等待。

而且我会增加超时时间。通常,代码将释放锁定,因此长时间超时不会影响该情况,但如果超时在代码完成之前结束,则可能导致问题。

如果有错误,则释放锁定。因此,以下代码添加了一个try / catch块来处理它。

此外,您应该在继续之前测试获得的锁定,如果未获得锁定,则退出并通知某人存在错误。

function zoneRepEmail(e) {
try{
  var lock = LockService.getScriptLock();
  lock.waitLock(60000);  // wait 60 seconds before timing out

  if (!lock.hasLock()) {//Failed to get lock

    MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
     'Code Failed', 'The code for ABC failed');
    //Logger.log('Could not obtain lock');
    return;
  }

  for (i=1;i<4;i++) {//Try up to 3 times
    try{
      //Rate limited service call code here
      break;
    }catch(e){
      if (i!==3){Utilities.sleep(i*2000);}
      if (i>=3) {
        MailApp.sendEmail(Session.getEffectiveUser().getEmail(), 
         'Code Failed', 'The code for ABC failed - ' + e.message + "\n\n" +
          e.stack);
      }
    };
  }

  //Code here

  lock.releaseLock();


} catch(e) {
  lock.releaseLock();//Release the lock if there is an error
  MailApp.sendEmail(Session.getEffectiveUser().getEmail(), 
    'Code Failed', 'The code for ABC failed - ' + e.message + "\n\n" +
     e.stack);
  //Logger.log('error: ' + e.message + ' stack: ' + e.stack);

}
}
© www.soinside.com 2019 - 2024. All rights reserved.