通过电子邮件发送表单并跟踪电子表格中的回复

时间:2013-09-07 01:42:47

标签: html email google-apps-script google-sheets google-form

我正在使用Google Apps脚本发送电子邮件 - 我知道该怎么做。我想嵌入“是或否”回复链接或多项选择问题,并将收件人的回复记录在Google电子表格中。

我该怎么做?

2 个答案:

答案 0 :(得分:15)

此工作流程涉及的组件包括:

  • 用于生成和发送带有HTML表单的电子邮件的脚本。
  • 该电子邮件的HTML模板,允许我们为每个收件人自定义电子邮件。
  • 处理响应的doPost()函数。该脚本必须为deployed as a Web App
  • 用于收集回复的电子表格。该脚本将包含在电子表格中,并使用菜单扩展电子表格UI,以发送调查副本。 (它可以适用于独立使用,没有UI组件。)

以下是进行通勤调查的此类工作流程示例。收件人将收到如下调查电子邮件:

Email

如果表单支持该功能,则收件人会在其电子邮件客户端中填写表单。回复将收集在电子表格中,如下所示:

在运行脚本之前自己创建电子表格标题。

Spreadsheet

添加了“序列号”列,以说明将响应与特定受访者相关联的方法;请注意,有些条目重复。生成调查电子邮件时,会为其提供唯一的序列号,然后将其作为隐藏值与响应一起传回。例如,我们可以扩展此系统以识别受访者的更新。

现在,代码。 (这也是available as a gist。)

emailTemplate.html

<div>
  <form action="<?= scriptUrl ?>" method="Post">
  <table>
  <tr>
  <td>
    <label for="commute">Do you commute to work?</label>
    </td>
    <td>
    <select name="commute">
      <option>Yes</option>
      <option>No</option>
    </select>
    </td>
  </tr>
  <tr>
    <td>
    <label for="vehicle">If "Yes", how do you get to work?</label>
    </td>
    <td>
      <input type="checkbox" name="vehicle" value="Bike">I have a bike<br>
      <input type="checkbox" name="vehicle" value="Car">I have a car
    </td>
  </tr>
  <tr>
    <td>
    <!-- A Hidden field is a handy way to pass information to the
         Server-side POST handler. For example, a serial number could
         be used to collate responses from a particular recipient. -->
    <input type="hidden" name="serial" value="<?= serialNumber ?>" />
    </td>
    <td>
    <input type="submit" value="Submit" />
    </td>
  </tr>
  </table>
  </form>
</div>

Code.gs

// doPost needs the spreadsheet ID, it has no concept of "active spreadsheet".
var _spreadsheetId = '--- Spreadsheet ID ---';

// Add custom menu with option to send survey
function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Send Survey",
    functionName : "sendSurvey"
  }];
  sheet.addMenu("Custom Menu", entries);
};

/**
 * Build & Send Survey, an HTML form in email.
 */
function sendSurvey() {
  var recipient = Browser.inputBox("Send Survey", "Enter Recipient Email", Browser.Buttons.OK_CANCEL);
  if (recipient === 'cancel') return;

  var subject = 'Commuting Survey';

  // Get the URL of the published Web App, to include in email for POST of response
  var scriptUrl = ScriptApp.getService().getUrl();
  if (!scriptUrl) throw new Error( 'You must Deploy as Web App first.' ); 

  // Build email body
  var template = HtmlService.createTemplateFromFile('emailTemplate');
  template.scriptUrl = scriptUrl;
  template.serialNumber = getGUID();  // Generate serial number for this response
  var html = template.evaluate().getContent();

  // During debugging, send emails to self. Remove this line for real operation.
  recipient = Session.getActiveUser().getEmail();  

  // Send email form
  GmailApp.sendEmail(recipient, subject, 'Requires HTML', {htmlBody:html} );

  Browser.msgBox("Survey Sent");
}

/**
 * POST handler for responses; 
 */
function doPost(e) {
  Logger.log(e);
  var ss = SpreadsheetApp.openById(_spreadsheetId);
  var sheet = ss.getSheets()[0];  // Assume first sheet collects responses

  // Build a row of data with timestamp + posted response
  var row = [
    new Date(),                     // Timestamp
    e.parameters.serial[0],         // Serial Number
    e.parameters.commute[0],        // Commuter? Yes / No
    e.parameters.vehicle.join(',')  // Vehicle
  ];

  // Make sure we are the only people adding rows to the spreadsheet
  var lock = LockService.getPublicLock();
  // Wait for up to 30 seconds for other processes to finish.
  var locked = lock.tryLock(30000);

  if (locked) {
    // Save response to spreadsheet
    var rowNum = sheet.getLastRow()+1;
    sheet.getRange(rowNum, 1, 1, row.length).setValues([row]);

    // Release the lock so that other processes can continue.
    lock.releaseLock();
    var result = "Response Recorded: \n  "+row.join('\n  ');
  }
  else {
    // Failed to get lock
    result = "System busy, please try again.";
  }

  // Report result of POST, in plain text
  return ContentService.createTextOutput(result)
                       .setMimeType(ContentService.MimeType.TEXT);
}


/**
 * Returns an rfc4122 version 4 compliant GUID / UUID string
 * Thanks to @broofa!
 * http://stackoverflow.com/a/2117523/1677912
 */
function getGUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
    return v.toString(16);
  });
}

部署

按原样使用此调查系统:

  1. 在云端硬盘帐户中新建一个电子表格。在第1行添加“Timestamp”,“Serial Number”,“Commuter?”和“Vehicle”的标题。
  2. 工具 - 脚本编辑器。复制Code.gs内容。复制电子表格的ID,然后更新文件顶部的_spreadsheetId变量。保存。
  3. 文件 - 新的HTML文件,将文件命名为emailTemplate。复制emailTemplate.html内容。保存。
  4. 发布 - 部署为Web应用程序...任何人都可以访问它,包括匿名用户。 (在Google Apps域中,您可以将其限制为域中的用户。)
  5. 通过重新加载电子表格或在编辑器中运行onOpen功能来授权脚本。
  6. 准备好了!您可以在电子表格中找到“自定义菜单”,其中包含“发送调查”命令。

答案 1 :(得分:4)

在开发ui和管理响应方面做一些工作的简单方法是创建一个使用Google Apps基础架构,通过电子邮件发送自己的表单并点击show original。

然后您可以使用嵌入式代码并使用您的脚本发送邮件,响应将自动记录在与表单关联的电子表格中。

然后,您可以覆盖onFormSubmit事件并执行所需的处理。

如果您需要更多信息,请与我们联系。