Mail.app scripts not running

I want a script to run IF an incoming email contains an attachment.
The conditional side of the rule works ok, but when I have one of the actions ‘Run AppleScript’ it doesn’t run the script. The author of my script, Nik J, an incredibly kind and patient fellow, got it running on his similar Mac (same OS, 10.4.11) but it just wouldn’t work on mine.
Is there anything anywhere that might have disabled Applescripts?

The script is this -

using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
repeat with eachMessage in theMessages
tell application "Mail"
set mysubject to subject of eachMessage
set theSender to sender of eachMessage
set newMessage to make new outgoing message with properties {subject:"New mail with an attachment", content:"You've got a new message sent to contact from " & theSender}
tell newMessage
set visible to true
make new to recipient at end of to recipients with properties {name:"Filtering", address:"me@isp.blackberry.net"}
send
end tell
end tell
end repeat
end perform mail action with messages
end using terms from

Thanks.

Model: Powerbook G4 (Thresher)
Browser: Safari 523.12.2
Operating System: Mac OS X (10.4)

I can’t think of anything that would have de-activated Applescript, but one thing I can think of that might be the problem is that your rule may not be high enough in the list of rules to get activated. Remember that rules are applied in order, so if one of the rules above this one matches the message you want, it could get diverted (depending on what the other rule does) and this rule never sees the message.

Just a thought…:cool:

I have the ‘Run Applescript’ action second in a rule that colours the message first. I’ll try changing the order, and taking out the ‘colouration’.
Thanks for the thought!

Here’s something else I tested - I made a dummy rule that looks for the word ‘test’ in the Subject. It then runs the script Speak Sender and Subject___ctl-s.scpt, a script built into OS X, that just announces the sender and subject.
And it works!

So, how and what do I check for the differences between the working (built in) script and the new custom made ones?

Further testing has showed that I can send mail to my Blackberry via Applescript - there’s a sample script that sends mail via a series of dialogue boxes, and it works fine.

Can anyone find anything wrong with the above script?

I’ve taken it apart and tried just running the email sending part without making it a rule. What I found is that you need to specify which account you are sending the email from, if you have more than one account (like I do). I don’t know if that applies to you, but when I tried this section:

tell application "Mail"
	set mysubject to "subj"
	set theSender to "someone"
	set newMessage to make new outgoing message with properties {subject:"New mail with an attachment 2", content:"You've got a new message sent to contact from " & theSender}
	tell newMessage
		set visible to true
		make new to recipient at end of to recipients with properties {name:"Filtering", address:"nw98@gmail.com"}
		send
	end tell
end tell

Mail tried to send (spinning whirlygig in the Sent folder) but no email was sent.

When I added a sender like this:

tell application "Mail"
	set mysubject to "subj"
	set theSender to "someone"
	set newMessage to make new outgoing message with properties {subject:"New mail with an attachment 2", content:"You've got a new message sent to contact from " & theSender, sender: "myaddress@whereami.com"}
	tell newMessage
		set visible to true
		make new to recipient at end of to recipients with properties {name:"Filtering", address:"nw98@gmail.com"}
		send
	end tell
end tell

The email was sent from the account specified.

See if that helps…?

The original script had

using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
repeat with eachMessage in theMessages

at the beginning. Do I need that?

And just to clarify - is the gmail address the one you’re sending the notification to, and the nonsense one the one you’re sending FROM ?

One thing I just found out…I can run the version posted above (without the ‘using terms…’ bit) from inside Script Editor and it works.

Technically, yes you need the repeat statement since it’s possible that you’ll get more than one message. In actual usage, I’ve only seen messages processed through the rules one at a time. I just took out the repeat to simplify the problem and see what it took to get the outgoing message to work.

Sorry, I wasn’t clear. I replaced your Blackberry address with my Gmail addy, so it is the intended recipient. The other address

sender: "myaddress@whereami.com"

is the addy for the account I’m sending from. Without a sender for the outgoing mail, it doesn’t seem to send. I know that probably sounds like a “duh” idea, but it’s possible that if you only have 1 account Mail might assume it should use it and go ahead and mail the message using that account.

Man i feel dumb. And what on earth could be wrong?

using terms from application "Mail"
	on perform mail action with messages theMessages for rule theRule
		repeat with eachMessage in theMessages
			tell application "Mail"
				set mysubject to subject of eachMessage
				set theSender to sender of eachMessage
				set newMessage to make new outgoing message with properties {subject:"New mail with an attachment", content:"You've got a new message sent to Contact from " & theSender & " Subject:" & mysubject, sender:"contact@nburmandesign.com"}
				tell newMessage
					set visible to true
					make new to recipient at end of to recipients with properties {name:"Filtering", address:"info@nburmandesign.com"}
					send
				end tell
			end tell
		end repeat
	end perform mail action with messages
end using terms from

This is my script exactly. At the mo, it runs if I get an email with ‘test’ in the subject.
I thought I’d take the Blackberry out of the equation. Still nuthin…

Are you saying that it does function with a ‘test’ in the subject but not for any other email?

No, it doesn’t work either way. The only way I can get a script to send an email anywhere is to take out the loop, and click RUN in script editor. I dont know if that helps…

This copy works for me, give it a try:

using terms from application "Mail"
	on perform mail action with messages theMessages for rule theRule
		repeat with eachMessage in theMessages
			tell application "Mail"
				try
					set mysubject to subject of eachMessage
					set theSender to sender of eachMessage
					set newMessage to make new outgoing message with properties {subject:"New mail with an attachment", content:"You've got a new message sent to contact from " & theSender, sender:"contact@nburmandesign.com", visible:true}
					
					tell newMessage
						make new to recipient at end of to recipients with properties {name:"Filtering", address:"info@nburmandesign.com"}
						send
					end tell
				on error the error_message number the error_number
					display dialog "Error: " & the error_number & ". " & the error_message buttons {"Cancel"} default button 1
				end try
			end tell
		end repeat
	end perform mail action with messages
end using terms from

I moved the visible property to the make command and put a try on error block around the whole set of commands for creating the outgoing message. That’s really all I changed, and it’s working now on my end.

Give it a go and let me know if it works.

WOOHOO! IT WORKS!
I owe you a hug, a beer, or both! Thank you so much!

Now - you didn’t think that was it, did you? - what other variables are available to make the email more informative? Can I include the email subject, the body (without the attachment), the attachment name and size perhaps?

Well, on looking through Mail’s dictionary in Script Editor, you can do all sorts of things. For example, there is a “forward” command that would create an outgoing message that contains the entire contents of the incoming message, so you could literally send the entire message to your Blackberry. There is also a “redirect” command that will do the same thing, basically.

The “message” object has a bunch of properties that you can get a hold of and re-use. Here’s the entry:

 message‚n [inh. item] : An email message
elements
contains bcc recipients, cc recipients, recipients, to recipients, headers, mail attachments; contained by message viewers, mailboxes.
properties
id (integer, r/o) : The unique identifier of the message.
all headers (string, r/o) : All the headers of the message
background color (blue/gray/green/none/orange/other/purple/red/yellow) : The background color of the message
mailbox (mailbox) : The mailbox in which this message is filed
content (string) : Contents of an email message
date received (date, r/o) : The date a message was received
date sent (date, r/o) : The date a message was sent
deleted status (boolean) : Indicates whether the message is deleted or not
flagged status (boolean) : Indicates whether the message is flagged or not
junk mail status (boolean) : Indicates whether the message has been marked junk or evaluated to be junk by the junk mail filter.
read status (boolean) : Indicates whether the message is read or not
message id (string, r/o) : The unique message ID string
source (string, r/o) : Raw source of the message
reply to (string) : The address that replies should be sent to
message size (integer) : The size (in bytes) of a message
sender (string) : The sender of the message
subject (string) : The subject of the message
was forwarded (boolean) : Indicates whether the message was forwarded or not
was redirected (boolean) : Indicates whether the message was redirected or not
was replied to (boolean) : Indicates whether the message was replied to or not

Out of these properties, you can build a custom email to suit your needs, and then using the “outgoing message” object, you can plug your information into this:

outgoing message‚n [inh. item] : A new email message
elements
contains bcc recipients, cc recipients, recipients, to recipients; contained by application.
properties
content (string) : The contents of the message
sender (string) : The sender of the message
subject (string) : The subject of the message
content (string) : The contents of the message
visible (boolean) : Controls whether the message window is shown on the screen. The default is false
message signature (signature) : The signature of the message
id (integer, r/o) : The unique identifier of the message

(Oddly, notice that “content” is specified twice! Mail’s scriptability has some flakiness as many scripters have noted. Most well-known is that in Tiger Apple broke the “signature” object so that you can’t set up a new signature in Applescript. Well, you can, but it’s not saved when the application quits for some reason…)

im’ supposed to be a designer, not a programmer, but a little geek part of me enjoys this! So just to show you that I’m not a complete moron, here is my new script. Yup, nothing fancy, but it does give me a bit more information:

using terms from application "Mail"
	on perform mail action with messages theMessages for rule theRule
		repeat with eachMessage in theMessages
			tell application "Mail"
				try
					set thesubject to subject of eachMessage
					set theSender to sender of eachMessage
					set bytes to message size of eachMessage
					
					set newMessage to make new outgoing message with properties {subject:"New mail with an attachment", content:"You've got a new message sent to Contact from " & theSender & ", Subject: " & thesubject & ". Size of message: " & bytes & " bytes. ", sender:"contact@nburmandesign.com", visible:true}
					
					tell newMessage
						make new to recipient at end of to recipients with properties {name:"Filtering", address:"nburman@rogers.blackberry.net"}
						send
					end tell
				on error the error_message number the error_number
					display dialog "Error: " & the error_number & ". " & the error_message buttons {"Cancel"} default button 1
				end try
			end tell
		end repeat
	end perform mail action with messages
end using terms from

Thanks for your help Kevin :slight_smile:
The other thing I need to do, is forward an email if there is NOT an attachment. So far, a rule stating


'If all of the following conditions are met: 
Any attachment Name Does not contain .pdf, 
Any attachment Name Does not contain .jpg, 
Any attachment Name Does not contain .gif, 
Any attachment Name Does not contain .eps,
 Any attachment Name Does not contain .ai, 
Any attachment Name Does not contain .doc, 

Perform the following actions: Forward Message to [email address]

doesn’t seem to work. Does it fail because there is no attachment, and it can’t check the attachment Name?
Oh I have an idea - what if I had a script that only forwarded mail that had a file size under 1k ? I don’t know how to do conditional statements…

Yes. If there isn’t an attachment then those rule conditions won’t catch the email.

Rules are, by definition, conditional statements of a sort. Yes, you could use file size as an indication, though I’m not sure if 1k is sufficient to get longer messages (or items formatted in HTML).

My thinking was this - most attachments have names like “image.jpg” or “textfile.txt,” right? What character is in the name of every attachment? The ‘.’ ! So if you make a rule that says:

Attachment name does not contain .

That might work. Another idea that might work is if you say:

Attachment name is (leave blank box)

Give those a try.

Thanks for the suggestions. I couldn’t get either to work. I tried blank, ‘.’ , does contain and doesn’t contain. I even tried ‘does not contain attachment’ incase there was some text in the text-only (nonHTML) version that mail sees.

Does mail care about the order of Rules? Is the whole thing a ‘if … else’?

I’m thinking I might have better luck with a script. Any ideas?

Rules (and the rule conditions in a rule) are, yes, applied in order, essentially making a huge conditional statement (an “if…elseif…else”).

However, that being said, you can always create a rule that will match ALL messages and then point it a a script and let the script do the selection of which messages to respond to and how to respond. It sounds like that’s what you want. You can make a rule that says if the mailbox of the incoming message is your default email account, that should catch everything.

Truthfully, I’ve forgotten now whether originally you DID or DID NOT want attachments… :confused:

Keep in mind, when testing for attachments that the mail attachment object is not a property of the message, it’s an element. So you’ll want to get:

set myAttachements to every mail attachment of theMessage

OH dear - sorry for the confusion! Actually, what I would really like is a script that says ‘if there is an attachment (perhaps over 5k to avoid the signatures,vcards, etc) then send an email to the Blackberry saying there is one (maybe send the message body too) , but if there is NO attachment, then just forward it to the Blackberry.’

I’m sorry this theme has gone on so long. But how would I script ‘if there is an attachment then … else …’ ? I can see how it would be easier to just have a rule that collects all the mail and just runs that script.

Then it sounds to me that a rule that just matches your mailbox and runs a script that does all the heavy lifting is in order. Again, the key is going to be along the lines of

 set myAttachments to every mail attachment of theMessage
if count (items of myAttachments) = 0 then
--do the forward of the email that has no attachments
else
--do the message that you have an email with attachments
end

That should be enough to get you going in the right direction. :slight_smile: