This week I got an eMail message containing important PDF files, but somehow Apple Mail was not able to display the whole thing including the attachments:
What to do? I really needed the attached PDF documents… First I tried to access the attachments with AppleScript (get mail attachments of item 1 of (selection as list)), but got an error message in return: AppleEvent handler failed.
Then - being an AppleScript & Python nut - I found an excellent script by Matthew Cowles that extracts attachments from eMail messages. And so I created an AppleScript that writes the raw source of a selected eMail message in Apple Mail to a temporary file and then processes this temporary file with a Python script similar to Matthew’s to save the extracted attachments to a chosen folder.
It worked like a charm on my Mac! I successfully extracted the attachments and the text. And if you ever encounter the same problem of a corrupted eMail message in Apple Mail, then I invite you to download the script and test it:
I used the script successfully on Mac OS X 10.5.5, but I guess it also runs without problems on Mac OS X 10.4.
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.
property mytitle : "mimex"
on run
try
-- getting the selected eMail message in Apple Mail
tell application "Mail"
set selmsgs to selection as list
end tell
if selmsgs is {} then
set errmsg to "You did not select a message in Apple Mail."
error errmsg
return
else if length of selmsgs is greater than 1 then
set errmsg to "You selected more than one message in Apple Mail."
error errmsg
return
end if
-- we are interested in the raw source of the eMail message to process it with Python...
tell application "Mail"
set msg to item 1 of selmsgs
set msgcont to source of msg
end tell
-- saving the eMail message source in a temporary file
set tmpfilepath to my gettmpfilepath("txt")
try
set tmpfile to open for access tmpfilepath with write permission
write msgcont to tmpfile
close access tmpfile
on error
close access tmpfile
set errmsg to "Writing the source of the eMail message to a temporary file failed."
error errmsg
return
end try
-- where should the extracted attachments be saved?
set destfolderpath to my getdestfolderpath()
if destfolderpath is missing value then
return
end if
-- processing the saved eMail message source with a Python tool which
-- (hopefully) extracts the attachments to the chosen folder path
set pyscriptpath to (path to me as Unicode text) & "Contents:Resources:mimex.py"
-- set pyscriptpath to (path to desktop as Unicode text) & "mimex.py"
set command to "/usr/bin/python " & quoted form of POSIX path of pyscriptpath & " " & quoted form of (POSIX path of tmpfilepath) & " " & quoted form of POSIX path of destfolderpath
set output to do shell script command
-- removing the temporary file
set command to "rm " & quoted form of POSIX path of tmpfilepath
do shell script command
if output is not "" then
error output
end if
on error errmsg number errnum
tell me
activate
display dialog "Sorry, an error occured:" & return & return & errmsg & return & "(" & errnum & ")" buttons {"OK"} default button 1 with icon stop giving up after 30 with title mytitle
end tell
end try
end run
-- I return a file path to a not yet existing temporary file
on gettmpfilepath(suffix)
set tmpfolderpath to (path to temporary items folder from user domain) as Unicode text
repeat
set randnum to random number from 10000 to 99999
set tmpfilepath to tmpfolderpath & randnum & "." & suffix
try
set tmpfilealias to tmpfilepath as alias
on error
exit repeat
end try
end repeat
return tmpfilepath
end gettmpfilepath
-- I am asking the user to specify a destination folder to save the attachements
-- If the user cancels, I return «missing value»
on getdestfolderpath()
try
set destfolderpath to choose folder with prompt "Please choose a folder to save the attachments:" without invisibles, multiple selections allowed and showing package contents
on error
return missing value
end try
return destfolderpath as Unicode text
end getdestfolderpath