Trying to write a script to open a random URL from a text file

Hello,

I’m new to Scriptable and Javascript in general. I’ve written this same script using Python on my PC, but I really want to use it on my iphone instead using scriptable.

The end goal is to open a random URL from a text file. (The URLs are chess drills from a chess website I subscribe to.)

This is what my code looks like. I’m storing the file urls.txt in the same folder as the script. When I run this on my iphone, absolutely nothing happens.There are no errors. If someone can spot something I’m doing wrong, I would be most appreciative!

// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-gray; icon-glyph: magic;
// This script opens a random URL from a text file

async function run() {
  // Read the contents of the text file
  let file = await File.read("urls.txt");
  let lines = file.split("\n");

  // Pick a random line from the file
  let index = Math.floor(Math.random() * lines.length);
  let url = lines[index];

  // Open the URL in the default web browser
  Safari.open(url);
}

run();

A sample of the contents of the urls.txt file looks like this:

https://chessly.com/dashboard/learn/courses/812a7981-0439-4de4-a86b-35b9833eea25/lessons/2ac9b6fe-e34d-44a9-a129-03960380c817
https://chessly.com/dashboard/learn/courses/812a7981-0439-4de4-a86b-35b9833eea25/lessons/228cb940-12c2-4280-ae1e-a2771ada3022
https://chessly.com/dashboard/learn/courses/812a7981-0439-4de4-a86b-35b9833eea25/lessons/22575f74-9064-4213-87fd-ae08b65bae4f
https://chessly.com/dashboard/learn/courses/812a7981-0439-4de4-a86b-35b9833eea25/lessons/e2139217-977a-4a8b-82c8-7ed70db725f4
https://chessly.com/dashboard/learn/courses/812a7981-0439-4de4-a86b-35b9833eea25/lessons/14a28fb0-1646-459c-88e2-2cbddfc2f081
https://chessly.com/dashboard/learn/courses/812a7981-0439-4de4-a86b-35b9833eea25/lessons/d922e1d3-23b6-4fbb-a8e4-4e822761afac
1 Like

Change this line

let file = await File.read("urls.txt");

with this

let fm = FileManager.iCloud()
let filePath = fm.joinPath( fm.documentsDirectory(), "urls.txt")
let file =  fm.readString(filePath);

Hello! thank you so much for the help. I made the recommended substitution, but now when I run the script, I get the following error:

"2022-12-20 09:01:03: urls.txt is stored in iCloud but the file have not been downloaded. Use downloadFileFromiCloud(filePath) on a FileManager to download the file before accessing it."

So I tried asking ChatGPT what might be wrong and it suggested that I edit my script adding the command mentioned in the error. My new script looks like this:

// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-gray; icon-glyph: magic;
// This script opens a random URL from a text file

async function run() {
  // Read the contents of the text file
  let fm = FileManager.iCloud()
  let filePath = fm.joinPath(fm.documentsDirectory(), "urls.txt")

  // Download the file from iCloud
  await fm.downloadFileFromiCloud(filePath)

  // Read the contents of the file
  let file = fm.readString(filePath);
  let lines = file.split("\n");

  // Pick a random line from the file
  let index = Math.floor(Math.random() * lines.length);
  let url = lines[index];

  // Open the URL in the default web browser
  Safari.open(url);
}

run();

But sadly, once again, when I run this nothing happens–no error message. I tried running a script that would verify Scriptable has access to my iCloud by writing a simple test.txt test file. And that worked fine.

I’m going to try to break this down into some very simple commands to see which one is failing. At this point I don’t know if it’s failing to read the URL from the file, or failing to open the URL. So I’ll try to figure out a test for each of these separately. I’m of course happy and grateful for any other tips or advise! Cheers. :slight_smile:

Just a hunch here. Can you try calling the run function with await? Basically await run();.

Although it shouldn’t matter, I’m just thinking the script might be terminating prematurely after the call to run and the promise is not being resolved.

Oh wow! Progress! Thank you!

Now it’s just telling me the URL is invalid. So it’s parsing and reading the file correctly–that’s great!

I must have my URL syntax slightly off or something…

Error on line 20:14: The URL is invalid: https://chessly.com/dashboard/learn/courses/812a7981-0439-4de4-a86b-35b9833eea25/lessons/78bffe55-3637-4712-b954-a6d56aa10f69

Progress is encouraging :blush:

Alrighty I figured it out. The URL error was because I wasn’t properly logged into the chess site on my phone. It’s working properly now–but only if I’m logged in. :+1:

But the real MVP is @supermamon! Thank you for the suggestion to use await run();–that was the source of all my woes with this one. :grin: