Ability to export all Notes in macOS Notes.app as PDFs.
execution error: Notes got an error: AppleEvent handler failed. (-10000)
Multiple scripts, latest below.
tell application "Notes"
activate
repeat with theFolder in every folder
repeat with theNote in every note of theFolder
tell application "System Events"
tell process "Notes"
set dockPrefs to dock preferences
set appearancePrefs to appearance preferences
delay 1
display dialog "Foo"
tell menu bar 1 of process "Notes"
click menu bar item "File"
click menu item "Export as PDF..." of menu "File" of menu bar of process "Notes"
end tell
click button "Save" of sheet 1 of window "Notes" of process "Notes"
delay 1
key code 125
end tell
end tell
end repeat
end repeat
end tell
execution error: Notes got an error: AppleEvent handler failed. (-10000)
There are a few problems in there:
You are already targeting the Notes process, so including that in
the click statements is adding another process target - use one or the other, but if you are
doing a lot of menu clicks you might look at using a general
purpose handler;
The export menu item uses an ellipse (a single character), not three
periods;
By placing a display dialog statement in the System Events tell statement, you are moving the focus away from the application.
Also note that the text field is selected and the save button is the default in the sheet, so you can use keystrokes instead of trying to click UI elements. A cleaned up example (tested in Mojave) would look something like:
tell application "Notes"
launch -- seems to work better than 'activate'
repeat with aFolder in folders
repeat with aNote in notes of aFolder
set noteName to (name of aNote)
try -- keep the name a reasonable length
set noteName to text 1 thru 20 of noteName
end try
tell (current date) to set timeStamp to text 2 thru -1 of (get (1000000 + (its hours) * 10000 + (its minutes) * 100 + (its seconds)) as text) -- hhmmss
tell application "System Events"
#display dialog noteName -- testing?
tell process "Notes"
set frontmost to true -- retarget the Notes app
delay 0.5
click menu item "Export as PDF…" of menu "File" of menu bar item "File" of menu bar 1
repeat until exists sheet 1 of window 1 -- wait for the sheet
delay 0.02
end repeat
end tell
keystroke noteName & "_" & timeStamp -- update the name, trying to avoid duplicates
delay 0.5
keystroke return -- dismiss the sheet
delay 0.5
key code 125
end tell
end repeat
end repeat
end tell
Related
I am trying to automate via AppleScript the addition and the selection of a specific language in macOS Big Sur (for example Spanish) from System Preferences > Language & Region.
I can display the UI via this code, but I cannot get the "+" button to click.
tell application "System Preferences"
reveal anchor "Language" of pane id "com.apple.Localization"
activate
tell application "System Events"
tell window 1 of application process "System Preferences"
set i to 0
repeat until exists button 1 of group 1
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
-- # Click the [+] button.
click button 1 of group 1
end tell
end tell
end tell
The example AppleScript code, shown below, was tested in Script Editor under macOS Big Sur with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
1 Assumes necessary and appropriate settings in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.
The value of the property thisLanguage needs to be set to that which will show in the list of the Select a preferred language to add: sheet, as it is set to the value of the text box on the Select a preferred language to add: sheet. This is necessary so AppleScript does not have to spend a lot of time searching the entire list as the target should now be it the top portion of the list.
Note that for, e.g., Español this script as is, is all that was necessary, however, on some languages one may get an additional sheet to reply to. For example, with 简体中文 (Simplified Chinese) one gets an additional Select input sources to add: sheet, and you will need to add additional code to handle it. You should be able to, from the example AppleScript code shown below, figure out how to deal with it as there is already an example therein.
Example AppleScript code:
property thisLanguage : "Español"
-- # Check to see if System Preferences is
-- # running and if yes, then close it.
-- #
-- # This is done so the script will not fail
-- # if it is running and a modal sheet is
-- # showing, hence the use of 'killall'
-- # as 'quit' fails when done so, if it is.
-- #
-- # This is also done to allow default behaviors
-- # to be predictable from a clean occurrence.
if running of application "System Preferences" then
try
tell application "System Preferences" to quit
on error
do shell script "killall 'System Preferences'"
end try
delay 0.1
end if
-- # Make sure System Preferences is not running before
-- # opening it again. Otherwise there can be an issue
-- # when trying to reopen it while it's actually closing.
repeat while running of application "System Preferences" is true
delay 0.1
end repeat
-- # Reveal the General tab of the Language
-- # & Region pane in System Preferences.
tell application "System Preferences"
reveal anchor "Language" of ¬
pane id "com.apple.Localization"
activate
end tell
-- # System Events handles the rest.
tell application "System Events"
launch
delay 0.2
tell application process "System Preferences"
-- # Click the [+] button.
click button 1 of group 2 of tab group 1 of window 1
-- # Wait for sheet 1 to be available.
set i to 0
repeat until exists text field 1 of sheet 1 of window 1
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
-- # Search for: thisLanguage
set the value of ¬
text field 1 of ¬
sheet 1 of ¬
window 1 to ¬
thisLanguage
delay 1 -- # May need to be increased.
-- # Get the row that matches thisLanguage.
set theTargetRow to ¬
the first row of ¬
table 1 of ¬
scroll area 1 of ¬
sheet 1 of ¬
window 1 whose value of ¬
static text 1 of ¬
UI element 1 is thisLanguage
-- # Select the row that matches thisLanguage.
select theTargetRow
-- # Click the Add button.
click button 3 of sheet 1 of window 1
-- # Wait for the sheet to change.
set i to 0
repeat until exists ¬
button "Use English (US)" of ¬
sheet 1 of window 1
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
-- # The button for thisLanguage
-- # should have focus, press enter.
keystroke return
end tell
end tell
delay 0.2
tell application "System Preferences" to quit
Notes:
The use of the launch command after tell application "System Events" is to try and help with a systemic issues in UI Scripting as a result of changes Apple had made in macOS Big Sur.
Also note that UI Scripting is often kludgy and prone to failure for a variety of reasons and why I have used the error handling that I have, however, one may need to add addition error handling and or delay commands and or adjust the value of existing ones, as needed.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
I've automated printing a weekly calendar with 'applescript' and 'Calendar'. There is a scroll area with collection of checkboxes. How do you iterate over every checkbox in a scroll area and uncheck it?
https://gist.github.com/spuder/c92dd0637ce85b6960b81e1415d7c52e
This works but is fragile since the rows are hard coded.
-- Click the “<fill in title>” checkbox.
delay 0.5
set timeoutSeconds to 2.0
set uiScript to "click checkbox 1 of row 2 of outline 1 of scroll area 1 of window \"Print\" of application process \"Calendar\""
my doWithTimeout(uiScript, timeoutSeconds)
-- Click the “<fill in title>” checkbox.
delay 1
set timeoutSeconds to 2.0
set uiScript to "click checkbox 1 of row 3 of outline 1 of scroll area 1 of window \"Print\" of application process \"Calendar\""
my doWithTimeout(uiScript, timeoutSeconds)
-- Click the “<fill in title>” checkbox.
delay 1
set timeoutSeconds to 2.0
set uiScript to "click checkbox 1 of row 4 of outline 1 of scroll area 1 of window \"Print\" of application process \"Calendar\""
my doWithTimeout(uiScript, timeoutSeconds)
This seems like it should work but it does not uncheck any of the boxes
delay 1
set timeoutSeconds to 2.0
set uiScript to "click checkbox 1 of every row of outline 1 of scroll area 1 of window \"Print\" of application process \"Calendar\""
my doWithTimeout(uiScript, timeoutSeconds)
This works for me using the latest version of macOS Mojave
tell application "Calendar"
activate
reopen
end tell
tell application "System Events" to tell application process "Calendar"
if not (exists of window "Print") then keystroke "p" using command down
repeat while not (exists of window "Print")
delay 0.1
end repeat
set everyCheckboxRef to a reference to every checkbox of rows of outline 1 ¬
of scroll area 1 of window 1
repeat with i from 1 to count of everyCheckboxRef
set thisCheckbox to item i of everyCheckboxRef
if value of thisCheckbox is 1 then perform action "AXPress" of thisCheckbox
end repeat
end tell
The following example AppleScript code is one way to achieve the goal of unchecking all checkboxes in the Calendars section of the Print dialog box in the Calendar application:
-- # Check to see if Calendar is open and act accordingly.
if running of application "Calendar" then
-- # Calendar is already open however, make sure the main window is showing not minimized.
tell application "Calendar"
if not (visible of window "Calendar") then set visible of window "Calendar" to true
activate -- # Bring the main window forward.
end tell
else
-- # Calendar is not open, so open it.
tell application "Calendar"
activate
-- # Wait for main window before proceeding.
repeat until exists window "Calendar"
delay 0.1
end repeat
end tell
end if
-- # Open the Print dialog box.
tell application "System Events" to keystroke "p" using command down
-- # Make sure the Print dialog box is showing before proceeding.
tell application "Calendar"
repeat until exists window "Print"
delay 0.1
end repeat
end tell
-- # Uncheck all checkboxes in the Calendars scroll area of the Print dialog box.
tell application "System Events"
tell outline 1 of scroll area 1 of window "Print" of application process "Calendar"
repeat with i from 1 to (count rows)
tell row i
if (count UI element) > 0 then
click checkbox 1
end if
end tell
end repeat
end tell
end tell
Note: The example AppleScript code is just that and does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also Working with Errors. Additionally, UI Scripting may require the use of the delay command as appropriate, needed or wanted.
I am trying to interact with iTunes "Export Library.." dialog.
I tried "set choices to every menu item of menu 1 of pop up button 1 of group 1 of window winName" but it says "group 1" is an invalid index?
Here's the relevant code: (the call parameters are: "iMac-8GB", "iTunes", "iTunes", false"
on handleDir(dir, winName, appName, createIt)
local foundIt, ndx
set foundIt to false
if winName is not "" then
tell application "System Events" to tell process "iTunes"
set choices to every menu item of menu 1 of pop up button 1 of group 1 of window winName
You want to use the menu "Export Library…" from iTunes :
The first step is to select the relevant menu. In my iTunes version (12.5.5.5) the menu is in "File" menu, sub menu item "Library" and then sub Menu "Export Library…".
The second step is to fill the export file name and set the destination folder. The Mac "Save as…" window has many shortcuts, valid for all applications. Among others, command G allows to define the complete path to save the file. This path must be in Unix format (with "/" and not ":" for sub levels).
The bellow script does the complete Export Library function. The first 2 rows define the name of the file to save and the path where to save it. Adjust them to your needs.
set myTitle to "test" -- name of the exported file
set myPath to "/Users/myuser/Desktop/Test_folder" -- destination folder for export file
tell application "iTunes" to activate -- make iTunes front
tell application "System Events"
tell process "iTunes"
click menu 3 of menu bar 1 -- open the File menu
click menu item 12 of menu 3 of menu bar 1 -- select the Library menu item
delay 0.1
click menu item 5 of menu 1 of menu item 12 of menu 3 of menu bar 1 -- select the export library… item
delay 0.1
keystroke myTitle -- fill the export file name in the save as… dialog
keystroke "G" using command down -- shortcut to open Go-to folder window
keystroke myPath
keystroke return -- to close the go-to window
delay 0.1
keystroke return -- to close the export window
end tell -- process iTunes
end tell -- system Events
I added several delays to make sure your Mac has enough time to open or close windows.
Using this code, modified to specifically target iTunes':
tell application "System Events"
tell front window of (first application process whose frontmost is true)
set uiElems to entire contents
end tell
end tell
which came from an answer to Use AppleScript to list the names of all UI elements in a window (GUI scripting)
I discovered that a NSBox is referred to as an "outline" by Applescript.
I've been able to achieve 95% success using the following script on my Mac OS X 10.10.1 However, I can't get the email that I've opened to "Close". Any suggestions???
Here's the Applescript:
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
tell application "Mail"
-- walk through all matching messages
repeat with thisMessage in theMessages
-- open the message
set openedMail to open thisMessage
-- perform your UI scripting
tell application "System Events"
tell process "Mail"
-- Select the Print menu item
click (first menu item of menu "File" of menu bar 1 whose name begins with "Print")
tell window 1
-- Wait until the print sheet appears
repeat 30 times
if sheet 1 exists then exit repeat
delay 0.5
end repeat
tell sheet 1
-- Click the PDF button
click menu button "PDF"
-- Select the PDF to SBS Dropbox menu item
delay 0.5
click (first menu item of menu 1 of menu button "PDF" whose name begins with "PDF to SBS Dropbox")
delay 4
end tell
end tell
end tell
end tell
-- close the message
close openedMail
end repeat
end tell
end perform mail action with messages
end using terms from
If your code doesn't work then why not try the same technique you used earlier with system events...
click (first menu item of menu "File" of menu bar 1 whose name begins with "Close")
Or you can just tell mail to do it with...
close window 1
I am testing applescripts that I will use later in my OSX app.
I'm getting a 6 sec delay after the click button command below.
After some research it seems that this is a known issue.
What I find interesting is, if i use the commercial app QuicKeys to perform the same
button click there is no delay, so I assume they found a work around.
Anybody have any ideas?
tell application "System Events"
tell process "Pro Tools"
set frontmost to 1
click button "Track List pop-up" of window 1
-- 6 seconds delay before next command is sent
key code 36 -- return key stroke
end tell
end tell
Was having the same problem and resolved it by enclosing the click causing delay in the ignoring application responses block. Here is a quick summary:
OLD CODE (Causes 6 sec delay)
tell application "System Events" to tell process "SystemUIServer"
set bt to (first menu bar item whose description is "bluetooth") of menu bar 1
click bt
tell (first menu item whose title is "SBH80") of menu of bt
click
tell menu 1
if exists menu item "Disconnect" then
click menu item "Disconnect"
else
click menu item "Connect"
end if
end tell
end tell
end tell
NEW CODE (No delay)
tell application "System Events" to tell process "SystemUIServer"
set bt to (first menu bar item whose description is "bluetooth") of menu bar 1
ignoring application responses
click bt
end ignoring
end tell
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "SystemUIServer"
tell (first menu item whose title is "SBH80") of menu of bt
click
tell menu 1
if exists menu item "Disconnect" then
click menu item "Disconnect"
else
click menu item "Connect"
end if
end tell
end tell
end tell
Please check detailed answer in the thread listed below.
Speed up AppleScript UI scripting?
Hope this helps.
It seems click or axpress causes a big delay.
Instead - get position and use a third party shell script to do the clicking. Much Much faster.
using clicclik : https://www.bluem.net/en/mac/cliclick/
put in user library/application support/Click
set clickCommandPath to ((path to application support from user domain) as string) & "Click:cliclick"
set clickCommandPosix to POSIX path of clickCommandPath
tell application "System Events"
tell process "Pro Tools"
set frontmost to 1
tell button "Track List pop-up" of window 1
set {xPosition, yPosition} to position
set x to xPosition
set y to yPosition
end tell
do shell script quoted form of clickCommandPosix & " c:" & xPosition & "," & yPosition
key code 36 -- return key stroke
end tell
end tell