BridgeTalk Export as Binary failure

BridgeTalk, the system that enables messaging between applications in the Adobe scripting ecosystem, is prone to failure when evaluating functions via .toSource() – be aware and stringify them in advance!

BridgeTalk 101

This simple script sends a message from Photoshop to Adobe Bridge – that is to say, Photoshop gives Bridge some code to execute:

#target photoshop
var bt = new BridgeTalk()
bt.target = 'bridge';
bt.timeout = 30;
bt.body = "$.writeln('Greetings from Bridge'); true;";
bt.onReceived = function(btObj) {
	return $.writeln('Message received.');
};
bt.onResult = function(btObj) {
	return $.writeln('BridgeTalk result: ' + btObj.body);
};
bt.onError = function(btObj) {
	return $.writeln(btObj.body);
};
bt.onTimeOut = function(btObj) {
	return $.writeln(btObj.body);
};
bt.send(31);

The Console outputs:

Greetings from Bridge
BridgeTalk result: true
Result: true

It does the job configuring a BridgeTalk Object, which .body is the actual part of the script in charge of Bridge (here just a String).

You can specify callbacks invoked by the target application (in the example Bridge) such as:

  • onResult()¬†– to return a response (to Photoshop), which is handled by the function;
  • onError() – to return and handle an error;
  • onTimeout() – when a timeout occurs;
  • onReceived() – handler fired when the target app receives the message. For some reason, it’s triggered after, and not before, onResult().

Mind you, if the .send() method is called without any argument, the message is asynchronous, while if you specify the number of seconds to wait for before returning from the function, the message is sent synchronously. More info about BridgeTalk in the JavaScript Tools Guide CC, from page 170 onwards.

Using functions

When the message body is trivial, it can be assigned to a String literal; conversely, when you need the target app to perform some more elaborated tasks, it’s common practice to use a separate function. This is the same as the first example (I will omit some of the callbacks):

var bridgeFun = function () {
	$.writeln('Greetings from Bridge');
	return true;
}
var bt = new BridgeTalk()
bt.target = 'bridge';
bt.body = "var bridgeFun = " + bridgeFun.toSource() + "; bridgeFun();";
bt.onResult = function(btObj) {
	return $.writeln('BridgeTalk result: ' + btObj.body);
};
bt.send(31);

The .toSource() method returns a string representing the source code for the function. So the message body (bt.body) is:

var bridgeFun = (function () { $.writeln('Greetings from Bridge'); return true; }); bridgeFun();

Beware .toSource()

There are at least a couple of issues with .toSource(). First be careful when commenting lines in the separate function – always use /* */ and not // because chances are that the latter will comment out everything after it.

Second, if you Export as Binary the code from ESTK, it fails:

eval("@JSXBIN@ES@2.0@MyBbyBn0AJJAnASzJjCjSjJjEjHjFiGjVjOByBNyBnAMAbyBn0ACJBnAEXzHjXjSj\
JjUjFjMjOCfjzBhEDfRBFeViHjSjFjFjUjJjOjHjThAjGjSjPjNhAiCjSjJjEjHjFffZCnAFct0DzAE\
CDnftJFnASzCjCjUFyBEjzKiCjSjJjEjHjFiUjBjMjLGfntnftJGnABXzGjUjBjSjHjFjUHfVFfyBne\
GjCjSjJjEjHjFfJHnABXzHjUjJjNjFjPjVjUIfVFfyBndgefJInABXzEjCjPjEjZJfVFfyBCzBhLKCK\
nEXzIjUjPiTjPjVjSjDjFLfVBfyBnfeQjWjBjShAjCjSjJjEjHjFiGjVjOhAhdhAnnneOhbhAjCjSjJ\
jEjHjFiGjVjOhIhJhbnfJJnABXzIjPjOiSjFjTjVjMjUMfVFfyBNyBnAMJbyBn0ABZKnAEXCfjDfRBC\
KnXJfVzFjCjUiPjCjKNfAeTiCjSjJjEjHjFiUjBjMjLhAjSjFjTjVjMjUhahAnffABN40BhAB0AECLn\
fJMnABXzHjPjOiFjSjSjPjSOfVFfyBNyBnAMMbyBn0ABZNnAEXCfjDfRBXJfVNfAffABN40BhAB0AEC\
OnfJPnABXzJjPjOiUjJjNjFiPjVjUPfVFfyBNyBnAMPbyBn0ABZQnAEXCfjDfRBXJfVNfAffABN40Bh\
AB0AECRnfJSnAEXzEjTjFjOjEQfVFfyBRBFdgfffACF4B0AiAB40BiAACAEByB");

(Remember to surround the binary chars blob with eval(" ") and close the lines with a \). The Console outputs:

Error in
Line 2: var bridgeFun = (function anonymous() {  [compiled code] } ); bridgeFun();
Expected: ]

Result: true

That’s because the purpose of binary encoding is hiding the code, so the function reads [compiled code] and is not stringified nor interpreted correctly.

Workarounds

You have a couple of choices to make it work. Either you can move the separate function out of the binary encoding and leave it readable:

var bridgeFun = function () {
	$.writeln('Greetings from Bridge');
	return true;
}

eval("@JSXBIN@ES@2.0@MyBbyBn0AIJAnASzCjCjUByBEjzKiCjSjJjEjHjFiUjBjMjLCfntnftJBnABXzGjU\
jBjSjHjFjUDfVBfyBneGjCjSjJjEjHjFfJCnABXzHjUjJjNjFjPjVjUEfVBfyBndgefJDnABXzEjCjP\
jEjZFfVBfyBCzBhLGCGnEXzIjUjPiTjPjVjSjDjFHfjzJjCjSjJjEjHjFiGjVjOIfnfeQjWjBjShAjC\
jSjJjEjHjFiGjVjOhAhdhAnnneOhbhAjCjSjJjEjHjFiGjVjOhIhJhbnfJEnABXzIjPjOiSjFjTjVjM\
jUJfVBfyBNyBnAMEbyBn0ABZFnAEXzHjXjSjJjUjFjMjOKfjzBhELfRBCGnXFfVzFjCjUiPjCjKMfAe\
TiCjSjJjEjHjFiUjBjMjLhAjSjFjTjVjMjUhahAnffABM40BhAB0AzANCGnfJHnABXzHjPjOiFjSjSj\
PjSOfVBfyBNyBnAMHbyBn0ABZInAEXKfjLfRBXFfVMfAffABM40BhAB0ANCJnfJKnABXzJjPjOiUjJj\
NjFiPjVjUPfVBfyBNyBnAMKbyBn0ABZLnAEXKfjLfRBXFfVMfAffABM40BhAB0ANCMnfJNnAEXzEjTj\
FjOjEQfVBfyBRBFdgfffABB40BiAABANByB");

(Mind you: I’ve cut the function out, then exported the binary, then pasted the function back above the binary).

Or you can stringify the function and insert it as a String literal: for instance calling $.writeln(bt.body) on the original version and copy/paste the result from the Console back to the message body. The following version exports as binary without a glitch!

var bt = new BridgeTalk()
bt.target = 'bridge';
bt.body = "var bridgeFun = (function () { $.writeln('Greetings from Bridge'); return true; }); bridgeFun();"
bt.onResult = function(btObj) {
	return $.writeln('BridgeTalk result: ' + btObj.body);
};
bt.send(31);