微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Google Apps 脚本中为电子邮件抄送字段使用变量?

如何解决如何在 Google Apps 脚本中为电子邮件抄送字段使用变量?

我正在使用经过稍微调整的 this apps script 副本,使用包含各种数据的 Google 表格在 Gmail 中进行邮件合并。我在工作表中有一个列,供我也希望将电子邮件发送到的抄送收件人。但我不确定如何在 Apps 脚本中使用它。

enter image description here

我需要调整的代码如下,但是如何在表格中的抄送栏中添加抄送邮件

// copyright Martin Hawksey 2020
//
// Licensed under the Apache License,Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy
// of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,software
// distributed under the License is distributed on an "AS IS" BASIS,WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.  See the
// License for the specific language governing permissions and limitations under
// the License.
 
/**
 * @OnlyCurrentDoc
*/
 
/**
 * Change these to match the column names you are using for email 
 * recipient addresses and email sent column.
*/
const RECIPIENT_COL  = "Recipient";
const EMAIL_SENT_COL = "Email Sent";
 
/** 
 * Creates the menu item "Mail Merge" for user to run scripts on drop-down.
 */
function onopen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('Mail Merge')
      .addItem('Send Emails','sendEmails')
      .addToUi();
}
 
/**
 * Send emails from sheet data.
 * @param {string} subjectLine (optional) for the email draft message
 * @param {Sheet} sheet to read data from
*/
function sendEmails(subjectLine,sheet=SpreadsheetApp.getActiveSheet()) {
  // option to skip browser prompt if you want to use this code in other projects
  if (!subjectLine){
    subjectLine = browser.inputBox("Mail Merge","Type or copy/paste the subject line of the Gmail " +
                                      "draft message you would like to mail merge with:",browser.Buttons.OK_CANCEL);
                                      
    if (subjectLine === "cancel" || subjectLine == ""){ 
    // if no subject line finish up
    return;
    }
  }
  
  // get the draft Gmail message to use as a template
  const emailTemplate = getGmailTemplateFromDrafts_(subjectLine);
  
  // get the data from the passed sheet
  const datarange = sheet.getDatarange();
  // Fetch displayed values for each row in the Range HT Andrew Roberts 
  // https://mashe.hawksey.info/2020/04/a-bulk-email-mail-merge-with-gmail-and-google-sheets-solution-evolution-using-v8/#comment-187490
  // @see https://developers.google.com/apps-script/reference/spreadsheet/range#getdisplayvalues
  const data = datarange.getdisplayValues();

  // assuming row 1 contains our column headings
  const heads = data.shift(); 
  
  // get the index of column named 'Email Status' (Assume header names are unique)
  // @see http://ramblings.mcpher.com/Home/excelquirks/gooscript/arrayfunctions
  const emailSentColIdx = heads.indexOf(EMAIL_SENT_COL);
  
  // convert 2d array into object array
  // @see https://stackoverflow.com/a/22917499/1027723
  // for pretty version see https://mashe.hawksey.info/?p=17869/#comment-184945
  const obj = data.map(r => (heads.reduce((o,k,i) => (o[k] = r[i] || '',o),{})));

  // used to record sent emails
  const out = [];

  // loop through all the rows of data
  obj.forEach(function(row,rowIdx){
    // only send emails is email_sent cell is blank and not hidden by filter
    if (row[EMAIL_SENT_COL] == ''){
      try {
        const msgObj = fillInTemplateFromObject_(emailTemplate.message,row);

        // @see https://developers.google.com/apps-script/reference/gmail/gmail-app#sendEmail(String,String,Object)
        // if you need to send emails with unicode/emoji characters change GmailApp for MailApp
        // Uncomment advanced parameters as needed (see docs for limitations)
        GmailApp.sendEmail(row[RECIPIENT_COL],msgObj.subject,msgObj.text,{
          htmlBody: msgObj.html,// bcc: 'a.bbc@email.com',// cc: 'a.cc@email.com',from: 'myemail@email.co.uk',name: 'Custom From Name',// replyTo: 'a.reply@email.com',// noreply: true,// if the email should be sent from a generic no-reply email address (not available to gmail.com users)
          attachments: emailTemplate.attachments,inlineImages: emailTemplate.inlineImages
        });
        // modify cell to record email sent date
        out.push([new Date()]);
      } catch(e) {
        // modify cell to record error
        out.push([e.message]);
      }
    } else {
      out.push([row[EMAIL_SENT_COL]]);
    }
  });

function getccs() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('Sheet1');
  return sh.getRange(2,4,sh.getLastRow()-1,1).getValues().flat().join(',');
}
  
  // updating the sheet with new data
  sheet.getRange(2,emailSentColIdx+1,out.length).setValues(out);
  
  /**
   * Get a Gmail draft message by matching the subject line.
   * @param {string} subject_line to search for draft message
   * @return {object} containing the subject,plain and html message body and attachments
  */
  function getGmailTemplateFromDrafts_(subject_line){
    try {
      // get drafts
      const drafts = GmailApp.getDrafts();
      // filter the drafts that match subject line
      const draft = drafts.filter(subjectFilter_(subject_line))[0];
      // get the message object
      const msg = draft.getMessage();

      // Handling inline images and attachments so they can be included in the merge
      // Based on https://stackoverflow.com/a/65813881/1027723
      // Get all attachments and inline image attachments
      const allInlineImages = draft.getMessage().getAttachments({includeInlineImages: true,includeAttachments:false});
      const attachments = draft.getMessage().getAttachments({includeInlineImages: false});
      const htmlBody = msg.getBody(); 

      // Create an inline image object with the image name as key 
      // (can't rely on image index as array based on insert order)
      const img_obj = allInlineImages.reduce((obj,i) => (obj[i.getName()] = i,obj),{});

      //Regexp to search for all img string positions with cid
      const imgexp = RegExp('<img.*?src="cid:(.*?)".*?alt="(.*?)"[^\>]+>','g');
      const matches = [...htmlBody.matchAll(imgexp)];

      //Initiate the allInlineImages object
      const inlineImagesObj = {};
      // built an inlineImagesObj from inline image matches
      matches.forEach(match => inlineImagesObj[match[1]] = img_obj[match[2]]);

      return {message: {subject: subject_line,text: msg.getPlainBody(),html:htmlBody},attachments: attachments,inlineImages: inlineImagesObj };
    } catch(e) {
      throw new Error("Oops - can't find Gmail draft");
    }

    /**
     * Filter draft objects with the matching subject linemessage by matching the subject line.
     * @param {string} subject_line to search for draft message
     * @return {object} GmailDraft object
    */
    function subjectFilter_(subject_line){
      return function(element) {
        if (element.getMessage().getSubject() === subject_line) {
          return element;
        }
      }
    }
  }
  
  /**
   * Fill template string with data object
   * @see https://stackoverflow.com/a/378000/1027723
   * @param {string} template string containing {{}} markers which are replaced with data
   * @param {object} data object used to replace {{}} markers
   * @return {object} message replaced with data
  */
  function fillInTemplateFromObject_(template,data) {
    // we have two templates one for plain text and the html body
    // stringifing the object means we can do a global replace
    let template_string = JSON.stringify(template);

    // token replacement
    template_string = template_string.replace(/{{[^{}]+}}/g,key => {
      return escapeData_(data[key.replace(/[{}]+/g,"")] || "");
    });
    return  JSON.parse(template_string);
  }

  /**
   * Escape cell data to make JSON safe
   * @see https://stackoverflow.com/a/9204218/1027723
   * @param {string} str to escape JSON special characters from
   * @return {string} escaped string
  */
  function escapeData_(str) {
    return str
      .replace(/[\\]/g,'\\\\')
      .replace(/[\"]/g,'\\\"')
      .replace(/[\/]/g,'\\/')
      .replace(/[\b]/g,'\\b')
      .replace(/[\f]/g,'\\f')
      .replace(/[\n]/g,'\\n')
      .replace(/[\r]/g,'\\r')
      .replace(/[\t]/g,'\\t');
  };
}

感谢您的建议。

解决方法

获取抄送:

function getccs() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('sheetname');
  return sh.getRange(2,4,sh.getLastRow()-1,1).getValues().flat().join(',');
}

在这里试试:

GmailApp.sendEmail(row[RECIPIENT_COL],msgObj.subject,msgObj.text,{
          htmlBody: msgObj.html,// bcc: 'a.bbc@email.com',cc: getccs(),from: 'myemail@email.co.uk',name: 'Custom From Name',// replyTo: 'a.reply@email.com',// noReply: true,// if the email should be sent from a generic no-reply email address (not available to gmail.com users)
          attachments: emailTemplate.attachments,inlineImages: emailTemplate.inlineImages
        });

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。