CallbackURL() hangs if app does not return

actions

#1

When I use CallbackURL() in a script, if the app does not return the x-success value, the script will hang - I presume until a timeout value happens.

For example, if I call an app that has a “Return to Drafts” button, but instead Cmd-Tab back to Drafts, the action step is stuck awaiting the return. Another example: when I link to Working Copy and my action throws an error, like “Invalid URL key”, my action is unusable after that. I have to quit Drafts and relaunch to use the action again.

The URL step does not have this issue.


#2

That is correct. CallbackURL scripted action is designed to allow use of the results of an x-callback-url to be used and to conditionally continue execution of the action based on that result - so it pauses execution.

If you do not need a result, use app.openURL, which will not pause execution.


#3

So with that I have to manually add x-source, x-success, and encodeURIComponent() for everything as I build a string piece by piece?

And with callbackUrl() you have to check if there’s any return value anyway. Wouldn’t it make more sense to await callbackResponse() rather than open()?

Maybe I need to build some kind of wrapper object around openUrl() to do the convenience stuff.


#4

CallbackURL should probably have an option to disable waiting on the response, like the Callback URL action step does - that was an oversight.


#5

Awesome!

In the meantime, I made a workaround function here. (I returned the string instead of a boolean mostly for debugging. Not that I would ever use the string)

var URLScheme = (function() {
	return {
		create: function() { return this; },
		baseUrl: "",
		params: {},
		addParameter: function(name, value) {
			this.params[name] = value;
		},
		useSafari: false,
		open: function() {
			var rv = "?";
			rv += "x-source=" + "Drafts&";
			rv += "x-success=" + encodeURIComponent("drafts5://") + "&";
			for (var p in this.params) {
				if (this.params.hasOwnProperty(p)) {
					rv += p + "=" + encodeURIComponent(this.params[p]) + "&";
				}
			}
			if (this.baseUrl !== "") {
				app.openURL(this.baseUrl + rv.slice(0, -1), this.useSafari);
			}
			return this.baseUrl + rv.slice(0, -1);
		}
	};
})();

#6

Turns out the oversight was just in documenting the property. The CallbackURL object already has and supports a waitForResponse property. I’ll get the docs updated. Example:

let cb = CallbackURL.create();
cb.baseURL = "...";
cb.waitForResponse = false;
cb.open();

#7

Cool. I tried it but still had some issues. I tried using it with Working Copy. In this action I run one callback, awaiting a response. This works fine at first.

For the second call (writing the file, using waitForResponse = false) I tried passing in an invalid URL key to interrupt the x-success flow. WC flags an error (as it should) and the script seems to complete. However, I can’t run the script again, the first call (fetching the list of repositories) locks up. I am not defining waitForResponse on that instance, I presume it must be true.

I am using 2 different instances of CallbackURL, one for each call.

Thanks for your attention to this.