In the article Exporting emails from Mail I used 3 different methods to export emails out of Mail:

  • Export the emails to mbox.
  • Make a copy of the emails.
  • Drag the emails to the Finder.

Today I'm going to use AppleScript to also export the emails. As always I start with a simple script and make that more complex.

One of the criteria for evaluating the different methods for exporting was speed. Whatever I read about Monterey being faster with AppleScript this is not true for Mail. Any AppleScript is dog slow in Mail. For testing I'm going to start with the selection of emails and not a complete mailbox.

In an application I can have lots of options like for creating PDFs in Mail Archiver:

Options for creating PDFs in Mail Archiver

I can try to do similar options in AppleScript. But there the code gets unwieldy pretty quickly.

The tasks for exporting emails from Mail

Here is what I need to do:

  1. Get some emails. I'll start with the selected emails.
  2. Do a loop with the emails I have.
  3. Get some data out of an email.
  4. Prepare the data for writing to a file.
  5. Create a file for writing.
  6. Write the data to a file.

I will now go over every step.

Get some emails to export

As mentioned above AppleScript for Mail is slow. It's not fun to export thousands of emails. Therefore I'm going to start with the selection and will select about 6-10 emails for testing:
   
set SelectedMessages to (get selection)
   
if SelectedMessages = {} then
       
display dialog "Please select an email first!"
       
return
   
end if
   

Doing a loop with the emails

Doing the loop is easy:
   
repeat with theMessage in SelectedMessages

    -- do something with the email theMessage        
   
end repeat
   

Get some data out of an email

What data do I need from the email? For starting out I need the subject of the email because that is going to be the filename. Then I need the source for the content of the email:
       
set theSubject to subject of theMessage
       
set theSource to source of theMessage as Unicode text

Because I want to get all special characters of the emails I use "as Unicode text".
       

Prepare the data for writing

Subjects can contain any character. However, macOS doesn't allow the ":" in a filename. Therefore, the ":" character needs to be replaced:
       
set theSubject to my replace_chars(theSubject, ":", "_")     

I have used the function replace_chars before so I'll only post it below.   

Create a file for writing

For testing I'll use the desktop. But I could easily exchange the folder with another one or use a folder selection dialog. And then I make a file in the folder with the name of subject + file ending "eml":
       
set this_file to (((path to desktop folderas string) & theSubject & ".eml")
       

Write the data to a file

The final step is to write the data to the file:

 my write_to_file(theSourcethis_filetrue)

Like the replace_chars function I've used write_to_file before.

Full script so far

Here is what I have done so far with the 2 helper functions for replacing text and writing data to a file:

tell application "Mail"

   
--check if there is an email selected
   
set SelectedMessages to (get selection)
   
if SelectedMessages = {} then
       
display dialog "Please select an email first!"
       
return
   
end if

   
repeat with theMessage in SelectedMessages

       
--get basic data
       
set theSubject to subject of theMessage
       
set theSource to source of theMessage as Unicode text

       
--prepare data for writing
       
set theSubject to my replace_chars(theSubject, ":", "_")

       
--use file on desktop
       
set this_file to (((path to desktop folderas string) & theSubject & ".eml")

       
--write data to file
       
my write_to_file(theSourcethis_filetrue)
   
end repeat

end tell

--routine for writing data to file
on write_to_file(this_datatarget_fileappend_data)
   
try
       
set the target_file to the target_file as string
       
set the open_target_file to open for access file target_file with write permission
       
if append_data is false then set eof of the open_target_file to 0
       
write this_data to the open_target_file as «class utf8» starting at eof
       
close access the open_target_file
       
return true
   
on error
       
try
           
close access file target_file
       
end try
       
return false
   
end try
end write_to_file

--replace characters in text
on replace_chars(this_textsearch_stringreplacement_string)
   
set AppleScript's text item delimiters to the search_string
   
set the item_list to every text item of this_text
   
set AppleScript's text item delimiters to the replacement_string
   
set this_text to the item_list as string
   
set AppleScript's text item delimiters to ""
   
return this_text
end replace_chars

Now I have a good framework to do improvements.

Testing the export

For parsing emails in Mail Archiver I divide emails into 3 categories: html, spam and other emails. Html usually is fine. For Mail Archiver the spam emails are important because they may try to break how emails work. Here I don't care about spam emails. That leaves me the personal emails for testing.

Emails have information in the header on how to interpret the email. When the information is missing then the result may be character salad which is called mojibake. I found one problematic email:

Original in Mail:Original email in Mail

Exported email which I double-clicked to open it in Mail:

Email with MojibakeLooking at the email I can see that some header information is missing so it's likely a Windows email. The raw data in Mail also shows the mojibake. Mail fixes the mojibake when viewing or exporting the email. But the AppleScript source does not.

Verdict

For selected emails the export from Mail into eml files works fine. The AppleScript gives me a nice control over the export. Except the one single email with the mojibake the export went fine.

However, in AppleScript I can do way more than I what have done above.

  1. When exporting lots of emails I usually want to have the date in front of the subject.
  2. Emails with super long subject have the same problem as when dragging them to the Finder: writing fails. I need to find a way to make the filename shorter.
  3. From the article on getting mailboxes for Mail I know how the name of a mailbox looks like. The last task is to export one large mailbox.

I'm going to tackle the three features in the next article.