Search code examples
google-apps-scriptgoogle-apigmailgmail-api

I can't get Google Apps Script run for my Gmail


I followed the script posted in Any way to send Gmail auto-response at certain times every week?. However, my Gmail account didn't reply any message during out of work hours per my current test.

Did I do something wrong or incomplete?

What I have done:

  1. Created a script on https://script.google.com/ via copying and pasting.
  2. Saved the script and tested it. It worked fine. enter image description here
function myFunction() {
  function autoReply() {
var interval = 5;    //  if the script runs every 5 minutes; change otherwise
  var date = new Date();
  var day = date.getDay();
  var hour = date.getHours();
  if ([4,5,6,0].indexOf(day) > -1 || (day == 1 && hour < 9) || (day == 3 && hour >= 17)) {
    var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
    var threads = GmailApp.search('is:inbox after:' + timeFrom);
    for (var i = 0; i < threads.length; i++) {
      if (threads[i].isUnread()){
      threads[i].reply("xxxx");
      threads[i].markRead();
      threads[i].markImportant();
      }
    }
  }
}
}
  1. Enabled the Gmail API via the menu "Advanced Google Services" enter image description here
  2. Set up a trigger for the script as every 5 mintues. enter image description here
  3. Sent several test emails from another Gmail account to see if there would be any auto-reply.
  4. Didn't manually modify any received emails from another account.

Any hints will be very appreciated!

enter image description here enter image description here enter image description here

Update: I wonder why the following script itself will result in a "Script function not found: myFunction" error?

function autoReply() {
  
  // find calendar event
  var today = new Date();
  var events = CalendarApp.getDefaultCalendar().getEventsForDay(today, { search: 'OOF' });
  var unavailableToday = false;
  for (var i = 0; i < events.length; i++) {
    
    if(events[i].isAllDayEvent() && events[i].isOwnedByMe()) {
      
      unavailableToday = true;
      break;
      
    }
    
  }
  
  var myEmail = Session.getEffectiveUser().getEmail();
  
  Logger.log('unavailableToday');
  Logger.log(unavailableToday);
  if(unavailableToday === true) {
    
    // get html message
    var files = DriveApp.getRootFolder().getFilesByName('autoreply.html');
    var htmlbody;
    while (files.hasNext()) {
      var file = files.next();

      htmlbody = file.getBlob().getDataAsString('utf8');
      
    }
   
    // get emails
    var interval = 2;
    var date = new Date();
    var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
    var threads = GmailApp.search('is:inbox !label:autoresponded after:' + timeFrom);
    var label = GmailApp.getUserLabelByName("autoresponded");

    for (var i = 0; i < threads.length; i++) {
      
      var message = threads[i].getMessages()[0];
      if (message.getFrom().indexOf(myEmail) < 0 && message.getFrom().indexOf("no-repl") < 0 && message.getFrom().indexOf("bounce") < 0 && message.getFrom().indexOf("spam") < 0) {
        
        Logger.log("Replied now");
        
        // reply
        threads[i].reply("", {
          htmlBody: htmlbody
        });
        
        // label
        label.addToThread(threads[i]);
        
      }
      
    }
    
  }
  
}

Which made me think MyFunction{} is essential?


Solution

  • Answer:

    You need to remove the autoReply() function outside of myFunction() and set the trigger up on autoReply().

    More Information:

    The code should look like it does in the answer you linked:

    function autoReply() {
      var interval = 5;    //  if the script runs every 5 minutes; change otherwise
      var date = new Date();
      var day = date.getDay();
      var hour = date.getHours();
      if ([5,6,0].indexOf(day) > -1 || (day == 1 && hour < 8) || (day == 4 && hour >= 17)) {
        var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
        var threads = GmailApp.search('is:inbox after:' + timeFrom);
        for (var i = 0; i < threads.length; i++) {
          threads[i].reply("I am out of office. Your email will not seen until Monday morning.");
        }
      }
    }
    

    NOT like this:

    function myFunction() {
      function autoReply() {
        var interval = 5;    //  if the script runs every 5 minutes; change otherwise
        var date = new Date();
        var day = date.getDay();
        var hour = date.getHours();
        if ([5,6,0].indexOf(day) > -1 || (day == 1 && hour < 8) || (day == 4 && hour >= 17)) {
          var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
          var threads = GmailApp.search('is:inbox after:' + timeFrom);
          for (var i = 0; i < threads.length; i++) {
            threads[i].reply("I am out of office. Your email will not seen until Monday morning.");
          }
        }
      }
    }
    

    autoReply() isn't being called when you call myFunction(), only declared.

    You will need to edit the code and then re-set up your trigger to run on autoReply().

    From w3schools:

    Declared functions are not executed immediately. They are "saved for later use", and will be executed later, when they are invoked (called upon).

    References: