Using JavaScript in iOS Shortcuts

Hello everyone, I’m developing an application that does the following tasks:

  • receives a list of text lines as input from the user (one or more text lines);
  • combines those text lines with a pre-inserted URL and opens the web pages one after the other (for example I write “text” and it combines “website.com/” with “text” to open “website.com/text”);
  • injects JavaScript into that web page to do some tasks;
  • go back to Commands app and continues with the next line.

I know that JavaScript in Shortcuts is available only when launching the shortcut from Safari share sheet.
The thing I need is: how can I inject JavaScript in a web page without using Safari share sheet? Using Safari share sheet is not useful for me because I have to inject the same JavaScript in more than one web page automatically.
Any help will be very appreciated.
Thanks in advance.

Angelo G.

I would use Scriptable for this. You could use Webview.loadRequest() and then call evaluateJavascript to execute some Javascript against the page.

1 Like

Thanks for you answer!
I’m not very familiar with JavaScript and Scriptable, could you please explain me what do I have to do to follow your advice?
I guess that webview is used to interact with a web page, is that right?
At the moment my shortcut perfectly collects all of the elements from the input and opens the web pages one after the other, it’ll be fantastic if I could inject JavaScript into the page in the moment the page is open, then going ahead with the next page, injecting JavaScript, and so on…

In case you need it, the JavaScript is used to click on a button on the web page, so pratically I have to open a number of web pages and click a button on all of those pages one after the other.

Yes webview is used to interact with a webpage. In Scriptable you can do something such as:

let sites = ['http://apple.com', 'http://facebook.com'];
let webview = new WebView();
site.forEach( site => {
   await webview.loadURL(site);
   await evaluateJavascript('document.querySelector("button").click()');
});
2 Likes

Very nice!
I will try it as soon as possible and then I’ll tell you if it works. Thank you very much

I’m sorry but I need to ask you something more.

Now I’m working exclusively on shortcuts, so when I need to use scriptable what do I have to do?

I Know that I can create a new script and use it in Commands app, but to inject JavaScript do I need to open URL in my shortcut and then put the Scriptable script after the opened URL?

And also I see that the code you sent me has two website as examples, how can I replace those example with the website generated by my shortcut? I mean: I think that those examples have to be changed with the variable that my shortcut uses to generate the URL, is it right?

And last: I already have the piece of code that gets the button from the web page and uses the click method, how can I insert that piece of code into the script?

Thanks a lot for your help and patience

I’m a bit confused with what you are really trying to do and how you are getting the list of websites you want to process. Here are some pointers which may or may not help you:

  • You can call a Scriptable script from Shortcuts passing parameters such as:

scriptable:///run?scriptName=NameOfScript&customParm1=value&customParm2=value

This would allow you to pass website names you would receive from Shortcuts to be passed to your Scriptable script.

In the end perhaps Scriptable may not be the best solution for you. I really don’t know since I can’t 100% comprehend what you are trying to do. Hopefully you have enough info to at least progress a little farther.

1 Like

Sorry for the confusion, I’ll try to explain easily what my program does.

  • asks you to insert a list of text lines, separated by new lines like this:
    text1
    text2
    text3

  • removes any symbol not desired, like @, ", and other symbols not appropriate for a URL

  • puts the list of lines in a dictionary

  • repeats an action for each line of text, opening a pre-inserted website combining the url of the website with the line: for example website.com/text1, website.com/text2

  • injects javascript into the just opened page in safari *

  • goes back to Commands app by using the “open app…” command

  • continues with the next line of text, and continues for as many lines I have wrote

As you can see I cannot use “Run JavaScript on web page” command because the app is already running and I’m not using Safari share sheet.
So my question is: how can I put Scriptable script in the position that I want my program to run the script? The position where I want the program to run the script is where I put *

I hope that my explanation is this time as simple as possible
I would like to excuse me again for the confusion and thank you for your precious help

If this can help, I attach the screenshots of my command
I want to execute JavaScript right after opening the URL and right before the “wait 5 secs” command

Imgur
Imgur
Imgur
Imgur
Imgur

When I run this I get a syntax error on line 4 saying Unexpected Identifier web view. I’m referring to the code by scottfwalter.

I was getting the same error:
Error on line 4: SyntaxError: Unexpected identifier ‘webview’

I’m guessing it’s because of the typo of “site.forEach”, which probably should be “sites.forEach”

I was getting other errors after that, so I tried to simplify the script for my use case:

let site = "https://edukemy.enhance.rxgindia.com/web#action=hr_dashboard&cids=1&menu_id=112";
let webview = new WebView();
await webview.loadURL(site);
await webview.evaluateJavaScript("document.querySelector('.fa.fa-sign-out.o_hr_attendance_sign_in_out_icon').click()");

This runs but gives me the error:
Error: Failed evaluating JavaScript with error on line 1: TypeError: null is not an object (evaluating ‘document.querySelector(’.fa.fa-sign-out.o_hr_attendance_sign_in_out_icon’).click’)

Any help would be appreciated :blush:

PS: I’ve used this javascript using Keyboard Maestro, and that works, just not sure how I can get this to work using Scriptable.

What if you remove the await from the evaluate JavaScript line?

The error is saying that the element was not found on which you tried to call .click() on. This happens probably because the website loads data asynchronous after page load and then generates the element when it got the data. To fix the problem, simply retry getting the element in a setInterval or setTimeout until you have found it. You can also add a timeout after e.g. 5 tries and then cancel the whole thing you want to do, so the script does not block.

1 Like