Thursday, March 11, 2010

Thunderbird, Mail.app, and Exchange 2007 Rules, Filters, and Calendar Integration

I've been using Thunderbird in OS X for a few years now. For the most part it has worked pretty well. However, we were just asked to transition accounts from our current mail server to an exchange server. As part of this, we were told that Mail.app and iCal integrate well in Snow Leopard with the version of Exchange that is being used. The first thing I thought was, "How could I migrate/recreate my Thunderbird message filters/rules?" and the second was, "Can't I just use Thunderbird with Lightning for Exchange calendar integration?".

I found that Thunderbird v2 stores its rules in a few places under your Thunderbird profile in OS X: "/Users/username/Library/Thunderbird/Profiles/yourprofileid.default/ImapMail/imap.acme.com/msgFilterRules.dat" and "/Users/username/Library/Thunderbird/Profiles/yourprofileid.default/Mail/Local Folders/msgFilterRules.dat" in a format like:

version="8"
logging="no"
name="Acme Reports"
enabled="yes"
type="1"
action="Move to folder"
actionValue="imap://someusername@imap.acme.org/NameOfMoveToFolder"
condition="OR (to or cc,contains,acme-reports) OR (from,contains,someemail@acme.com) OR (subject,contains,Acme Report)"
... (repeat everything starting with name= over and over for each rule)

How about converting Thunderbird's filters to Mail.app format? Mail.app 4.2 stores its rules in "/Users/username/Library/Mail/MessageRules.plist" in a format like (just using the single rule above as example):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>rules</key>
        <array>
                <dict>
                        <key>Active</key>
                        <string>1</string>
                        <key>AllCriteriaMustBeSatisfied</key>
                        <string>NO</string>
                        <key>AutoResponseType</key>
                        <integer>0</integer>
                        <key>CopyToMailbox</key>
                        <string>~/Library/Mail/IMAP-someusername@imap.acme.org/INBOX/NameOfMoveToFolder.imapmbox</string>
                        <key>CopyToMailboxURL</key>
                        <string>imap://someusername@imap.acme.org/INBOX/NameOfMoveToFolder</string>
                        <key>Criteria</key>
                        <array>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>a5f2ada7-c0bd-4dff-a1bb-469545f1e5d4</string>
                                        <key>Expression</key>
                                        <string>acme-reports</string>
                                        <key>Header</key>
                                        <string>AnyRecipient</string>
                                </dict>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>53c7189b-6772-42f8-a0ae-53d238d2d5b0</string>
                                        <key>Expression</key>
                                        <string>someemail@acme.com</string>
                                        <key>Header</key>
                                        <string>From</string>
                                </dict>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>7952f5ae-22a6-445c-9657-35607d924d8e</string>
                                        <key>Expression</key>
                                        <string>Acme Report</string>
                                        <key>Header</key>
                                        <string>Subject</string>
                                </dict>
                        </array>
                        <key>Deletes</key>
                        <string>NO</string>
                        <key>HighlightTextUsingColor</key>
                        <string>NO</string>
                        <key>Mailbox</key>
                        <string>~/Library/Mail/IMAP-someusername@imap.acme.org/INBOX/NameOfMoveToFolder.imapmbox</string>
                        <key>MailboxURL</key>
                        <string>imap://someusername@imap.acme.org/INBOX/NameOfMoveToFolder</string>
                        <key>MarkFlagged</key>
                        <string>NO</string>
                        <key>MarkRead</key>
                        <string>NO</string>
                        <key>NotifyUser</key>
                        <string>NO</string>
                        <key>RuleId</key>
                        <string>95880085-2370-4026-80F9-AEEA7BE9D4B2</string>
                        <key>RuleName</key>
                        <string>Acme Reports</string>
                        <key>ShouldCopyMessage</key>
                        <string>NO</string>
                        <key>ShouldTransferMessage</key>
                        <string>YES</string>
                        <key>TimeStamp</key>
                        <string>195425409</string>
                </dict>
                <dict>
                        <key>Active</key>
                        <string>1</string>
                        <key>AllCriteriaMustBeSatisfied</key>
                        <string>YES</string>
                        <key>AutoResponseType</key>
                        <integer>0</integer>
                        <key>Color</key>
                        <integer>12096856</integer>
                        <key>Criteria</key>
                        <array>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>BD45A79F-79EB-4C22-AC0F-98D5B0768C8B</string>
                                        <key>Header</key>
                                        <string>SenderIsNotInAddressBook</string>
                                </dict>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>623B6201-0B02-4842-BA2A-4196435AD888</string>
                                        <key>Header</key>
                                        <string>SenderIsNotInAddressHistory</string>
                                </dict>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>83B3EE72-F2CB-4EF2-B060-EFA62209D11B</string>
                                        <key>Header</key>
                                        <string>NoRecipientIncludesFullName</string>
                                </dict>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>B95AD422-A4C2-4831-B8C6-A7837A23A578</string>
                                        <key>Header</key>
                                        <string>IsJunkMail</string>
                                </dict>
                        </array>
                        <key>Deletes</key>
                        <string>NO</string>
                        <key>HighlightTextUsingColor</key>
                        <string>YES</string>
                        <key>IsOneAndOnlyJunkRule</key>
                        <string>YES</string>
                        <key>MarkFlagged</key>
                        <string>NO</string>
                        <key>MarkRead</key>
                        <string>NO</string>
                        <key>NotifyUser</key>
                        <string>NO</string>
                        <key>RuleId</key>
                        <string>21A4628B-AF2A-4447-A38E-FA1FC2C7FA47</string>
                        <key>RuleName</key>
                        <string>Junk</string>
                        <key>ShouldCopyMessage</key>
                        <string>NO</string>
                        <key>ShouldTransferMessage</key>
                        <string>NO</string>
                        <key>TimeStamp</key>
                        <string>195425409</string>
                        <key>Version</key>
                        <string>2</string>
                </dict>
                <dict>
                        <key>Active</key>
                        <string>1</string>
                        <key>AddInvitationAttachmentToICal</key>
                        <string>YES</string>
                        <key>AllCriteriaMustBeSatisfied</key>
                        <string>YES</string>
                        <key>AutoResponseType</key>
                        <integer>0</integer>
                        <key>Criteria</key>
                        <array>
                                <dict>
                                        <key>CriterionUniqueId</key>
                                        <string>423D56D1-6FA3-4581-9E90-94632EE569D9</string>
                                        <key>Header</key>
                                        <string>AnyMessage</string>
                                </dict>
                        </array>
                        <key>Deletes</key>
                        <string>NO</string>
                        <key>HighlightTextUsingColor</key>
                        <string>NO</string>
                        <key>IsOneAndOnlyICalRule</key>
                        <string>YES</string>
                        <key>MarkFlagged</key>
                        <string>NO</string>
                        <key>MarkRead</key>
                        <string>NO</string>
                        <key>NotifyUser</key>
                        <string>NO</string>
                        <key>RuleId</key>
                        <string>28BF8471-E57D-4685-A059-3855AE1682FD</string>
                        <key>RuleName</key>
                        <string>Add Invitations Automatically</string>
                        <key>ShouldCopyMessage</key>
                        <string>NO</string>
                        <key>ShouldTransferMessage</key>
                        <string>NO</string>
                        <key>TimeStamp</key>
                        <string>195425409</string>
                        <key>Version</key>
                        <string>2</string>
                </dict>
        </array>
        <key>version</key>
        <integer>12</integer>
</dict>
</plist>
So if you wanted to convert Thunderbird message filters to Mail.app rule format, it might take some work to also set the timestamp, UUIDs, etc. inside each rule.

I looked into the Thunderbird Message Filter Import/Export 1.3.7.5 Thunderbird plugin, but it basically exports in the same format as noted above except with two additional lines at the top for its import use:

RootFolderUri=imap://someusername@imap.acme.org
mailnews.customHeaders=
In addition, when Thunderbird starts, that plugin pops up the homepage of the add-on in a browser. I uninstalled it. It seemed just as easy to look at the files I mentioned if you are interested in the rules data, but let's hope that support for exporting filters to Mail.app rules format will be in a future version.

As an alternative to using Mail.app to manage the rules, I was told that Exchange 2007's (rich/IE/"regular") OWA client could be used to setup server-side rules. (Note: Exchange Server 2007's Outlook Web Access Light client must be used if you don't use IE, and you can't manage server-side rules with non-IE browsers in that version of Exchange.) Running Windows XP in VMWare Fusion, and using ieHTTPHeaders to view HTTP Headers in IE, it seemed that the process of adding rules via OWA (non-light/IE version) with Exchange 2007 was a session-based, multi-step process that had several IDs in the XML requests sent to Exchange during the process. It didn't seem very trivial to automate creation of even a single rule via scraping. However, I found reference of an exchange web service here. It looks like the URL to it typically looks like: http://someexchangeserver.somedomain.org/EWS/Exchange.asmx (see MS Exchange 2007 Exchange Web Services Managed API 1.0 docs intro and API docs). It would be nice if there were a plugin in Thunderbird to manage server-side rules in Exchange 2007 server, but I don't see any "Rule" object in the list of data classes.

In addition, while Mail.app was more powerful than Thunderbird 2.0.0.x as far as rules went (for example- you could have it bounce in the dock if gets a high priority mail, or speak a name if an incoming mail matched the rules, etc.), I could not see how to get OWA to allow me to create a rule like "if to or cc contains ____" (you have to specify the exact text, it seemed, rather than to do a "contains").

If you want to migrate rules from Thunderbird 2.0.0.26 to Mail.app v4.2 or Exchange Server 2007, just adding rules by hand in Mail.app or IE OWA client might be easiest, but note that Exchange 2007 OWA's rules may not let you do everything exactly the way you could in Thunderbird. However, if you use server-side rules, then when you connect via the web-based client, rules can be applied. So each have their benefits.

Note that I'm having to switch from one mail server to another for incoming mail, though, so for me, a simple conversion of filters to rules wouldn't work. And because I don't want to have to start VMWare whenever I want to add rules, the OWA Exchange 2007 client is probably not a good option (once they switch to Exchange 2010 though, I might think about using Safari to manage rules, since that is claimed to be supported). I could just manually add folders and rules in Mail.app and that is probably what I'll do.

I am not excluding sticking with Thunderbird either. Maybe Thunderbird's current (or future) integration with Exchange is (or will be) good enough. I installed Thunderbird 3 and Lightning. I'd also like to find Jamon Terrell's add-on as mentioned here. But I haven't found out yet how to hook Lightning/Thunderbird up to Exchange 2007 so that I could see my calendar, others' calendars, and respond to meeting requests easily.

(Specific versions of things I was working with: OS X 10.6.2, Thunderbird v2.0.0.24, Mail(.app) v4.2, and Exchange Server 2007.)

No comments: