I have read these four questions with examples for how to use the background activity count Applescript property in Mail.app:
Check for New Mail of specific Mailbox/Folder Applescript
AppleScript and Mail.app: checking if new messages contain a string
AppleScript can't read Mail.app's messages
Applescript to wait for AppleMail to download messages.
It seems simple enough but when I do I get an error:
error "Mail got an error: AppleEvent handler failed." number -10000
Some code:
tell application "Mail"
activate
set bg_count to background activity count
repeat until background activity count = 0
delay 0.1 --wait until all new messages are in the box
end repeat
end tell
Both the set- and the repeat-statement give the same error message.
What is going on here? Is this broken?
Related
I have an issue with my music library.
Some songs I am unable to play because they cannot be found locally.
Here's an example of the error messages I get when playing a specific song:
The song ... could not be used because the original file could not be found. Would you like to locate it?
I can simply press Cancel and the song will be matched via the Apple Music Service.
This allows me to then play the song.
This issue has been discussed here, albeit not in an automated way. Hence, I would like to find an automated solution.
For this, I took the approach of looping through my library by playing each song.
By default, if a song cannot be found, the script automatically skips to the next song.
However, I would like the script to deal with the "file not found" errors and press Cancel.
My current attempt unfortunately does not work:
-- Play first song in library (turn off shuffle and repeat)
set i to 4000 --number of songs in library
repeat while i > 0
tell application "Music" to play (next track)
tell application "System Events"
key code 53
end tell
set i to i - 1
end repeat
How can I force the script to deal with these pop-up errors?
Note: I am also open to any other, more efficient solution to my problem if you have any suggestions. I decided not to go for the Locate option because it takes more time and I will delete any unreferenced songs from my disk at a later stage anyways.
UPDATED VERSION. Following script doesn't play tracks and programatically clicks button "Cancel" when track is corrupted. Like described by OP fixing tracks manually workflow:
tell application "Music"
activate -- required
tell source "Library"
repeat with nextTrack in tracks
try
with timeout of 2 seconds
set theResult to play (contents of nextTrack)
end timeout
theResult
on error
delay 1
tell application "System Events" to tell process "Music" to tell window 1 to if UI element "Cancel" exists then click UI element "Cancel"
end try
stop
end repeat
end tell
end tell
I am looking for a script that will place the cursor in the text field in the Messages App. I have looked for a keyboard shortcut to do this but cannot find one. Can anyone provide a script, or a similar one I can modify.
NB I am not a programmer or very familiar with AppleScript, but have been able to modify scripts that are close to my needs.
I need this as I am trying to make the messages app controllable using the built in dictation feature in Mac OS. I need a script I can assign to a voice command to place the cursor in the text field so that I can then dictate a message.
Many thanks.
If you are using dictation commands, in any application all you need to do is say the command “Show Numbers” and you will see this:
Then you would just say the command “Twenty” which will place your cursor right where you want it… in this case it would be the text field
Also speaking the command “Show Comands” Will open up this window listing tons of dictation commands.
The following was tested and works under OS X 10.8.5 and Messages 7.0.1 and may need to be adjusted for other versions of OS X/macOS/Messages:
tell application "Messages"
activate
tell application "System Events"
set focused of text area 1 of scroll area 4 of splitter group 1 of window 1 of application process "Messages" to true
end tell
end tell
Note: This is coded with the assumption that Messages is already open with an open window. Additional coding will be necessary, in the form of try and or delay and or on error statements as needed and appropriate otherwise.
Here's an example of how I'd code it otherwise, which handles whether or not Messages is open, has its window showing, etc.
on setFocusToTextArea()
tell application "System Events"
if (count of windows of application process "Messages") is equal to 0 then
click UI element "Messages" of list 1 of application process "Dock"
delay 0.25
end if
try
set focused of text area 1 of scroll area 4 of splitter group 1 of window 1 of application process "Messages" to true
end try
end tell
end setFocusToTextArea
tell application "Messages"
if running then
my setFocusToTextArea()
else
activate
delay 2
my setFocusToTextArea()
end if
activate
end tell
Note: If Messages is closed when this script is run, the delay 2 command gives time for Messages to open before the other code runs. The value of the delay command can be adjusted as appropriate for the speed of your system.
I need to be able to get the currently highlighted message from the current message thread.
ie
thread 1
message 1
message 2
message 3 <- highlighted message
message 4
I have tried:
tell application "Mail"
set messages to selected messages of first message viewer
set msg to first item of messages
end tell
but this just returns the thread of the currently selected message. It also does not include any outgoing messages in the thread.
You don't say what version of Mail or Mac OS X you're using, but that script doesn't run with Mail 10.2 / OS 10.12.2. The error is "Mail got an error: Can’t set every message to selected messages of message viewer 1."
This slight modification works for me:
tell application "Mail"
set theMessages to selected messages of first message viewer
set theMessage to first item of theMessages
end tell
If I run it against the message structure you describe then it sets theMessage to whichever one is selected. If multiples are selected then in my testing the order is as expected (from top to bottom), unless "thread 1" is also selected. In that case the order could vary.
My use case is that I want to track for responses on some messages I write. My methodology now is to wait for the message to be sent the move it from the sent folder to the "Waiting for reply" folder which I go over periodically.
I'm looking for a way to automate this. Best would be if I press a key which makes Outlook both send the message and put it in the Waiting folder. E.g., by using an applescript.
Alternatively, I thought that pressing a key will add me as BCC, and also add a "WF" string at the bottom of the message. Again, with applescript. Then when I send the message it will also arrive at my Inbox where I'll have a rule to move messages to "Waiting" if they contain "WF"
I expanded the script from your other thread to this here:
tell application "Microsoft Outlook"
-- Simple definition of target mail folder
-- Works fine this way if only one folder with this name is available
set waitingForReplyFolder to folder "Waiting for reply"
-- bring Outlook to front
activate
-- remember the front window
set theWindow to window 1
-- check it's really draft
if class of theWindow is not draft window then
display dialog "Not a draft"
return
end if
-- save the draft
save theWindow
-- get the id of the object of the draft window
set myObjectID to id of (object of theWindow)
-- close the message window
close theWindow
-- checking the message' subject
set theSubject to subject of message id myObjectID
-- send the message
send message id myObjectID
-- check and wait until Outlook has moved the mail to the sent folder
-- move it to target folder after we have found it
set mailFoundAndMoved to false
repeat 20 times
-- check the next 20 message ids
repeat with idCounter from 1 to 20
try
set freshSentMail to outgoing message id (myObjectID + idCounter)
-- check if the subject is the same (just to be safe)
if subject of freshSentMail is equal to theSubject then
-- move the sent mail to the "waiting for reply" folder
move freshSentMail to waitingForReplyFolder
set mailFoundAndMoved to true
exit repeat
end if
on error errstr
end try
end repeat
if mailFoundAndMoved then exit repeat
delay 0.5
end repeat
end tell
Now you must just see how to trigger this. Open a new message, write the content etc. and run this script. It will send the mail and move it to your target folder, just after it appeared inside the sent folder.
Cheers,
Michael / Hamburg
I'd like to write an AppleScript to set the sender of the current outgoing message in Apple's Mail.app.
I've tried this:
tell application "Mail" to set sender of front outgoing message to "<my email address>"
but I get the error message error "Mail got an error: Can’t set sender of item to any." number -10006 from sender of item to any which doesn't make sense to me.
When I try to interrogate the front outgoing message as follows:
tell application "Mail" to get properties of front outgoing message
I get {class:item} in return, instead of an "outgoing message" object like I'd expect.
Any ideas?
Unfortunately, you cannot get or set the properties of the outgoing message object of Mail with Applescript.
Instead, you can accomplish this with GUI scripting, a workaround that directly manipulates window elements.
This code should work for you:
tell application "System Events"
tell process "Mail"
click pop up button 1 of window 1
click menu item 6 of menu 1 of pop up button 1 of window 1
end tell
end tell
Change the menu item 6 on the fourth line to whichever number in the list your desired sender is (e.g., if the sender you want to change to with this script is the fourth one listed, change menu item 6 to menu item 4).
Update: If you're curious, since this answer is over two years old: as of 2014-04-26, getting/setting the properties of outgoing messages is still impossible and this workaround still works in OS X 10.9 Mavericks.
I think it's a little more complicated. My own experiments agree with the conclusion of Alan Kimelman in this thread, that AppleScript works as expected for outgoing messages created from scratch by the script. For example, the following code works:
tell application "Mail"
set newMessage to (a reference to (make new outgoing message))
tell newMessage
make new to recipient at beginning of to recipients ¬
with properties {address:"hello#world.com", name:"The World"}
set the sender to "Jerry Krinock <jerry#sheepsystems.com>"
set the subject to "A Test"
set the content to "This is only a test."
send
end tell
end tell
However, if the message is created by other means (for example, I create HTML messages by telling Safari to Share via Email), then Matthew McVickar is correct that AppleScript is broken. You can't set or get any properties, and also it refuses the send command.
Actually you can set the sender of an outgoing message as described here:
Incorrect sender when sending Email via Applescript
It is more than a little frustrating that you can't set the sender of an outgoing message.
Here's a more general version of Matthew's script that I wrote many years ago and have used frequently. The argument is a string that contains exactly what you see in the "From:" pop up, e.g.
"Mitchell L Model <dev#software-concepts.org>"
(It is very tricky to get the details of something like this right if you don't do a lot of GUI scripting.)
to setFrom(address)
tell application "System Events"
activate application "Mail"
tell pop up button "From:" of window 1 of application process "Mail"
click
tell menu item address of menu 1 to click
end tell
end tell
end setFrom
The reason I use a parameterized handler is that I use keystroke macro facilities to bind a keystroke combination for each of my email addresses. Each executes an AppleScript that loads the file containing the above handler and invokes it with a specific email address. For example:
property util : load script alias (((path to home folder) as text) & "Scripts:Utilities.scpt")
util's 's setFrom("Mitchell L Model <dev#software-concepts.org>")
It's trivial to use AppleScript to create a new outgoing message with any outgoing address that you like (well, at least, the ones configured in your Mail.app preferences).
The discussions here hinge around trying (incorrectly) to change it after the message is created. Instead, specify it when you create the message:
set new_m to make new outgoing message with properties {sender:"My Name <me#my.com>"}
The text in quotes needs to match both the real name and the email address (in chevrons) of any configured account. If there's no match, Mail.app will use the default address
Try this instead.
tell application "Mail" to make new outgoing message with properties {sender:"<your_email_address>", visible:true}
UPDATE: I would look in Mail's scripting dictionary and see what you can and cannot do. The information provided there might help. :)
An alternative to the GUI scripting example I provided would be an Automator script that utilizes the 'Watch Me Do' command. I don't understand exactly how it works underneath the hood, but it ostensibly records mouse movement and GUI interaction and then reenacts what you recorded it when it runs. Unfortunately, I experienced significant lag when running the script. After asking it to run, it would sometimes execute after 5 or more seconds, which is clearly unusable.
The GUI scripting method is almost instantaneous and cleaner-looking (no mouse movement) to boot. I recommend it.