Integrate Astrid with Thunderbird

Astrid is just yet another todo list in the cloud. It has some advanced features like the small built in social network that allows you to manage todo lists collaboratively. Furthermore, there is a nice little Android app for it. My use cases, however, are usually much simpler: I just want to remember stuff.

One of the things that I regularly put on a todo-list is replying to emails. This happened so frequently that I was wondering whether there was any Thunderbird extension that supports the creation of new tasks with Astrid. A typical, basic scenario might for instance be the following:

  • Thunderbird receives a new email with the subject “XYZ”
  • I highlight the new message and click on a button in the toolbar
  • A new task with the title “Reply: XYZ” gets added to an Astrid list called “mail” with due date set for today

An advanced version could include the following functionality:

  • When I click said button, the email is assigned a “TODO” tag in Thunderbird
  • When I mark the task as finished in Astrid, the tag is removed
  • When I remove the tag in Thunderbird, the task is marked as finished in Astrid

Using saved searches, this could create the illusion of a virtual todo list within Thunderbird.

Unfortunately I could not find any extension that would do the job – so I decided to come up with something myself. As I am not a Thunderbird hacker, my first approach is a quick and dirty solution to implement the basic usecase described above. I don’t have any experiences in developing Thunderbird extensions, therefore I am using Custom Buttons instead. This extensions allows me to create a new button in my Thunderbird toolbar and to hack together some JavaScript that gets called whenever the button is clicked.

Astrid has an API. They even provide a small JavaScript library. However, I did not want to go through the hassle of requesting an API key (not even knowing whether this will get me anywhere) and I am afraid that my JavaScript-foo is somewhat limited. Thus, I decided to work around the problem using the email interface that Astrid provides – an idea that I stole from this blogpost.

Without further ado, this is what I came up with:

function   getMessageBody(aMessageHeader)  {
   // Credit goes to http://forums.mozillazine.org/viewtopic.php?f=19&t=1699075
   var messenger = Components.classes["@mozilla.org/messenger;1"]
                             .createInstance(Components.interfaces.nsIMessenger);  
   var listener = Components.classes["@mozilla.org/network/sync-stream-listener;1"]
                            .createInstance(Components.interfaces.nsISyncStreamListener);  
   var uri = aMessageHeader.folder.getUriForMsg(aMessageHeader);  
   messenger.messageServiceFromURI(uri)
            .streamMessage(uri, listener, null, null, false, "");  
   var folder = aMessageHeader.folder;  
   return folder.getMsgTextFromStream(listener.inputStream, 
                                      aMessageHeader.Charset, 
                                      65536, 32768, false, true, { });  
}

var mAccountMgrSvc = Components.classes["@mozilla.org/messenger/account-manager;1"]
                               .getService(Components.interfaces.nsIMsgAccountManager);
var account = mAccountMgrSvc.getAccount("account3");
var identity = account.defaultIdentity;
var composeFields = Components.classes["@mozilla.org/messengercompose/composefields;1"]
                              .createInstance(Components.interfaces.nsIMsgCompFields);
composeFields.characterSet = "UTF-8";

composeFields.to = "new@astrid.com";
composeFields.from = identity.email;
composeFields.replyTo = identity.replyTo;
composeFields.subject = "Reply: " + gFolderDisplay.selectedMessage.mime2DecodedSubject + " #mail (today)";
composeFields.body = getMessageBody(gFolderDisplay.selectedMessage) + "\r\n";

var MsgComposeParams = Components.classes["@mozilla.org/messengercompose/composeparams;1"]
                                 .createInstance(Components.interfaces.nsIMsgComposeParams);
MsgComposeParams.composeFields = composeFields;
MsgComposeParams.identity = identity;
MsgComposeParams.format = Components.interfaces.nsIMsgCompFormat.PlainText
MsgComposeParams.type = Components.interfaces.nsIMsgCompType.New;

var msgSend = Components.classes["@mozilla.org/messengercompose/send;1"]
        .createInstance(Components.interfaces.nsIMsgSend); 
var MsgCompose = Components.classes["@mozilla.org/messengercompose/compose;1"]
                           .createInstance(Components.interfaces.nsIMsgCompose);
MsgCompose.initialize(MsgComposeParams);
MsgCompose.SendMsg(msgSend.nsMsgDeliverNow, identity, account, null, null); 

Before I proceed, let me add that I am not a JavaScript hacker and the above is thus probably terrible code. As I mentioned before, I just wanted to get something working (suggestions & improvements are welcome).

To get it to work, make sure that “account3″ is replaced by the (Thunderbird-) key of the account with which you are registered at Astrid. As you can see, I add ” #mail (today)” to the subject line. The first part tells astrid to save the new task into a list called “mail”. The second part sets the due date of the new task to today.

This immediately reveals a potential problem of this code: If the subject of the original mail contains any #’s or other symbols recognised by Astrid, then this will lead to undesired effects. A big todo item is thus to add some escaping functionality. In the long run it is probably better to migrate to the Astrid API instead – in particular if I want to implement any of the advanced behaviour described above.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: