Search code examples
google-apps-scriptgmail-apigoogle-app-maker

Trigger on calculated date on Google AppMaker


I have function called alertnotice(to, message, body) that will be executed on a user onClick() event. The function will execute sendEmail(to, message, body) to send the email base on a calculated trigger as in variable triggerDay such as below:

function alertnotice(to, subject, body, dueDate, notifyBeforeDay) {//start of this class

  function sendEmail(to, subject, body){
    try {
      MailApp.sendEmail({
        to: to,
        subject: subject,
        htmlBody: body
      });
    } catch(e) {
      console.error(JSON.stringify(e));
    }
  }

  //check if there is an existing trigger for this process
  var existingTrigger = PropertiesService.getScriptProperties().getProperty("sendEmailTrigger");

  //set the renewal notice day
  var triggerDay = (dueDate - notifyBeforeDay) / (1000*60*60*24);

  //if the trigger already exists, inform user about it
  if(existingTrigger) {

    return "Alert notice had been sent"; 

  } else { // if the trigger does not exists, continue to set the trigger to send alert notice

    //runs the script every day at 1am on the time zone specified
    var newTrigger = ScriptApp.newTrigger('sendEmail')
    .timeBased()
    .atTime(triggerDay)
    .create();

    var triggerId = newTrigger.getUniqueId(); 

    if(triggerId) {
      PropertiesService.getScriptProperties().setProperty("autoExportTrigger", triggerId);
      return "Alert notice send successfully!";
    } else {
      return "Failed to send alert notice. Try again please"; 
    }
 }

}//end of this class

So for example, if the dueDate is 30/07/2018 and the notifyBeforeDay = 30, the function should send the email 30 days before the due date. I tried to achieve that but not so sure whether my algorithm will work. Can anyone give advice on this?


Solution

  • This implementation looks fragile to me. I would rather go with single trigger to avoid any possible duplicated emails and ensure at least one. Smth like this:

    // I am server script, trigger me on schedule (for instance nightly)
    function sendAlerts() {
      var query = app.models.Customers.newQuery();
    
      // query only for non-notified customers with upcoming due date
      query.filters.NorificationAttempts._lessThan = ATTEMPTS_THRESHOLD;
      query.filters.Notified._equals = false;
      query.filters.DueDate._lessThan = <dueDate>;
    
      var customers = query.run();
    
      customers.forEach(function(customer) {
        var success = sendNotification(customer);
    
        if (success) {
          customer.Notified = true;
        } else {
          customer.NorificationAttempts++;
        }
    
        // performance trade off in favor of consistency
        app.saveRecords([customer]);
      });
    }
    

    Trigger for such script can be installed by app's admin, you can find similar implementation in People Skills template.