I have a series of blog posts to save attachments from Mail:
- Save attachments with AppleScript for Mail
- Unzipping attachments for the Alfred workflow to save attachments from Mail into a folder
Today I'm going to change the script because I now have some slight changes in the data.
Changes to website security leads to problems with the Save Attachments script
Sometimes actions have unintended consequences. After improving the security for sending emails I had a problem: both Mail Archiver and the support form at Moth Software were sending emails as coming from the user who opened the ticket. With the new security this wasn't allowed anymore. Instead I had to use one of the sub accounts for Moth Software to send the email to the ticket system.
Every email from the ticket system to my Inbox now came from the Moth Software sub account and not the user email. The unintended consequence was that my AppleScript to save the attachments ended up in a folder with the same name and not the name and email of the user. However, the Reply-To still was allowed to show the original user.
The header of a normal email to me looks like this:
To: mail @ beatrixwillius.de From: [email protected]
The email from Mail Archiver now looks like this:
From: notif. @ mothsoftware.com Subject: Error Report X-Mailer: Moth Software Reply-To: mail @ beatrixwillius.de
Because I didn't want to change the folder name manually I had to rework the AppleScript of my Alfred workflow.
Getting the Reply-To
For Mail Archiver parsing the header takes care of all eventualities. For AppleScript I can do a much easier and simpler solution.
The From is accessible in AppleScript for Mail as sender of the message. The Reply-to address is not directly accessible. To get the Reply-to I need the full header. As always there are multiple ways to solve the problem. For instance, I could split the lines of the header and then find the one starting with Reply-To.
Instead I've used a shellscript with the shell variation of regex called grep. I could have used the regex in Foundation. But here I just want a really simple regex to find the Reply-to of the header. I also don't need to deal with Unicode here.
I'll only discuss the relevant changes for the "save attachments" Applescript. I get the selected emails. When looping over the selection I get the sender and the header.
Regex or pattern matching is a fascinating way to spend time if you are a developer. We don't call this "write only" code for fun. Fortunately, I only need a very simple regex:
set replyToHeaderRegex to "Reply-To:.*"
The regex has 2 parts. The first part is Reply-To: which is the string literal I'm searching for. The .* (dot star) is the second part. The dot means any character and the star means any number of characters. So .* means anything the comes after the Reply-To:. The regex only searches in individual lines so that I don't need to search for end of line characters.
After setting up the regex the next line uses the regex and gives me back the part of the line that comes after Reply-To:
set Originator to do shell script "echo " & quotedHeaders & " | grep -o " & quoted form of replyToHeaderRegex
set AppleScript's text item delimiters to "Reply-To: "
set Originator to text item 2 of Originator
if Originator = "" then
set Originator to sender of theMessage
end if
return Originator
First I need to use the quoted form of the header. This ensures that special characters or spaces within a string are properly escaped or quoted.
The next step is to use grep on the pattern I defined in the line above. grep is the shell equivalent of regex. The Reply-To: is removed with the text item delimiter.
If Reply-To is missing then I use the Sender of the message as before. This now gives me the full changes I need for my script to save the attachments:
tell application "Mail"
--get the selected emails
set selectedMessages to selection
--loop over the messages to get and save the attachments
try
repeat with theMessage in selectedMessages
set theHeaders to all headers of theMessage
set replyToHeaderRegex to "Reply-To:.*"
set quotedHeaders to quoted form of theHeaders
set Originator to do shell script "echo " & quotedHeaders & " | grep -o " & quoted form of replyToHeaderRegex
set AppleScript's text item delimiters to "Reply-To: "
set Originator to text item 2 of Originator
if Originator = "" then
set Originator to sender of theMessage
end if
return Originator
end repeat
on error errMsg number errNr
display dialog "Error: " & errMsg & " Nr.: " & errNr
end try
end tell