I'm trying to do the simplest thing in the world - a basic iterator in Automator. The workflow goes:
Get Value of a Variable (initially set to 1)
Run Applescript:
on run {input, parameters}
set input to input + 1
return input
end run
Set Value of a Variable
Loop
It works the first time, moving from 1 up to 2 as expected. But it fails on the second pass, giving the error
Can't make {} into type number. (-1700)
I'm clueless as to why - I've tried getting it to output from the Applescript as an integer and it makes no difference. Can anyone shed some light?
Your error is because on the second loop of your workflow your applescript is not receiving any input. I would guess that your loop function is not receiving any input and therefore it is not passing anything back into the applescript. Whatever is between your applescript and the loop function must be interfering somehow.
As an alternative, try this as your applescript. Your automator workflow should only have 2 actions, this applescript code and the loop action set to "use current results...".
In this code, on the first loop there won't be any input to the applescript so it will ask you for input, and then on subsequent loops the applescript will receive input from the loop action and thus it will increment your initial input.
Good luck.
on run {input, parameters}
if input is {} then
display dialog "Enter a number" default answer "1"
set input to (text returned of result) as number
else
set input to input + 1
end if
return input
end run
Related
PreNote: I am open and hungry for any information, advice, tip etc.
Hello Everyone!
I am trying to create automation with applescript. This is my first personal applescript task but I have some valuable questions. Basically I am trying to catch live notifications from a website and display them in mac os notification.
I am trying to build process for a few days but I don't want to give a mess to you :) so I have roughly explained my process below.
(* Variables used in whole process
set $webToCheck > This is Safari webpage which I want to run my script on it. It won't be front window, script should be run with its name or other property.
set $theClass > This is class name of DOM element to check if it is exist or not. This class is not always exist on DOM of $webpage. It comes with notifications so when use it in "do Javascript" I got error "variable is not defined"
set $num > number of class to use in "do Javascript"
set $input > variable to assign HTML text
set $modifiedInput > Text of input seperated from HTML tags
*)
-- Step 1
tell application "Safari"
work on $webToCheck
-- Step 2
repeat until $input is not empty
set input do Javascript
document.getElementsByClassName > $theClass, $num of $webToCheck
end repeat
-- Step 3
modify text of $input to seperate from RAW HTML -- For example: <a class="" value=""> TEXT to be seperated </a>
Display notification $modifiedInput
-- Step 4
Go back to step 1 or 2 to check and display notification again
First of all, here are some general tips though:
Applescript won't accept $ at the start of variable names.
The variable assignment you are looking for is set {variable} to {value}. You can optionally at the end of it clarify the variable's class using as {class} at the end of the assignment.
Focusing a certain website does not happen with work on {URL} but as with most object oriented things in Applescript with the tell-statement. It will be shown in the full solution.
Text concatenation in Applescript happens with &. So something like "Hello " & "World" is the standard way to do it.
Modification of most things in Applescript happens with set.
It is easier to use innerText instead of innerHTML as splitting text in Applescript is a bit of a pain.
There is no goto but you could wrap the first few steps into a function, which are declared with on or to in Applescript.
Here is the full code with some documentation sprinkled in there:
global webToCheck, theClass, num, input --This says that all variables can be used even in functions.
set webToCheck to "youtube.com" --Strings can only use double quotes.
set theClass to "style-scope yt-alert-with-actions-renderer" --I will use an actual demo to prove that it is working
set num to 0 as integer -- This is the type declaration I was talking about. For numbers we have integer, real(float) and number.
set input to "" -- You don't have define everything at the top, but I will do so for this.
on displayNotification()
tell application "Safari"
tell window 1 -- This will target only the first window. For multiple windows you would have to write a repeat with-loop(for-loop), which I'm not going to do, for the sake of simplicity.
tell (first tab whose URL contains webToCheck) -- This targets just the first tab which contains the webToCheck variable.
set input to do JavaScript "document.getElementsByClassName('" & theClass & "')[" & num & "].innerText" -- This is the way I would go about writing the Javascript. I think you had something different in mind, but this works for my example.
display notification (paragraph 1 of input) with title webToCheck -- This displays the first line of my input since that is the relevant part. I also set a title so I doesn't just say "Script Editor"
end tell
end tell
end tell
end displayNotification
repeat 4 times -- I think this is quite obvious. Adjust this to your needs.
displayNotification()
delay 4
end repeat
Running this while having not used youtube on Safari in a while it displays this:
Note that this isn't the most elegant solution, but I think it is readable and it (hopefully) works for your needs.
In my Automator action, I use an "Run AppleScript" action, that returns a list (via AppleScript). Here is the AppleScript:
on run {input, parameters}
set result to {"Foo", "Bar", "42"}
return result
end run
Later in my Automator action, I need to use values "Foo", "Bar", and "42" in different places.
How can I assign those 3 values to different Automator variables?
Taking your question literally, you have to first set the result of the Run AppleScript action, which in this case is a list, to a Set Value of Variable action.
Next, you'd add a Get Value of Variable1 action. setting its Options to [√] Ignore this actions input so as to make a disconnect from the Set Value of Variable action.
Next, add a Run AppleScript action with the following example AppleScript code:
on run {input, parameters}
return item 1 of input
end run
Then add a Set Value of Variable action for this first item in the list returned from to original Run AppleScript action.
Repeat again for the next two items in the list.
1Technically you could send the output of the first Set Value of Variable action directly to the second Run AppleScript action to set the first list item to it new variable; however, I broke it into a separate action so the creation of the three list items as separate variables followed the same action path.
Note: The example AppleScript code is just that and does not contain any 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.
I am making a calendar alarm workflow that pulls text from a website and compares it to the text stored in a local file once a day. I store the text in the two variables "newText" and "oldText" in Automator. With the following apple-script code I try to access and compare these two variables. If they are equal, I want the break out of the workflow.
on run {input, parameters}
set newText to value of variable "newText" of front workflow
set oldText to value of variable "oldText" of front workflow
if newText is equal to oldText then
tell me to quit
end if
end run
The workflow works fine when run from automator, but when launched from the calendar-event I get the following error (second line):
Syntax Error, Expected end of line, etc. but found “"”.
All suggestions appreciated!
Outside of Automator you must wrap the related code in an application tell block
tell application "Automator"
set newText to value of variable "newText" of front workflow
set oldText to value of variable "oldText" of front workflow
end tell
if newText is equal to oldText then
tell me to quit
end if
I have made a small automator script that runs a bash shell script and gets two outputs... On viewing results it appears like this below...
I want them in two automator variables
Assume I used a script like
echo "200"
echo "19 hours, 4 minutes and 42.765 seconds"
and on viewing the results it shows this (and I want each of these as automator variables called count and duration). I want it to be sent to a display notification with subtitle as "count files processed" and message as "duration elapsed". How can I achieve this?
You can modify Automator variables by applescript. The variables must exists in the workflow, so you first should add two variables, to get something like on the next image:
You can set anyting as their initial value...
After the above, you can use the next applescript, right after your shell script
on run {input, parameters}
set value of variable "Count" of front workflow to item 1 of input
set value of variable "Duration" of front workflow to item 2 of input
return input
end run
It is not fully correct, (for example it isn't check the number of arguments on the input), but you get an idea.
So after the next:
Your automator variable Count will contain 200, and the variable Duration will contain the text.
I am trying to create a service in OSX leopard that counts the number of words of selected text. I have automator set to run an applescript, with the following put in it:
on run {input, parameters}
count words of input
display alert "Words: " & input
return input
end run
When I compile the script, it says it cannot count every word. What am I doing wrong?
Thanks for the help,
Elliott
First of all, I presume you are testing this in Automator, and that's where the error is taking place? If so, the likely problem is that there is no input—so it can't count the words of nothing. In order to test it successfully, you need to temporarily add a "Get Specified Text" action before the Run AppleScript action, and enter some test text into that field. You'll have to remove the Get Specified Text action before using it as an actual service.
Secondly, you need to use
count words of (input as string)
in order to get a proper count, otherwise it'll return zero.
I made one here, on Github:
https://gist.github.com/1616556
The current source is:
on run {input, parameters}
tell application "System Events"
set _appname to name of first process whose frontmost is true
end tell
set word_count to count words of (input as string)
set character_count to count characters of (input as string)
tell application _appname
display alert "" & word_count & " words, " & character_count & " characters"
end tell
return input
end run
Use Automator.app to create a new service, and then select the Run AppleScript action. Paste this code in to the text box, and save as Word and Character Count. Now switch to a new app, select some text, and open the context menu to find the new option.