bio blog

Building a Gmail message parser using Google Apps Script

11/30/2018

A client recently wanted to prototype a marketing automation strategy as a last-minute addition to an upcoming campaign. The primary criteria was that emails sent to a specific address had to be programatically processed and entered into a proprietary content management system. Given that the client was already using GSuite as their email and identity management (IDM) tool, I suggested building a minimum viable product (MVP) using Google Apps Script. This would allow us to quickly test market reaction before building a more robust solution using the Gmail Push Notification API

Google Apps Script provides programmatic access to the entire Google Apps suite, including Gmail, using simple JavaScript snippets and timed triggers – basically, it allows you to create JavaScript cronjobs that can manipulate Google Apps documents, such as emails.

In the tutorial below, I’ll walk you through building your own Gmail message parser using just a few lines of JavaScript.

The plan is:

  • Create a Gmail rule that will automatically label some messages with ParseThis,
  • Create an HTTP endpoint that will parse messages that are POSTed to it,
  • Create a Google Apps Script that will periodically check for Gmail messages that have the ParseThis label (if any are found, submit their content to the HTTP endpoint as a POST payload).

Configuring Gmail

To get started, we'll need to create a Gmail label called ParseThis. Next, we'll create a Gmail filtering rule to automatically apply the ParseThis label to any incoming message whose subject is ParseThis. Of course, in a real world use case the filtering rule would be more sophisticated and designed to capture the messages you're interested in parsing.

Creating an HTTP endpoint to receive POSTed messages

Since our focus is on Google Apps Script, we won't spend time building a parser for an imaginary use case. Instead, we'll use the awesome https://webhook.site service, which provides fully-logged endpoints that can be used to test HTTP requests -- this will allow us to verify that our Google Apps Script is indeed submitting Gmail message contents to the selected endpoint. 

Simply navigate to https://webhook.site and make a note of the unique URL that is generated for you.

In the example above, all HTTP requests sent to https://webhook.site/495fc170-cdc5-474f-9972-eca2a5c50ce0 will be logged; remember, your URL will be different and you'll need to use your unique URL in the Google Apps Script you create. Keep this window open as it will display requests to your unique URL in realtime.

Creating a Google Apps Script to monitor Gmail for matching messages

With all of the setup complete, navigate to https://script.google.com/home and click the "New script" button.

You'll be taken to a code editor that looks something like:

Replace the sample code with the JavaScript snippet below (obviously, you'll have to  replace <<< YOUR UNIQUE URL >>> with the URL you generated on https://webhook.site):

function parseEmailByLabel() {
    var gmailLabelName = "ParseThis",
        externalHandlerScript = "<<< YOUR UNIQUE URL >>>",
        gmailLabelObject = GmailApp.getUserLabelByName(gmailLabelName),
        threads = gmailLabelObject.getThreads(),
        messages,
        message,
        params,
        response;

    if (threads) {
        // handle each thread (see https://developers.google.com/apps-script/reference/gmail/gmail-thread)
        for (var i = 0; i < threads.length; i++) {
            messages = threads[i].getMessages();
            // handle each message (see https://developers.google.com/apps-script/reference/gmail/gmail-message)
            for (var j = 0;  j < messages.length;  j++) {
                message = messages[j];
                params = {
                    'method' : 'post',
                    'payload' : {
                        'from': message.getFrom(),
                        'subject': message.getSubject(),
                        'replyTo': message.getReplyTo(),
                        'cc':   message.getCc(),
                        'body': message.getBody(),
                        'date': message.getDate(),
                        'bodyPlain': message.getPlainBody(),
                        'rawContent': message.getRawContent(),
                    },
                    'headers' : {
                        'foo': 'bar'
                    }
                };
                // submit the POST request
                response = UrlFetchApp.fetch(externalHandlerScript, params).getContentText();
                // log the results
                Logger.log(response);
                // mark the message as read
                message.markRead();
            }
            // remove the label on the thread
            threads[i].removeLabel(gmailLabelObject);
        }
    }
}

The code is commented and self-explanatory: using the Gmail Service, the script looks for any messages that have the ParseThis label. If any are found, their content is submitted as a POST request to the HTTP endpoint created earlier. You'll note that you can include arbitrary headers in the request as well.

To test the script, click the ▶ button in the toolbar. The first time you do so, you will be prompted to authorize access to your Gmail account. To proceed, you will have to review and authorize the request.

Finally, go back to your https://webhook.site window and ensure that the POST payload was received:

The last step is to save and automate the script: simply navigate to File -> Save. Once you've done so, return to the Google Apps Script dashboard, right-click on the script you just created, and select Triggers.

Finally, configure the trigger to run once a minute and click save. That's it! Now this script will run once a minute, look for any messages that have the ParseThis label, forward them to your unique HTTP endpoint, and remove the label from the message so it isn't processed again.

Obviously, this is a very simple use-case that interacts only with the Gmail Service, but you can see more advanced end-to-end examples on the Google Apps Script tutorials page. The key takeaway is that Google Apps Script provides powerful scripting capabilities that can be rapidly prototyped and iterated with, and which are therefore, worthy additions to any developer's toolkit.