I'm very very new to KM so sorry if I'm overlooking something.
I'm trying to create a KM macro that when I select a Status Menu item it will save all attachment from selected emails in Apple Mail to a specific folder. This is for an school assigment where students will send me a PDF in the mail that I have to archive to a folder. To prevent myself from having to do this multiple times I'd like to automate.
What I've tried so far is:
Triggered by any of the following:
The Status Menu
Will execute the following actions:
Activate Mail
Select Menu Item in Mail
Select: File ⇢ Save Attachments…
Stop macro if menu cannot be selected
Where I'm stuck is how I can tell the dialogue that opens that it has to select a specific folder. I don't want to have to interact with the save dialogue.
So I'm guessing that there is a better way, maybe where I don't choose a menu Item.
Is there a feature in KM that can read attachments from selected messages and copy them to a certain path?
Hopefully someone can point me in the right direction to better start understanding KM.
There is an extremely useful feature of the Open/Save dialog that allows it to be easily automated.
In the dialog, press Command-Shift-G. You can now enter the full path of the file you wish to select/save.
This is easily controlled with Keyboard Maestro, since you can Type a Keystroke: Command-Shift-G, followed by Insert Text by Pasting or Typing the desired path, followed by Type a Keystroke: Return, and perhaps another Return to complete the dialog. You may need Pause actions to ensure any windows are opened or closed before the next action proceeds.
A User-Setting for the Save Destination Path was added to the macro.
Hey Jan,
This job is AppleScriptable if you're using Apple Mail.
Save the script text with the Applescript Editor on your system.
Put the script somewhere convenient.
Run the script file with an Execute AppleScript Keyboard Maestro action.
This would be easy to customize to include the name and/or email address of the student as part of the saved-folder-name, or you could have a dated folder, etc.
----------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2014/05/30 19:41
# dMod: 2014/09/08 16:38
# Appl: Mail.app
# Task: Save email attachments to a named folder.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Mail, @Save, @Attachments
----------------------------------------------------------------
--» MAIN
----------------------------------------------------------------
try
set attachmentList to {}
set savePathHFS to ((path to downloads folder as text) & "Mail_Attachments_Saved:")
tell application "Mail"
set selected_messages to selection
if length of selected_messages > 0 then
repeat with _message in selected_messages
set msgAttachmentList to every mail attachment of _message
set attachmentList to attachmentList & msgAttachmentList
end repeat
if attachmentList ≠ {} then
# Test for existence of savePathHFS and create it if necessary.
try
alias savePathHFS
on error
do shell script "mkdir -p " & quoted form of (POSIX path of savePathHFS)
end try
repeat with _attachment in attachmentList
set _name to name of _attachment
set saveFilePath to savePathHFS & _name
if my exTant(saveFilePath) = true then
error "A file already exists here!" & linefeed & linefeed & saveFilePath
end if
save _attachment in saveFilePath
end repeat
else
error "No attachments found!"
end if
end if
end tell
on error e number n
set e to e & return & return & "Num: " & n
beep
tell current application to set dDlg to display dialog e with title "ERROR!" buttons {"Cancel", "Copy", "OK"} default button "OK"
if button returned of dDlg = "Copy" then set the clipboard to e
end try
----------------------------------------------------------------
--» HANLDERS
----------------------------------------------------------------
on exTant(_path) # Takes an HFS, Posix, or ~/Posix path as input.
local _path
try
if _path starts with "~/" then
set _path to (POSIX path of (path to home folder as text)) & text 3 thru -1 of _path
end if
if _path starts with "/" then
alias POSIX file _path
else if _path contains ":" then
alias _path
end if
return true
on error
return false
end try
end exTant
----------------------------------------------------------------
That is terrific. I’m going to try this out and report back.
Regarding the solution Peter offered, that didn’t work for me. Strangely enough it filled the path in the filename section, the shortcut didn’t open the mentioned window automatically. When I tried manually it did. I fiddled with pauzes (even long ones) but also didn’t get is to work. Due to further lack of time I left it for now but the concept was clear so I learned a lot about open/save dialogues
Also the fact that I’m on OS X 10.10 Dev 7 and use Default Folder X might cause problems.
Whenever you brute-force the UI there are sticky wickets.
For this particular job AppleScript is the best choice.
Take note though that Default Folder is also scriptable, so with it installed you can change a dialog location via AppleScript more transparently than you can with Keyboard Maestro.
Thanks again for your help and posting your script. I report back here so that others can learn from this too... if needed
Your script works as described, created a folder when it didn’t exist and copied the files. At the end I did get an error message though:
The files I was saving where definitely not there. So I’m not sure what caused this.
My next quest was to alter the script a bit to be able to set another path.
I changed:
set savePathHFS to ((path to downloads folder as text) & "Mail_Attachments_Saved:")
to:
set savePathHFS to ("Macintosh HD:Users:username:Box Sync:testfolder:" & "Mail_Attachments_Saved:")
This worked fine.
My next effort I didn’t succeed in.
I thought it would be great if I could use a KM Action to set the Applescript variable ‘savePathHFS’.
I deleted the line
set savePathHFS to ((path to downloads folder as text) & "Mail_Attachments_Saved:")
in your script and added a
Set Variable ‘savePathHFS’ to Text
Macintosh HD:Users:username:Box Sync:testfolder:" & "Mail_Attachments_Saved:
Action before your script.
But helas, that didn't work. Maybe I didn't set the variable well.
Any ideas are welcome.
If not, the other way works, but I thought it would be great if you could use one applescript and duplicate the KM Macro, and change the Path in the variable for each specific ocassion instead of creating multiple AppleScript.
I hope my report is clear enough, if not let me know.
Have been using this script with success but today I started getting the following error. Can anyone help me out on this?
“osascript: OpenScripting.framework - scripting addition “/Library/ScriptingAdditions/Adobe Unit Types.osax” cannot be used with the current OS because it has no OSAXHandlers entry in its Info.plist.”
I just came across this as well. I know @ccstone hasn’t been around as much lately, but his expertise (in this case, expertise from several years ago) continues to benefit us even now.
Thanks for your contribution: your macro works like a charm on the internal drive; but when running it on any external drive it gives an error message (-10000), i first set permissions of every user to 'read and write' then tried to ignore permissions, checked them against the internal ssd, wich seems to have more strict permissions.
The error is engaged by the script, not the km macro itself, but i just can't find the culprit.
Any suggestion is much appreciated