Setting up Mail rule in Yosemite not working

G’day

I’m trying to automatically set up a Mail rule in Yosemite’s Mail, using Applescript, that…

  1. Shifts every incoming message from an Inbox named ‘Gmail’ (out of 4 Inboxes) to a mailbox named ‘* items to shift’.

  2. Calls an applescript named ‘Mail Manager Caller’.

From what I’ve read I might strike problems calling the script after moving each message, but my problem goes deeper than that; the script I’m trying refuses to get past the first line, only says ‘zero’.


#tell application "Mail" to activate # unnecessary?
using terms from application "Mail"
	say 0
	on perform mail action with messages theMessages for rule theRule
		say 1
		tell application "Mail"
			if (exists rule "* items to shift") then
				delete rule "* items to shift"
			end if
			set newRule to make new rule at beginning of rules with properties {name:"Move to '* items to shift'", move message:mailbox "* items to shift", enabled:true, all conditions must be met:false}
			tell newRule
				make new rule condition at beginning of rule conditions with properties {rule type:message content, move message:"* items to shift"}
			end tell
		end tell
	end perform mail action with messages
end using terms from

I’m wondering what the heck is going on? I’ve Quit Mail, and re-booted, to no effect.

Any thoughts, please?

Regards

Santa

Model: Late 2014 retina i7
AppleScript: 2.4
Browser: Safari 600.2.5
Operating System: Other

G’day once more.

Well, plenty of viewers, but no answers.

If possible, would someone mind testing the code in my question, and letting me know whether or not if it works, please?

I’m beginning to think I might have a hardware problem. I’ve got the updated Graphics Card (AMD Radeon R9 M295X 4096 MB) and 32GB ram. I had an updated card in my last configuration, and had problems, so I’m wondering if it could be the case again. I need to ascertain if I need to lodge a bug report or not.

Regards, and thanks to any takers,

Santa

I don’t use Yosemite, but I’ve had problems with the mail rule handler since the advent of Mavericks. If you browse the forum, you can see that others have had similar issues. As you don’t appear to be using the messages or rule variables from that handler anywhere in your script, maybe you don’t need it. A rule can directly trigger scripts that perform actions in Mail.

G’day Marc

The script I posted is a standard Mail script. Every instance of…

using terms from application “Mail”
say 0
on perform mail action with messages theMessages for rule theRule

that I try to use in Applescript, or in Xcode, fails on the…

on perform mail action with messages theMessages for rule theRule

line. Strange thing is that it seemed to work intermittently for a small amount of time, then started constantly failing.

I’ve even gone to the trouble of re-inslalling Yosemite to make sure that I did not have either a corrupted Applescript or Mail app, and it made no difference. I’d really appreciate anyone running Yosemite to test the script and post their results.

Regards

Santa

Model: Late 2014 retina i7
AppleScript: 2.4
Browser: Safari 600.2.5
Operating System: Other

Exactly. The “On perform mail action…” handler appears to serve no purpose in your code, and it’s known to be problematic. On further inspection, it also looks like a nonexistent property”move message”is being issued in your rule condition. When triggered by a rule, this works well:


tell application "Mail"
	delete (rules whose name is "* items to shift")
	make new rule at beginning
	tell rule 1
		set properties to {name:"Move to '* items to shift'", move message:mailbox "* items to shift", enabled:true, all conditions must be met:false}
		make new rule condition at beginning with properties {rule type:message content, expression:"whatever"}
	end tell
end tell

Thanks for the feedback, Marc

I’ve tried your code, and it certainly seems possible to create a new rule without the clumsiness of my previous attempts.

However, I get an error with my attempt.

The error is that Mail 'Can’t set mailbox “* items to shift” of rule 1 to {name:"Move to ‘* item to shift’, move message:mailbox “* items to shift” of rule 1 etc} where the move message:mailbox “* items to shift” is actually failing.

Any advice as to why your version works, but mine doesn’t, greatly appreciated.

Regards

Santa

Edit: I forgot to add that I’m trying to add the rule to a specific Account (“Gmail”), and the last line also errors when the offending statement is removed from the ‘set properties’ line.

try
		if not (exists mailbox "* items to shift") then make new mailbox with properties {name:"* items to shift"}
		set inBoxList to name of every account whose enabled is true as list
		if (count of inBoxList) = 1 then
			set theAddRuleAccount to item 1 of inBoxList
		else
			set theAddRuleAccount to choose from list inBoxList with prompt "Please choose a mailbox to add the rule " & return & "\"Move to '* items to shift'\" to." with title "Mail Manager add rule" OK button name "Choose this Inbox account" cancel button name "I'll set the rule myself"
		end if
		delete (rules where name is "* items to shift")
		make new rule at beginning
		tell rule 1
			say 1
			set properties to {name:"Move to '* items to shift'", move message:mailbox "* items to shift", enabled:true, all conditions must be met:true}
			say 2
			make new rule condition at beginning with properties {rule type:account theAddRuleAccount, run script:"Mail Manager Caller"}
		end tell
	on error errmsg
		display dialog errmsg
	end try
end tell

G’day once more

I’ve altered my script to…

tell application "Mail"
	activate
	try
		if not (exists mailbox "* items to shift") then make new mailbox with properties {name:"* items to shift"}
		set inBoxList to name of every account whose enabled is true as list
		if (count of inBoxList) = 1 then
			set theAddRuleAccount to item 1 of inBoxList
		else
			set theAddRuleAccount to choose from list inBoxList with prompt "Please choose a mailbox to which to add the rule " & return & "\"Move to '* items to shift'\"." with title "Mail Manager add rule" OK button name "Choose this Inbox account" cancel button name "I'll set the rule myself"
		end if
		delete (rules whose name is "Move to '* items to shift'")
		say 1
		set newRule to make new rule at beginning of rules with properties {name:"Move to '* items to shift'", all conditions must be met:true, move message:mailbox "* items to shift", enabled:true}
		tell newRule
			say 2
			make new rule condition at end of rule conditions with properties {rule type:account, expression:(theAddRuleAccount as rich text)}
			say 3
			make new rule condition at end of rule conditions with properties {rule type:matches every message, qualifier:none}
			say 4
			make new rule condition at end of rule conditions with properties {rule type:run script, expression:"Mail Manager Caller"}
			#set run script to file "Mail Manager Caller"
		end tell
		(*make new rule at beginning
		tell rule 1
			say 1
			set properties to {name:"Move to '* items to shift'", run script:"Mail Manager Caller", enabled:true, all conditions must be met:true} #, move message:mailbox "* items to shift"
			say 2
			make new rule condition at beginning with properties {rule type:account (theAddRuleAccount as rich text)}
		end tell*)
	on error errmsg
		display dialog errmsg
	end try
end tell

and it errors with ‘Can’t make account into constant, after saying ‘2’’. I think the term ‘account’ is a reserved word, and I cannot work out how to get it recognized as a constant. I tried piping it, but it just becomes a variable.

Any ideas anyone, please?

Regards

Santa

Hi. I didn’t have a mailbox with that name, so I didn’t fully test that portion, which accounts for some of the discrepancy. I’ve adjusted to correct for that. Another problem was that run script is a rule, but you used it as a rule condition. Try this.


tell application "Mail"
	if not (exists mailbox "* items to shift") then make new mailbox with properties {name:"* items to shift"} --creates a LOCAL mailbox
	--ACTIONS --edit the HFS path to the script!
	make new rule at beginning with properties {name:"Move to '* items to shift'", should move message:1, run script:file "Macintosh HD:Users:you:wherever:rule name.scpt", stop evaluating rules:0, enabled:true, move message:mailbox "* items to shift", all conditions must be met:1} --adjust HFS path
	--CONDITIONS 
	tell rule 1 to make new rule condition at beginning with properties {rule type:any recipient, expression:"whatever@gmail.com"} --edit address
end tell

Marc, I’m extremely appreciative of your efforts, but I think you’re missing a couple of points…

  1. I’m using Yosemite, which does not allow Mail scripts to be called from anywhere but the folder “Application scripts:com.apple.mail:”, and so the path is simply the name of the script in Yosemites ‘Mail’ app.

  2. The problem I’m having is that the term ‘account’, used to set the account (1 out of at least 4) that the mail rule will apply to is not working. It gives an ‘account can’t be addressed as a constant’ error (it uses other terminology, but that’s the gist of it).

Your code errors on the ‘run script’ line, which I cannot resolve until I get past the ‘account’ problem.

Are you running Yosemite?

Regards

Santa

I’m using Mavericks. The script file I tested lives in my Mail folder, however, I specified the full path; I didn’t realize that using just the name of the file was acceptable.

I believe the problem lies with the expression, for which your theAddRuleAccount variable”which is just the name”is not acceptable, in this case. If you manually create a rule with these conditions and then return the rule’s condition’s properties, you should see a POSIX path similar to the following:
“~/Library/Mail/V2/IMAP-name@whatever.com@imap.mail.provider.com”

Thanks Marc

As I can’t see any way of overcoming the ‘account’ terminology, I’ve resorted to the old standby, the GUI.

My script doesn’t really need the delays, they’re there ‘just in case’.

I would prefer to use the direct approach, but beggars can’t be choosers. :stuck_out_tongue:

Regards

Santa


my mailRuleCreator:("StartUp")

on mailRuleCreator:sender
	 set isThisStartUp to sender as text is "StartUp"
	tell application "Mail"
		activate
		try
			if not (exists mailbox "* items to shift") then make new mailbox with properties {name:"* items to shift"}
			set theAddRuleMailbox to false
			if not (exists rule "Move to '* items to shift'") or not isThisStartUp then
				set inBoxList to name of every account whose enabled is true as list
				if (count of inBoxList) = 1 then
					set theAddRuleMailbox to item 1 of inBoxList
				else
					set theAddRuleMailbox to choose from list inBoxList with prompt "Please choose an Account to which to add the Mail rule " & return & return & "\"Move to '* items to shift'\"." & return with title "Mail Manager add Mail rule" OK button name "Choose this Inbox Account" cancel button name "I'll set the rule myself"
				end if
			end if
			if theAddRuleMailbox ≠ false then
				try
					if not isThisStartUp then delete (every rule where name contains "items to shift")
				end try
				try
					delete (every rule where name contains "Automation")
				end try
				if not (exists rule "Move to '* items to shift'") then
					tell application "System Events" to tell process "Mail"
						try
							keystroke return
						end try
						click menu item "Preferences." of menu 1 of menu bar item "Mail" of menu bar 1
						tell current application to delay 0.1
						click button 8 of toolbar 1 of window 1
						# 
						# Set descriptive name of rule
						#
						click button "Add Rule" of group 1 of group 1 of window "Rules"
						set value of text field 1 of sheet 1 of window "Rules" to "Move to '* items to shift'"
						#
						# First, select the 'all' menu item
						#
						click pop up button 1 of sheet 1 of window "Rules"
						click menu item "all" of menu 1 of pop up button 1 of sheet 1 of window "Rules"
						# 
						# Set first scroll area, 'Conditions'
						#
						click pop up button 1 of scroll area 1 of sheet 1 of window "Rules"
						# The darn popups change numbers whilst 'Account' is being selected
						try
							click menu item "Account" of menu 1 of pop up button 1 of scroll area 1 of sheet 1 of window "Rules"
						end try
						# so we have to try both 1 & 2 popups
						try
							click menu item "Account" of menu 1 of pop up button 2 of scroll area 1 of sheet 1 of window "Rules"
						end try
						tell current application to delay 0.1
						click pop up button 1 of scroll area 1 of sheet 1 of window "Rules"
						click menu item (theAddRuleMailbox as text) of menu 1 of pop up button 1 of scroll area 1 of sheet 1 of window "Rules"
						tell current application to delay 0.1
						#
						click button "add criterion" of scroll area 1 of sheet 1 of window "Rules"
						#
						click pop up button 3 of scroll area 1 of sheet 1 of window "Rules"
						click menu item "Every Message" of menu 1 of pop up button 3 of scroll area 1 of sheet 1 of window "Rules"
						tell current application to delay 0.1
						# 
						# Set second scroll area, 'Actions'
						#
						click pop up button 1 of scroll area 2 of sheet 1 of window "Rules"
						click menu item "Move Message" of menu 1 of pop up button 1 of scroll area 2 of sheet 1 of window "Rules"
						tell current application to delay 0.1
						click pop up button 2 of scroll area 2 of sheet 1 of window "Rules"
						click menu item "* items to shift" of menu 1 of pop up button 2 of scroll area 2 of sheet 1 of window "Rules"
						tell current application to delay 0.1
						#
						click button "add action" of scroll area 2 of sheet 1 of window "Rules"
						#
						click pop up button 3 of scroll area 2 of sheet 1 of window "Rules"
						click menu item "Run Applescript" of menu 1 of pop up button 3 of scroll area 2 of sheet 1 of window "Rules"
						tell current application to delay 0.1
						click pop up button 4 of scroll area 2 of sheet 1 of window "Rules"
						try
							click menu item "Mail Manager Caller" of menu 1 of pop up button 4 of scroll area 2 of sheet 1 of window "Rules"
						on error
							try
								click menu item 1 of menu 1 of pop up button 4 of scroll area 2 of sheet 1 of window "Rules"
							end try
						end try
						tell current application to delay 0.1
						click button "OK" of sheet 1 of window "Rules"
						try
							click button 1 of window 1
						end try
					end tell
				end if
			end if
		on error errmsg number errNum
			tell application "System Events" to tell process "Mail"
				try
					tell current application to delay 0.1
					click button "OK" of sheet 1 of window "Rules"
				end try
				try
					click button 1 of window 1
				end try
			end tell
			display dialog "mailRuleCreator error " & errmsg
		end try
	end tell
end mailRuleCreator:


That okay, I guess, but I’d almost rather abandon an idea completely than to resort to GUI scripting. There does appear to be a genuine”and glaring”bug in Mail’s terminology, but I tinkered around with this a little further and arrived at this workaround.


set acctConstant to «constant eruttacc»
set libFolder to (path to library folder from user domain)'s POSIX path

tell application "Mail"
	--delete rules
	if not (exists mailbox "* items to shift") then make new mailbox with properties {name:"* items to shift"}
	set acctName to (choose from list (get accounts's name))
	if acctName ≠ false then
		set acctName to acctName's item 1
		set directory to ((account acctName's account directory) as rich text)'s POSIX path
	else
		error number -128
	end if
	--ACTIONS
	make rule at beginning with properties {name:"Move 'em", should move message:true, move message:mailbox "* items to shift", all conditions must be met:true, stop evaluating rules:false, run script:file "Macintosh HD:Users:YOU:Library:Application Scripts:com.apple.mail:Mail Manager Caller.scpt", enabled:true} --edit HFS path
	--CONDITIONS 
	make rule condition at rule 1 with properties {rule type:acctConstant, expression:(my augment(libFolder, directory))}
end tell


on augment(libFolder, directory)
	set text item delimiters to libFolder
	("~/Library/" & directory's text item 2)'s text 1 thru -2
end augment

Thanks Marc, that works well, except that I need to also call the script, “Mail Manager Caller”.

I’ve tried downloading and altering your script, but it refuses to be modified. Every edit except commented parts that I make, simply disappear!

I think it’s the first line, accConstant. I think your actual script or posting has been altered. Would you mind posting what it should be please?

I’m trying to add run script:“Mail Manager Caller” to the initial properties.

Regards

Santa

I edited my last post to include the run script command. FYI: I have to refer to it by the path, so maybe that’s a version difference between our OS’s. Nothing looks changed to me, and the first line intentionally contains a raw event.

Marc, a big ‘thank you’.

I’ve modified your script to suit, and all is well. The enabled:true is not setting the enabled for some reason, but that was easily fixed.

I really don’t know WHY I could not edit your script, even copying and pasting did not allow an edit of any sort. However, I persisted, and eventually was able to download and edit it. Don’t know what I did. Just thought the raw event was to blame.

My script is as posted.

Regards

Santa (Brian Christmas)



my mailRuleCreator:("StartUptest")

on mailRuleCreator:sender
	set isThisStartUp to sender as text is "StartUp"
	set acctConstant to «constant eruttacc»
	set libFolder to (path to library folder from user domain)'s POSIX path
	set pathToApplicationScripts to (path to library folder from user domain) & "Application Scripts" as text
	
	set acctName to false
	tell application "Mail"
		if not (exists mailbox "* items to shift") then make new mailbox with properties {name:"* items to shift"}
		--delete rules
		try
			if not isThisStartUp then delete (every rule where name contains "items to shift")
		end try
		try
			delete (every rule where name contains "Automation")
		end try
		if not (exists rule "Move to '* items to shift'") or not isThisStartUp then
			set acctName to choose from list (get accounts's name whose enabled is true) with prompt "Please choose an Account to which to add the Mail rule " & return & return & "\"Move to '* items to shift'\"." & return with title "Mail Manager add Mail rule" OK button name "Choose this Inbox Account" cancel button name "I'll set the rule myself"
		end if
		if acctName ≠ false then
			set acctName to acctName's item 1
			set directory to ((account acctName's account directory) as rich text)'s POSIX path
			--ACTIONS
			if not (exists rule "Move to '* items to shift'") then
				make rule at beginning with properties {name:"Move to '* items to shift'", should move message:true, move message:mailbox "* items to shift", all conditions must be met:true, stop evaluating rules:false, enabled:true, run script:file (pathToApplicationScripts & ":com.apple.mail:Mail Manager Caller.scpt" as rich text)}
				--CONDITIONS 
				make rule condition at rule 1 with properties {rule type:acctConstant, expression:(my augment(libFolder, directory))}
			end if
		end if
		set the enabled of rule "Move to '* items to shift'" to true
	end tell
end mailRuleCreator:

on augment(libFolder, directory)
	set text item delimiters to libFolder
	("~/Library/" & directory's text item 2)'s text 1 thru -2
end augment

G’day all

After initial success with Marcs efforts, I continued to test my version of his script, and found that its reliability gradually diminished, until it no longer works at all when setting both the ‘enabled:true’ and the name of the script that I want to use. I always see ‘No script selected’ in the rule. I’ve also re-booted twice.

As I require the Mail rule to ALWAYS be set, I’m going to have to fall back on the GUI, which seems reliable, but slow and cumbersome in comparison to direct scripting.

Marc, either something is wrong with my Yosemite install or hardware, or Mail rule scripting is unreliable. I have never, with your script, had success at setting ‘enabled:true’, so I’m wondering if it works consistently with your setup, or if there’s a bug in my Mail app.

I tried setting the script file to both a file (path) and an alias, but the script still won’t select the file.

My latest effort is below.

Regards, and Merry Christmas to all,

Brian Christmas (aka Santa)



my mailRuleCreator:("StartUpTest")

on mailRuleCreator:sender
	set isThisStartUp to (sender as text is "StartUp")
	set acctConstant to «constant eruttacc»
	set libFolder to (path to library folder from user domain)'s POSIX path
	set pathToApplicationScripts to (path to library folder from user domain) & "Application Scripts:" as text
	tell current application to delay 0.2
	set existMMCallerScript to false
	try
		tell application "Finder" to set theCallerFile to (pathToApplicationScripts & "com.apple.mail:Mail Manager Caller.scpt" as alias)
		set existMMCallerScript to true
	end try
	if existMMCallerScript then
		tell application "Mail"
			activate
			if not (exists mailbox "* items to shift") then make new mailbox with properties {name:"* items to shift"}
			--delete rules
			try
				delete (every rule where name contains "Automation")
			end try
			set acctName to false
			if not (exists rule "Move to '* items to shift'") or not isThisStartUp then
				set acctName to choose from list (get accounts's name whose enabled is true) with prompt "Please choose an Account to which to add the Mail rule " & return & return & "\"Move to '* items to shift'\"." & return with title "Mail Manager add Mail rule" OK button name "Choose this Inbox Account" cancel button name "I'll set the rule myself"
			end if
			if acctName ≠ false then
				try
					if not isThisStartUp then delete (every rule where name contains "items to shift")
				end try
				tell current application to delay 0.2
				set acctName to acctName's item 1
				set directory to ((account acctName's account directory) as rich text)'s POSIX path
				--ACTIONS
				if not (exists rule "Move to '* items to shift'") then
					make rule at beginning with properties {name:"Move to '* items to shift'", should move message:true, all conditions must be met:true, stop evaluating rules:false, enabled:true, run script:theCallerFile, move message:mailbox "* items to shift"} # 
					--CONDITIONS 
					make rule condition at rule 1 with properties {rule type:acctConstant, expression:(my augment(libFolder, directory))}
			 	end if
			end if
			set the enabled of rule "Move to '* items to shift'" to true
		end tell
	else
		tell application "System Events" to display dialog "There does not appear to exist a Mail Script called 'Mail Manager Caller.scpt'." & return & return & "Mail Manager cannot continue." buttons "OK"
	end if
end mailRuleCreator:

on augment(libFolder, directory)
	set text item delimiters to libFolder
	("~/Library/" & directory's text item 2)'s text 1 thru -2
end augment


Model: Late 2014 retina i7, Yosemite
AppleScript: 2.4
Browser: Safari 600.2.5
Operating System: Other

My enabled property works, however, it seems to take a second to register”like it’s on a delay. Mail occasionally and inexplicably showed “no script selected” on some of my earlier attempts, and I couldn’t discern any reason for that other than there seems to be a few undocumented bugs in the program. If you must use the GUI, then do what you have to do, but, since these settings can all be arranged manually, you could also try borrowing properties from existing disabled rules to create an active new one; that method would avoid the event constant hack in my workaround. Good luck, and merry Christmas, Christmas.

Thanks to this thread, I came up with this. I run it as an application triggered from a hotkey macro, but it should work as a script just as well.


(**
Script to create a new filetering rule in Yosemite Mail. Select a message, run the script. If you enter a rule name, you will be asked for a destination mailbox name. If not, it will simply open the rules panel for manual rule creation or editing. This is set up to run based on subject, but you can use other values by like theSender, etc. This uses GUI scripting because I couldn't get it to work with Mail otherwise, bah! This operates only on the first message of the selction, since it's intended to create only one rule.
Script by Michael Riesman with thanks to several MacScripter contributors who showed the path.
**)

tell me to activate
display dialog "Enter name for rule:" default answer ""
set myRule to text returned of the result
if myRule is not "" then
	display dialog "Enter name of destination mailbox:" default answer ""
	set myBox to text returned of the result
else
	set myBox to ""
end if

tell application "Mail"
	activate
	set theseMessages to (get selection)
	repeat with thisMessage in theseMessages
		--set theSender to sender of thisMessage
		--set senderName to extract name from sender of thisMessage
		--set theAddress to extract address from sender of thisMessage
		set theSubject to subject of thisMessage
		exit repeat -- if multiple messages selected, ignore the rest
	end repeat
end tell

tell application "System Events"
	tell process "Mail"
		activate
		set frontmost to true
		delay 0.2
		click menu item "Preferences." of menu 1 of menu bar item "Mail" of menu bar 1
		delay 0.2
		click button 8 of toolbar 1 of window 1
		if myRule is not "" then
			click button "Add Rule" of tab group 1 of group 1 of group 1 of window "Rules" of application process "Mail" of application "System Events"
			set the clipboard to myRule
			keystroke "v" using command down
			keystroke tab
			set the clipboard to theSubject
			keystroke "v" using command down
			delay 1 --you need to wait for stuff to happen. Might be able to be shortened.
			click pop up button 1 of scroll area 1 of sheet 1 of window "Rules"
			click menu item "Subject" of menu 1 of pop up button 1 of scroll area 1 of sheet 1 of window "Rules"
			click pop up button 2 of scroll area 2 of sheet 1 of window "Rules"
			click menu item myBox of menu 1 of pop up button 2 of scroll area 2 of sheet 1 of window "Rules"
			delay 1 --another needed pause. Might be able to be shortened.
			--another click was needed to finish the rule creation, otherwise it stopped and waited for user input. 
			click menu item myBox of menu 1 of pop up button 2 of scroll area 2 of sheet 1 of window "Rules"
		end if
	end tell
end tell

Lose Yosemite and go back to Maverick