在谷歌应用程序中理解并应用withccesshandler

时间:2015-12-17 14:28:18

标签: google-apps-script google-sheets

背景

我有这个问题,我真的不明白如何解决。所需的行为是访问Google电子表格并从包含三个scriptlet的模板发送HTML电子邮件,以便根据电子表格中的数据链接到不同的表单。我对评估模板的调用接近脚本的结尾。

我正在使用两行测试数据。当我阅读执行日志时,一切正常,但奇怪的是,有时会发送两封电子邮件,有时会发送一封电子邮件(当我期待两封时),而且并不总是我期望的电子邮件。但结果每次都不一样。我认为这是因为当HtmlService.createTemplateFromFile('file').evaluate()被调用时,它在服务器上的计算,但我的代码只是继续前进并在我得到响应之前完成。它只是猜测。我看过谷歌的HtmlService Page on communicating with serversreferences on google.script.run

代码和努力

function sendForms () {
  var masterSS = SpreadsheetApp.openById("id");
  var masterSheet = masterSS.getSheets()[0];
  var masterRange = masterSheet.getDataRange();
  var masterData = masterRange.getValues();
  var startRow = 1;
  for (var i = 1; i < masterData.length; i++) {
    var row = masterData[i];
    var emailAddress = row[2];
    var routineContact = row[5];
    var requireDrive = row[6];
    var compCheck = row[7];
    var affidavit = " ";
      if (routineContact != "SENT" && routineContact != "RECEIVED" && routineContact != "No") {
      var affidavit = "<li>Form: <a href='https://docs.google.com/forms/d/formid/viewform?usp=send_form'>Affidavit of Compliance with PA Background Checks</a> Verification Code: 169827C9</li>";
      masterSheet.getRange(startRow + i, 6).setValue("SENT");
  }
    var motorVehicleUsage = " ";
      if (requireDrive != "SENT" && requireDrive != "RECEIVED" && requireDrive != "No") {
      var motorVehicleUsage = "<li>Form: <a href='https://docs.google.com/forms/d/formlink/viewform?usp=send_form'>Motor Vehicle Agreement</a> Verification Code: 13444C9</li>";
      masterSheet.getRange(startRow + i, 7).setValue("SENT");
  }
    var workersCompForm = " ";
      if (compCheck != "SENT" && compCheck != "RECEIVED") {
      var workersCompForm = "<li>Form: <a href='https://docs.google.com/forms/d/formid/viewform?usp=send_form'>Workers Compensation</a> Verification Code: 13589C9</li>";
      masterSheet.getRange(startRow + i, 8).setValue("SENT");
  }    
      if (motorVehicleUsage != " " && workersCompForm != " " && affidavit != " ") {
      var sendingDate = new Date();
      var formatSendingDate = Utilities.formatDate(sendingDate, "GMT-05:00", 'DD');
      masterSheet.getRange(startRow + i, 10).setValue(formatSendingDate);
      var subject = "Additional Onboarding Forms";  
      var template = HtmlService.createTemplateFromFile('Initial Form Email Message');
      template.workersCompForm = workersCompForm;
      template.motorVehicleUsage = motorVehicleUsage;
      template.affidavit = affidavit;
      var html = template.evaluate().getContent();
      MailApp.sendEmail(emailAddress, subject, "Requires HTML", {htmlBody:html});
      }
    }
  }

这是我的HTML文件中包含scriptlet的部分。

<p>We would like you to complete the following additional...</p>
            <ul>
                <?!= workersCompForm ?><?!= motorVehicleUsage ?><?!= affidavit ?>
            </ul>

我最初在var html上面有if语句,并且有var html = template.evaluate()。getContent();在底部,就在MailApp之上。那是因为我的结果不一致。

google.script.run.html()根本不起作用,因为即使在阅读完文档后我也不知道如何使用它。

问题

我很确定我在这个脚本中的某个地方需要一个withSuccessHandler,但是我无法概念化它的位置或者如何使它工作。我试着创建var html = function();但没有运气使它工作。我应该使用withSuccessHandler吗?我会把它放在哪里?我无法绕过与服务器通信并处理时间。

更新

为此问题添加了属于Apps脚本项目的HTML文件,将代码文件更改为我的原始代码,而没有按照Sandy的建议调用google.script.run,因为它不会在.gs文件中运行。虽然看似随机的电子邮件正在发送,但我仍然有同样的问题。有时它是第一个获取电子邮件发送的for循环,有时它是第二个for循环获取电子邮件,当我在电子表格上设置条件发送以发送两个循环的电子邮件时。

我将var template = HtmlService.createTemplateFromFile('Initial Form Email Message');替换为var template = HtmlService.createHtmlOutputFromFile('Initial Form Email Message');没有运气,所以我尝试var template = HtmlService.createHtmlOutputFromFile('Initial Form Email Message').getContent();并且这些尝试无法收到任何电子邮件。但电子表格始终使用正确的值进行更新。

1 个答案:

答案 0 :(得分:2)

google.script.run就是所谓的“客户端API”。 “客户端”表示它在用户计算机上的浏览器中运行。 google.script.run并非意在使用.gs服务器代码。因此,您不会从具有google.script.run扩展名的脚本文件中获取.gsgoogle.script.run将在HTML的事件属性中运行,例如onclick()<script>标记以及其他JavaScript。

可以在服务器代码中创建HTML,并将其发送到某个地方。您可以使用代码中包含的文字字符串来执行此操作,也可以使用服务器评估的.html文件,然后转换为内容。但这不是用google.script.run完成的,而是用HTML服务完成的。

var theHtml = HtmlService.createHtmlOutputFromFile(filename).getContent();