Search code examples
emailgoogle-apps-scripttimegoogle-formseventtrigger

Google Forms Script sends emails to respondents 6 months later


I want a Google Form to send a mail to respondents, but not right after it. I want the mail to be send 6 months later. It's a mail that sends a second customer satisfaction survey, evaluating if my enterprise's services really helped in the long term.

My main problem is : I can't take the mail directly, so it won't even send a mail right after we submitted the form.

I took the Google Script tutorials, so the code to send a map is only here to test the code.

function sendMap(event) {
  var map = Maps.newStaticMap().addMarker("76 pth Ave, New York");
  var mail = e.values[1];
  MailApp.sendEmail(mail, 'Map', 'See below.', {attachments:[map]});
}

I have set the project's triggers correctly but everytime I submit the form, I get a fail notification :

ReferenceError: e is not defined (ligne 35, fichier "Code")

For the trigger based on time, I saw this code, but I'm not even sure how to insert it in mine :

function myFunction() {
 // Creates a trigger that runs 5 minutes later
ScriptApp.newTrigger("myFunction")
  .timeBased()
  .after(5 * 60 * 1000) // 5 minutes plus tard
  .create();
}

Thank you in advance for your help.


Solution

  • ReferenceError: e is not defined (ligne 35, fichier "Code")

    implies that you are trying to run the function manually, this is something you cannot do if your code contains an event object, see here for more information.

    You can give any name to the event parameter, but the name of the function parameter and inside the funciton has to be the same. So, if you define sendMap(event) - then it should also be var mail = event.values[1]; and not var mail = e.values[1];

    What you can do is the following:

    • Have a function that you bind to the installable onFormSubmit trigger
    • This function will be called automatically when new form data populates the spreadsheet to which your script is bound
    • Create a trigger within this function - and retrieve the unique Id of the trigger
    • Call from within the first function a second function that will create a time-driven trigger Use script properties to save the event object corresponding to each trigger event
    • When your funciton on trigger is called - retrive the script properties corresponding to the trigger event
    • Carry out the desired funcitonality (e.g. send email)
    • Delete old triggers given that the allowed amount of triggers is limited

    Sample

    function sendMap(event) {
      var mail = event.values[1];
      var triggerUid = event.triggerUid;
      var trigger = ScriptApp.newTrigger("myFunction")
      .timeBased()
    //change to .after(6 * 30 * 24 *60 * 60 * 1000) for approx 6 month or calculate the exact date
      .after(5 * 60 * 1000) // 5 minutes plus tard
      .create();  
      var id = trigger.getUniqueId();
      PropertiesService.getScriptProperties().setProperty(id, mail);
    }
    
    function myFunction(event) {
      var id = event.triggerUid;
      var mail = PropertiesService.getScriptProperties().getProperty(id);
       var map = Maps.newStaticMap().addMarker("76 pth Ave, New York");
      MailApp.sendEmail(mail, 'Map', 'See below.', {attachments:[map]});
      PropertiesService.getScriptProperties().deleteProperty(id);
      var triggers = ScriptApp.getProjectTriggers();
      for (var i = 0; i < triggers.length; i++) {
        if(triggers[i].getUniqueId() == id){
          ScriptApp.deleteTrigger(triggers[i]);
        }
      };
    }