Google apps script 是否可以在google应用程序脚本中的单个触发器(即“表单提交”上)上运行连续函数?

Google apps script 是否可以在google应用程序脚本中的单个触发器(即“表单提交”上)上运行连续函数?,google-apps-script,google-sheets,Google Apps Script,Google Sheets,我知道每个项目只能运行一个doGet()或doPost(),我正在尝试在自定义表单提交上做两件事。不可能使用谷歌表单,因为表单太复杂了 首先,我想将表单数据发送到GoogleSheets,并将其输入新行。 其次,我想向某人发送一封电子邮件,以读者友好的方式显示提交的数据 我曾尝试使用承诺链来实现这一点,但我在使用道具和访问参数方面遇到了问题。在这个问题上,我真的把头撞到了键盘上 作为旁注,我知道应用程序脚本不支持承诺,所以我使用了一个有人善意设置的polyfill 我想我只需要正确地传递属性/参

我知道每个项目只能运行一个doGet()或doPost(),我正在尝试在自定义表单提交上做两件事。不可能使用谷歌表单,因为表单太复杂了

首先,我想将表单数据发送到GoogleSheets,并将其输入新行。 其次,我想向某人发送一封电子邮件,以读者友好的方式显示提交的数据

我曾尝试使用承诺链来实现这一点,但我在使用道具和访问参数方面遇到了问题。在这个问题上,我真的把头撞到了键盘上

作为旁注,我知道应用程序脚本不支持承诺,所以我使用了一个有人善意设置的polyfill

我想我只需要正确地传递属性/参数?或者整个事情都错了

以下是我到目前为止的情况:


var SHEET_NAME = "Sheet1";

var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service

function doPost(e) {

(function () { 
  
 // this loads the es6-promises polyfill to make promise syntax available in Apps Script
 // copyright notice - https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE

 var Promise,
    setTimeout = setTimeout || function (func,ms) {
      Utilities.sleep(ms);
      func();
    };

  // get the polyfill and eval

  if (!Promise) {
    var result = UrlFetchApp.fetch('https://cdnjs.cloudflare.com/ajax/libs/es6-promise/3.2.1/es6- 
    promise.min.js');
    eval (result.getContentText());

    // add done for compatibility with other promise systems
    // Promise.prototype.done = Promise.prototype.done || Promise.prototype.then ;

  }
  
}());
  
var p1 = handleResponse(e);
var p2 = sendEmail(e);

Promise.all ([p1,p2,], 3000).then ( 
  function (results) {
     Logger.log("success");
  },
  function (errors) {
     Logger.log("Something went wrong: " + errors);
  }
);
  
}

function handleResponse(e) {
  
  return new Promise (function ( resolve, reject ) {

    var lock = LockService.getScriptLock();
    lock.tryLock(10 * 1000);
  
    try {
    // next set where to write the data
    var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet = doc.getSheetByName(SHEET_NAME);
    
    //var headRow = e.parameter.header_row || 1;
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row = [];
    // loop through the header columns
    for (var i in headers){
      if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
        row.push(new Date());
      } else { // else use header name to get data
        row.push(e.parameter[headers[i]]);
      }
    }
      
    resolve(sheet.getRange(nextRow, 1, 1, row.length).setValues([row]));

    // return json success results
    return ContentService
          .createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
          .setMimeType(ContentService.MimeType.JSON);
} catch(error){
  // if error return this
  reject(error);
  return ContentService
  .createTextOutput(JSON.stringify({"result":"error", "error": error}))
  .setMimeType(ContentService.MimeType.JSON);
} finally {
  return lock.releaseLock();
}
  })

}

function sendEmail(e) {
  
    return new Promise (function ( resolve, reject ) {
    
      var lock = LockService.getScriptLock();
      lock.tryLock(10 * 1000);
      
      try {
        // fetching the data
        var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
        var sheet = doc.getSheetByName(SHEET_NAME);
        
        //var headRow = e.parameter.header_row || 1;
        var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
        var nextRow = sheet.getLastRow()+1; // get next row
        var lastRow = sheet.getLastRow(); // get last row
        var formValues = sheet.getRange(36, 1, 1, sheet.getLastColumn()).getValues()[0];
        
        let emailValues = new Map();
        for (var i in formValues){
          if (formvalues[i] !== '') {
            emailValues.set(headers[i], formvalues[i]);
          }
        }
        Logger.log(emailValues);
        
        var htmlTemplate = HtmlService.createTemplateFromFile("message.html");
        htmlTemplate.row = emailValues;
        var message = htmlTemplate.evaluate().getContent();
        
        var email = "insert-email@here.com";
        var subject = "Test";
        var body = "";
        resolve(MailApp.sendEmail(email, subject, body, {
          htmlBody: message,
          name: "Send Mail Test"
        }));
        Logger.log("mikesteeletaylor@gmail.com");
        Logger.log(MailApp.getRemainingDailyQuota());
      } catch(error) {
        Logger.log("There is a problem sending the email: " + error);
        reject(error);
      } finally {
        return lock.releaseLock();
      }
    })
}

function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}
编辑:在@TheMaster的评论之后,这是我的更新代码:

var SHEET_NAME = "Sheet1";

var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service

function doPost(e) {
  
 handleResponse(e);
 sendEmail(e);
  
}

function handleResponse(e) {

    var lock = LockService.getScriptLock();
    lock.tryLock(10 * 1000);
  
    try {
    // next set where to write the data
    
    var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet = doc.getSheetByName(SHEET_NAME);
    
    var headRow = e.parameter.header_row || 1;
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row = [];
    // loop through the header columns
    for (var i in headers){
      if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
        row.push(new Date());
      } else { // else use header name to get data
        row.push(e.parameter[headers[i]]);
      }
    }
     
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);

    // return json success results
    return ContentService
          .createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
          .setMimeType(ContentService.MimeType.JSON);
} catch(error){
  // if error return this
  Logger.log(error);
  return ContentService
  .createTextOutput(JSON.stringify({"result":"error", "error": error}))
  .setMimeType(ContentService.MimeType.JSON);
} finally {
  return lock.releaseLock();
}

}

function sendEmail(e) {
    
      var lock = LockService.getScriptLock();
      lock.tryLock(10 * 1000);
      
      try {
        // fetch the data
        var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
        var sheet = doc.getSheetByName(SHEET_NAME);
        
        var headRow = e.parameter.header_row || 1;
        var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
        var nextRow = sheet.getLastRow()+1; // get next row
        var lastRow = sheet.getLastRow(); // get last row
        var formValues = sheet.getRange(36, 1, 1, sheet.getLastColumn()).getValues()[0];
        
        let emailValues = new Map();
        for (var i in formValues){
          if (formvalues[i] !== '') {
            emailValues.set(headers[i], formvalues[i]);
          }
        }
        Logger.log(emailValues);
        
        var htmlTemplate = HtmlService.createTemplateFromFile("message.html");
        htmlTemplate.row = emailValues;
        var message = htmlTemplate.evaluate().getContent();
        
        var email = "insert-email@here.com";
        var subject = "Test";
        var body = "";
        MailApp.sendEmail(email, subject, body, {
          htmlBody: message,
          name: "Send Mail Test"
        });
        Logger.log("mikesteeletaylor@gmail.com");
        Logger.log(MailApp.getRemainingDailyQuota());
      } catch(error) {
        Logger.log("There is a problem sending the email: " + error);
      } finally {
        return lock.releaseLock();
      }
}

function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}
是的,可以在一个触发器中运行“连续函数”

超级简单的例子:

/**
*要由触发器调用的函数
*
*@param{Object}事件对象
*/
函数myTrigger(事件){
myFirstFunction(event);//这可能是将表单数据发送到电子表格的函数,因为该事件保存表单数据
mySecondFunction(event);//这可能是发送电子邮件的函数
myThirdFunction();//这可能是另一个函数
}

只需连续调用两个函数即可。应用程序脚本urlfetch中没有异步。不需要promisesAlso应用程序脚本支持原生语法。简单地说,
e
未定义的
。查看以找出真正的错误(如果有)。此外,您需要创建一个新版本,并在代码发生更改后发布该版本“更新的代码”是否有效?@Rubén很抱歉响应太晚,是的,它确实有效,但不是立即有效,在我运行这两个函数之后,我没有收到表单提交中的值。除了再次运行安装脚本外,我尝试了一切(到处记录)。这就成功了。谢谢你的帮助。我觉得自己很愚蠢,但这是值得的。起初我确实尝试过,但什么也没发生,所以我认为函数的计时等方面存在问题。我的代码中一定有其他错误,我看不到。我只需要弄清楚为什么我现在会出现引用错误,我想这应该是可行的。