Mail automated detachments

Good day,

I have adjust a few snippets of scripts I found online (I’m embarrassed to say I no longer have proper attribution for them) to create the following script, whose job it is to detach attachments from incoming eMails and drop them in a local folder.
While the script works, it doesn’t work 100% of the time - for example, if an eMail has a number of attachments it will either detach only one, or none at all! Single eMail sent with just a single attachment work pretty much all the time. Does anyone know why the script might be failing with multiple attachments to a single eMail?
Many thanks indeed for any advice.

/timothy

using terms from application “Mail”
on perform mail action with messages theMessages for rule theRule
repeat with theMessage in theMessages
– The folder to save the attachments in (must already exist)
set homeFolder to (path to home folder) as rich text
set attachmentsFolder to (homeFolder & “Documents:GAMPhotosIn”) as rich text
– Get the date the message was sent
set {year:y, month:m, day:d, hours:h, minutes:min} to theMessage’s date sent
set timeStamp to (“” & y & “-” & my pad(m as integer) & “-” & my pad(d) & “-” & my pad(h) & “-” & my pad(min))
– Save the attachment
repeat with theAttachment in theMessage’s mail attachments
set originalName to name of theAttachment
set savePath to attachmentsFolder & “:” & originalName
try
save theAttachment in file savePath
end try
end repeat
end repeat
end perform mail action with messages
end using terms from

– Adds leading zeros to date components
on pad(n)
return text -2 thru -1 of (“00” & n)
end pad

Hi. In skimming it, the code appears generally workable—excepting the inert timestamp lines—however, my experience with rule-driven scripts is that they aren’t particularly reliable. You may want to experiment with running a variant manually from the ScriptEditor or triggering an AppleScript from a rule without the rule-specific verbiage. If you do this, you’ll need a different target than ‘theMessages’, which was captured by the mail action handler.

#Evaluate last 15 messages:
set saveLocus to (path to documents folder as text) & "GAMPhotosIn:”
tell application "Mail"
	repeat with counter from 1 to 15
		tell inbox's message counter's mail attachments to if not it is {} then save it in file (saveLocus & name)
	end repeat
end tell
#Evaluate 24 hours worth:
set saveLocus to (path to documents folder as text) & "GAMPhotosIn:”
tell application "Mail"
    set arbitraryTargetsbydate to inbox's messages whose date received comes after (((current date)) - 1 * days)
    repeat with aMessage in arbitraryTargetsbydate
        tell aMessage's mail attachments to if not it is {} then save it in file (saveLocus & name)
    end repeat
end tell

Thank you very much for your response.
Unreliable is certainly the case so far. A user may send one eMail with several attachments and all detach properly, while their next eMail has a single attachment that doesn’t detach, then a third eMail with a single or two attachments that detach properly, etc, etc.

I am unclear on what you mean here:
"You may want to experiment with running a variant manually from the ScriptEditor or triggering an AppleScript from a rule without the rule-specific verbiage. " What is rule-specific verbiage? Sorry if I am asking about something basic.

I have Mail running on a server to run unattended to detach incoming files and drop them to a local folder. I then use Hazel (https://www.noodlesoft.com) to move the attachments (based on file type) on to appropriate network mounts. So, it’s an ongoing mechanism, and not a last 15min or last 24hr detaching scenario.

Additionally and oddly, Script Editor is throwing a Syntax shoe with this line in both your scripts:
tell application “Mail”

  • highlighting the word Mail with: Expected end of line, etc. but found identifier.

How peculiar.

There is a typo at the end of two instructions.
A double quote is erroneously replaced by a curly one.

In both scripts we must read :

set saveLocus to (path to documents folder as text) & "GAMPhotosIn:" # here standard double quote

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 16 octobre 2019 21:57:18

Ah! That would do it. Good catch.

The text that is specific to rules is the following code block that I already removed:
[format]using terms from application “Mail”
on perform mail action with messages theMessages for rule theRule
[/format]
In theory, the mail handler and preceding line work together to interpret syntax and iterate items that triggered the rule. In practice, this mechanism may be a point of failure. Mail can run its own code using other criteria.

OK, thank you. That makes sense.
I am playing with your ‘check for 24hrs’ worth’ script, but changed:
set arbitraryTargetsbydate to inbox’s messages whose date received comes after (((current date)) - 1 * days)

to

set arbitraryTargetsbydate to inbox’s messages whose date received comes after (((current date)) - 1 * minute)

in an attempt to have the script trigger and execute the moment any new message arrives with an attachment. However, it sort of makes sense that this won’t trigger on the first eMail incoming as it will have arrived in less than a minute. But a subsequent test eMail with attachment is not triggering the script either (the attachment is not being moved to ~/Documents/GAMPhotosIn. Am I missing something?

The time adjustment should be plural.

[format]… - 1 * minutes[/format]

Thank you Marc. That did the trick.
However, if I send a test eMail with multiple attachments, none are detached.
Looking at the script shouldn’t “tell aMessage’s mail attachments” indicate that multiple attachments would be honoured? Although I see also “then save it in file”, suggesting a single attachment is expected. I tried changing ‘it’ to ‘them’ without success. Any suggestion?

/timothy

You may try:

#Evaluate 24 hours worth:
set saveLocus to (path to documents folder as text) & "GAMPhotosIn:"
tell application "Mail"
	set arbitraryTargetsbydate to inbox's messages whose date received comes after (((current date)) - 1 * days)
	repeat with aMessage in arbitraryTargetsbydate
		set theAttachments to aMessage's mail attachments
		if theAttachments ≠ {} then
			repeat with anAttachment in theAttachments
				set itsName to name of anAttachment
				save anAttachment in file (saveLocus & itsName)
			end repeat
		end if
	end repeat
end tell

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 21 octobre 2019 17:31:47

Thank you very much Yvan.
Testing has shown this to work well. I guess the component that allowed for multiple attachments is:
“if theAttachments ≠ {} then”, do I see that correctly?
Many thanks again to both you and Marc.

/timothy

Hey again.
An interesting glitch has arisen:
When an eMail is sent with attachments, the photos do not detach until a subsequent eMail is sent. The first eMail’s attachments then detach as expected. It’s like the method is ‘waiting for a push’ or similar?
Can you think of any reason the script isn’t being spontaneous with an immediately incoming eMail?

/timothy

Multiple attachments are honored on my Sierra (10.12.6) install with the original syntax, however, it’s possible that Yvan’s double loop is required with your setup; it may be useful for you both to put your versions into an old post, for posterity. As to why the rule won’t work without another item being sent, my suspicion is that running it every minute is problematic; if the refractory period hasn’t tolled for the listener, it would ignore events until the next cycle’s trigger.

Yes, Marc. You guess makes sense to me.
I have adjusted poll time from less than a minute to two minutes and the script detach appears to be happening well. FWIW, after Mail detaches the attachments, Hazel has been an awesome tool for us to move files around based on all kinds of aspects.
Does this thread not constitute saving the script for posterity?
Here is the final version of the script as we have it working now (thanks to your and Yvan’s kind assistance):

#Evaluate 2 minutes’ worth:
set saveLocus to (path to documents folder as text) & “GAMPhotosIn:”
tell application “Mail”
set arbitraryTargetsbydate to inbox’s messages whose date received comes after (((current date)) - 2 * minutes)
repeat with aMessage in arbitraryTargetsbydate
set theAttachments to aMessage’s mail attachments
if theAttachments ≠ {} then
repeat with anAttachment in theAttachments
set itsName to name of anAttachment
save anAttachment in file (saveLocus & itsName)
end repeat
end if
end repeat
end tell

Not really, it checks that there is at least one attachment.
If there is, the code execute a loop which may treat one or several attached items.

I never used an other syntax so I didn’t know if the syntax proposed by Mark worked.
As I am curious, I just tested it with two messages, one with two attachments and one with three.

I’m not surprised to see that it saves only one attachment for each message.

the log report was :

(*
tell current application
	path to documents folder as text
end tell
tell application "Mail"
	get selection
	get every mail attachment of message id 873609 of mailbox "sssss sssssss"
	get name of every mail attachment of message id 873609 of mailbox "sssss sssssss"
	save every mail attachment of message id 873609 of mailbox "sssss sssssss" in file "SSD 1000:Users:**********:Documents:4Brian.numbersbareScript.scpt2015-05-26T15.24.14.png" of every mail attachment of message id 873609 of mailbox "sssss sssssss"
	get every mail attachment of message id 874315 of mailbox "sssss sssssss"
	get name of every mail attachment of message id 874315 of mailbox "sssss sssssss"
	save every mail attachment of message id 874315 of mailbox "sssss sssssss" in file "SSD 1000:Users:**********:Documents:2015-05-11T14.36.27.png2015-05-11T12.17.32.png" of every mail attachment of message id 874315 of mailbox "sssss sssssss"
end tell
*)

You may see that the first mail “exported” a file whose name was made by concatenation of the 3 names of attachments : 4Brian.numbers, bareScript.scpt, 2015-05-26T15.24.14.png

and that the second mail “exported” a file whose name is made by concatenation of the 2 names of attachments : 2015-05-11T14.36.27.png, 2015-05-11T12.17.32.png

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 22 octobre 2019 16:18:35