I wanted to script Apple Mail to mark all messages in any particular mailbox as read. I have a menu-driven approach that first selects all, and then selects 'Mark as Read.' Works fine as long as the starting message is not read. However, when the starting message is read, the macro cancels because 'Mark as Read' has been replaced by 'Mark as Unread.' As I better first step, I'd like to check the marked status, toggle the Mark menu if required, and then proceed as above. I'm not KM-savvy enough to know how to do that, but I think it could be done either by checking the message or the menu. Don't care at the moment. Any help or better advice appreciated.
OK, answering my own post. This Applescript seems to do it. Clicking 'menu item 10' obviates the issue.
activate application "Mail"
tell application "System Events"
tell process "Mail"
tell menu bar 1
tell menu bar item "Edit" to tell menu 1 to click menu item "Select All"
tell menu bar item "Message" to tell menu 1 to click menu item 10
end tell
end tell
end tell
tell application "Mail"
set theMessages to selection
set theMailBox to mailbox of item 1 of theMessages
set theMessage to first message of theMailBox
set selected messages of first message viewer to theMessage
end tell
tell application "System Events" to key code 126
I have no idea why the last line is required, but without it, the 'first message of theMailBox' is the second one down.
activate application "Mail"
tell application "System Events"
tell process "Mail"
tell menu bar 1
tell menu bar item "Edit" to tell menu 1 to click menu item "Select All"
end tell
end tell
end tell
tell application "Mail"
set theMessages to selected messages of first message viewer
set theMailBox to mailbox of item 1 of theMessages
set the read status of every message of theMailBox to true
set theMessage to first message of theMailBox
set selected messages of first message viewer to theMessage
end tell
tell application "System Events" to key code 126
tell application "System Events" to key code 116
I still don't know why I end up with the second message down sometimes. ;-(
Here's how to do it with more canonical AppleScript:
--------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2020/09/29 16:25
# dMod: 2020/09/29 16:41
# Appl: Mail
# Task: Set Read-Status of Messages of the "Front Mailbox" to True.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Mail, @Set, @Read, @Status, @Messages
--------------------------------------------------------
try
tell application "Mail"
tell (some message viewer whose index is 1) -- In case more than 1 message viewer is open.
set {selectedMailbox} to selected mailboxes
tell selectedMailbox
set read status of messages whose read status is false to true
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
--------------------------------------------------------
The problems with this approach are as follows:
It will slow down if there is a huge number of unread emails in the given mailbox.
Smart Mailboxes are not supported. (Because Apple is negligent in providing proper AppleScript support for its own applications.)
If you're going to use System Events then you might as well go whole-hog and select the menu item Mail > Mailbox > Mark all Messages as Read.
But... If you're going to resort to brute-force anyway you might as well just use Keyboard Maestro:
Thank you for getting back to me. And now with even new, improved, code!
At my age, I’m now just a hobbyist. I write code to make my computer do the repetitive tasks its good for, coding in AppleScript, CSS, and VBA for a firewalled distance education website where I’m an adjunct. I moved from Quickeys to KM in that pursuit.
You are the second to make a remark about my ‘less than professional’ code. The first was on Stackoverflow where the remark was actually that my code snippet was illegal. Not sure what makes a line or three of code illegal when it met the task. But to explore, what separates the hobby code from the pro’s code?
Thanks again for the help. I lurk often, not usually signed in. I’m glad there’s now a good answer to my question. ;-0