I made several attempts but I never got a rule able to run an applescript.
Bingo. Today I’m more lucky. I was able to get a script running.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) vendredi 13 janvier 2017 11:09:10
I made several attempts but I never got a rule able to run an applescript.
Bingo. Today I’m more lucky. I was able to get a script running.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) vendredi 13 janvier 2017 11:09:10
Here is where I am.
I edited the script a bit because the compiler refused to compile the instruction
set attachmentsFolder to (path to documents folder as text) & "4attachments:"
I replaced tell application “System Events” by tell application “Finder” because with the original instruction the existing folder was not seen.
As you may see, I added several say instructions to trace the execution.
At this time execution reach point 7 but fail to execute the instruction
set theAttachments to theMessage's mail attachments
Here is the script called by the rule :
using terms from application "Mail"
on perform mail action with messages theMessages for rule SAVE_ATTACHMENT_SIERRA
say "point 1"
tell application "Finder"
tell me to say "point 2"
tell me to set attachmentsFolder to (path to documents folder as text) & "4attachments:"
tell me to say "point 3"
if not (exists folder attachmentsFolder) then
tell me to say "the folder " & attachmentsFolder & " doesn't exist!"
error "the folder " & attachmentsFolder & " doesn't exist!"
end if
tell me to say "point 4"
end tell
say "point 5"
tell application "Mail"
set selectedMessages to theMessages
tell me to say "point 6"
repeat with theMessage in selectedMessages
tell me to say "point 7"
set theAttachments to theMessage's mail attachments
tell me to say "point 8"
tell me to say (get count of theAttachments)
repeat with theAttachment in theAttachments
tell me to say "point 9"
# CAUTION: if the Hfs name of an attachment contain a slash, Mail replace it by a colon
try
set originalName to name of theAttachment
tell me to say "point 10"
tell me to say originalName
if originalName contains ":" then
set savePath to my remplace(originalName, ":", "/")
end if
set savePath to attachmentsFolder & originalName
tell me to say "point 11"
tell me to say savePath
tell me to close access (open for access savePath) # THE TIP
tell me to say "point 12"
# As this script is a workaround for Sierra 10.12.2/3, «class furl» is available
(*
set POSIXPath to POSIX path of savePath
tell me to set savePath to POSIX file POSIXPath
*)
tell me to set savePath to savePath as «class furl»
tell me to say "point 13"
save theAttachment in savePath
tell me to say "point 14"
end try
end repeat # theAttachment
end repeat # theMessage
end tell # Mail
end perform mail action with messages
end using terms from
#=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
local oTIDs, l
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d1}
set l to text items of t
set AppleScript's text item delimiters to d2
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end remplace
#=====
and here is the script used to mimic the one above.
tell application "Mail"
activate
set theMessages to (get the selection)
end tell
say "point 1"
tell application "Finder"
tell me to say "point 2"
tell me to set attachmentsFolder to (path to documents folder as text) & "4attachments:"
tell me to say "point 3"
if not (exists folder attachmentsFolder) then
tell me to say "the folder " & attachmentsFolder & " doesn't exist!"
error "the folder " & attachmentsFolder & " doesn't exist!"
end if
tell me to say "point 4"
end tell
say "point 5"
tell application "Mail"
set selectedMessages to theMessages
tell me to say "point 6"
repeat with theMessage in selectedMessages
tell me to say "point 7"
set theAttachments to theMessage's mail attachments
tell me to say "point 8"
tell me to say (get count of theAttachments) --> say 1
repeat with theAttachment in theAttachments
tell me to say "point 9"
# CAUTION: if the Hfs name of an attachment contain a slash, Mail replace it by a colon
try
set originalName to name of theAttachment
tell me to say "point 10"
tell me to say originalName --> say "bouquins.rtf"
if originalName contains ":" then
set savePath to my remplace(originalName, ":", "/")
end if
set savePath to attachmentsFolder & originalName
tell me to say "point 11"
tell me to say savePath --> say "SSD 500:Users:myHome:Documents:4attachments:bouquins.rtf"
tell me to close access (open for access savePath) # THE TIP
tell me to say "point 12"
# As this script is a workaround for Sierra 10.12.2/3, «class furl» is available
(*
set POSIXPath to POSIX path of savePath
tell me to set savePath to POSIX file POSIXPath
*)
tell me to set savePath to savePath as «class furl»
tell me to say "point 13"
save theAttachment in savePath
tell me to say "point 14"
end try
end repeat # theAttachment
end repeat # theMessage
end tell # Mail
#=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
local oTIDs, l
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d1}
set l to text items of t
set AppleScript's text item delimiters to d2
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end remplace
#=====
This late version behaves flawlessly so I’m hitting a wall : why is the instruction
set theAttachments to theMessage's mail attachments
failing when the script is triggered by the rule ?
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) vendredi 13 janvier 2017 12:47:45
I found this info about having Applescript execute properly under Mail rules :
The article is from 2013, so its way back under earlier OS X versions I guess. But the writer has a point, in the middle part… Quoting:
“But I have found that the most problems appear when running scripts are combined in a rule that also moves the message to another mailbox. It is almost like the moving will appear asynchronous such that the script fails to find it and therefore cannot parse the necessary info it needs to run right.”
–
I removed all my other rule actions (mark email as read and move email to a different email-folder). Then it actually seems to work. Leaving just the “Run applescript” action.
I can live with marking the emails as read manually myself, or if it would be possible to include that in the applescript it self… at some point :
set read status of selectedMessages to true
Niklas
Thanks but the script which I am testing is the only item triggered by the rule. This one moves nothing, changes no attribute. It only triggers the script.
I studied an other track to do the job but it failed.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) vendredi 13 janvier 2017 18:26:30
With which system were you able - if you ever did - to save the attachments with a script triggered by a rule ?
As it fails with 10.12.2, I tried with 10.12.1 : fails too.
I tried with 10.11.5 : fails too.
It fails always upon the instruction : set theAttachments to theMessage’s mail attachments.
As I was tired to hit a wall I decided to try an other scheme.
It rely upon three files.
A script attached to a rule which apply no change to the messages
(*
tell application "Mail"
set test_list to selection
tell me to perform mail action with messages (test_list)
end tell
*)
# Entry point used by the Mail rule
using terms from application "Mail"
on perform mail action with messages theMessages --for rule SAVE_ATTACHMENT_SIERRA
tell application "Mail"
set theList to {}
repeat with theMessage in theMessages
set messageID to (get message id of theMessage)
set end of theList to messageID
end repeat
end tell
set theString to my recolle(theList, linefeed)
tell application "Finder"
tell me to set thePath to ((path to desktop) as text) & "messagesIDs_sDIsegassem.txt" # Adjust to fit your needs
end tell
my writeto(thePath, theString, «class utf8», false)
tell application "Finder"
set theApp to open ((path to desktop as text) & "driven.app") as alias # Adjust to fit your needs
end tell
end perform mail action with messages
end using terms from
#=====
on recolle(l, d)
local oTIDs, t
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end recolle
#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeto(targetFile, theData, dataType, apendData)
-- targetFile is the path to the file you want to write
-- theData is the data you want in the file.
-- dataType is the data type of theData and it can be text, list, record etc.
-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
try
set targetFile to targetFile as «class furl»
set openFile to open for access targetFile with write permission
if not apendData then set eof of openFile to 0
write theData to openFile starting at eof as dataType
close access openFile
return true
on error
try
close access targetFile
end try
return false
end try
end writeto
#=====
The script creates the second file which contain the message id of every passed message.
When the 2nd file is written, the script call the 3rd file which is a script saved as an application.
on run
set finalMailBox to "aaa/aac" # Edit to fit your needs
# Builds the path to the text file containing the message IDs.
# It must match the path defined by the script triggered by the rule
set thePath to ((path to desktop) as text) & "messagesIDs_sDIsegassem.txt" #
# Read the message IDs
set theIDs to paragraphs of (read file thePath)
# Build the list of messages
set theMessages to {}
repeat with anID in theIDs
set end of theMessages to my searchMail(anID)
end repeat
tell me to say "point 2"
# Build the path to the folder were attachments must be saved
set attachmentsFolder to (path to documents folder as text) & "4attachments:" # Edit to fit your needs
tell application "Finder" # was System Events
tell me to say "point 3"
if not (exists folder attachmentsFolder) then
tell me
say "point 4"
error "the folder " & attachmentsFolder & " doesn't exist!"
end tell # current application
end if
end tell
tell application "Mail"
tell me to say "point 6"
tell me to say "il y a " & (count theMessages) & " messages"
set pass to 0
repeat with theMessage in theMessages
set pass to pass + 1
tell me to say "point 7 message " & pass
set theAttachments to every mail attachment of theMessage # FAILS when called by a rule
tell me
say "point 8 message " & pass
say (get count of theAttachments) --> say 1
end tell # current application
set attch to 0
repeat with theAttachment in theAttachments
set attch to attch + 1
tell me to say "point 9 message " & pass & " attachment " & attch
# CAUTION: if the Hfs name of an attachment contain a slash, Mail replace it by a colon
try
set originalName to name of theAttachment
tell me
say "point 10 message " & pass & " attachment " & attch
say originalName --> say "bouquins.rtf"
if originalName contains ":" then
set savePath to my remplace(originalName, ":", "/")
end if
set savePath to attachmentsFolder & originalName
say "point 11 message " & pass & " attachment " & attch
--say savePath --> say "SSD 500:Users:myHome:Documents:4attachments:bouquins.rtf"
close access (open for access savePath)
say "point 12 message " & pass & " attachment " & attch
# As this script is a workaround for Sierra 10.12.2/3, «class furl» is available
(*
set POSIXPath to POSIX path of savePath
tell me to set savePath to POSIX file POSIXPath
*)
set savePath to savePath as «class furl»
say "point 13 message " & pass & " attachment " & attch
end tell # current application
save theAttachment in savePath
tell me to say "point 14 message " & pass & " attachment " & attch & " is saved"
end try
end repeat # theAttachment
set read status of theMessage to true
tell me to say "point 15 message " & pass
move theMessage to mailbox "aaa/aac"
tell me to say "point 16 message " & pass
end repeat # theMessage
end tell # Mail
end run
on searchMail(messageID)
tell application "Mail"
repeat with a in accounts
repeat with mb in mailboxes of a
set x to (messages whose message id is messageID) of mb
-- if length of x is greater than 0 then return (item 1 of x)
if (count x) > 0 then return (item 1 of x)
end repeat
end repeat
repeat with mb in mailboxes
set x to (messages whose message id is messageID) of mb
-- if length of x is greater than 0 then return (item 1 of x)
if (count x) > 0 then return (item 1 of x)
end repeat
end tell
end searchMail
This late item will read the text file containing every message id .
It use them to build a list of references to the messages
If a message has attachments they are saved in the dedicated folder
The read status of the message is set to true
The message is moved to the dedicated mailbox.
I know that it’s awful but at least, it does the job.
Of course, if you decide to use the scripts, it would be a good idea to remove the instructions say something which are just useful to trace the script behavior during tests.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) samedi 14 janvier 2017 18:27:02
Im on Sierra 10.12.2 now. And Apple Mail.app version 10.2 (3259).
Im currently able to save the attachments in a folder (dropbox folder if that matters) using a rule that triggers this script :
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
set attachmentsFolder to "Users:niklas:Dropbox:folder1:folder2:"
--set attachmentsFolder to (path to documents folder as text) & "4attachments:"
--set attachmentsFolder to (path to desktop as text) & "4attachments:"
--return attachmentsFolder
tell application "System Events"
if not (exists folder attachmentsFolder) then error "the folder " & attachmentsFolder & " doesn't exist!"
end tell
tell application "Mail"
set theMessages to the selection
set selectedMessages to theMessages
repeat with theMessage in selectedMessages
repeat with theAttachment in theMessage's mail attachments
# CAUTION: if the Hfs name of an attachment contain a slash, Mail replace it by a colon
try
set originalName to name of theAttachment
if originalName contains ":" then
set savePath to my remplace(originalName, ":", "/")
end if
set savePath to attachmentsFolder & originalName
close access (open for access savePath) # THE TIP
# As this script is a workaround for Sierra 10.12.2/3, «class furl» is available
(*
set POSIXPath to POSIX path of savePath
tell me to set savePath to POSIX file POSIXPath
*)
tell me to set savePath to savePath as «class furl»
save theAttachment in savePath
end try
end repeat # theAttachment
end repeat # theMessage
set read status of theMessages to true
end tell # Mail
end perform mail action with messages
end using terms from
#=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
local oTIDs, l
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d1}
set l to text items of t
set AppleScript's text item delimiters to d2
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end remplace
#=====
But it only seems to work when having just one action connected to the Mail Rule, that is “Run Applescript” so Im not able to move the message to a specific email folder or even mark it as read…
(This is just my thoughts, but it appears when adding more actions to the rule in mail, Mail.app sort the actions uncorrectly, i.e moving the first action (that I would like to be) “Run Applescript” to the bottom if I add “Mark email as read” and “Move to different folder”. So thats why Mail.app looses the references to the mail that applescript is supposed to be working with later on… But I don’t know how to confirm that.)
Im too novice with Applescript, been using it for about a month or two, I’ve just googled and picked up bits and pieces from here and there and put together my script But its a lot of fun Maybe there is a way to solve this with the unique message id’s, I wouldn’t know how to do that yet.
Niklas
I will try to run the system in English to see if the oddity striking here is linked to the French localisation.
The problem has nothing common with the inability to write in a custom folder which is solved by the
close access (open for access savePath) # THE TIP instruction.
Here, when the script is triggered by a rule it fails when it reach the instruction :
repeat with theAttachment in theMessage’s mail attachments
It’s to try to see what is failing that I split the instruction in two parts:
set theAttachments to theMessage’s mail attachments
repeat with theAttachment in theAttachments.
When testing in Script Debugger I discovered that repeat with theAttachment in theMessage’s mail attachments has no raw format (chevrons one).
This is why I edited as :
set theAttachments to every attachment of theMessage
which, when I ask for raw syntax appears as :
set theAttachments to every «class atts» of theMessage
Everything behaves well when the script is called by:
tell application "Mail"
set test_list to selection
tell me to perform mail action with messages (test_list)
end tell
When triggered by a rule which does no other task, the script execute the say “point 7” instruction but fails to execute the instruction
set theAttachments to every attachment of theMessage.
The fact that the script fails if you ask the rule to do what you described before isn’t too surprising.
Changing the read status isn’t a problem but when the rule move a message in a mailbox, it seems that the script receive the original location, not the new one.
In the message #16 you may find the instructions to add to your code so that it change the read status and moves the message in a dedicated mailbox.
end repeat # theAttachment # existing instruction
set read status of theMessage to true
-- tell me to say "point 15 message " & pass
move theMessage to mailbox "aaa/aac" # EDIT to fit your needs
-- tell me to say "point 16 message " & pass
end repeat # theMessage # existing instruction
I’m a bit skeptical because the instruction
set attachmentsFolder to “Users:niklas:Dropbox:folder1:folder2:”
doesn’t define a valid path. The name of the volume is missing !
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) samedi 14 janvier 2017 19:27:38
It’s perfectly foolish.
I re-tested with the code borrowed from your late message and the attachment was not moved.
I re-booted in English and the same code behaved flawlessly so I thought that there is a bug dedicated to French localization.
I re-booted in French and to be sure I made an other attempt. This time the attachments were correctly saved.
I must assume that something was odd in a file which was repaired when I ran in English.
I took time to test the script with the added instructions listed before.
It worked flawlessly. Of course you will have to edit the instruction moving to a mailbox because I doubt that “aaa/aac” exists on your machine.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) samedi 14 janvier 2017 20:05:54
At last I found why your script seems to work.
It’s not working upon the list of messages massed by the rule, it’s working upon what is selected in Mail.
tell application "Mail"
set theMessages to the selection # THE INSTRUCTION WHICH FOOLED US
set selectedMessages to theMessages
Remove the instruction grabbing the selection and you will not get the attachments saved.
If we want to save files attached to selected messages, a script triggered by a rule isn’t the good scheme.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) dimanche 15 janvier 2017 17:00:03
I stand corrected.
My script with Mail.app rules does not work - all the time.
It doesn’t save the attachment as its supposed to. Its not stable.
Back to the drawing board
Niklas
The script does its duty when it is called from the Scripts Editor. It fails when it’s called by a Mail’s rule.
It’s not the only one behaving this way.
There is at least one other thread about this kind of problem.
My understanding is that it’s clearly an Apple problem.
The tip :
close access (open for access savePath)
solves only the oddity due to the inability to save in most of the folders.
This time the problem is that when triggered by a rule, Mail fails to execute several actions upon the attached files.
I’m afraid that we will have to live with that for “some” time.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) mercredi 18 janvier 2017 11:30:26
I have solved this problem using an Automator script, running once every night (with the help of iCal / Calendar.app)
Until the guys at Apple fix this issue.
Niklas
With the current version of beta 10.12.4 the tip :
close access (open for access savePath)
is no longer needed (but it doesn’t hurt)
Yvan KOENIG running Sierra 10.12.3 in French (VALLAURIS, France) vendredi 17 février 2017 13:46:44
Nice… does that mean they are fixing this issue for the coming OS X release ?
Niklas
A part of the problem will be solved, the one forbidding to save the attachment without using the TIP.
At this time, the problem related to the rule which doesn’t pass the correct list continue to strike and I’m afraid that it will strike for long.
Yvan KOENIG running Sierra 10.12.3 in French (VALLAURIS, France) vendredi 17 février 2017 17:13:41
Hi,
I’ve tried implementing the solutions in this thread but can’t seem to make this work. Admittedly I don’t really understand applesctipt. I’ve tried inserting the tip to my script but no joy. It seems as though no matter what I do applecript will not recognize that an attachment exists. (I tried inserting a say statement before the “if theMessage’s mail attachments is not {} then” line but it never triggers. This is a script that I found here years ago and keep adjusting slightly with each release when it stops working.
I get an email every day with an attachment titled OPIS_Pricing.csv. I need to save that in my downloads directory and kick off a script. I wish apple would simply include a damn rule for saving attachments and save me this recurring headache. /rant
Any help would be much appreciated.
using terms from application "Mail"
on perform mail action with messages theMessages --for rule theRule
-- Only use hardcoded path! DO NOT USE choose folder. It will crash Mail if you do
-- Script modified for 10.8 on 09/12/13 MV
-- as of Mac OS X 10.8 Mail.app applescripts can only save to the downloads directory
-- the shell script below moves the file from downloads to its proper place for processing
set theOutputFolder to ("/Users/me/Downloads/") as rich text -- replace quoted text with your desired path
set theNextDelivery to "OPIS_Pricing.csv"
tell application "Mail"
repeat with theMessage in theMessages
if theMessage's mail attachments is not {} then
repeat with theAttachment in theMessage's mail attachments
set theFileName to theOutputFolder & theNextDelivery
try
save theAttachment in theFileName
on error errnum
end try
end repeat
end if
end repeat
end tell
do shell script "/Users/me/Documents/Scripts/CurrentFuelCost/CurrentFuelCostScript_OPIS.sh"
end perform mail action with messages
end using terms from
It seems that you are facing what I wrote in message #26:
A part of the problem will be solved (is solved under 10.12.4), the one forbidding to save the attachment without using the TIP.
At this time, the problem related to the rule which doesn’t pass the correct list continue to strike and I’m afraid that it will strike for long.
Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) samedi 15 avril 2017 12:24:10
I cobbled together a temporary workaround in this find command
/usr/bin/find "/Users/me/Library/Mail/V4/" -type f -name "opis_racks_6to6.csv"| sed 's/.*/"&"/' | xargs ls -lTU |sort -k 9,9n -k 6,6M -k 7,7n | awk '{ print $10,$11 }' |tail -1 | xargs -I{} cp "{}" /tmp/opis_racks_6to6.csv
The only weird thing is that it doesn’t seem to find the attachment right away. The email comes in at 7:07ish every day. Sometimes when I run the file at 8 it works flawlessly. Other days I am forced to re-run it the next morning. The timestamp on the file in the /Mail/V4/… directory indicates it wasn’t created till 10 PM
Now I have a LaunchDaemon set to make sure mail is running at 6PM so it never misses the email. The timestamp on the email is 7:07 PM. The timestamp on the opis_racks_6to6.csv file is 22:12. Can someone explain this behavior to me? I’d like to run the script at 8PM the latest. Currently I’m forced to run it at 5AM just to be certain the the correct file actually exists.
NickeZ28, could you let us know how you created the Automator work-around for this?
I have set up an Automator workflow that gets the selected messages in Mail and saves their attachments to the documents folder. The limitation is that the emails must first be selected in Mail. Is it possible for a Mail rule AppleScript to pass the received emails as input to the Automator workflow?
Hi all,
I managed to work out how to do this by actually reading what has been discussed above. Yvan’s TIP did the trick for me (thanks Yvan). The problem was that Mail was refusing to save the attachments due to some kind of permissions issue. The following code sorted it out:
set savePath to attachmentsFolder & originalName
close access (open for access savePath)
set savePath to savePath as «class furl»
save theAttachment in savePath