11

I only work Monday through Wednesday. I would like to set it up so when clients email me on these days every week, they get a friendly reminder. How can I do this? It seem I would have to do it manually every week from the looks of it.

1

7 Answers 7

6

I adapted my answer to a similar question to your situation. This Apps Script will reply if the current day is one of Thursday (4), Friday (5), Saturday (6), or Sunday (0). The set of days can be adjusted as indicated below.

function autoReply() {
  var interval = 5;          //  if the script runs every 5 minutes; change otherwise
  var daysOff = [4,5,6,0];   // 1=Mo, 2=Tu, 3=We, 4=Th, 5=Fr, 6=Sa, 0=Su
  var message = "This is my day off.";
  var date = new Date();
  var day = date.getDay();
  if (daysOff.indexOf(day) > -1) {
    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(message);
    }
  }
}
5

I think you're correct; I only see a way to add a start date and an optional end date. You'll not be able to automate this with Gmail alone. You'd need some external tool, assuming someone has created such a thing. Someone with skill with Google Apps Script might be able to create something, though.

For what it's worth, Outlook doesn't let you do this sort of thing either.

At best, with Gmail, you could use the vacation auto-responder to send a message to anyone on any day. It's pretty smart in that it won't send the message multiple times if you receive several messages from one person.

1

I've write an updated version compare to user79865's, add label for replyed email instead of using time, will be more accurate.

function autoReply() {
  var scheduled_date = [
    '2016-12-19', '2016-12-20',
  ];
  var auto_reply = "I am out of office. Your email will not seen until Monday morning.";

  var now = new Date();
  var today = now.toISOString().slice(0, 10); // today format: '2017-01-01'

  var label = GmailApp.getUserLabelByName('auto-replyed') || GmailApp.createLabel('auto-replyed');

  // today is the scheduled date
  if (scheduled_date.indexOf(today) >= 0) { 
    // get all email inbox, unread, without label auto-replyed
    var threads = GmailApp.search('is:unread is:inbox -{label:auto-replyed}');
    for (var i = 0; i < threads.length; i++) {
      var thread = threads[i]
      // reply the email and add auto-replyed label
      thread.reply(auto_reply);
      thread.addLabel(label);
    }
  }
}
1

I have further updated the script provided by others. Features:

  1. No configuration in the actual Google Script
  2. Configure e-mail content in a separate html file from your Google Drive.
  3. Dynamically update when the script should be active through your Google Calendar.

This example needs to following setup:

  1. Create a label on gmail.com called autoresponded
  2. Create a file called autoreply.html on the root folder of your Google Drive containing the e-mail content you want to reply. You can use HTML here.
  3. Create a script on script.google.com with the contents posted below
  4. Add a trigger for every minute on the script you just created
  5. Allow all permissions asked
  6. Add 'all day' events with OOF (out of office) in the title for the days you want auto-reply to work. If you want to use another term, instead of OOF, you can edit it on line 5 of the script.
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]);
        
      }
      
    }
    
  }
  
}
1

I think user @j-d has a good answer, but the "right" way (at least for me) to do this is to use Gmail's autoresponder feature, rather than just sending messages via gmail directly. The script extends user J-D's answer and adds the use of the autoresponder object to properly turn on/off Gmail's autoresponder system based on presence/absence of an all-day Calendar event of a particular title..

function autoReply() {
  Logger.log('Script start');
  var strCalendarOOFKey = 'OOF'; // Title of calendar event to look for
  var strUserEmailToSetVacationOn = 'user email here you want to modify (maybe just your own)';
  // find calendar event
  var today = new Date();
  var msTodayStart = today.getTime();
  var msTodayEnd = today.getTime()+60000; // adding 1 min, but in effect it means start and end on the same day
  var unavailableToday = false;

  Logger.log('Looking for Calendar trigger "'+strCalendarOOFKey+'" for today '+today.toDateString());

  var events = CalendarApp.getDefaultCalendar().getEventsForDay(today, { search: strCalendarOOFKey });
  for (var i = 0; i < events.length; i++) {
    if(events[i].isAllDayEvent() && events[i].isOwnedByMe()) {
      Logger.log("Setting vacation response to true due to event titled '"+events[i].getTitle()+"'")
      unavailableToday = true;
      break; 
    }
  }
  
  Logger.log("Setting Vacation response to: "+unavailableToday.toString());
  
  var jsonVacationSettingsOn = {
    "enableAutoReply": true,
    "responseSubject": "I'm currently out of the office",
    "responseBodyPlainText": "If you need any help while I'm gone contact [email protected]",
    "responseBodyHtml": "If you need any help while I'm gone contact [email protected]",
    "restrictToContacts": true,
    "restrictToDomain": false,
    "startTime": msTodayStart,
    "endTime": msTodayEnd
  };

  var jsonVacationSettingsOff = {
    "enableAutoReply": false,
  };

  if(unavailableToday == true){
    Logger.log('Updating Vacation Responder to On');
    var vacationSettings = Gmail.Users.Settings.updateVacation(
      jsonVacationSettingsOn,
      strUserEmailToSetVacationOn
    );
  } else {
    Logger.log('Updating Vacation Responder to Off');
    var vacationSettings = Gmail.Users.Settings.updateVacation(
      jsonVacationSettingsOff,
      strUserEmailToSetVacationOn
    );

  };

  Logger.log('Finished updating vacation responder:'+today.toDateString());
  
}
2
  • 1
    This works brilliantly. I much prefer setting the built-in autoresponder than scripting emails. One thing I did notice is that the out of office events that you can have Google Calendar create for you on an automated schedule are failing the isAllDayEvent() check, so I had to remove that.
    – dmnc
    Commented May 2 at 10:55
  • @dmnc Thanks for the tip - maybe they removed that method from the object model? It was working fine when I wrote it.. But if you have a fully unique string that defines Out of Office events from all other events, it doesn't matter.. For anyone keeping score, the new line would be: if(events[i].isOwnedByMe()) { Commented Jun 17 at 22:57
0

I've combined the 2 scripts to get a version with linjunhalida's labels, but be able to choose a day rather than enter dates, like in user79865's script:

function autoReply() {
  var scheduled_date = [
    '2019-09-20', '2019-09-27',
  ];
  var auto_reply = "I am out of office today. I'll get back to you as soon as possible next week.";

  var now = new Date();
  var today = now.toISOString().slice(0, 10); // today format: '2017-01-01'

  var label = GmailApp.getUserLabelByName('auto-replyed') || GmailApp.createLabel('auto-replyed');

  // today is the scheduled date
  if (scheduled_date.indexOf(today) >= 0) { 
    // get all email inbox, unread, without label auto-replyed
    var threads = GmailApp.search('is:unread is:inbox -{label:auto-replyed}');
    for (var i = 0; i < threads.length; i++) {
      var thread = threads[i]
      // reply the email and add auto-replyed label
      thread.reply(auto_reply);
      thread.addLabel(label);
    }
  }
}
0

After using this a while, there are a few other gotchas and improvements you might want to look at:

function autoReply() {
  var interval = 5;        //  if the script runs every 5 minutes; change otherwise
  var daysOff = [1,5,6,0];   // 1=Mo, 2=Tu, 3=We, 4=Th, 5=Fr, 6=Sa, 0=Su
  var date = new Date();
  var day = date.getDay();
  var label = GmailApp.getUserLabelByName("autoresponded");
  if (daysOff.indexOf(day) > -1) {
    var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
    var threads = GmailApp.search('is:inbox !label:autoresponded after:' + timeFrom);
    for (var i = 0; i < threads.length; i++) {
      var message = threads[i].getMessages()[0];
      if (message.getFrom().indexOf("[email protected]") < 0 && message.getFrom().indexOf("no-repl") < 0 && message.getFrom().indexOf("bounce") < 0 && message.getFrom().indexOf("spam") < 0) {
        threads[i].reply("", {
          htmlBody: "<p>Thank you for your message. I am not in the office today. If you have urgent questions you can email [email protected]. If you have other urgent enquiries you can call the office on 1800 999 002.</p><p>Best regards,<br>Name</p>"
        });
        label.addToThread(threads[i]);
      }
    }
  }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.