Sort Email by Automator + AppleScript

I made this to help with the crush of email. Why not implement sort rules? Well then the messages don’t hit my inbox and I never see them. This way, I read messages, select all, and run this script from the Scripts menu bar which you can enable from AppleScript.app. This is for Apple’s Mail.app. This script is not fast, maybe there’s a better way to do it, but I just run it and leave after reading my messages.

Note: It’s less important now with a TouchBar Mac because the automatic sort button is awesome. I’m putting this out there so it can be an example of how to automate Mail.

  1. open Automator
  2. create a new Script
  3. add Get Selected Mail Messages
  4. add Run AppleScript
  5. Paste in something like this:
-- Post-process Mail messages
-- By Troy Koelling, 2013

-- This script requires creating a plist (the location of which is defined below)

-- <?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"> 
--   <array> 
--     <dict> 
--       <key>subject_search</key> 
--       <string>Subject of Email to filter</string> 
--       <key>mailbox_key</key> 
--       <string>MailboxName to put it in</string> 
--     </dict> 
--   </array> 
-- </plist> 
-- Every rule must have a mailbox_key and one of these:
--     recipient_search
--     subject_search
--     sender_search

on run {input, parameters}
	-- Edit this path (or see below for an inline solution without dependent files)
	set shared_rules_path to "~/Dropbox/Scripts/MailRules.plist"
	
	-- Edit this account name to match the account you have in mail. It is possible to add account_key: to the my_rules instead, if you want to route things per rule but this is not tested.
	set account_key_global to "Apple"
	
	-- Edit this list of rules and un-comment, or implement the above plist solution
	-- set my_rules to {¬
	-- 	{subject_search:"Discover Card", mailbox_key:"Bills"}, ¬
	-- 	{recipient_search:"cocoa-dev", mailbox_key:"Cocoa"}, ¬
	-- 	{sender_search:"brooksreview", mailbox_key:"Very Important"} ¬
	-- 		}
	
	-- Dropbox solution
	tell application "System Events"
		set rules_p_list to property list file (shared_rules_path)
		set my_rules to value of rules_p_list
	end tell
	
	-- Loop through the input messages
	repeat with the_message in input
		tell application "Mail"
			
			-- First, get some information from the message that will be checked against each rule
			set subject_line to subject of the_message as string
			set sender_line to sender of the_message as string
			
			-- check the recipient list by building a long string to search through
			set recipient_line to ""
			repeat with to_recipient in to recipients of the_message
				set recipient_line to recipient_line & address of to_recipient as string
			end repeat
			
			-- loop also through the cc recipients	
			repeat with to_recipient in cc recipients of the_message
				set recipient_line to recipient_line & address of to_recipient as string
			end repeat
			
			repeat with a_rule in my_rules
				
				-- Fill in our search strings based on the current rule (and some defaults)
				set a_account to account_key of (a_rule & {account_key:account_key_global})
				set a_mailbox_name to mailbox_key of a_rule
				set a_subject to subject_search of (a_rule & {subject_search:default})
				set a_recipient to recipient_search of (a_rule & {recipient_search:default})
				set a_sender to sender_search of (a_rule & {sender_search:default})
				
				-- This is the best way to get a nested mailbox
				set target_mailbox to (get 1st mailbox in account a_account whose name is a_mailbox_name)
				
				-- check the subject
				if subject_line contains a_subject then
					move the_message to target_mailbox
					exit repeat
				end if
				
				if sender_line contains a_sender then
					move the_message to target_mailbox
					exit repeat
				end if
				
				-- set recipient_line to to recipients of the_message as string
				if recipient_line contains a_recipient then
					move the_message to target_mailbox
					exit repeat
				end if
				
			end repeat -- over rules in my_rules
		end tell -- application "Mail"
	end repeat -- over messages in input
end run

Leave a comment