Google Scripts для черновика ответов на электронные письма с ключевым словом в теме и вводом данных из Google Sheets - PullRequest
0 голосов
/ 24 февраля 2020

Я новичок в Google Apps Script, поэтому я ищу несколько советов. Есть много частей, и мне удалось сделать некоторые из них, но я застрял на других. Любая помощь будет принята с благодарностью.

Я пытаюсь создать скрипт, который:

  1. готовит ответ на электронные письма, содержащие определенные c ключевые слова (найденные в теле или сюжетная линия).
  2. Я также хочу, чтобы он включал шаблон с данными, введенными из файла Google Sheets.
  3. Было бы предпочтительно, чтобы черновик можно было обновлять без дублирования при каждом изменении листа.
  4. Я планирую также включить строку значений (первое), которые соответствуют столбцам Subject во втором ряду, но я еще не дошел до этого.

Screenshot of a test Sheet

Некоторые сведения о Google Sheet:

  • Каждая строка соответствует отдельному человеку и адресу электронной почты, которые регулярно мне пишут.
  • Первые три столбца - это сведения о человеке, которого я включаю в текст своего черновика.
  • Каждый столбец после этого представляет отдельную строку или ключевое слово, которое я ожидаю найти в теме сообщения. письма отправлены мне.
  • Строки внизу содержат два кодовых слова с шаблонами, разделенных пробелом в одной ячейке, из которых я хочу выбрать. Например:

    • 3 буквы, которые могут содержать перестановки букв m, g, r (например, mmg, rgm, rgg, gmg)

    • и 0-3 букв только с p (например, p, pp, ppp или пробел)

Я хочу, чтобы можно было обнаружить другие коды и назначить его для переменной, которую я могу ввести в свой черновик.


Что у меня есть:

  • Я могу составлять ответы для письма в моем указанном фильтре. Однако он настроен только для ответа на самое последнее сообщение этого человека. Я хочу иметь возможность сортировки через фильтр для определенных c электронных писем, которые содержат ключевое слово в строке темы, когда оно проходит по столбцам.

  • Я могу ввести данные c строк из листа в тело моего письма, но у меня все еще проблемы с шаблонными кодовыми словами.

  • Мне удалось l oop через более чем одну строку в более ранней версии, но теперь это не так. Я еще раз посмотрю его позже.

Вот мой код:

function draftEmail() {
  var sheet = SpreadsheetApp.getActiveSheet();    // Use data from the active sheet
  var startRow = 1;                            // First row of data to process
  var numRows = sheet.getLastRow() - 1;        // Number of rows to process
  var lastColumn = sheet.getLastColumn();      // Last column
  var dataRange = sheet.getRange(startRow, 1, numRows, lastColumn) // Fetch the data range of the active sheet
  var data = dataRange.getValues();            // Fetch values for each row in the range

  // Work through each row in the spreadsheet
  for (var i = 2; i < data.length; ++i) {
    var row = data[i];  
    // Assign each row a variable
    var grader = row[0];                    // Col A: Grader's name
    var firstName = row[1];                 // Col B: Student's first name
    var studentEmail = row[2];              // Col C: Student's email
    var grade = row[3].split(' ');           // Col D: Grade
    var pgrade = grade[1];
    var hgrade = grade[0];
      for (var n = 1; n < data.length; ++n) {
      var srow = data[n];  
      var subjectCol = srow[3];

    var threads = GmailApp.getUserLabelByName('testLabel').getThreads();

    for (i=0; i < threads.length; i++)
    {
          var thread = threads[i]; 
          var messages = thread.getMessages(); // get all messages in thread i
          var lastmsg  = messages.length - 1;  // get last message in thread i

          var emailTo    = WebSafe(messages[lastmsg].getTo());    // get only email id from To field of last message
          var emailFrom  = WebSafe(messages[lastmsg].getFrom());  // get only email id from FROM field of last message
          var emailCC    = WebSafe(messages[lastmsg].getCc());    // get only email id from CC field of last message


    // form a new CC header for draft email
        if (emailTo == "")
        {
           var emailCcHdr = emailCC.toString();
        } else
        {
          if (emailCC == "")
          {
            var emailCcHdr = emailTo.toString();
          } else
          {
            var emailCcHdr = emailTo.toString() + "," + emailCC.toString();
          }
        }

        var subject  = messages[lastmsg].getSubject().replace(/([\[\(] *)?(RE|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/igm,"");
        // the above line remove REs and FWDs etc from subject line

        var emailmsg = messages[lastmsg].getBody(); // get html content of last message

        var emaildate   = messages[lastmsg].getDate(); // get DATE field of last message

        var attachments = messages[lastmsg].getAttachments(); // get all attachments of last message

        var edate = Utilities.formatDate(emaildate, "IST", "EEE, MMM d, yyyy"); // get date component from emaildate
        var etime = Utilities.formatDate(emaildate, "IST", "h:mm a"); // get time component from emaildate

    if (emailFrom.length == 0)
        {
          // if emailFrom is empty, it probably means that you may have written the last message in the thread. Hence 'you'.
          var emailheader = '<html><body>' + 
                            'On' + '&nbsp;' +
                             edate + '&nbsp;' + 
                            'at' + '&nbsp;' + 
                             etime +  ',' + '&nbsp;' + 'you' + '&nbsp;' + 'wrote:' + '</body></html>';
        } else 
        {
          var emailheader = '<html><body>' + 
                            'On' + '&nbsp;' +
                             edate + '&nbsp;' + 
                            'at' + '&nbsp;' + 
                             etime +  ',' + '&nbsp;' + emailFrom + '&nbsp;' + 'wrote:' + '</body></html>';
        }
          var emailsig = '<html>' + 
                         '<div>your email signature,</div>' +
                         '</html>'; // your email signature i.e. common for all emails.

                  // Build the email message
          var emailBody =  '<p>Hi ' + firstName + ',<p>';
              emailBody += '<p>For ' + subjectCol + ', you will be graded on #1, 2, and 3: <p>';
              emailBody += '<p>Participation: ' + pgrade + '</p>';
              emailBody += '<p>HW grade: ' + hgrade + '</p>';
              emailBody += '<p>If you have any questions, you can email me at ' + grader + '@email.com.<p>';
              emailBody += '<p>- ' + grader;


          var draftmsg = emailBody + '<br>' + emailsig + '<br>' + emailheader + '<br>' + emailmsg + '\n'; // message content of draft

      // Create the email draft
      messages[lastmsg].createDraftReply(
        " ", // Body (plain text)
        {
        htmlBody: emailBody    // Options: Body (HTML)
        }
      );

    }

}
}

function WebSafe(fullstring)
{
  var splitString = fullstring.split(",");
  var finalarray = [];
  for (u=0; u < splitString.length; u++)
  {
    var start_pos = splitString[u].indexOf("<") + 1;
    var end_pos   = splitString[u].indexOf(">",start_pos);
    if (!(splitString[u].indexOf("<") === -1 && splitString[u].indexOf(">",start_pos) === -1)) // if < and > do exist in string
    {
      finalarray.push(splitString[u].substring(start_pos, end_pos));
    } else if (!(splitString[u].indexOf("@") === -1))
    {
      finalarray.push(splitString[u]);
    }
  }
  var index = finalarray.indexOf(grader + "@email.com"); // use your email id. if the array contains your email id, it is removed.
  if (index > -1) {finalarray.splice(index, 1);}
  return finalarray
}
}

Я никогда раньше не кодировал JavaScript и не использовал Google Scripts, поэтому я в основном смотрел на похожие примеры.

Спасибо за любые отзывы.

1 Ответ

0 голосов
/ 25 февраля 2020

Я предпочитаю читать код, который не слишком вложен. Поэтому я позволил себе переписать ваш код и упростить его чтение.

Ваша основная функция:

function mainFunction(){

  // Use data from the active sheet
  var sheet = SpreadsheetApp.getActiveSheet(); 
  var data = sheet.getDataRange().getValues();
  var threads = GmailApp.getUserLabelByName('<YOUR-LABEL-HERE>').getThreads();
  var subject1 = data[1][3];

  // Work through each row in the spreadsheet omit headers
  for (var i = 2; i < data.length; ++i) {

    // Get grader's data
    var grader = getGrader(data[i]);
    console.log(grader);

    // Loop through threads
    for (j=0; j < threads.length; j++){
      var thread = threads[j];
      // Get last message in thread
      var messages = thread.getMessages(); 
      var lastMsg = messages[messages.length - 1];
      var email = new Email(grader, lastMsg, subject1);
      // Create the draft reply.
      var draftMessageBody = createDraftMessage(email);
      lastMsg.createDraftReply(draftMessageBody);
    }
  }
}

Функции поддержки:

  1. Функция getGrader:
function getGrader(array){ 
  var row = array
  var grader = {}
  grader.grader = row[0];                    
  grader.firstName = row[1];                 
  grader.studentEmail = row[2];              
  var grade = row[3].split(' ');          
  grader.pgrade = grade[1];
  grader.hgrade = grade[0];
  return grader
}
Функция webSafe:
function webSafe(fullstring, grader){
  var splitString = fullstring.split(",");
  var finalarray = [];
  for (u=0; u < splitString.length; u++){
    var start_pos = splitString[u].indexOf("<") + 1;
    var end_pos   = splitString[u].indexOf(">",start_pos);
    // if < and > do exist in string
    if (!(splitString[u].indexOf("<") === -1 && splitString[u].indexOf(">",start_pos) === -1)){
      finalarray.push(splitString[u].substring(start_pos, end_pos));
    } else if (!(splitString[u].indexOf("@") === -1)){
      finalarray.push(splitString[u]);
    }
  }
  // use your email id. if the array contains your email id, it is removed.
  var index = finalarray.indexOf(grader.grader + "@mangoroot.com"); 
  if (index > -1) {
    finalarray.splice(index, 1);
  }
  return finalarray
}
Функция Email: Ведет себя как класс
var Email = function(grader, lastMsg, subject){
  this.signature = "your_email_signature,";
  this.grader = grader;
  this.to = webSafe(lastMsg.getTo(), this.grader);
  this.from = webSafe(lastMsg.getFrom(), this.grader);
  this.cc = webSafe(lastMsg.getCc(), this.grader);
  this.subject = lastMsg.getSubject().replace(/([\[\(] *)?(RE|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/igm,"");
  this.message = lastMsg.getBody();
  this.date = lastMsg.getDate();
  this.attachments = lastMsg.getAttachments();
  this.subject1 = subject;

  this.ccHeader = function() {
    var ccHeader = "";
    if (this.to == "" || this.cc == ""){
      ccHeader = this.cc.toString();
    }
    else {
      ccHeader = this.to.toString() + "," + this.cc.toString();
    }
    return ccHeader
  }

  this.eDate = function() {
    return Utilities.formatDate(this.date, "IST", "EEE, MMM d, yyyy");
  }

  this.eTime = function() {
    return Utilities.formatDate(this.date, "IST", "h:mm a");
  }

  this.header = function() {
    var header = ''.concat('On ');
    if (this.from.length == 0){
      header += this.eDate().concat(' at ',this.eTime(),', you wrote: ');
    }
    else {
      header += this.eDate().concat(' at ',this.eTime(),', ',this.from,' wrote: ');
    }
    return header
  }

  this.body = function(){
    var grader = this.grader;
    var body =  '<div>'.concat('<p>Hi ',grader.firstName,',</p>');
    body += '<p>For '.concat(this.subject1,', you will be graded on #1, 2, and 3: </p>');
    body += '<p>Participation: '.concat(grader.pgrade,'</p>');
    body += '<p>HW grade: '.concat(grader.hgrade,'</p>');
    body += '<p>If you have any questions, you can email me at '.concat(grader.grader,'@mangoroot.com.</p>');
    body += '<p>- '.concat(grader.grader,'</p>','</div>');
    return body;
  }
}
Функция createDraftMessage:
function createDraftMessage(email){
  var draft = '<html><body>'.concat(email.body);
  draft += '<br>'.concat(email.signature);
  draft += '<br>'.concat(email.header);
  draft += '<br>'.concat(email.message);
  draft += '<br>'.concat('</body></html>');
  return draft;
}

Теперь, когда вы запустите mainFunction(), вы должны получить ожидаемые шашки.


Примечания:

  • Хорошей практикой является сохранение функций плоскими, плоские лучше, чем вложенные. Делает код более читабельным и понятным.
  • Также будьте последовательны в своем стиле именования переменных.
var emailMsg = ''; // Good. 
var emailmsg = ''; // Hard to read. 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...