Using the results of an x-callback-url (Working Copy)

I’m trying to retrieve a list of repos in Working Copy - so I can pick one.

According to the Working Copy documentation you can do this with x-callback-url and the repos command. It returns JSON.

How do I - in the URL action, in javascript, or otherwise - retrieve this JSON?

I have successfully got Working Copy write and commit commands working, including using chaining of commands. The difference here is that these don’t return any data, whereas the repos commond does.

Thoughts?

1 Like

I’ve been working on and off with Working Copy and Drafts for a while now and got some Javascript up and running for retrieving a list of repository names. It’s probably still a bit rough, but it has been functional enough for my purposes. Like many of my projects some of the work like this I’ve been doing with Working Copy will see the light of day online at some point.

Anyway, see if this helps you.

//Retrieve a list of Working Copy repositories
function fetchWCRepositories(p_strSeparator)
{
	//Initialise
	//Capture/prep to retrieve the URL key for working copy
	let wcCredential = Credential.create("Working Copy", "Store the URL key for your local install of working copy.");
	wcCredential.addPasswordField("password", "Password");
	wcCredential.authorize();
	//Working copy base x-callback URL for retrieving repositories
	const baseURL = "working-copy://x-callback-url/repos";

	// create and configure callback object
	let cb = CallbackURL.create();
	cb.baseURL = baseURL;
	cb.addParameter("key", wcCredential.getValue("password"));
	// open and wait for result
	if (cb.open())
	{
		//At some point the timing got a bit funny and even though the callback had completed,
		//the data wasn't all back and status was still showing as created
		//Now giving it 4 seconds to return before failing it, but in the meantime,
		//if there's a return then start using it.
		let intCounter = 0;
		const intRepeat = 20;
		const intCheckPeriod_ms = 200;
		while (intCounter < intRepeat)
		{
			//Wait for it...
			sleep(intCheckPeriod_ms);
			//Check the status and prematurely end the loop if we have success
			if (cb.status == "success")
			{
				intCounter = intRepeat;
			}
			intCounter++;
		}

		//Did we have a successful call?
		if (cb.status == "success")
		{
			//Get the returned JSON and parse it
			let jsonReturn = cb.callbackResponse;
			let jsonRepositories = JSON.parse(jsonReturn.json);

			//Build a separated list of repository names
			//Initialise
			let strRepositories = "";
			let intCounter = 0;
			//Loop through all the keys (i.e. all of the sets of repository data) in the repositories set of data
			for (let strKey in jsonRepositories)
			{
				intCounter++;
				//Ensure we have a valid key to work with ... just in case
				if (jsonRepositories.hasOwnProperty(strKey))
				{
					//Append the name of the current repository to the list
					strRepositories += jsonRepositories[strKey].name;
					//If it isn't the last entry in the list append the separator
					if (intCounter < Object.keys(jsonRepositories).length)
					{
						strRepositories += p_strSeparator;
					}
				}
			}
			//Return the repositories
			return strRepositories;
		}
		else
		{
			//Return a message and the callback status code
			return "OPEN - Success: " + cb.status;
		}
	}
	else
	{
		//Return a message and the callback status code
		return "OPEN - Fail: " + cb.status;
	}
}

//Wait for a duration specified in milliseconds
function sleep(p_intMSDelay)
{
	let dtStart = new Date().getTime();
	let dtEnd = dtStart;
	while (dtEnd < dtStart + p_intMSDelay)
	{
		dtEnd = new Date().getTime();
	}
}

//Example call
alert(fetchWCRepositories("\n"));

Thanks for this. I’ll experiment with it.

I had been trying to use HTTP object (having used XMLHttpRequest in the distant past). I’m not sure how to get whatever that passes back.

I’m not sure where Credential comes into it as I’ve set all my WC key values the same and pass them in the url as a key= parameter.

The Working Copy URL key in effect a password. Storing it in the credential means it prompts a user to enter it rather than having them edit the script.

I still actually need to revise the credential part to work with per device settings for Working Copy as the key varies between devices. Easy enough, but just not something I’ve done yet.

As I noted previously, this is still an in progress bit of script. Not one I was planning to publish just yet as it will eventually be a part of something bigger.

Is that a new question or just a comment as to how you were triggering Working Copy?

Hi Stephen. Thanks for your help so far.

It was a comment about how I was hoping to trigger Working Copy. My guess is I need to play with the HTTP class in a simpler context to learn how to retrieve what you get back from a XHR request. Then work with what I’ve learnt to make it work with Working Copy.

I solved it - to my satisfaction - a different way:

I have an action with 2 steps.

  1. Callback URL with URL working-copy://x-callback-url/repos?key= where I get the step to await success.

  2. A javascript step that uses the context.callbackResponses object. See below for sample javascript that alerts for each repository with just the name.

resps=JSON.parse(responses[0]["json"])
for(r of resps){
  alert(r["name"])
}

This is not an “all in javascript” solution - but then I don’t need one.

Hoping this helps somebody.

1 Like

Aargh! The javascript is missing one vital first line:

var responses = context.callbackResponses;
1 Like

Understand that the HTTP object is for http requests…it will not work with other apps local on the device, it will make remote http (or https) requests…e.g. only URLs with “http” schemes. Custom URL schemes are not HTTP and do not operate in the same fashion.

Thanks. I realized this when I couldn’t find anywhere whether to use GET or POST with it. (Guessed GET.)

Don’t try to think of custom URLs like HTTP. The method verbs like GET, PUT, POST do not apply because there is no response inherent to the system. If there was a method that makes sense to describe how custom URLs work, it would be SEND. You are simple sending a message encoded into a URL to another app.

The whole point of x-callback-url is to overcome that limitation by creating a way for another app to SEND a message back.

2 Likes