Today I needed a reliable way to extract eMail addresses from the content of eMail messages in Apple Mail. After fiddling around with AppleScript’s text item delimiters first, I finally came up with a robust Python helper script utilizing regular expressions.
To share this solution with you, I have created a sample script. The procedure is as follows:
The AppleScript iterates over selected eMail messages in Apple Mail and writes each message content to a temporary file. Then the Python script searches the temporary file for contained eMail addresses and prints them back to AppleScript. Fairly simple ![]()
If you want to take a look at the sample script, please feel free to download it right here:
Extract eMail addresses (ca. 36.7 KB)
It was successfully tested on Intel and PowerPC based Macs running Mac OS X 10.5.3 & Apple Mail 3.3.
The Python script is based on a recipe found on the excellent ASPN: Python Cookbook website.
Important: Opening and saving the below script code in Script Editor won’t result in a usable AppleScript! That is because the AppleScript internally relies on a Python script, which is located inside its Script bundle. Therefor please download the complete script here.
-- created: 17.06.2008
-- This AppleScript iterates over selected eMail messages in Apple Mail
-- and tries to extract eMail addresses from the message content.
-- The AppleScript writes the message content to a temporary file, then a Python
-- script parses the temporary file for eMail addresses and prints them back
-- to the calling AppleScript. Finally the temporary file is removed.
property mytitle : "Extract eMail addresses"
-- I am called when the user opens the script with a double-click
on run
	try
		-- maybe the script was started without Apple Mail being running?
		if not my appisrunning("Mail") then
			set infomsg to "Sorry, Apple Mail is currently not running." & return & return & "Please open Apple Mail, select appropriate eMail messages and try again."
			my dspinfomsg(infomsg)
			return
		end if
		-- getting the selected eMail messages in Apple Mail
		tell application "Mail"
			set msgs to selection as list
		end tell
		-- did the user select any eMail messages?
		if msgs is {} then
			set errmsg to "You did not select any eMail messages in Apple Mail."
			my dsperrmsg(errmsg, "--")
			return
		end if
		-- processing the selected eMail messages
		repeat with msg in msgs
			tell application "Mail"
				set msgsubject to subject of msg
			end tell
			-- extracting the eMail addresses from the message content
			set mailaddrs to my extrmailaddrs(msg)
			-- no eMail addresses found...
			if mailaddrs is {} then
				
				set errmsg to "We could not detect eMail addresses in the content of the eMail message with the subject:" & return & return & msgsubject & return
				my dsperrmsg(errmsg, "--")
			else
				-- displaying the found eMail addresses
				choose from list mailaddrs with prompt "We found these eMail addresses in the eMail message content:" & return & return & "(" & msgsubject & ")" with title mytitle with empty selection allowed
			end if
		end repeat
	on error errmsg number errnum
		my dsperrmsg(errmsg, errnum)
	end try
end run
-- I am returning a list of eMail addresses embedded in the message content
-- If no addresses are found, I return an empty list
on extrmailaddrs(msg)
	-- getting the content of the eMail message
	tell application "Mail"
		set msgcont to content of msg
	end tell
	-- writing the content of the eMail message to a temporary file
	set tmpfilepath to my TmpFile's newpath()
	my writetofile(msgcont, tmpfilepath)
	-- extracting the eMail addresses from the temporary file using a Python script
	set pyscriptpath to POSIX path of (((path to me) as Unicode text) & "Contents:Resources:findmails.py")
	set command to "/usr/bin/python/ " & quoted form of pyscriptpath & " " & quoted form of (POSIX path of tmpfilepath)
	set mailaddrs to paragraphs of (do shell script command)
	-- removing the temporary file
	my TmpFile's remove()
	return mailaddrs
end extrmailaddrs
-- I am indicating if a given application is currently running or not
-- only the (full) application name must be given, e.g. "Address Book"
on appisrunning(appname)
	tell application "System Events"
		set processnames to name of every process
	end tell
	if appname is in processnames then
		return true
	else
		return false
	end if
end appisrunning
-- I am displaying error messages
on dsperrmsg(errmsg, errnum)
	tell me
		activate
		display dialog "Sorry, an error occured:" & return & return & errmsg & " (" & errnum & ")" buttons {"Never mind"} default button 1 with icon stop with title mytitle
	end tell
end dsperrmsg
-- I am displaying info messages
on dspinfomsg(infomsg)
	tell me
		activate
		display dialog infomsg buttons {"OK"} default button 1 with icon note with title mytitle
	end tell
end dspinfomsg
-- I am writing given content to a given file using UTF-8 text encoding
on writetofile(cont, filepath)
	try
		set openfile to open for access filepath with write permission
		set eof of openfile to 0
		set BOM_UTF8 to ((ASCII character 239) & (ASCII character 187) & (ASCII character 191))
		write (cont as «class utf8») to openfile
		close access openfile
		return true
	on error
		try
			close access openfile
		end try
		return false
	end try
end writetofile
-- script object to manage a temporary file
script TmpFile
	property filepath : missing value
	
	-- I am creating a new, not yet existing file path in the temp folder
	on newpath()
		set tmpfolderpath to (path to temporary items folder from user domain) as Unicode text
		repeat
			set rndnum to random number from 1000 to 99999
			set tmpfilepath to (tmpfolderpath & (rndnum as Unicode text) & ".tmp")
			try
				set tmpfilepath to tmpfilepath as alias
			on error
				set filepath to tmpfilepath
				exit repeat
			end try
		end repeat
		return filepath
	end newpath
	
	-- I am returning the file path of the temporary file 
	on getpath()
		return filepath
	end getpath
	
	-- I am trying to delete the temporary file using the Finder
	on remove()
		try
			set command to "rm " & quoted form of (POSIX path of filepath)
			do shell script command
		end try
	end remove
end script