【问题标题】:Mail merge Pre-filled Google form link邮件合并预先填写的 Google 表单链接
【发布时间】:2021-09-08 01:46:56
【问题描述】:

我使用 Google 表格和应用程序脚本来创建邮件合并,它适用于姓名、电子邮件和一般文本信息。

我正在添加一个带有预先填写的 Google 表单链接的列,例如 this.

Gmail 邮件合并模板

虽然邮件合并工作正常,但链接不起作用。电子邮件收件人无法点击预填信息的 Google 表单链接。

收件人的邮件合并结果

我希望看到的是电子邮件正文中的 Google 表单超链接,电子邮件收件人可以单击它并被定向到带有预填信息的 Google 表单。

有没有办法也包含预先填写的信息?

Example of the Google sheet used for mail merge.

邮件合并应用脚本 [来自 Google 应用脚本模板]

const RECIPIENT_COL  = "Email";
const EMAIL_SENT_COL = "Email Sent";
 
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('Mail Merge')
      .addItem('Send Emails', 'sendEmails')
      .addToUi();
}
 
function sendEmails(subjectLine, sheet=SpreadsheetApp.getActiveSheet()) {
   if (!subjectLine){
    subjectLine = Browser.inputBox("Mail Merge", 
                                      "Type or copy/paste the subject line of the Gmail " +
                                      "  ",
                                      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();
  const data = dataRange.getDisplayValues();

  // assuming row 1 contains our column headings
  const heads = data.shift(); 
  
  const emailSentColIdx = heads.indexOf(EMAIL_SENT_COL);
  
  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);

        GmailApp.sendEmail(row[RECIPIENT_COL], msgObj.subject, msgObj.text, {
          htmlBody: msgObj.html,
          //bcc: 'fusip@gmail.com',
          //cc: 'fusip@gmail.com',
          //from: 'fusip@gmail.com',
          // name: 'fusip@gmail.com',
          // 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
        });
        // 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]]);
    }
  });
  
  // updating the sheet with new data
  sheet.getRange(2, emailSentColIdx+1, out.length).setValues(out);
  
  function getGmailTemplateFromDrafts_(subject_line){
    try {
      const drafts = GmailApp.getDrafts();
      const draft = drafts.filter(subjectFilter_(subject_line))[0];
      const msg = draft.getMessage();
      const attachments = msg.getAttachments();
      return {message: {subject: subject_line, text: msg.getPlainBody(), html:msg.getBody()}, 
              attachments: attachments};
    } catch(e) {
      throw new Error("Oops - can't find Gmail draft");
    }

    function subjectFilter_(subject_line){
      return function(element) {
        if (element.getMessage().getSubject() === subject_line) {
          return element;
        }
      }
    }
  }
  
  function fillInTemplateFromObject_(template, data) {
    let template_string = JSON.stringify(template);

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

我想在电子邮件正文中添加 Google 表单链接。

【问题讨论】:

  • 你能提供你正在处理的脚本吗?如果我们不知道我们正在做什么,就很难提供解决方案。还包括您当前的输出和您想要的预期输出。
  • @NaziA 我包含了脚本的详细信息和预期结果。请参阅已编辑的问题。谢谢!
  • 感谢您的帮助。

标签: google-apps-script


【解决方案1】:

问题:

  • 您正在使用实际文本填充模板,因此当通过电子邮件发送时,它仍然具有工作表中的确切值。

解决办法:

  • 您需要使用内置函数encodeURI 正确转换您的链接。我修改了您的函数 fillInTemplateFromObject_ 并在其中添加了一行以使用 encodeURI,因为这将是解决问题的最简单方法。

代码:

function fillInTemplateFromObject_(template, data) {
  let template_string = JSON.stringify(template);
  // convert your link into proper link using encodeURI
  data['Google Form Link'] = encodeURI(data['Google Form Link']);
  
  // token replacement
  template_string = template_string.replace(/{{[^{}]+}}/g, key => {
    return data[key.replace(/[{}]+/g, "")] || "";
  });

  return  JSON.parse(template_string);
}

输出:

【讨论】:

  • 嗨@jazzy,如果我们回答了您的问题,请点击左侧的接受按钮(复选图标)。通过这样做,社区中可能与您有同样担忧的其他人将知道他们的问题可以得到解决。如果您无法使用接受按钮,请随时告诉我。 how to accept answer
猜你喜欢
  • 1970-01-01
  • 2014-12-11
  • 2011-06-24
  • 2016-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多