Asynkronix

Indie app developer

Archiving and moving Gmail with AppleScript on Mavericks and Yosemite

The latest public version of the mail client in OS X 10.9 Mavericks has some issues working together with Gmail, especially when it comes to automating tasks with AppleScript. Some blame Apple for this, some blame the Gmail non-standard way of handling imap folders. My take is that Gmail’s filosophy of labels instead of folders is good, and that the mail app does a pretty good job of handling both traditional imap servers and non traditional like Gmail. However, when it comes to scripting, the problems begin. In previous versions of OS X, Gmail could be archived with the following AppleScript:

move message to mailbox "[Gmail]/All Mail" of account "Gmail"

In recent versions of the mail app, the mail is copied, not moved. This is covered in more detail in the article Making Apple Mail, Gmail, IMAP and AppleScript work together. The solution proposed in the article is to turn off “Show in IMAP” for “All Mail” in Gmail settings, but then some of the good features of Gmail labels get lost.

I suggest an alternative solution for using AppleScript to move Gmail-messages, where the original Gmail settings can be kept. One technique can be used to move mail to the archive folder, the other technique can move to any folder.

  • The trick to move to the archive folder is to let the AppleScript invoke the Menu command Message -> Archive (ctrl-cmd-A).
  • To move to any folder, a rule must be added that moves the mail, and then the AppleScript triggers the Menu command Message -> Apply rules (option-cmd-L)

Here is the script for technique 1, that archives (moves to Gmail/All mail) mail in the inbox that is read:

on run {input, parameters}
 tell application "System Events"
  if process "Mail" is frontmost then
   tell application "Mail" to activate
   tell application "Mail"
    --archive read mail in inbox
    
    set readGmailMessages to every message of mailbox "INBOX" of account "Gmail" whose read status is true    
    --select inbox
    tell application "System Events"
     tell process "Mail"
      --here we go to Favorite mailbox 1
      keystroke "1" using command down
      delay 0.5
     end tell
    end tell
    
    --mark all read Gmail messages
    tell front message viewer to set selected messages to readGmailMessages
    delay 0.5
    
    --archive all read Gmail messages
    tell application "System Events"
     tell process "Mail"
      --here we invoke the Menu command Message->Archive
      keystroke "a" using {control down, command down}
     end tell
    end tell
    
   end tell --tell application "Mail"
  end if
 end tell
 return input
end run

A requirement for this script to run is that the Inbox (the mail app inbox that may contain inboxes from different accounts) is favorite inbox number 1. If not, rearrange the top of the mail window until it looks like this:

inboxfavorite

This technique works only for archiving, but sometimes it is required to move to any IMAP folder (or mark with any label if you prefer that terminology). To do this, the first step is to define a rule that moves mail messages. Here is an example of a rule that moves mail from the inbox to a folder named FlaggedGmail (but could be named anything). The folder/label must be created first.

moverule

Make sure that the rule moveflaggedgmail is not checked:

notchecked

Now everything is prepared for this script that takes all read mail that is also flagged and moves it to FlaggedGmail.

(*
- This script requires a rule, normally disabled, named moveflaggedgmail
*)
on run {input, parameters}
 tell application "System Events"
  if process "Mail" is frontmost then
   tell application "Mail" to activate
   tell application "Mail"
    --move all read flagged mail from inbox to FlaggedGmail
    --Select inbox
    tell application "System Events"
     tell process "Mail"
      keystroke "1" using command down
      delay 0.5
     end tell
    end tell

    set flaggedGmailMessages to every message of mailbox "INBOX" of account "Gmail" whose read status is true and flagged status is true
    tell front message viewer to set selected messages to flaggedGmailMessages
    delay 0.5
    set enabled of rule "moveflaggedgmail" to true
    delay 0.5
    tell application "System Events"
     tell process "Mail"
      -- Apply rules to selected messages
      keystroke "l" using {command down, option down}
      delay 0.5
     end tell
    end tell
    set enabled of rule "moveflaggedgmail" to false 
   end tell --tell application "Mail"
  end if
 end tell
 return input
end run

I put the scripts in Automator service workflows and trigger them through the Services menu. They only work if Mail is active. If you would like to run the scripts when Mail is not frontmost, just delete the line

if process "Mail" is frontmost then

and the corresponding

end if

Now let’s hope this will work for Yosemite as well! UPDATE: it works on Yosemite.

Comments are closed.