My small contribution to the ongoing struggle of Apple Mail archiving. I put this together because my wife’s mailbox recently passed 130,000 messages.
See script comments for details.
(*
This script creates a folder called "saved-email" in Documents and saves each message in its own folder, also saving attachments if any. Message folders & files are named with the sender, subject, and UID of the message to prevent duplication or overwriting. The script also sets the timestamp of each saved message to its date sent, for easy chronological sorting & searching.
Select some subset of old messages in the Mail app and run the script. It works pretty well if you do a couple thousand messages at a time.
This script includes various chunks of other people's scripts that I found here and there. Much gratitude to these valiant partners in the struggle.
*)
tell application "Finder"
do shell script "mkdir -p ~/Documents/saved-email"
set path_to_docs to ((path to documents folder) & "saved-email:") as string
end tell
tell application "Mail"
set selected_messages to selection -- might crash if you select more than a couple of thousand messages at a time!
repeat with this_message in selected_messages -- loop thru all selected messages
set the_mailbox to (mailbox of this_message)
set the_account to (account of the_mailbox)
set msg_sender to (extract name from (sender of this_message))
if msg_sender = "" then set msg_sender to (extract address from (sender of this_message))
set msg_text to content of this_message -- retrieve message body
set msg_subject to (subject of this_message) as Unicode text
set msg_date to (date received of this_message)
set msg_id to id of this_message as string
tell current application
do shell script ("echo " & quoted form of (msg_sender & "-" & (msg_subject & "-" & msg_id)) & " > /tmp/scratch.txt") -- dump message info to a temp file
set msg_save_name to (do shell script ("cat /private/tmp/scratch.txt | sed -r 's/re://g ; s/[^[:alnum:]-]/-/g ; s/-+/-/g ; s/^-//g' ")) -- clean up message names
do shell script ("mkdir -p ~/Documents/saved-email/" & msg_save_name) -- make sure folder exists
set msg_save_folder to (path_to_docs & msg_save_name) as alias
do shell script ("touch " & (POSIX path of alias (path_to_docs & msg_save_name) & "/" & msg_save_name & ".txt")) -- create file for writing
set msg_save_file to ((msg_save_folder as string) & msg_save_name & ".txt" as string) as alias
set msg_save_file_id to open for access file msg_save_file with write permission -- open the_ new file for writing
write msg_text to msg_save_file_id -- write the_ body text of the_ current email into the_ new file
close access msg_save_file_id -- close the_ file
end tell
if (count mail attachments of this_message) > 0 then
repeat with the_attachment in (mail attachments of this_message)
set the_attachmentfilename to (((msg_save_folder as string) & the_attachment's name))
save the_attachment in alias the_attachmentfilename -- saves the_ attachment
end repeat
end if
tell application "Finder"
set msg_save_folder's modification date to msg_date
set (entire contents of msg_save_folder)'s modification date to msg_date
end tell
delete this_message -- moves message to Trash mailbox. You'll still have to empty the Trash manually if you have that preference set.
end repeat
end tell