从谷歌电子表格发送电子邮件 - 编码建议

时间:2012-12-23 14:52:35

标签: google-apps-script google-sheets google-spreadsheet-api

我还在这里学习绳索。根据其他贡献者建议的代码,我整理了一个脚本,向使用Google表单记录其时间条目的顾问发送提醒电子邮件。电子表格首先导入日历条目,其中包含每位顾问的所有工作信息。导入日历条目后,如果顾问尚未记录其时间条目,则以下脚本将向他们发送一封电子邮件,其中包含提醒:

function sendReminder() {

  var rmndrFrom = "XYZ, Inc.";
  var myemail   = "support@xyz.com";

  var sheet     = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Pending");
  var numRows   = sheet.getLastRow();
  var lastCol   = sheet.getLastColumn();
  var dataRange = sheet.getRange(2, 1, numRows, lastCol); // row 1 is the header row
  var sheetData = dataRange.getValues();

  for (var i = 0; i < sheetData.length; ++i) {
    var row = sheetData[i];
    if (row[0]){
      var jobNumb = row[0]; // Job Number
      var conName = row[2]; // Consultant Name
      var conMail = row[3]; // Consultant Email
      var jobDate = row[4]; // Date

      // format email string
      var subject = "Time Entry Reminder: " + conName + " / Job " + jobNumb;

        try {
          var conMsgH = 'This is a reminder for you to record your time entry for Job #<strong>' + jobNum + '/' + jobDate + '</strong>';

          // strip HTML for plain text message
          var conMsgP = conMsgH.replace(/\<br\/\>/gi, '\n').replace(/(<([^>]+)>)/ig, "");

          // send reminder to consultants
          MailApp.sendEmail(conMail, subject, conMsgP, { htmlBody:conMsgH, name:rmndrFrom });

        } catch (e) { // error handler
          MailApp.sendEmail(myemail, "Error in sending reminder email.", e.message);
        }
      }
  }
}

所以基本上,这个脚本解析Pending表,如果A列有一个Job Number,它会向顾问发送一个提醒电子邮件,上面写着该职位号。但是,单个顾问可能会有几个工作号码。我希望脚本能够向每位顾问发送一封电子邮件,其中包含他们必须记录时间条目的工作号码列表。

提前感谢您的帮助。任何关于如何优化代码的建议也将非常受欢迎。

2 个答案:

答案 0 :(得分:2)

有很多方法可以解决这个问题。一种方法是使用顾问的电子邮件,姓名和工作号码列表保存一张表。将此数据加载到脚本中,列出所有作业ID和作业信息。然后根据顾问列表过滤作业ID并构建您的电子邮件,或者您只需发送一个非常短的脚本的数字列表。

另一种方法是在代码中对每个顾问进行所有排序,并以这种方式发送电子邮件。这是我采用的方法,我也使用了迭代的JS函数映射,过滤并减少了more details at MDN

代码发布在下面,但是如果您想查看附加到电子表格并注释的内容(以及仅使用顾问信息构建额外工作表的功能),请查看{{ 3}}

以下是我的函数迭代。我希望它对你的情况有所帮助:

var rmndrFrom = "XYZ, Inc.";
var myemail   = "me@emailisawesome.com";
var subject   = "Time Entry Reminder";

function sendReminder() {
  var sheet       = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Pending");
  var numRows     = sheet.getLastRow();
  var lastCol     = sheet.getLastColumn();
  var sheetData   = sheet.getRange(2, 1, numRows-1, lastCol).getValues();
  var cons = sheet.getRange(2,3,numRows-1,1).getValues().reduce(flatten_).filter(getUniqueConsultants_);
  cons.forEach(sendEmail_, sheetData);
}

function sendEmail_(consultant) {
  var consultantsJobs = this.filter(getJobsForConsultant_, consultant);
  var jobList = consultantsJobs.map(buildJobLine_).join("<br>"); 
  try {
    var conMsgH = "Hi " + consultant + ",<br>";
    conMsgH    += "This is a reminder for you to record your time entry for the following jobs:<br><br>";
    conMsgH    += jobList;
    conMsgH    += "<br><br>Thank you for your cooperation.";
    var conMsgP = conMsgH.replace(/\<br\/\>/gi, '\n').replace(/(<([^>]+)>)/ig, "");
    MailApp.sendEmail(consultantsJobs[0][3], subject, conMsgP, {htmlBody:conMsgH, name:rmndrFrom});
  } catch (e) {
    MailApp.sendEmail(myemail, "Error in sending reminder email.", e.message);
  } 
}

function buildJobLine_(job) {
  return "Job #" + job[0] + " on " + Utilities.formatDate(job[4], Session.getTimeZone(), "MMM dd yyyy");
}

function getJobsForConsultant_(row) {
  return row[2] == this;
}

function getUniqueConsultants_(v,i,a) {
  return a.indexOf(v) == i;
}

function flatten_(a,b) {
  return a.concat(b);
}

答案 1 :(得分:1)

我必须说fooby的答案远远超出了我的JS技能,我相信它会很好地运作但我仍然想提出一些不同的东西(和我的pov一样简单),只是为了好玩它; - )

与原始脚本的主要区别在于数组的排序,这使我能够检测重复的名称并相应地对其进行威胁。 html组合可能会更好,但这不是你的主要要求。

这是代码

function sendReminder() {

  var rmndrFrom = "XYZ, Inc.";
  var myemail   = "support@xyz.com";
  var sheet     = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Pending");
  var initial = "Hi conName,<BR>This is a reminder for you to record your time entry for the following jobs : <BR><BR><table border = 1 cellpadding = 3 bgcolor='#FFFFBB'><TR><TD>";

  var sheetData = sheet.getDataRange().getValues();// simplified code to get the data array
  sheetData.shift();//skips the headers
  sheetData.sort(function(x,y){
  var xp = x[2];// sort on column 3 but you can change  here...
  var yp = y[2];// sort on column 3 but you can change  here...
  return xp == yp ? 0 : xp < yp ? -1 : 1;// sort ascending, eventually change here...
  });
//  Logger.log(sheetData);// sorted
  var last = sheetData.length
  var i = 1;//index 0 is handled outside the loop
  var row = sheetData[0];
  var subject = "Time Entry Reminder: " + row[2] + " / Job "
  var conMsgH = initial
  var msgComponent = makeline_(row)
  subject += msgComponent[0]
  conMsgH += msgComponent[1]

  while (i<last){
    if(sheetData[i][2]!=sheetData[i-1][2]||i==last-1){
      sendData_(sheetData[i-1][3],sheetData[i-1][2],subject,conMsgH)
      var subject = "Time Entry Reminder: " + sheetData[i][2] + " / Job "
  var conMsgH = initial;
      }
  msgComponent = makeline_(sheetData[i])
  subject += msgComponent[0]
  conMsgH += msgComponent[1]
  ++i
  }
}

function sendData_(conMail,conName,subject,conMsgH){
  conMsgH = conMsgH.substr(0,conMsgH.length-8)+'</TABLE>'
  conMsgH = conMsgH.replace('conName',conName)
  var conMsgP = conMsgH.replace(/<\/tr>/ig, '\n').replace(/<br>/ig, '\n').replace(/(<([^>]+)>)/ig, "")
  subject = subject.substr(0,subject.length-2);// remove the last '+ '
//  Logger.log(subject)
//  Logger.log(conMsgH)
  Logger.log(conMsgP)
//  Logger.log(conMail)
  try{
          // send reminder to consultants          
          MailApp.sendEmail(conMail, subject, conMsgP, { htmlBody:conMsgH, name:rmndrFrom });
        } catch (e) { // error handler
//          MailApp.sendEmail(myemail, "Error in sending reminder email.", e.message);
    }
}

function makeline_(row){
      var jobNumb = row[0]; // Job Number
      var conName = row[2]; // Consultant Name
      var conMail = row[3]; // Consultant Email
      var descr = row[1]; // description
      var FUS1=new Date(row[4]).toString().substr(25,6)+':00';// get timezone of this event, taking care of daylight savings
      var jobDate = Utilities.formatDate(row[4], FUS1, "MMM dd yyyy @ hh:mm aaa"); // Date
      var subject =  jobNumb+' + ';
      var conMsgH =  'Job #'+jobNumb + '</TD><TD>' + jobDate + '</TD><TD>' + descr + '</TD></TR><TR><TD>';
return [subject,conMsgH];
}

编辑:对邮件格式进行了一些改进,使用表格显示工作和&amp;日期+删除了一些错误;-) (老实说,我这也是为了个人使用,因为我有几乎相同的用例)