Move Apple Mail to Specified Finder Folder
@Nige_S @ComplexPoint
Risking axes, pitchforks, torches, and howls to kill the beast, here is another blackbox Frankenstein monster, courtesy of our beloved creator and rapist of small children and animals, ChatGPT, for your egg and rotten vegetable throwing pleasure.
But seriously, I would like your critical eye to see if you can optimize this AppleScript code as there is a 1-2 second delay when the script runs. I also have a parallel set of macros that opens the Finder location so I can watch and confirm the mail item shows up. At some point when I fully trust the script, I’ll simplify this by adding an action to delete the selected mail item and just move to the next message.
The script takes the selected Mail message and (I guess) moves/creates a copy in the specified Finder folder. There is the location of the Finder folder that needs to be specified for each instance of the script and three other parameters that need to be updated in the script each time a new folder is selected within a new script.
Doing this via AppleScript is a big upgrade from using the UI scripting I had in place before getting this script to work.
It took around 15 iterations to get it to work and sanitize the file names, ensure a unique file name, and handle duplicates.
All your input and comments are appreciated.
Note about how the script shows up here:
I did put ``AppleScript before and ``` after (three ticks before doesn't show up so I deleted one) the script per Using the Keyboard Maestro Forum but the script still comes up without the indentations and with spaces between each line. The code is copy/pasted from Script Debugger.
AppleScript ( expand / collapse )
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
tell application "Mail"
set selectedMessages to selection
if selectedMessages is {} then
display dialog "No email selected. Please select one or more emails and try again." buttons {"OK"} default button "OK"
return
end if
-- Full path to the target folder
set FolderDT to "/Users/bernshanfield2/Desktop/" -- Absolute full path
-- Ensure the folder exists
do shell script "mkdir -p " & quoted form of FolderDT
-- Process each selected email
repeat with msg in selectedMessages
try
-- Retrieve the email subject
set messageSubject to subject of msg
if messageSubject is "" then
set messageSubject to "Untitled Email"
end if
-- Sanitize the subject to create a valid filename
set safeSubject to my makeSafeFileName(messageSubject)
set filePath to FolderDT & safeSubject & ".eml"
-- Ensure unique filename
set uniqueFilePath to my makeUniqueFilePath(filePath)
-- Get the raw source of the email
set rawSource to source of msg
if rawSource is missing value then
error "The email source could not be retrieved."
end if
-- Write the email source to the file
set fileRef to open for access (POSIX file uniqueFilePath as rich text) with write permission
try
write rawSource to fileRef
on error errMsg
close access fileRef
error errMsg
end try
close access fileRef
on error errMsg
-- Handle any errors during the selection or writing process
display dialog "Error saving email: " & safeSubject & ". Error: " & errMsg buttons {"OK"} default button "OK"
end try
end repeat
end tell
-- Function to sanitize the subject for use in file names
on makeSafeFileName(inputString)
set forbiddenCharacters to ":/\\?%*|\"<>"
set cleanedString to inputString
-- Replace forbidden characters with underscores
repeat with char in forbiddenCharacters
set AppleScript's text item delimiters to char
set cleanedString to text items of cleanedString
set AppleScript's text item delimiters to "_"
set cleanedString to cleanedString as string
end repeat
-- Replace emojis and other non-standard characters with an underscore
set AppleScript's text item delimiters to ""
set cleanedString to my replaceNonStandardChars(cleanedString)
return cleanedString
end makeSafeFileName
-- Function to replace non-standard characters (like emojis) with underscores
on replaceNonStandardChars(inputString)
set safeString to inputString
-- Define a list of common non-standard characters (including emojis)
set nonStandardChars to {"💡", "★", "❤", "☺", "😊", "🎉", "🔔"} -- Add other emojis as needed
repeat with char in nonStandardChars
set safeString to my replaceText(char, "_", safeString)
end repeat
return safeString
end replaceNonStandardChars
-- Function to replace text in a string
on replaceText(findString, replaceString, inputString)
set {oldDelims, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ""}
set AppleScript's text item delimiters to findString
set inputString to text items of inputString
set AppleScript's text item delimiters to replaceString
set inputString to inputString as string
set AppleScript's text item delimiters to oldDelims
return inputString
end replaceText
-- Function to ensure the file has a unique name
on makeUniqueFilePath(originalPath)
set uniquePath to originalPath
set fileCounter to 1
set baseName to do shell script "basename " & quoted form of originalPath & " .eml"
set dirPath to do shell script "dirname " & quoted form of originalPath
-- Check for file existence and append a counter if necessary
repeat while (do shell script "test -e " & quoted form of uniquePath & "; echo $?") is "0"
set uniquePath to dirPath & "/" & baseName & "_" & fileCounter & ".eml"
set fileCounter to fileCounter + 1
end repeat
return uniquePath
end makeUniqueFilePath
Here is the simple Execute script file macro to point to each new script needed for each Finder file location:
And this is the UI in Mail: