Friday, July 13, 2012

Google App Scripts

In the last few days I discovered that it is possible to script Google apps using just plain Javascript. For some time I wanted to automate a few tasks that I do in Gmail and never found an appropriate way to do it. What makes this even more exciting is that the scripting environment is all integrated with the Google Drive environment. That is, you can create and manage your scripting projects just as easily as managing your sdpreadsheets and documents.

So I wouldn't waste time explaining the details of the scripting environment since there are some very good documentation and tutorials already. But I will explain how I started using this feature.

The Backgroound

We are running a website with the usual email feedback forms. Unfortunately because of the way the email system and the website's domain name is set up I cannot automate sending the emails directly to the corporate email addresses. I suspect that an experienced system administrator may be able to sort out the details quite easily but that is not me. So instead I send all feedback to a Gmail account from where it is then distributed to the appropriate addresses. Up to now the distribution was done manually. Wouldn't it be nice, I say to myself frequently, if I could write a script that simply forwarded these messages on automatically?

The Solution

I started by creating a new script in Google Drive.

Then I created a function to search the inbox and parse the emails and forward the relevant ones. The thing is, the email address of the department in the organization is actaully in the body of the email. This was originally done just as a summary of the entire transaction will be recorded in the email itself. So the function has to parse the body for the email address.

function forwardWebsiteMail(){  
  var address = "The address of emails from the website";
  var d = new Date();   //todays date
  var msg = "Starting send function at: " + d.toLocaleTimeString();
  if(GmailApp.getInboxUnreadCount() > 0){ //are there any unread messages?
    var threads ='is:unread from:(address)'); //search for all unread messages from the website
    var msgcount = 0;
    var threadcount = threads.length;
    for(var i = 0;i < threads.length; i++ ){     //loop through the threads
        var messages = threads[i].getMessages();
        for(var j = 0; j < messages.length;j++){  //loop through messages in this thread
          var body = messages[j].getBody();     //parse the body of the mail.    
          var p = body.indexOf("@");
          var found = false;
          var n = p-1;
          while(!found){   //find the start of the address
            if(body.charAt(n) == " "){
              found = true;
              n = n - 1;
          found = false;
          var m = p + 1;
          while(!found){   //find the end of the address
            if(body.charAt(m) == "<" ){
              found = true;
              m = m + 1;
          var faddress = body.substring(n + 1, m); //now get the address         
          messages[j].forward(faddress, {noReply:true});  //forward
          messages[j].markRead(); //mark the message as read        
          msgcount = msgcount + 1; //keep track of the total number of messages forwarded
      var label = GmailApp.getUserLabelByName("Work/AutoSent");//add a special label to the thread
    msg = msg + "\n" + msgcount + " messages sent";
    msg = msg + "\nFrom " + threadcount + " threads";
    msg = msg + "\nNo Unread Messages";
  //finally notify myself that the script ran
  GmailApp.sendEmail("my email address", "Auto Email Script Report " + d.toLocaleTimeString(), msg);

You can see from the above function that I am using the GmailApp object to interact with Gmail, the GmailThread and GmailMessage objects to interact with the Threads and Messages respectively.

Automating the Script

Finally I need a way to run this script without interaction from me. There are two possibilities: Time Driven triggers or Simple triggers. Simple Triggers respond to events such as onOpen and Time Driven Triggers can be scheduled to run at periodic intervals.
The Script environment has an option to manage triggers.

It is then a simple matter to set an interval for your function to run. I am runnimng my function once every hour.

Friday, April 08, 2011

A Simple Observer

Today someone on StackOverflow asked about allowing 2 panels on a JFrame interact with each other. 

In order to answer the question I wrote a simple class to illustrate the concept of the Observer Pattern. Not the observer the way you would see it in a text book but the observer none the less. You can see the code on my website here.

For more details on design patterns check out Head First Design Patterns. It is a fantastic book.

And here is the answer that I posted on StackOverflow.

Thursday, November 18, 2010

Algorithm Design: Longest Common Subsequence

A group of students in the COMP6400 course in UWI have started a blog to share the material covered in class. Hopefully we can publish everything in this location in such a way that everyone can benefit from each other. Its the study group gone WWW.

Here is an example of one post:

Algorithm Design: Longest Common Subsequence: "Here is an implementation of the Longest Common Subsequence (LCS) problem that was discussed in class. The Problem You are given a sequence..."

Wednesday, June 23, 2010

New Website

I finally managed to finish the new design of my website. Of course it is still early days so the content is a bit sparse. I have started publishing a number of tutorials and lecture notes on various topics.

Over the years I have written many tutorials on a number of subjects but unfortunately they are not in the correct format to be published on the web. The time consuming task of converting them all has begun.

This website will be my main point of contact with students this coming year. I am publishing all course outlines and handouts here.

Take a look:

Reading List

I found myself reading Stieg Larsson's The Girl with the Dragon Tattoo recently and was pleasantly surprised. It was a pretty good mystery with enough action to keep you reading till the end.

At first it took some getting used to the Swedish terms and places but that really added to the appeal of the book.

There are plenty of likeable characters with unique traits. All in all a good reading experience.

I have already started on the second of the series  The Girl Who Played with Fire.

Monday, May 03, 2010

South Cluster Launches IPG

The Baha'i community of South Trinidad have launch an intensive programme of growth (IPG) on 2 May 2010. The occasion was joyous and the excitment of the friends could be felt. Over 70 persons from around the country attended the event.

Messages of congratulations from the National Spiritual Assembly of Trinidad and Tobago and the Counsellor were read.

A spiritual atmosphere was created by opening the program with a 15 minute devotional and numerous songs were sung during the program.

Many friends from other clusters offered congratulations to the Southern Cluster.

For the past few years the Baha'i friends in South have been working very hard to make a significant advance in building their capacity to effect change in the society. It is widely recognized that the present order of society is crumbling and there is very little that can be done to save it.

Any real change has to come from the fundamental understanding that we are spiritual beings and not just animals. As such our actions can reflect a nobler reality. Once this understanding is achieved an individual can start working towards building a new world civilization.

The Baha'i community is searching for the individuals in the wider community that is concerned about the breakdown in society and would like to take an active role in building the new civilization. Together these individuals will study and develop skills that are necessary to carry out this incredible task.

The Universal House of Justice has described the activities that are necessary for this work:

...meetings that strengthen the devotional character of the community; classes that nurture the tender hearts and minds of children; groups that channel the surging energies of junior youth; circles of study, open to all, that enable people of varied backgrounds to advance on equal footing and explore the application of the teachings to their individual and collective lives...
The Universal House of Justice, Ridvan 2010.
When many individuals are actively engaged in these four activities it is called an Intensive Programme of Growth (IPG). The launch of an IPG is exciting because it signals that the community have grown to the point that this process can now be self sustaining. The community now has the capacity to steadily introduce new individuals to this programme and continuously widen the circle of friends that are actively building the new world civilization.
Congratulations South Cluster.

Friday, April 02, 2010

Endevour Overpass

Sometimes you notice something that is so inconsequential that you do not even notice that you notice. There is absolutely nothing of note in this picture.

Looking north to the Endevour overpass.

Tuesday, March 30, 2010

Upgrading a Laptop

Upgrading is never easy. No matter how much preparation you make.

We decided to upgrade all the developers laptops on the team by increasing the RAM and moving from Windows XP to Windows 7 64 bit. We started by getting more RAM and increasing to 4 GB. Of course, because we were running Windows XP 32 bit, so we only got a usable 3.48 GB of RAM. While that is an improvement over the 2GB we had before we wanted more.

So we are now attempting to upgrade to Windows 7. I spent the better part of the last two days backing up and installing. Backing up took all night despite the use of some helpful migration tools available from Microsoft.

The installation went quite smoothly and so far the new system is working nicely. Unfortunately, I still have only 3.48 GB of RAM. It turns out that I installed the 32 bit version. Hmm. Now I will have to get the 64 bit cd and do it all over again. At least this time I have everything backed up so if the installation runs smoothly then I will not have  to spend too much time on the operation.