e.source returns Spreadsheet instead of Form objec

2019-09-07 21:38发布

问题:

I create google form 'on the fly' using data in spreadsheet. Also I install trigger on submit form event.

ScriptApp.newTrigger('onSubmit')
     .forForm(form)
     .onFormSubmit()
     .create();

onSubmit function placed in the spreadsheet script because there is no way to point the function on the form's side (I make the copy of existent form with script code but it is no use as I can't make that functions run).
Well, I process the submission event on the spreadsheet side. No problem. But when I tried to get the source of 'e' object:

function onSubmit(e) {
  var response, items, i, item, hash, answer, id;
  var sheet, arr, source;
  sheet = SpreadsheetApp.openById(RESPONSE_SS_ID).getSheetByName(RESPONSE_SHEET);
  response = e.response;
  source = e.source;
  Logger.log(e);
...

I get not the Form object as promissed in manual, but Spreadsheet object

Logger.log([{response=FormResponse, source=Spreadsheet, triggerUid=4071774310898422364, authMode=FULL}

Perhaps, I'm doing something wrong? How to get the Form source properly in this case?

回答1:

Clearly the form is not behaving as its documentation says it does, which has been documented in Google Code Issue 4810

Luckily, there is at least one workaround, provided in the comments on that issue, which is to use the getEditResponseUrl method of the response to get to the form. Here is my implementation of the fix in the form of a function that fixes up the event object to add the missing source:

function fixBrokenEvent (event) { 
  if (! event.source ) {
    var responseEditUrl = event.response.getEditResponseUrl(); //gets     edit response url which includes the form url
    var responseUrl = responseEditUrl.toString().replace(/viewform.*/,''); //returns only the form url
    event.source = FormApp.openByUrl(responseUrl); //gets the submitted form id
  }
  return event
}

This workaround does the trick for me. Another solution would be to use the Trigger UID and search through the list of triggers from ScriptApp.getProjectTriggers() for the right trigger UID.

Something like...

function fixEventWithTriggers (event) {
   ScriptApp.getProjectTriggers().forEach(function (trigger) {
       if (trigger.getUniqueId()==event.triggerUid) {
         event.source = FormApp.openFormById(trigger.getSourceId())
         return event
       }
    }
}

This last workaround comes from Comment #5 on Issue 3786