从 Google 表单更新单元格后从 Google Sheet 发送电子邮件

Sending email from Google Sheet after a cell is updated from Google Form

你好,我现在有这个代码可以发送电子邮件:

function sendNotification(e){
  
if(e.range.getColumn()==4 && e.value=='Air Filter'){
 var recipients = "xx@email.com";
 var subject = "Update on "+e.range.getSheet().getName();
 var body = "Air filter 50751-123 needs ordered for the Hurco"
 MailApp.sendEmail(recipients, subject, body)
 }
  
if(e.range.getColumn()==4 && e.value=='Coolant'){
 var recipients = "xx@email.com"&&"xyx@email.com";
 var subject = "Update on "+e.range.getSheet().getName();
 var body = "Coolant is needed for the Hurco"
 MailApp.sendEmail(recipients, subject, body)
 
}  
  
}

我的问题是,当一个Google表单提交到我的GoogleSheet时,然后某个单词被提交到某个列,我想要Google向所需的收件人发送电子邮件。

当我实际进入 Sheet 并编辑该列时,它可以工作,但我希望它在输入表单时工作。 (这仅在我触发 onEdit 时有效,当它在 onChange 时,我收到未定义的 "TypeError: Cannot call method "getColumn" 错误。(第 3 行,文件 "Email Notif")")

它将要查看的列将有 4 个不同的词可以查找,每个词可以链接到不同的收件人。 "Air filter" 送给一个人,而 "Coolant" 会送给两个不同的人。

谢谢

要在提交表单时发送电子邮件,您需要使用 "on form submit" installable trigger

必须更新代码才能使用正确的 event properties。您使用的是 "on edit" 事件的 .value 属性,但 "on form submit" 事件具有 .values,这是一个值数组,或者 .namedValues是一个 object,其中表单问题是键(即响应 sheet 的列 headers)。

范围将是表单提交,因此检查第 4 列的范围没有多大意义,就像您需要为编辑事件所做的那样。

function sendNotification(e) {
  var recipients = "xx@email.com";
  var subject = "Update on " + e.range.getSheet().getName();
  var body = "";
  if (e.namedValues["Item that is needed."] == 'Air Filter') {
    body = "Air filter 50751-123 needs ordered for the Hurco";
  } else if (e.namedValues["Item that is needed."] == 'Coolant') {
    recipients += ",xyx@email.com";
    body = "Coolant is needed for the Hurco";
  }
  if (body.length > 0) {
    MailApp.sendEmail(recipients, subject, body);
  }
}

编辑:

根据评论中的要求,更新包括根据选定的列号检查以前提交的重复项。

function sendNotification(e) {
  var recipients = "xx@email.com";
  var subject = "Update on " + e.range.getSheet().getName();
  var body = "";
  if (checkForSameSubmission(e, 24, [2, 3])) { // event, hours to look back, columns to check (zero index!)
    subject += " DUPLICATE";
    body += "WARNING: DUPLICATE!\n";
  }
  if (e.namedValues["Item that is needed."] == 'Air Filter') {
    body += "Air filter 50751-123 needs ordered for the Hurco";
  } else if (e.namedValues["Item that is needed."] == 'Coolant') {
    recipients += ",xyx@email.com";
    body += "Coolant is needed for the Hurco";
  }
  if (body.length > 0) {
    MailApp.sendEmail(recipients, subject, body);
  }
}

// JSON.stringify will let us compare array values as strings
function checkForSameSubmission(event, hours) {
  var sheetData = event.range.getSheet().getDataRange().getValues();
  sheetData.shift(); // remove header row
  sheetData.pop(); // remove just submitted row
  var byColumns = function (_, index) { // for Array.prototype.filter
    return columns.indexOf(index) > -1;
  }
  var toStrings = function (value) { // for Array.prototype.map
    return String(value); // ensure all numbers become strings for final comparison
  };
  var thisSubmissionData = JSON.stringify(event.values.filter(byColumns).map(toStrings));
  var isSameSubmission = function (dataRow) {
    return thisSubmissionData === JSON.stringify(dataRow.filter(byColumns).map(toStrings));
  }
  return checkPreviousDataByHours(hours, sheetData, isSameSubmission);
}

function checkPreviousDataByHours(hours, data, someCallback) {
  var minusHours = Date.now() - 1000*60*60*hours;
  var lastHoursData = data.filter(function (row) { return +row[0] > minusHours; });
  return lastHoursData.some(someCallback);
}