Playing with Google Apps Scripts

Google has an Apps Script platform which allows you yo write scripts for most of Google products, such as Gmail, Drive, Spreadsheets, etc. The google script (extension .gs) is an JavaScript language subset. Google provides online editor for scripts, which is available at The editor is an online IDE with basic autocompletion support, which is really nice. But I prefer to write Google Scripts in some mature desctop editors such as Visual Studio or at least Sublime Text.

I came across need of writing Google Script, when I wanted to sort my GitHub notification and remove some subscription emails.

Ok, lets start. First, open the page in your favourite browser. The page will ask you to choose an project type, or open recent project.

Step 1

I'm going to select the "Blank Project" option.

Step 2

If you click on "Untitled project" you'll be able to give a sensible name for your project.

Step 3

Step 4

Then you can write a code. As manipulating emails means a lot of work with collection, so it would be nice to have something like underscore.js or lodash.js in place. I'll go with Lo-Dash. Just go to and dowload minified modern build.

When you have Lo-Dash downloaded you need to import it to your Google Apps Script project. Press File->New->Script File

Step 5

Enter the name of the file: LoDash

Step 6

Then copy and paste content of lodash.min.js to and save the file.

And finally there is my code to sort Github label in the Gmail.

function split() {
  // I have a filter in Gmail, which will put all emails from 
  // to "GitHub" label and skip inbox for them
  // Get the 'GitHub' label
  var label = GmailApp.getUserLabelByName('GitHub');

  // Group all threads by Project Name. All notification emails have Project Name 
  // in square brackets in the email title. 
  var groups = _.groupBy(label.getThreads(), function(t) {
    var subject = t.getFirstMessageSubject();

    var tag = /\[([^\]]+)\]/.exec(subject);
    if (tag) {
      return label.getName() + '/' + tag[1];
    return label.getName();

  _.forEach(groups, function(threads, l) {
    if (label.getName() != l) {

      // Get or create a label for a project 
      var new_label = GmailApp.getUserLabelByName(l) || GmailApp.createLabel(l);

      // Label.addToThreads / Label.removeFromThreads has an restriction of
      // 100 threads per call, so we need to page our threads.
      var pages = _.groupBy(threads, function(t, i) { return (i / 100) >> 0; });

      _.forEach(pages, function(page) {

        // If you call API to often you can reach call limit and script will stop execution

When we have code in place we want to add a trigger to run the script regularly. Click Resources->Current project's triggers

Step 9

Then click on "No triggers set up. Click here to add new now."

Step 10

Select the frequence you want your trigger to run. I've chosen to run this script every five minutes. Click Save. The script will ask you for Authorisation.

Step 11

Press "Continue". And then in the pop-up window review and Accept permissions for your script.

Step 12

Happy scripting!

comments powered by Disqus