Mailsmith
Other Programs
Scripts
Mailsmith.scpt
Archive to sub-mailbox
Check Spelling
Find reply
Change font size
Submit Script to JEM
Fix common spelling errors
Setting SMTP server
URL from Safari
Address from AB
linkMunge
Export to Address Book
Saving attachments
Digest Script
File with same
POP window position
Position of new windows
iCal and Mailsmith
Edit From Line
Modified Thread Script
Reply to Selection
Temporary Text Window
Compact gain
Tracking backups
Edit subject
Googler
Auto-rewrap
MMA
SMTP server
Open, fetch, and close
URL Manager
BrainForest
Thread by Author
Thread by subject
Export Email
Get Selection
Read Addresses
Export Email
Organize Email
Account setup
Mailsmith 2 BBEdit
BBEdit 2 Mailsmith
Search II
Check One
Delete Enclosure
Open, fetch, close
Set Answered
Set Redirected
Empty Trash
List found
Print Several
Del. old. msg.
Delete Enclosures
Accounts
Address Book
Editing
Filters
General
Import/Export
Links
Mailboxes
Memory
Scripting
Speed
send/receive
Tips/Tricks


Organize Email

Author Jan Erik Moström
Last modified 2000-06-24
What is this?

Using AppleScript to organize email
Here is as example of how I use an AppleScript to help me organizing my email. I use email a lot in my daily work, I get emails that tells me that things needs to be done, there are things to plan, I tell people to do things etc. In short, a part of Mailsmith works as a todo list and this AppleScript helps me to maintain that list. There is actually two more scripts but I leave those for another time.

The problem I had was that sometimes I "lost" an email in some mailbox and forgot to do something. My second problem was that I needed to refer back to earlier emails once in awhile and I needed some way of filing the emails. I started by using labels, using them to mark messages as important, do later, completed etc.

labels

Although things got better by this I still had problems finding the emails that needed to be done, it was difficult to remember where to file things, sometimes things got filed in wrong location, etc. In short, the system wasn't perfect. So I decided to write an AppleScript that moved around the messages like I wanted.

This AppleScript is only for me ... in the sense that it moves the messages in the way I want, but perhaps someone else will find this script useful as a starting point for their own "move-messages-around" script.

Before starting to describe how the script works I better describe my mailboxes, the labels and how I use them. Above you will find a picture that shows the labels I'm using, the text means "special", "Fix 1", "Fix 2", "Fix 3", "Follow up", "Archive", "Finished", and "Note". The first is used for indentifying mails from special people and is not used here. The last label is used for another script and is not used here.

mailboxes

The second pictures shows an edited version of my mailboxes. The first important step is to set up a number of filters so that the emails end up in the correct mailbox automatically. I think that in my case about 80-90% is stored correctly. The mailbox "10 listor" and those "inside" it all belongs to different mailing lists. The "40 att göra" is my "important-things-to-do" mailbox and "kolla up" contains the messages I need to follow up later. "50 mina" and the mailboxes "inside" it are mails that are sent to me personally. "80 mostrom" for mail to my domain, for example the xxxx@xxx.com address. The "90 stimdi" takes cares of messages to another domain and "99 arkivet" and those "inside" it contains my email archive (in this case a small part of it).

In this script I don't care about mailing list emails but only mail directed to me in some way or the other. What happens is that I read emails and mark them with a label, for example if I need to create new user accounts I mark it "Fix 3" (needs to be done but not terrible important) and a message that says that I need to fix the bikes for my children might get a "Fix 2" label while the one that says that "the items have been orderd and will arrive at a later date" gets a "Follow up" label.

When I have completed some task I mark the email as "Finished" and continue with my other tasks

These labeled emails are now stored in a number of mailboxes so it gets very difficult to find the important ones and this is where the script comes in. It searches through my mailboxes looking for the labels "Fix 1", "Fix 2", and "Fix 3" and move these to the "40 att göra" mailbox which is sorted according to label. It also looks for "Follow up" labels and moves these messages to the "Kolla upp" mailbox. And while the script is looking for these labels it also looks for "Finished" labels and move them in to their proper archive folder and change the label to "archived".

This is where another small problem occurs: I want messages that orginally ended up in the "HUMlab" mailbox to be archived in the "HUMlab arkiv" mailbox but if I previously have labeled it "Fix 2" it might now be in the "40 att göra" mailbox together with messages from the "50 mina" and "Umeå" mailboxes. But I want mail that orginally were filtered into these last two mailboxes to end up in the mailbox "generellt arkiv".

So to be able to differ between these messages the script enters a text tag in the note field of each message that is moved due to a "Fix 1", "Fix 2", "Fix 3" and "Follow up" label. This tag contains the name of the orginal mailbox so all the script has to do is to look up the note field for a message and see which the orginal mailbox was.

OK, that was an explaination of the logic of the script ... or at least a try. Next ... the script.

The script

I'm not going to bore you with all the details in the code, I've tried to comment the code so hopefully you will be able to read it. The first thing to remember is that you have to customize the code to fit your way of organizing email but to make it easier I've defined a number of constants that you can change. Here is a description of those constants.

The first group is the defintion of labels:

code1

Depending on where you have your labels you have to change the numbers, the first label that you define in Mailsmith preference panel has the index 8 (in my case this is the label "special" in the first picture)

The next group is

code2

skipMailboxes
To speed things up I don't check the outgoing mailboxes, see the code. I addtion to those I also skip a number of other mailboxes, I define those here. As you can see I don't check the mailing lists, "10 listor" and it's sub-mailboxes, the trash or the archive.
todoName
This is the name of the "Todo mailbox", see below.
followupName
This is the name of the "Follow up mailbox", see below.
archive
The name of the archive mailbox, it is assumed that all archive folders are sub-mailboxes to this.
archivePost
The extenstion I add to archive mailboxes, for exampel the archive mailbox for the "stimdi" mailbox is the "stimdi arkiv" mailbox.
specialArchive
Normally I archive all messages in the same mailbox, however a number of mailboxes are stored in separate mailboxes. This list defines those mailboxes.
generalArchive
The name of the general archive mailbox.

The next thing that needs some configuring is the start of the script where I define some global variables.

code3

It's the last four lines that are interesting, they define references to some mailboxes. If you have you mailboxes defined in some other way you can change the references here, for example if you have both the followup and the todo mailbox as top level mailboxes you would change the line

set followupMailbox to mailbox followupName of todoMailbox

to

set followupMailbox to mailbox followupName

OK, hopefully this script will give someone else some ideas for their own scripts. If you got some questions/comments send me an email xxxx@xxxxx.xxx and if you see something that could be coded in a better way please send me an email explaining how to do it (I'm still just a newbie when it comes to AppleScript).


-- If you are going to use this script yourself then you HAVE to modify the
-- script so that is fits your way of working and your folder structure

-------------------------------------------
-- First some constant defintions
--
-- I use the following labels to mark my email for further processing
-- 
-- labelPriority1 Important email that needs to be taken care of quickly
-- labelPriority2 Take care of these emails as soon as possible
-- labelPriority3 Needs to be taken care of
-- labelFinished  I've dealt with this email, so it can be archived
-- labelFollowup  Something that I need to check at a later time
-- labelArchived  This email is archived (in Mailsmith)
-- labelExported  This email has been exported to a FileMaker database
-- labelNote      This email should be exported to the note database
--                before being marked as finished
-------------------------------------------

property labelPriority1 : 9
property labelPriority2 : 10
property labelPriority3 : 11
property labelFollowup : 12
property labelArchived : 13
property labelFinished : 14
property labelNote : 15

-------------------------------------------
-- Read the documentation so you understand how this why I have
-- these names defined
-------------------------------------------

property skipMailboxes : {"10 listor", "(trash)", "99 arkivet"}
property todoName : "40 att göra"
property followupName : "kolla upp"
property archive : "99 arkivet"
property archivePost : " arkiv"
property specialArchive : {"HUMlab", "Institutionen", "stimdi", "tdbb11 2000"}
property generalArchive : "Generellt arkiv"

on run
  global todoMailbox
  global followupMailbox
  global generalMailbox
  global archiveMailbox

  tell application "Mailsmith 1.1"
    -- Start by getting a list of all mail folders
    set allMailboxes to id of every mailbox
    -- Now get all outgoing mail folders
    set outMailboxes to id of every outboxes
    -- Now, get references to some special mailboxes
    set todoMailbox to mailbox todoName
    set followupMailbox to mailbox followupName of todoMailbox
    set archiveMailbox to mailbox archive
    set generalMailbox to mailbox generalArchive of archiveMailbox
    -- OK, I don't want check the outgoing mail folders
    -- so before processing a mailbox I check to see if
    -- it's a outgoing mailbox
    repeat with mbox in allMailboxes
      if outMailboxes does not contain mbox then
        -- OK, so it was not an outgoing mailbox. Now we are going to
        -- check if it's one of the top level mailboxes that are not
        -- going to be processed
        set currentName to the name of mailbox id mbox
        if skipMailboxes does not contain currentName then
          -- OK, this mailbox should be processed further
          my processMailbox(mailbox id mbox)
        end if
      end if
    end repeat
  end tell
end run

on processMailbox(mbox)
  global todoMailbox
  global followupMailbox
  global generalMailbox
  global archiveMailbox
  tell application "Mailsmith 1.1"
    -- This is where things gets complicated. There are a number of things
    -- that is going to happen here. The first thing is to define the string
    -- that the script uses to note where it orginated from. This feature is
    -- used when the script moves from a mailbox to the todo or the followup
    -- mailbox. Later when the mailbox has been marked as finished the info
    -- is used to find the correct mailbox to archive the email in.
    set orgFolder to "<Orginal mbox:" & the name of mbox & ">" & return

    -- OK, see if this mailbox has any "prio-messages" that should be moved to
    -- the todo mailbox ... but skip if it's the todo mailbox itself
    if mbox ≠ todoMailbox then
      set msgList to every message of mbox whose label index is labelPriority1 or ¬
        label index is labelPriority2 or label index is labelPriority3
      if msgList ≠ {} then
        repeat with i in msgList
          -- Since these messages are going to be moved we want to save some
          -- information of where they orginally came from.
          set notes of i to orgFolder & notes of i
        end repeat
        -- OK, move the messages to the todo mailbox
        move msgList to todoMailbox
      end if
    end if
    -- Next step is to move the messages that should be followed up. This
    -- time skip the mailbox if it's the followup mailbox
    if mbox ≠ followupMailbox then
      set msgList to every message of mbox whose label index is labelFollowup
      if msgList ≠ {} then
        repeat with i in msgList
          -- Since these messages are going to be moved we want to save some
          -- information of where they orginally came from.
          set notes of i to orgFolder & notes of i
        end repeat
        -- OK, move the messages to the followup mailbox
        move msgList to followupMailbox
      end if
    end if

    -- And now for the big finale. The script is going to look for messages
    -- that are marked as finished and move them to the proper "archive folder"
    set msgList to every message of mbox whose label index is labelFinished
    repeat with msg in msgList
      -- Now the question is where message should be archived.
      -- We have found a message but it might have been moved to this folder
      -- by this script on an earlier occasion. So to be able to move the
      -- message to the proper folder we need to find out if it has been moved
      -- to this folder. This is done by looking in the notes and see if the 
      -- info is there.
      set the_note to notes of msg
      set the_offset to offset of "<Orginal mbox:" in the_note
      if the_offset = 0 then
        -- The message is it's orginal mailbox so we can use that
        -- name to see where to archive the message
        set mail_name to the name of mbox
      else
        -- The message has been moved so we have to find out where the
        -- message comes from.
        set endMark to offset of ">" in the_note
        repeat while endMark < the_offset
          -- This is neccessary since one note can contain
          -- many tags so we have to find the correct ">"
          set the_note to (characters (endMark + 1) thru (length of the_note) of the_note) as text
          set the_offset to offset of "<Orginal mbox:" in the_note
          set endMark to offset of ">" in the_note
        end repeat
        -- Now we now where the tag is
        set mail_name to (characters (the_offset + 14) thru (endMark - 1) of the_note) as text
      end if
      -- OK, we have found the name of the "orginal mailbox" for this message
      -- so we are now able to find out where to archive it but before moving it
      -- set the label of the message so that it's clearly indicated that it has been archived
      set label index of msg to labelArchived
      -- Start by checking if it's a 'special' mailbox
      if specialArchive contains mail_name then
        -- Yep, it was special mailbox, move it to the proper destination mailbox
        move msg to mailbox (mail_name & archivePost) of archiveMailbox
      else
        move msg to generalMailbox
      end if
    end repeat

    -- And finally do a recursive decent into all sub-mailboxes of this mailbox
    repeat with submbox in mailboxes of mbox
      my processMailbox(submbox)
    end repeat
  end tell
end processMailbox