I use Apple Mail Rules for many things. They help me organize and flag incoming messages, which I find very useful. Recently however I came across a problem trying to implement a rule which is supposed to run a script as its action. The AppleScript code was never executing. Attempts to seek solutions via Twitter, StackOverflow, and mailing lists all yielded no working results. I finally got it working, and thought I’d share how it’s done.

If you’re not familiar with Rules, here a quick explanation. Rules operate on incoming messages and test them against each rule’s conditions. If conditions are met, the message is subject to perform the rule’s action. In Mail’s Preferences pane, you select the Rules icon and click on Add Rule. Give your rule a description (name it, essentially), then define some conditions and actions. The conditions can be logically ANDed (“all”) or ORed (“any”) together to get the desired results. There’s a lengthy list of conditions in the popup menu. Options for each condition help narrow it down, for example, the Account condition has a list of all your active accounts. The built-in actions for a rule include moving to a folder, marking it flagged, playing a sound, etc.


One action that I hadn’t used before was “Run AppleScript.” In this case I need to use a script to extract the email address of the sender from a message. Maybe there’s an easier way, but I decided to try to write a simple script and see what would happen. I’m no stranger to AppleScript because I was using it before the System 7 rollout over 20 years ago.† So what would such an AppleScript look like? If you look at the Help for using scripts as rule actions, it says to simply select your existing script file from the file chooser. Then it says, “To see sample scripts for mail, open the AppleScript dictionary for Mail.” Aha! That should be insightful. Clicking on the link brings up the AppleScipt editor (found in /Applications/Utilities) with the dictionary for Mail. An AppleScript dictionary shows the publicly exposed message suites that Mail supports. This basically defines how you can interact with Mail through Apple Events, the underlying technology behind AppleScript.

But there are no sample scripts. OK, I try the menu item File->New From Template->Mail->Mail Rule Action.scptd, which prompts you for a save location. In my internet search results people mentioned saving such scripts into ~/Library/Mail Scripts. That folder doesn’t exist, but I created it and saved my file. The script has the thinnest of possible example code to show how you might use it to process each message. Then I added something innocuous to the script, like a beep command, so I could tell if it’s working or not. Going back to Mail, I selected my new script and saved the rule. To make it even easier, I made the rule’s condition match any message from a particular account. One way to test rules is to select some message in a mailbox and choose “Apply Rules” from the context menu. [NOTE: this will apply ALL the rules for the selected messages, not the one you just created!]

In my case, the rule matched the conditions, but the script didn’t run. You can add another action in the rule to play a sound (this is different from the beep command in the script) and that action runs, so you know the condition is met. So what’s the problem? Well, it turns out there’s a bug in Mail, and when you choose the file in your ~/Library/Mail Scripts folder, it can’t parse the path name. Instead of inserting /Users/mmartel/Library/Mail Scripts/MyScript.scptd it inserts the friendly ~/Library/Mail Scripts/MyScript.scptd path.


Now that’s a real bummer. If you dig a little deeper, you can find out that in Lion the sample Mail scripts are actually in a new folder, in the system Library folder:


OK, now these are some useful script samples, and if you look here you’ll find some good examples. But what happens if you try to save your scripts to that folder? Not possible, sorry. That Library folder is restricted in Lion, so you can’t put your files in there without mucking with permissions. So now what? Can’t put scripts in my own folders, can’t put them in the system’s folders. This isn’t looking good.

My solution is to put them in a shared folder which I can write to. Such a folder is /Users/Shared/ and if you select a script in there then Mail won’t need to use the ~ substitution which causes the bug which makes it unable to locate and run the AppleScript. I don’t know why this process isn’t better documented. Until then I’ve filed a bug with Apple and hopefully someday we can again put scripts in our own user folders and have Mail find/execute them.

For the curious among you, here’s part of my script, which just says the name of the sender of a message that meets the conditions:

using terms from application “Mail”

on perform mail action with messagestheseMessagesfor ruleSaveSender

tell application “Mail”

repeat with eachMessage in theseMessages

set name_ to extract name from the sender of eachMessage

do shell script “say ‘Received email from ” & name_ & “‘”

end repeat

end tell

end perform mail action with messages

end using terms from

The “do shell script” is just a way to run bash scripts inline, and from there your imagination is the limit as to what this AppleScript can do. Check out the example scripts mentioned above to find out more about the specific syntax requirements.

I hope you find this useful. I just wish I hadn’t wasted the better part of a day figuring it out. If you know of better documentation, please let me know where to find it.


† Does anybody remember Inside Macintosh: Volume VI or all 1008 pages of Inside Macintosh: Interapplication Communication?