Is it possible to update a mac mail rule with KM7?

I use a mail rule to shift newsletters etc. into a ‘Read_Later’ folder.

At the moment:

  1. I select the appropriate email the first time it hits the inbox.
  2. Press CMD Comma to open Mail Preferences
  3. Select ‘Rules’ if not already active
  4. Choose the ‘Read_Later’ rule if not already active
  5. Click ‘edit’
  6. Click the ‘Plus’ on one of the existing entries. Mail automatically puts the sender details into the rule FROM CONTAINS [Sender details]
  7. Click on OK to save the edited rule. The Edit rule dialog box closes
  8. Click on APPLY in the next dialog box.

Future emails from that sender get moved to the ‘Read Later’ folder and so don’t interrupt my workflow.

Rather than go through the process above it would be great to just press a key when mail is active :smile:

Is this possible in KM7? If so, what is the best approach?

Here is one approach (for Yosemite and KM7, using an Execute JavaScript for Applications action)

Add emails of selected Mail messages to Read_Later rule.kmmacros (19.8 KB)

The first draft of the script looks something like:

(function () {

	var strRuleName = 'Read_Later',

		// Email disentangled from any <brackets>
		addr = function (s) {
			var m = s.match(/\<(\S+)\>/);
			return m ? m.slice(-1)[0] : s;
		},

		appMail = Application("Mail"),
		condns = appMail.rules[strRuleName].ruleConditions; 

	// FOR ANY SELECTED MESSAGES, ADD THE EMAIL ADDRESS
	// IF IT IS NOT ALREADY INCLUDED IN THE RULE
	return appMail.selection().reduce(
		function (list, msg) {
			var strAddr = addr(msg.sender()),

				// ALREADY THERE ?
				blnFound = condns.where({
					expression: strAddr
				}).length,

				// CREATE A NEW CONDITION IF NEEDED
				ruleNew = blnFound ? null :
				appMail.RuleCondition({
					qualifier: 'does contain value',
					expression: strAddr,
					ruleType: 'from header'
				});

			return ruleNew ?
				(
					condns.push(ruleNew),
					list + strAddr + '\n'
				) : list;

		}, ''
	);
})();
2 Likes

Many thanks, works great, I wasn't expecting such a comprehensive reply, it is much appreciated. :+1:

I have added an Applescript to the end to trigger the rules to run, not sure how to do this in JavaScript, though it might have been better to just use 'Type a Keystroke' rather than Applescript

Here's the code:

tell application "System Events"
  tell application "Mail" to activate
  keystroke "l" using {command down, option down}
end tell

Updated macro attached. Add emails of selected Mail messages to ReadLater rule.kmmacros (21.4 KB)

Thanks once again.

Good – I'm glad that's working.

(and for the final step, you could also, of course, use a Select Menu Item action)

I was typing up a question for this, and realized you had already answered it. Should have known. Awesome! Thanks!

1 Like

@ComplexPoint - I know I thanked you for this already, but there’s rarely a day that goes by that I don’t think “God, I love this macro!” So thanks again.

Promise I’ll keep the rest to myself. But if you feel a warm fuzzy feeling during the day, it might be from me. :slight_smile:

Hey Folks,

When I create a Mail rule automagically I usually want to verify it was created correctly, and I frequently want to make some adjustment to its criteria.

This AppleScript creates a new rule entry in the designated rule and then opens it for inspection and/or alteration.

* NOTE: The script resizes Mail’s Rules prefs window, and the handler that does that might not work well with multi-monitor setups. Set resizeRuleWindow to false if you don’t want the window resized.

-Chris

---------------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2015/10/01 09:04
# dMod: 2016/06/03 04:27
# Appl: Mail, System Events
# Task: Add items to Promotions Rule
# Libs: ELb
# Osax: None
# Tags: @Applescript, @Script, @Mail, @System_Events, @Add, @Email, @Address, @Promotions, @Rule
---------------------------------------------------------------------------------
property ruleName : "Promotions - IN"
property resizeRuleWindow : true
---------------------------------------------------------------------------------

try
  
  set {winPosition, winSize} to winSizeByPercent(35, 100) of me
  
  tell application "Mail"
    set msgSelList to selection
    
    if length of msgSelList = 1 then
      set mailRule to rule ruleName
      
      if mailRule exists then
        set theMsg to item 1 of msgSelList
        set msgFromAddress to (sender of theMsg)
        
        tell mailRule
          make new rule condition at end of rule conditions with properties ¬
            {rule type:from header, qualifier:does contain value, expression:msgFromAddress}
        end tell
        
      else
        error "The named Mail-Rule does not exist!"
      end if
    else
      error "Problem with message selection!"
    end if
  end tell
  
  tell application "System Events"
    tell application process "Mail"
      set frontmost to true
      
      click menu item "Preferences…" of menu 1 of menu bar item "Mail" of menu bar 1
      
      tell front window
        if its name is not "Rules" then tell toolbar 1 to click button "Rules"
        
        if resizeRuleWindow = true then
          if {position, size} ≠ {winPosition, winSize} then
            set {position, size} to {winPosition, winSize}
          end if
        end if
        
        tell tab group 1 of group 1 of group 1
          set selected of row 1 of table 1 of scroll area 1 to true
          click button "Edit"
        end tell
        
        tell text field 1 of scroll area 1 of sheet 1
          set focused to true
        end tell
        
      end tell
      
    end tell
  end tell
  
on error e number n
  set e to e & return & return & "Num: " & n
  if n ≠ -128 then
    try
      tell application (path to frontmost application as text) to set ddButton to button returned of ¬
        (display dialog e with title "ERROR!" buttons {"Copy Error Message", "Cancel", "OK"} ¬
          default button "OK" giving up after 30)
      if ddButton = "Copy Error Message" then set the clipboard to e
    end try
  end if
end try

---------------------------------------------------------------------------------
--» HANDLERS
---------------------------------------------------------------------------------
on desktopBounds()
  tell application "Finder"
    set _bnds to bounds of window of desktop
    return _bnds
  end tell
end desktopBounds
---------------------------------------------------------------------------------
on getScreenY()
  tell application "Finder"
    set screenY to (last item of (get bounds of window of desktop))
  end tell
end getScreenY
---------------------------------------------------------------------------------
on winSizeByPercent(xPercent, yPercent)
  set {x1, y1, x2, y2} to desktopBounds() of me
  set y1 to 23
  set newWidth to (x2 * (xPercent / 100)) as integer
  set newHeight to (y2 * (yPercent / 100)) as integer
  set newXPos to ((x2 / 2) - (newWidth / 2)) as integer
  return {{newXPos, y1}, {newWidth, newHeight}}
end winSizeByPercent
---------------------------------------------------------------------------------