首页 > 解决方案 > 邮件合并中的 AppScript 执行 - 可靠性和稳定性的最佳实践

问题描述

请验证我是否在脚本执行方面没有遇到问题。我有五张 Google 表格,都绑定到一张 Google 表格上。该工作表附有以下代码(我已从错误处理等中删除了代码)。

设想:

我正在尝试为 5 门不同课程的用户颁发证书。在课程完成时(大约在一天中的同一时间),用户输入他们的详细信息(姓名、电子邮件),下面的脚本负责创建个性化证书并将其发送到他们的电子邮件地址。比如说,所有课程每天最多有 100 个用户。

以下是问题:)

我在想脚本是如何执行的?它是每次提交的一个实例,还是会从一张表中提供 100 个作业的队列?我知道 javascript 一次运行一件事,但我不完全确定它在运行应用程序脚本和 onFormSubmit 事件方面意味着什么——我只是不知道这些脚本/实例是如何管理和执行的。

这是我第二次尝试为多种形式颁发证书。以前的解决方案每个表格只有一张纸,五个脚本生成证书,但是进行任何更改和测试都很痛苦。

非常感谢您的任何回答。

最好的。拉法尔

var ss = SpreadsheetApp.getActiveSpreadsheet();
var chosenId;

var templates = {
  "templateId_PL_1" : "1oS_11gz_123456789abcdefghijklmnop",
  "templateId_PL_2" : "11gasdsz_123456789abcdefghijklmnop",
  "templateId_PL_3" : "1JMo11gz_123456789abcdefghijklmnop",
  "templateId_EN_1" : "1KTx11gz_123456789abcdefghijklmnop",
  "templateId_EN_2" : "1_VQBgsz_123456789abcdefghijklmnop",
}
// reaction to form submit event
function onFormSubmit(e) {
  //check source of data by getting sheet name, i.e. "PL_1" or "EN_2"
  var range = e.range;
  chosenId = range.getSheet().getName();
  //get corresponding named range in "master" worksheet
  var trainingData = ss.getRangeByName(chosenId).getValues();
  //create new user object
  var userData = {
    //get submitted data from post
    "Title":[e.values[1]],
    "Name":[e.values[2]],
    "Surname":[e.values[3]],
    "Email":[e.values[4]],
    //get data from named range
    "Client":[trainingData[1][0]],
    "Training":[trainingData[1][3]],              
    "Date":[trainingData[1][1]],
     };
  //generate certs
  createAndUpdateCertificate(userData);
 }


function createAndUpdateCertificate(userObj){
  //create template copy according to data source
  var tempId = "templateId_"+chosenId; 
  var copy = DriveApp.getFileById(templates[tempId]).makeCopy("temp");
  var presentationID = copy.getId();
  //open copied presentation and go to 1st (only) slide
  var presentation = SlidesApp.openById(presentationID);
  var firstSlide = presentation.getSlides()[0]
  //replace texts in the slide
  firstSlide.replaceAllText("<<Title>>", userObj.Title);
  firstSlide.replaceAllText("<<Name>>", userObj.Name);
  firstSlide.replaceAllText("<<Surname>>", userObj.Surname);
  firstSlide.replaceAllText("<<Training>>", userObj.Training);
  firstSlide.replaceAllText("<<Date>>", userObj.Date);
  //close the copy
  presentation.saveAndClose();

  //sending certs
  sendCerts(
    presentationID, 
    userObj.Email, 
    userObj.Name, 
    userObj.Surname, 
    userObj.Training, 
    userObj.Date
  );

  //delete copy
  copy.setTrashed(true);
}


function sendCerts(cert, email, name, surname, training, date){
 //fetch cert as pdf
 var docblob = DriveApp.getFileById(cert).getAs('application/pdf');
 docblob.setName(date+"-"+"CERT "+training+"-"+name+" "+surname+".pdf");
 //save the pdf in appropriate  folder as a backup
 var dest = DriveApp.getFolderById("1K2k-123456789abcdefghijklmnop")
 var file = dest.createFile(docblob);
    MailApp.sendEmail(
    email, 
    "test", // title
    "test", // body
    { noReply: true,
     attachments: [file]
    }
  );
}

标签: google-apps-script

解决方案


我没有看得很仔细,但是使用范围来获取响应表名称是在同一个电子表格中处理多个表单的关键。看起来您的表单非常相似,因此使事情变得容易得多。为什么不只发送一个对象而不是所有单个参数?总的来说,我认为代码看起来井井有条。


推荐阅读