【问题标题】:Google Apps Script: email trigger only for new entries (without using Google Forms)Google Apps 脚本:仅针对新条目的电子邮件触发器(不使用 Google 表单)
【发布时间】:2014-09-25 16:14:57
【问题描述】:

我是编码初学者,我尝试了很多东西(解决方案),但没有运行脚本。 我正在使用现有的 sendEmail 脚本(见下文)将电子邮件发送到新的电子表格条目。

https://docs.google.com/spreadsheet

我没有使用 Google 表单。我正在从另一个电子表格表中复制所需的信息。使用 onEdit 触发器,脚本将向新条目发送电子邮件。

我遇到的问题是脚本会向电子表格的每一行发送一封电子邮件,即使该信息已经发送。

我尝试了一些解决方法,虽然这些方法在论坛中被命名,但对我的情况没有任何帮助。我不想只向最后一个条目发送电子邮件。我想向不同数量的新条目发送电子邮件,如果可能的话,这应该由 onEdit 事件触发。 我希望,有人能尽快帮助我……

  var EMAIL_SENT = "EMAIL_SENT";

  function sendEmails(onlyLast) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = ss.getSheets()[0];
  var startRow = 2;
  var lastRow = datasheet.getlastRow()-1;
  if (onlyLast)
  startRow = endRow;
  var dataRange = dataSheet.getRange(startRow, 1, lastRow, 4);

  var templateSheet = ss.getSheets()[1];
  var emailTemplate = templateSheet.getRange("A1").getValue();

  // Create one JavaScript object per row of data.
  var objects = getRowsData(dataSheet, dataRange);

  // For every row object, create a personalized email from a template and send
  // it to the appropriate person.
  for (var i = 0; i < objects.length; ++i) {
    // Get a row object
    var rowData = objects[i];


    var file = DriveApp.getFileById('');
    // Generate a personalized email.
    // Given a template string, replace markers (for instance ${"First Name"}) with
    // the corresponding value in a row object (for instance rowData.firstName).
    var emailText = fillInTemplateFromObject(emailTemplate, rowData);
    var emailSubject = "Tutorial: Simple Mail Merge";
    var emailSent;   
    if (emailSent != EMAIL_SENT) {  
      var subject = "Tutorial: Simple Mail Merge";
      MailApp.sendEmail(rowData.emailAddress, emailSubject, emailText, {attachments:[file.getAs(MimeType.PDF)]});
      dataSheet.getRange(startRow + i, 5).setValue(EMAIL_SENT);
      SpreadsheetApp.flush();
    }
  }
}

【问题讨论】:

  • 从不共享具有编辑权限的工作表,即使在这个论坛上,人们有时也会有不良习惯,并且会在工作表中填写奇怪的内容;-) 我将其设置为仅查看,任何人都可以根据需要制作副本进一步测试。

标签: google-apps-script google-sheets google-docs google-apps


【解决方案1】:

这对我来说太棒了,它是对 Bjorn 在那里所做的事情的修改。脚本 Bjorn 的道具谢谢你,希望这个线程能像今晚帮助我一样帮助别人。谢谢大家!

    function ssForward() {

    // DEFINE YOUR MAIN SPREADSHEET
    var ss = SpreadsheetApp.openById("SPREADSHEET_ID_ITS_IN_THE_SS_URL");

    // DEFINE THE DATA SHEET THAT RECIEVES THE SUBMISSIONS HERE
    var dataSheet = ss.getSheetByName("data");

    // DEFINE THE TEMPLATE SHEET THAT HAS THE EMAIL TEMPLATE INSIDE OF IT
    var templetSheet = ss.getSheetByName("template");

    //DEFINE THE CELLS THAT CONTAIN THE TEMPLATE TEXT FOR THE SUBJECT
    var templateSubject = templetSheet.getRange(1, 2).getValue();

    //DEFINE THE CELLS THAT CONTAIN THE TEMPLATE TEXT FOR THE SUBJECT
    var templateBody = templetSheet.getRange(2, 2).getValue();

    //NOW RUN A FOR LOOP THAT GOES THROUGH EACH ENTRY IN EACH ROW (var i = the row in your spreadsheet )      
    for (var i = 2; i <= dataSheet.getLastRow(); i++) {

        // ADD CURRENTLY VIEWED ENTRY TO VAR (var phone = the sheet in row i, column 3)
        // all 3 of these var work the same way    
        var phone = dataSheet.getRange(i, 3).getValue();
        var location = dataSheet.getRange(i, 4).getValue();
        var status = dataSheet.getRange(i, 10).getValue();

        // NOW USE THE templetSheet VAR DEFINED ABOVE AND REPLACE THE PLACEHOLDER TEXT WITH THE APPROPRIATE VARIABLE

        //REPLACE THE SUBJECT TEMPLATE TEXT <<phone>> WITH THE CONTENTS OF THE VAR 'phone' defined above.
        var subject = templateSubject.replace("<<phone>>", phone);

        //REPLACE THE 'SUBJECT TEMPLATE' TEXT: <<location>> - WITH THE CONTENTS OF THE VAR 'location' defined above.
        var body = templateBody.replace("<<location>>", location);

        //REPLACE THE 'SUBJECT TEMPLATE' TEXT: <<phone>> - WITH THE CONTENTS OF THE VAR 'phone' defined above.
        body = body.replace("<<phone>>", phone);

        // IF OUR STATUS CELL IS EMPTY
        if (status == "") {

            // SEND THE EMAIL FROM 'DESIRED@EMAIL.com', USE THE 'subject' VAR FOR THE SUBECT, AND THE VAR 'templateBody' FOR THE MESSAGES BODY
            MailApp.sendEmail('YOUR@EMAIL.com', subject, body);

            // MARK THE ROW AS COMPLETED
            dataSheet.getRange(i, 10).setValue("Email Notification Sent");
        }
    }
}

【讨论】:

    【解决方案2】:

    这是一个示例电子表格:https://docs.google.com/spreadsheets/d/1RdwZcK6tsOr1m44ZyawWsWXGa26zhd8J1ZZs_GsRRtY/edit?usp=sharing

    把它放在一个定时触发器上:

    function sendNew(){
      var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("data");
      var templetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("template");
      var templateSubject = templetSheet.getRange(1, 2).getValue();
      var templateBody = templetSheet.getRange(2, 2).getValue();
    
      for (var i =2; i<= dataSheet.getLastRow(); i++){
        var name = dataSheet.getRange(i, 1).getValue();
        var color = dataSheet.getRange(i, 2).getValue();
        var status = dataSheet.getRange(i, 3).getValue();
    
        var subject = templateSubject.replace("<<Name>>", name);
        var body = templateBody.replace("<<Name>>", name);
        body = body.replace("<<Color>>", color);
    
        if (status == ""){
          MailApp.sendEmail('youremail@gmail.com', subject, body);
          dataSheet.getRange(i,3).setValue("Email Sent");
        } 
      }
    }
    

    【讨论】:

      【解决方案3】:

      首先,我建议不要使用 onEdit,而是使用时间驱动的触发器来检查更改。这样您的脚本就不会一直尝试发送电子邮件,即使您错过了输入内容。

      其次,您将需要某种方式来指示数据是否已处理的天气。您可以让脚本将所有处理过的信息加粗,然后通过电子邮件发送非粗体的任何内容。

      这是我为某人编写的类似脚本的链接,如果脚本看到“已取消”一词,该脚本将通过电子邮件发送一份人员名单。

      https://docs.google.com/a/askbj.net/spreadsheets/d/1Y82TwZWC8Nh2HQhpKWcdxgnrU0ANo8d2JLenK3gWyY4/edit?usp=sharing

      -bj

      【讨论】:

        【解决方案4】:

        在您的代码中定义var emailSent;,但不为其分配任何值...

        所以下面的比较总是返回 trueif (emailSent != EMAIL_SENT) {

        尝试简单地将var emailSent; 替换为:

        var emailSent = dataSheet.getRange(startRow + i, 5).getValue();
        

        它应该按预期工作。

        最后,正如另一个答案中提到的,在计时器触发器而不是 onEdit 上运行此函数以避免部分电子邮件发送(如果用户更改了单元格内容或输入错误的内容......)

        编辑: 最后说明,请删除第一行 var EMAIL_SENT = "EMAIL_SENT",我知道它来自 Google 示例,但在这里没有用,而且(恕我直言)非常混乱,因为最后你不知道 EMAIL_SENT 是变量还是值...,将你的条件更改为

        if (emailSent != 'EMAIL_SENT') { // which compares a value to a string, clearly ;-)
        

        【讨论】:

        • 嗨,你是对的。对不起,我的回复晚了,第二个帖子我现在已经删除了。感谢比约恩。我根据自己的需要对编码进行了一些更改,效果非常好!谢谢大家。
        • 没问题,如果你对他的回答感到满意,你应该考虑接受他的回答......这就是stackoverflow的工作方式:-)。欢迎您,祝您好运。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-10
        • 1970-01-01
        • 2020-12-15
        • 1970-01-01
        相关资源
        最近更新 更多