22

I've been reading through gmail addons. They have contextual triggers that trigger when you open an email.

Is it possible to trigger a service when an email is received by me? Best I can find is unconditional but that only triggers when the email is opened.

Rubén
  • 34,714
  • 9
  • 70
  • 166
Jeff
  • 4,285
  • 15
  • 63
  • 115
  • 1
    Does this answer your question? [How to trigger a Google Apps Script once an email get in the inbox?](https://stackoverflow.com/questions/36108478/how-to-trigger-a-google-apps-script-once-an-email-get-in-the-inbox) – Joe Feb 15 '21 at 09:14

4 Answers4

24

You can't create a trigger for every email, however you can do something similar as described in this answer.

For example you can:

  1. Set up a filter that puts a special label on incoming emails that you want to process.

  2. Set up a reoccurring script that runs every 10 minutes, or even every minute. In the script, you can pull all of the emails that have the given label, and process them accordingly, removing the label when you are done.

function processEmails() {
  var label = GmailApp.getUserLabelByName("Need To Process");
  var threads = label.getThreads();  
  for (var i = threads.length - 1; i >= 0; i--) {
    //Process them in the order received
    threads[i].removeLabel(label).refresh();
  }
}

You can then set this on a time based trigger to have it run as often as you would like.

If you want to keep track of the emails you have processed, you can create another "processed" label and add that to the message when you are done processing.

ryan.d.williams
  • 620
  • 5
  • 14
  • So, either I do a time based trigger of one minute or... is there another option? Is there a gmail api that I can just write my own application for it (although this is starting to sound like a mail client). I'm thinking of the app "Unroll.me" and wondering what they do. – Jeff Apr 26 '18 at 11:13
  • Yes there is a [Gmail API](https://developers.google.com/gmail/api/) that you can use. However, there doesn't seem to be any subscriptions or callbacks available, so you will still have to set up some kind of reoccurring script or cron job to hit the API and find out if you have a new message every so often. – ryan.d.williams Apr 26 '18 at 11:42
  • @user3312395 It seems we can't use a time-based trigger in Gmail Addons. I use them in my own Google Apps Script (for myself), but is there a way to distribute to customers a Google Apps Script that uses a time-based trigger? – Basj May 28 '18 at 19:10
  • 1
    @Basj you can make it run very minute, and in that script d oa for loop that delays for 250 milliseconds, so really you're running rvery 250 ms – B''H Bi'ezras -- Boruch Hashem Jan 28 '20 at 21:29
4

I had a little trouble with getting the labels right so I'm including code to log your labels. I modified user3312395's code also to add new label also. Thanks for the original answer too!

function emailTrigger() {

  var label = GmailApp.getUserLabelByName('Name of Label to Process');
  var newLabel = GmailApp.getUserLabelByName('New Label Name');

  if(label != null){
    var threads = label.getThreads();
    for (var i=0; i<threads.length; i++) {
      //Process them in the order received
      threads[i].removeLabel(label);
      threads[i].addLabel(newLabel);
      //run whatever else here
    }
  }

}

function getLabels(){
  var labels = GmailApp.getUserLabels();
  for(i=0; i<labels.length; i++){
    Logger.log(labels[i].getName());
  }
}
  • I'm seeing the following error: ```Exception: Invalid argument: label emailTrigger @ Code.gs:11``` When clicked it takes the cursor to the 'a' in 'addLabel'. Is that expected, or a change in the code over 2 years? – Eliot Cole Jun 15 '21 at 20:21
  • Ahhhhhhh ... there was an errant space in the second label name variable. SORRY! – Eliot Cole Jun 15 '21 at 20:37
2

Yes, you can trigger a function for every new email!

Just use the search query newer_than:1h. Have your trigger run every 10 minutes for example. Then you will essentially be running logic for every new email (with up to 10 minutes delay, which is probably fine).

var TRIGGER_NAME = 'handleNewEmails'

// Maximum number of threads to process per run.
var PAGE_SIZE = 150

var INTERVAL = 10

function Install() {
    // First run 2 mins after install
    ScriptApp.newTrigger(TRIGGER_NAME)
        .timeBased()
        .at(new Date(new Date().getTime() + 1000 * 60 * 2))
        .create()

    // Run every 10 minutes there after
    ScriptApp.newTrigger(TRIGGER_NAME)
        .timeBased().everyMinutes(INTERVAL).create()
}

function Uninstall() {
    var triggers = ScriptApp.getProjectTriggers()
    for (var i = 0; i < triggers.length; i++) {
        if (triggers[i].getHandlerFunction() === TRIGGER_NAME) ScriptApp.deleteTrigger(triggers[i])
    }
}

function handleNewEmails() {
    var threads = GmailApp.search("newer_than:1h", 0, PAGE_SIZE)
    for (var i = 0; i < threads.length; i++) {
        var thread = threads[i]

        // Do something with the thread.
    }
}
trusktr
  • 44,284
  • 53
  • 191
  • 263
1

Actually, they have somewhat complex pub/sub service that requires setting up OAuth authentication. With this service you'll must be able to get push notifications. But I also think its easier to set up a trigger to run every 10 or even 1 minute.

alexkovelsky
  • 3,880
  • 1
  • 27
  • 21