on perform vs. on run

I’m having trouble figuring out when certain handlers are being called.

There is a handler :

using terms from application "Mail"
on perform mail action with messages selectedMessages
 -- do stuff
end perform mail action with messages
end using terms from

And there is this handler:

on run 
  display dialog "Only run script from within Mail.app, with messages selected"
end run 

When I run the script ‘standalone’ (double click it), it does display the right message. However, when I do run it with messages selected from Mail.app, it seems to do call both handlers. How would I go about dealing with this?

(And also, instead of the handler structured as mentioned above, would constructing it this way :

on perform mail action with messages theSelectedMessages using terms from application "Mail"

work too? It seems more readable, structured and logical that way … )

A ‘run’ handler is the code that’s executed when the script’s run from an application or when the script is an application that’s run by double clicking. It’s the same as not using a handler at all. When you use ‘on run … end run’, it’s known as an explicit run handler. When you don’t use this, any code that’s not in a handler is regarded as being in an implicit run handler. You can only have one run handler in any script.

Other handlers are the ones you write for carrying out frequent subtasks in your script. However, there are also two other special handler types, of which you can only have one each in each script:

  1. An ‘open’ handler, which handles files or folders that are dropped onto your script when it’s a droplet.

  2. In ‘idle’ handler, which is run periodically by the system when your script’s a stay-open application.

Your ‘on perform mail action’ handler looks like a behaviour-modifying handler. I’d expect it to intercept calls to a “Mail” command called ‘perform mail action’ and carry out its own code instead.

thanks for that short tutorial

so this means that i just need one of the two ? either i delete the ‘on run’ handler, or i move the ‘using terms from application “mail”’ block into the ‘on run’ handler?


I’m thinking that there is something wrong here. I think it should return back to whatever called the handler after all the statements of the handler are executed. Maybe it’s a version of Mail or the system bug. I looked at this post:


I didn’t go through the post indebt, but it looks like if the user used the run handler, then it must be for double clicking (i.e. you can run the script from a rule or double clicking). If the scripter’s script works in a similar manner to your script, then the mail handler would run twice which probably doesn’t make sense. Maybe I’ll test how mine is working later on.



I thought something looked fishy. My Mail rules use handlers that look something like this:

– info is a record of 2 fields {|SelectedMessages|:list of references,|Rule|:reference}
on perform_mail_action(info)
set message_list to |SelectedMessages| of info
set the_rule to |Rule| of info – not used in this script
set first_message to item 1 of message_list
tell application “Mail”
set the_subject to subject of first_message
end tell
display dialog the_subject
end perform_mail_action

Did they change something?


This looks like something that’s new with recent versions of Mail, which is why I didn’t understand what gadg was driving at. (I don’t use Mail and don’t have a recent version.)

It seems from the above link - and from the replies to it - that the ‘perform mail action’ handler is used when the script’s run by Mail itself (from its own ‘Scripts’ menu, if it has one) and that the ‘run’ handler is used otherwise. They shouldn’t both be executed unless one contains a call to the other or else contains something that might be intercepted by the other.

Is there something in gadg’s ‘perform mail action’ handler that might be invoking the ‘run’ handler?

True, the script is invoked from the Mail.app scripts menu. There is no calling the run handler or vice versa though.

Something is definitely wrong. I set up a basic test of Mail’s handling of Applescript rules, and it appears to be well and truly broken.

Here’s the test: Set up a mail action which executes the following script and trigger it.

(* Run from a rule *)
using terms from application "Mail"
	on perform mail action with messages theMessages in mailboxes theMailboxes for rule theRule
		say "I am running a rule entitled: " & theRule
		end perform mail action with messages
end using terms from

(* Just plain run *)
on run
	say "the On Run handler has been invoked."
end run

What should happen is that the “perform mail action with messages” handler should be invoked by a script. However, what you’ll find is that instead the “on run” handler is invoked.

If you remove the on run handler (as is done in Apple’s demonstration script for mail rules), the script won’t do anything.

I think Mail’s Applescript functions may be truly broken.