I am trying to create a script that will upload products for me using Applescript and Automator. Im getting an error when the script tries to use the variable for the file path as it iterates through my list. The code is below. I am also inputing the contents of a folder from automator into this script. The error is on line 22. Also, if you could help with the second keystroke on line 42 which needs to iterate with the repeat but in a different folder. Thanks in advance!
on run {input, parameters}
repeat with theItem in input
tell application "Safari"
do JavaScript "document.getElementsByClassName('btn-com btn-info btn-large btn-icon-left add-product-button')[0].click();" in document 1
delay 1
do JavaScript "document.getElementsByClassName('btn-com btn-info btn-large btn-icon-left add-product-button')[0].click();" in document 1
delay 1
do JavaScript "document.getElementById('editor_commerce_product_short_description').innerHTML = 'All photos include full rights to the image and arrive via email. Comes in full 4K resolution. Image displayed is 1080P resolution. Orders may take up to 2 hours to be delivered. Watermarks will be removed!';" in document 1
delay 1
do JavaScript "document.getElementById('editor_commerce_product_price').value = '1.99';" in document 1
do JavaScript "document.getElementsByClassName('btn dropdown-toggle selectbox-display')[0].click();" in document 1
do JavaScript "document.getElementsByClassName('selectbox-content')[1].click();" in document 1
do JavaScript "document.getElementsByClassName('w-upload-input')[2].click();" in document 1
end tell
delay 1
tell application "System Events"
keystroke "G" using {command down, shift down}
delay 1
keystroke theItem
delay 1
keystroke return
delay 1
keystroke return
delay 1
end tell
delay 60
tell application "Safari"
do JavaScript "document.getElementsByClassName('w-upload-input')[1].click();" in document 1
end tell
tell application "System Events"
keystroke "G" using {command down, shift down}
delay 1
keystroke "~/Desktop/Test_Samples/Test_1.png"
delay 1
keystroke return
delay 1
keystroke return
delay 1
end tell
tell application "Safari"
do JavaScript "document.getElementsByClassName('save-product btn-com btn-success')[0].click();" in document 1
end tell
end repeat
return input
end run
It depends on the class of input / theItem. Keystrokes must be text, input can be anything.
Try
keystroke (theItem as text)
or
keystroke (POSIX path of theItem)
And in System Events the equivalent of ⇧⌘G is
keystroke "g" using {command down, shift down}
Related
Is it possible to get the text of Pages app, from its current cursor position?
My requirement is like, when user type something in "Pages", I have to show suggestions for the word they are typing.
so I want to find out the current or last word, near current cursor position from "Pages" app.
Either by using AppleScript or Accessibility?
Text is not selected.
I am not looking for "Services" also.
For apps other than "Pages", I used Accessibility and appleScript. but for pages I am not finding any way.
I have also tried below AppleScript, but some reason it works perfectly in "Script Editor", but when I use it in my code, it goes to infinite loop.
tell application "Pages"
activate
end tell
tell application "System Events"
tell application "System Events"
key code 123 using {shift down, command down} -- shift-command-left
end tell
tell process "Pages"
keystroke "c" using {command down}
delay 1
tell application "System Events"
key code 124 -- shift-command-left
end tell
set myData to (the clipboard) as text
return myData
end tell
end tell
If I run this AppleScript in my app, it freeze my Mac only, I have to force quit the Mac to stop it.
This works for me using the latest versions of macOS Mojave and Pages
property theApp : "Pages" -- change value to name of any other application (TextEdit)
tell application theApp to activate
delay 3
tell application "System Events"
tell application process theApp
-- Move the insertion point to the beginning of the previous word.
key code 123 using {option down} -- left arrow key while holding option down
delay 0.2
-- Move the insertion point to the end of the next word. (selects the word)
key code 124 using {shift down, option down} -- right arrow key while holding option and shift down
delay 0.2
keystroke "c" using {command down} -- copies selected wprd
delay 0.2
-- Next 2 key code commands attempt to restore cursor location
key code 124 using {option down} -- right arrow key while holding option down
delay 0.2
key code 123 using {option down} -- left arrow key while holding option down
tell current application to set myData to (the clipboard) as text
delay 4
return myData
end tell
end tell
I have an AppleScript script that works flawlessly most of the time. The script is intended to execute from within FileMaker, taking information from it and texting a message to a phone number. Between 10 and 20% of the time, however, after entering the phone number, it enters the content there as well instead of placing it in the message field.
Here's the full AppleScript:
set _delay to 1
set _phone_number to repetition 1 of cell "APPLESCRIPT_PIPE" of layout "DEV"
set the clipboard to _phone_number
set _msg to repetition 2 of cell "APPLESCRIPT_PIPE" of layout "DEV"
tell application "System Events"
tell process "Messages"
set frontmost to true
keystroke "n" using {command down}
delay _delay
keystroke "v" using {command down}
delay _delay
keystroke return
delay _delay
set _line_count to count of paragraphs of _msg
repeat with _line_number from 1 to _line_count
set _line to paragraph _line_number of _msg
if _line_number = _line_count then
keystroke _line
delay _delay
else if length of _line = 0 then
keystroke return using {option down}
else
keystroke _line
keystroke return using {option down}
end if
end repeat
keystroke return
end tell
end tell
As you can see, I'm trying to use a delay to reduce the likelihood of the bug, but it hasn't worked. I started with a delay of .25 seconds, then .5, and now 1, but it's still happening.
Any suggestions?
Maybe this solution will work a little better for you instead of involving system events...
set theMessage to "Whatever Text To Send"
set thePhoneNumber to "555-555-5555" -- Any Phone Number INCLUDE THE QUOTE MARKS
-- * Other Acceptable Phone Number Formats *
-- ("1(555)555-5555","(555)555-5555", "5555555555", "15555555555")
tell application "Messages"
launch
delay 5 -- Gives Messages Time To Open (May Need To Adjust)
send theMessage to buddy thePhoneNumber of service "SMS"
end tell
If the above solution does not work for you, you can set the values directly rather than using the clipboard.. Like this...
set theMessage to "Whatever Text To Send"
set thePhoneNumber to "555-555-5555" -- Any Phone Number INCLUDE THE QUOTE MARKS
-- * Other Acceptable Phone Number Formats *
-- ("1(555)555-5555","(555)555-5555", "5555555555", "15555555555")
tell application "Messages" to activate
tell application "System Events"
delay 1 -- May Need To Adjust
click UI element "Compose" of splitter group 1 of window ¬
"Messages" of application process "Messages"
delay 1.5 -- May Need To Adjust
set value of text field "To:" of scroll area 3 of splitter group 1 of window ¬
"Messages" of application process "Messages" to thePhoneNumber
keystroke return
delay 1.5 -- May Need To Adjust
set value of text area 1 of scroll area 4 of splitter group 1 of window ¬
"Messages" of application process "Messages" to theMessage
delay 2 -- May Need To Adjust
keystroke return
end tell
Instead of using keystroke, I used UI Browser to figure out the path to the content field in Messages, then replaced the entire loop with this:
set value of text area 1 of scroll area 4 ¬
of splitter group 1 of window "Messages" to _msg
As a graphic designer, I am constantly having to identify which fonts to use in a document or match a font. Currently I have over 5000 different fonts. I don't keep all 5000 installed on my system. However, I usually do have to scroll through custom collections of 1000 fonts or more using the down arrow key. Sometimes the whole process takes me the better part of an hour
I created a script for auto scrolling in Font Book and saved it as an application named “FontBook_Auto_Scroll.app”. Basically it opens a dialog window giving me three options. If I select “arrow down”, it brings Font Book to the front and pushes the arrow down key 35 times in increments of half a second.
Then the dialogue window opens again. If I select “arrow up”, it brings Font Book to the front and pushes the arrow up key 7 times, etc. But here is the problem. If in the process of “scrolling down”, I see the font I want to use and it happens to appear as the second font in the “scrolling down” cycle, I would prefer not to have to wait until the 35 arrow key down entries are completed.
I'm still playing around with this script and making revisions as I continue reading AppleScript help documents. This is what I have so far.
property selectedFontFamily : missing value
tell application "Font Book"
activate
delay 5
try
set (selected collections) to font domain "AllFonts"
on error errMsg number errNum
set (selected collections) to font domain "AllFonts"
end try
try
set (selected font families) to font family 1
on error errMsg number errNum
set (selected font families) to font family 1
end try
end tell
tell application "System Events"
repeat 2 times
key code 48
end repeat
end tell
delay 1
repeat 40 times
activate
display dialog "Font Book Scrolling" buttons {"Arrow Down", "Arrow Up", "Cancel"} default button 1 giving up after 7
set the button_pressed to the button returned of the result
if the button_pressed is "" then
tell application "Font Book"
activate
delay 1
set (selected collections) to font domain "AllFonts"
tell application "System Events"
key code 37 using {command down, option down}
end tell
delay 1
set selectedFontFamily to (selected font families)
end tell
tell application "System Events"
delay 3
repeat 55 times
delay 0.6
key code 125
end repeat
delay 1
end tell
tell application "Font Book"
set selectedFontFamily to (selected font families)
tell application "System Events"
key code 37 using {command down, option down}
end tell
end tell
else if the button_pressed is "Arrow Down" then
tell application "Font Book"
activate
set (selected collections) to font domain "AllFonts"
tell application "System Events"
key code 37 using {command down, option down}
end tell
set selectedFontFamily to (selected font families)
end tell
tell application "System Events"
delay 3
repeat 55 times
delay 0.6
key code 125
end repeat
delay 1
end tell
tell application "Font Book"
set selectedFontFamily to (selected font families)
tell application "System Events"
key code 37 using {command down, option down}
end tell
end tell
else if the button_pressed is "Arrow Up" then
tell application "Font Book"
activate
set (selected collections) to font domain "AllFonts"
tell application "System Events"
key code 37 using {command down, option down}
end tell
set selectedFontFamily to (selected font families)
end tell
tell application "System Events"
delay 1
repeat 15 times
delay 0.7
key code 126
end repeat
delay 1
end tell
tell application "Font Book"
set selectedFontFamily to (selected font families)
tell application "System Events"
key code 37 using {command down, option down}
end tell
end tell
else if the button_pressed is "Cancel" then
tell application "Font Book"
quit
end tell
return
end if
end repeat
quit
end
on quit
tell application "Font Book"
quit
end tell
continue quit -- allows the script to quit
end quit
It's been my experience that once an AppleScript application starts running its script, sans coded exit points, the only way to get out of a loop is to force quit the application.
Because one may have more then one AppleScript application running at a time and the executable's name, regardless of what one named the application, is applet, you don't want to use a command like do shell script "kill -9 $(pgrep applet)", as it will kill all running AppleScript applications.
I'd have second AppleScript application handy, e.g. "Terminate - FontBook_Auto_Scroll.app", in the Dock for quick access, to isolate the PID of the target AppleScript application, using the following command syntax:
do shell script "kill -9 $(ps -x | awk '/[N]ame.app/{print $1}'); exit 0"
In the case of your "FontBook_Auto_Scroll.app", the command would be:
do shell script "kill -9 $(ps -x | awk '/[F]ontBook_Auto_Scroll.app/{print $1}'); exit 0"
The first character of the application's name is in square braces so as not to confuse the PID returned of the awk query that has the target AppleScript application's name in it.
The ; exit 0 it there so if you accidentally run the AppleScript application that terminates the target AppleScript application when it's not running, it does not error out.
Then when you want to stop the scrolling, use the "Terminate - FontBook_Auto_Scroll.app" AppleScript application to terminate the "FontBook_Auto_Scroll.app" AppleScript application.
BTW Looking at the coding of your AppleScript application, the issue you're going to run into is while it's in the loop, if you set focus elsewhere, the key code events are going to go to whatever has focus.
Update:
Here is some example code, using cliclick, to programmatically mathematically calculate, based on the properties of the UI Elements, where to click.
Tested under macOS 10.12.5, this code will click the All Fonts collection, then the first Font in that collection.
Note: Change the value of the cliclick variable based on where it's located on your system.
set cliclick to POSIX path of (path to home folder as string) & "bin/cliclick"
tell application "Font Book"
activate
-- delay 1
tell application "System Events"
set position of window 1 of application process "Font Book" to {0, 22}
set size of window 1 of application process "Font Book" to {800, 622}
set theFontBookAllFontsProperties to ¬
get properties ¬
of static text 1 ¬
of UI element 1 ¬
of row 2 ¬
of outline 1 ¬
of scroll area 1 ¬
of splitter group 1 ¬
of window 1 ¬
of application process "Font Book"
set theFontBookAllFontsPosition to position in theFontBookAllFontsProperties
set theFontBookAllFontsSize to size in theFontBookAllFontsProperties
set theXpos to (item 1 of theFontBookAllFontsPosition) + (item 1 of theFontBookAllFontsSize) / 2 as integer
set theYpos to (item 2 of theFontBookAllFontsPosition) + (item 2 of theFontBookAllFontsSize) / 2 as integer
tell current application
-- delay 0.25
do shell script cliclick & " c:" & theXpos & "," & theYpos
end tell
set theFontBookAllFontsFirstFontsProperties to ¬
get properties ¬
of static text 1 ¬
of UI element 1 ¬
of row 1 ¬
of outline 1 ¬
of scroll area 2 ¬
of splitter group 1 ¬
of window 1 ¬
of application process "Font Book"
set theFontBookAllFontsFirstFontsPosition to position in theFontBookAllFontsFirstFontsProperties
set theFontBookAllFontsFirstFontsSize to size in theFontBookAllFontsFirstFontsProperties
set theXpos to (item 1 of theFontBookAllFontsFirstFontsPosition) + (item 1 of theFontBookAllFontsFirstFontsSize) / 2 as integer
set theYpos to (item 2 of theFontBookAllFontsFirstFontsPosition) + (item 2 of theFontBookAllFontsFirstFontsSize) / 2 as integer
tell current application
-- delay 0.25
do shell script cliclick & " c:" & theXpos & "," & theYpos
end tell
end tell
end tell
Note: The delay commands may or may not be necessary and or may or may not need to have the value of the delay modified. Uncomment and set as appropriate to the needs.
I have the script like this here:
on run argv
set pid to item 1 of argv
set fileLocation to item 2 of argv
tell application "System Events"
set theprocs to every process whose unix id is pid
repeat with proc in theprocs
set the frontmost of proc to true
using terms from application "Safari"
set theScript to "document.querySelector(\"input[name='fileField']\").click()"
tell application "Safari" to do JavaScript theScript in current tab of first window
end using terms from
tell proc
keystroke "G" using {command down, shift down}
delay 2
key code 51
delay 2
keystroke fileLocation
delay 10
key code 52
delay 5
key code 52
delay 5
end tell
end repeat
end tell
end run
which is trying to do the file upload process on the Safari browser. The main goal is to run the script against the given process id ( as many Safari will be running on the machine).
I have problem here with the line do JavaScript from:
tell application "Safari" to do JavaScript theScript in current tab of first window
this is executing the click call on the different Safari browser, rather than the one given in the pid.
I just want to make sure that the script runs against the given Safari PID.
How can I do that?
I'm trying to automate opening and saving a file in applescript. I can't seem to get consistent results with the save dialog though. Is it possible to change a save dialog to a specific folder in applescript?
This might help you navigate to a folder once the save dialog is raised:
set the clipboard to "/path/to/your/folder"
tell application "System Events" to tell process "SketchUp" -- I'm guessing on SketchUp name
keystroke "G" using {command down, shift down}
delay 1
keystroke "v" using {command down}
delay 1
keystroke return
delay 1
keystroke return
delay 1
end tell
You can do it and keep your clipboard intact, I think. If your save dialog is in TextEdit, if you last saved something to the desktop, for example, the following would change your destination back to Documents. It's easier just to use ⌘+D for that, of course, but you can use substitute pretty much whatever path you need. If you have a path with a folder having non-AppleScript allowable characters in the path (such as quotes), you can escape each with the backslash ("\") character.
tell application "TextEdit"
activate
try
tell application "System Events"
keystroke "g" using {shift down, command down}
do shell script "sleep 0.2"
keystroke "~/Documents"
do shell script "sleep 0.2"
keystroke return
end tell
end try
end tell