API calls using runCommand and parsing json result

I’m making API calls for UID of the specific page in Roam Research.
The code I use in the terminal:


# Call the Roam Research API and extract the UID
output=$(curl -s -X POST "https://peer-58.api.roamresearch.com:3001/api/graph/GraphName/q" \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-XXX" \
-H "Content-Type: application/json" \
-d "{
    \"query\" : \"[:find (pull ?b [:block/uid :node/title]) :in $ ?search-string :where [?b :node/title ?page-title] [(clojure.string/includes? ?page-title ?search-string)]]\",
    \"args\": [\"@bokszanski2016\"]

uid=$(echo $output)
echo $uid

The result I get for the specific page ‘@bokszanski2016’ is in JSON format:

	"result": [
				":node/title": "@bokszanski2016",
				":block/uid": "nCh-Ttau4"

I want to use runCommand in Tinderbox to run the code using $Name (name of the note in Tinderbox and Roam Research is the same) and parse the result into URL attribute.
I’ve tried to run this code

$MyString= runCommand("curl -s -X POST 'https://peer-58.api.roamresearch.com:3001/api/graph/GraphName/q' -H 'accept: application/json' -H 'Authorization: Bearer roam-graph-token-XXX' -H 'Content-Type: application/json' -d '{\"query\" : \"[:find (pull ?b [:block/uid :node/title]) :in $ ?search-string :where [?b :node/title ?page-title] [(clojure.string/includes? ?page-title ?search-string)]]\",\"args\": [\""+$Name+"\"]}'");

but I get

/bin/sh: line 1: unexpected EOF while looking for matching `''
/bin/sh: line 2: syntax error: unexpected end of file

I think the problem is in "+$Name+", but I’m not sure… Should I escape the quotes, if so, how do you do it?

Let’s say I somehow managed to make it work, how can I parse the result to make and pseudo-URL look like this one: roam://#/app/GraphName/page/nCh-Ttau4?
Will the code below work in my case?

$RoamResearchPage="roam://#/app/GraphName/page/" + $MyString.json[:block/uid];

Really appreciate any help!

Your command line has parts like:

\"args\": [\""+$Name+"\"]}'"

You can’t escape quotes in action code, e.g. this won’t work "\"Hello\"". You can nest quote types "Hello" but this poses problems in the command line.

See runCommand(commandStr[, inputsStr, dirStr]).

However, most of your massive command line is a string, which I can recreate accurately as an action code output like so:

Not how a space+single quote either as the end of $MyString or he beginning of $MyString1 didn’t work but a using a literal string did.

So we can make the whole command line this way in the Test note:

$MyString("CL") = $MyString+" '"+ $MyString2+$MyString3+$MyString4;

Now you should be able to to call, in note ‘CL’:


Or you may choose the runCommand(command, args) double argument form and assemble the data accordingly.

If you want to populate attributes, you should be able to use action code variables instread, e.g. untested:

var:string vCL = $MyString+" '"+ $MyString2+$MyString3+$MyString4;

I think a variable should work in this context. A sensible approach is to get the process working with an attribute value, then try substituting a variable.

Indeed as much of the data here is essentially boilerplate, you might want to store it as global strings, e.g. via a ‘config’ note, so a note at path /config could hold the parts of the CL and be called via $MyString(/config), etc.

1 Like

I just got it to work, thank you so much for the time you spent on my problem!

I couldn’t get the .json parsing right, but .extract(‘(?<=:block/uid":“)[^”]+’) also works well!
Thanks again!

1 Like

Yes, I think there are some gremlins with JSON capture at present.

Here’s another approach— no better/woese that your solution, just another way.

I used the JSON you supplied above and set it as the $Text of a note and then used stream processing:

var:string vStr;
$Text.skipTo(':block/uid": "').captureTo('"',vStr);
$MyString = vStr;

The last line was just to prove I got a clean extract of the nCh-Ttau4 value with no extraneous quotes.

I’m not sure why Roam thought a colon and a forward slash were sensible or needed in a JSON key name, but I think they are allowed. Luckily the API is returning little data so the methods about are giving you the $Name you need. At that point, if it works, who cares why! :slight_smile:

1 Like