Discussing the nuts and bolts of software development

Tuesday, October 09, 2007

 

Extending Applications on Mac OS X - Entourage with Applescript, Part 1

Introduction
It is quite common nowadays for people to want to use software in ways the original developers did not envision, and this fosters the growth of ISVs to fill this niche. ISVs make use of plug-in APIs and other such mechanisms in order to extend the functionality of existing applications in order to add features people want. On the Macintosh platform, there's a powerful mechanism for interacting with and extending the functionality of an existing application - Applescript. By making the Applescript language an integral part of the operating system, Apple has created a consistent system-wide mechanism for automating and controlling applications on their platform. Today we will look at using Applescript in order to add some functionality to Microsoft Entourage.

Microsoft Entourage is the Outlook-equivalent that is available on the Macintosh platform. While it is quite feature-filled and powerful, there are some features that are desired by users that do not exist within the base install of Microsoft Entourage. We will look at adding one such feature with some Applescript.

One feature that Entourage is missing is the ability to create messages based on a template. One common usage of such a feature would be responding to emails in a common fashion - for example, if you were a Human Resources manager, responding to applicants who were not successful, you could use a templateto help you. In this case, most of the text is boilerplate, with just some items needing customization, such as the name of the recipient. One way to solve this problem would be to create a simple Applescript.

The approach I am going to take is:
- Use some script that will reply to a given message, and fill in some prepared text
- Take the text from a file rather than have it hardcoded in the script (editable)
- Identify some areas for improvement


What You Need
To follow along, you will require: a Mac (I am testing with Mac OS X 10.4.10 on an Intel Mac), and Microsoft Entourage 2004. Also, I will not be teaching the basic underlying syntax of Applescript itself - for that, there are a number of tutorials and an excellent O'Reilly book available. However, if you have never done Applescript programming before, but have some general application development knowledge (in C, C++, C#, Java or other similar development languages), you should have no problems following along with the script we will develop in this article.

Creating Our First Script
First, let's try to write some code that pops up a new message. For now, we will be writing our scripts in the Script Editor and invoking the script from there.

To invoke the Script Editor, use the Finder to go to the folder /Applications/AppleScript and execute Script Editor. Once the script editor is started, the first thing you should do is to load the dictionary for Entourage and have a look at all the functionality that is exposed from Entourage to Applescript. You can do this by selecting File -> Open Dictionary..., and selecting "Microsoft Entourage." A new window will open with the Dictionary for Microsoft Entourage. Take a moment and explore the various suites of exposed functionality - you have access to messages, account settings, the address book, calendar items, etc. - basically every bit of data stored in Entourage can be interacted with, and any functionality can be automated with Applescript.

Now that we are a bit acquainted with what is at our disposal, let's try to make a simple Applescript that replies to the selected message in Entourage. In the Script Editor, select File -> New to start a new script. Next enter the following text (I will explain what it does in a moment:)

Listing 1:
tell application "Microsoft Entourage"
set theCurrentMessages to current messages

repeat with theMsg in theCurrentMessages

reply to theMsg
end repeat

end tell



If you click the "Run" button (the editor will make you save the file before it will actually run - pick any filename you wish) you will see a new reply message window pop up for each message that is selected (assuming of course you have messages selected in Entourage).

So, what is the code doing?

First we have a tell block. This instructs Applescript to transit a request to execute some code to an application that has support for executing Applescript - Entourage in this case. Everything in this block will be executed by the application being "told", interacting with objects/properties/actions exposed by that application to Applescript. Inside of the tell block, the first thing is we set a variable to be equal to "current messages" - If you look at the Entourage dictionary, under "Standard Suite -> Application," you will notice that current messages is a property of the object Application - and that it is "the current message(s) depending on context, including message currently being filtered" In this case, it is equal to all the messages that are highlighted in the main folder view of Entourage. It is a list of references to message objects.

Next we will have a repeat loop; this will iterate through every message in the messages list that we obtained so that we can do an action on each message. Inside the repeat loop block, you can see one line, which is the command "reply to theMessage", which invokes the functionality of creating a new message reply for that particular message. Note that this will happen for each message in the list - and that there will be a message object in the list for each message that is selected inside Entourage.

It doesn't do much, but we have created our first Applescript script! It interacts with an external application (Entourage), making use of its resources, and programmatically invoking some of its functionality (creating a new message).


Inserting Prepared Text Into The Reply Message
Now that we are able to create a "reply" message window, we will begin our first step to making our template utility a bit more functional. We will need to add some text to the message we will be replying to. The following is the code from listing 1, modified slightly in order to add some text to our new reply.

Listing 2:
tell application "Microsoft Entourage"
set theCurrentMessages to current messages
repeat with theMsg in theCurrentMessages
set replyWindow to reply to theMsg
set replyText to content of replyWindow as string
set replyText to "Dear Sir," & return & "Thank you for your email,↩
but we are not able to consider your application at this time." & ↩
return & replyText
set content of replyWindow to replyText
end repeat
end tell
As before, we are telling Entourage to reply to each message that been selected in turn, but now we are retaining the return value from that operation - we get a reference to the window of the reply message returned to us when we tell Entourage to create a reply to a message. Next, we retrieve the current contents of the reply message (which would contain the quoted contents of the message being replied to), and modify it to be equal to some hardcoded reply we wish to insert into our reply. Finally, we modify the content of the reply window to contain replyText, which contains our new hardcoded, templated text as well as the text that was already in the reply window. All of these properties and actions that can be applied to various Entourage objects can be seen in Entourage's Applescript dictionary, so you should make sure to refer to it when trying to do your own development to see what is possible.


Read Template from Disk
Now that we are able to add content to our message that we are replying to, the next step would be to make it so that templated content was not hardcoded within our script itself, but was stored in a file on disk somewhere and could be edited without having to modify the text of the script itself. For the purposes of this small demo application we are constructing, I will add code (see listing 3) that will simply read a text file off the desktop called "template.txt", and use that as the basis for the content that is added to our messages that we reply to. I've bolded the lines that have changed.

Listing 3:
set thePath to (path to desktop as Unicode text) & "template.txt"
set templateText to (read file thePath) as string

tell application "Microsoft Entourage"
set theCurrentMessages to current messages
repeat with theMsg in theCurrentMessages
set replyWindow to reply to theMsg
set replyText to content of replyWindow as string
set replyText to templateText & replyText
set content of replyWindow to replyText
end repeat
end tell

First, we set a variable to be equal to the path of the file that we will be reading in our template text, then we set another variable to the contents of that file, making use of Applescript's read function. Finally, within the repeat loop where we are replying to each message individually, we set the reply message's contents to be equal to the contents of our template file and the quoted message text appended to the end.



Where to Go From Here?
While we do have some functionality in our little template add-in that we've cobbled together in Applescript, it's missing a lot of functionality that would be useful. It would be nice if we had a means of configuring where the template file is stored. It would be nice to use more than one file. It would be nice for the text that is used to be templated itself - ie. have the text configurable with filler words like "RECIPIENT" that gets replaced with the name of the person we are replying to, for example. Then there are a number of usability issues - it would be nice for the script to be integrated into Entourage itself, accessible from a menu or a control key, for example. Also the script is not very robust from a error-handling point of view. I will touch on these in a future blog post, so please stay tuned.


Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?