3

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

我怎么做?

4

2 回答 2

16

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

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

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

电子邮件

收件人在其电子邮件客户端中填写表格(如果它支持该功能)。响应将收集在电子表格中,如下所示:

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

电子表格

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

现在,代码。(这也可作为要点。)

电子邮件模板.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>

代码.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 行中添加“时间戳”、“序列号”、“通勤者?”和“车辆”的标题。
  2. 工具 - 脚本编辑器。复制Code.gs内容。复制电子表格的 ID,并更新_spreadsheetId文件顶部的变量。节省。
  3. 文件 - 新建 HTML 文件,将文件命名为 emailTemplate。复制emailTemplate.html内容。节省。
  4. 发布 - 部署为 Web 应用程序... 让任何人都可以访问它,包括匿名的。(在 Google Apps 域中,您可以将其限制为域中的用户。)
  5. onOpen通过重新加载电子表格或在编辑器中运行函数来授权脚本。

准备好出发!您会在电子表格中找到一个“自定义菜单”,其中包含“发送调查”命令。

于 2013-09-07T03:56:15.360 回答
4

在开发 ui 和管理响应方面,只需少量工作即可做到这一点的一种简单方法是使用 Google Apps 基础架构创建一个,通过电子邮件将表单发送给自己,然后单击 show original。

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

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

如果您需要更多信息,请告诉我。

于 2013-09-07T04:06:51.450 回答