10 Replies Latest reply on Feb 2, 2016 8:07 AM by Gonterman1201

    How to get result from BridgeTalk message?

    Kasyan Servetsky Level 5
      Dear all,

      I want to add a new function to my preflight script which should check color settings chosen in Photoshop. My major problem is that I cant get result outside of bt.onResult function.
      Here is where I got so far:


      #target indesign-5.0
      #targetengine "session"
      var myResult2 = infoFromPS();
      $.writeln("myResult2 = " + myResult2);

      function infoFromPS() {
         var bt = new BridgeTalk;
         bt.target = "photoshop";
         bt.body = "app.colorSettings;"
         bt.onResult = function(resObj) {
            var myResult1 = resObj.body;
            $.writeln("myResult1 = " + myResult1);
            return myResult1;
         }
         bt.send();
      }

      It writes myResult1 variable to console as expected, but myResult2 is undefined. Why?

      Another question:
      Ive been experimenting with BridgeTalk for some time and found out a strange phenomenon. When I send a BridgeTalk message, lets say, from InDesign to Photoshop in main target engine this script doesnt work, but when in session or a custom one it works. Why so?

      I want to explore the possibilities of interapplication communication for a long time. But I cant get reliable information on this topic. Ive read Interapplication Communication with Scripts chapter in JavaScript Tools Guide several times but I couldnt get the example scripts (in Communicating Through Messages section) working.
      Ive found a few examples in Adobe Bridge CS3 SDK: SnpSendArray.jsx, SnpSendMessageToInDesign.jsx etc. They work like a charm but their code is hard for me to understand Im not a programmer by background.

      So, I have two favors to ask of you:
      1st Could someone give me complete and working examples, similar to given in Communicating Through Messages section?
      2nd Could somebody explain to me, in simple terms , some example from Bridge CS3 SDK?

      Thanks in advance.
      Kasyan
        • 1. Re: How to get result from BridgeTalk message?
          Level 1
          Your questions tell me that you don't really understand the asynchronous behavior or BridgeTalk.

          When you call bt.send() to send your BridgeTalk message, your script doesn't stop. I continues to execute until completion. Your onResult handler function is called when a result is received from the target application.

          Without a persistent session, InDesign (and PS) start a scripting engine for your script. When your script completes, the scripting engine is killed off.

          If you send a BridgeTalk message in such a script, when the result comes back to InDesign, the reference to your script and its scripting engine no longer exists. That's why you MUST use a persistent session in InDesign if you are sending a BridgeTalk message and expecting a response.

          In the code you provided, think of the onResult handler as a separate function to be executed at some future time.

          Your function infoFromPS() does not return anything, which is why the first writeln returns "undefined".

          Your onResult function will execute when a result is received; but, that will be at some future time, long after your infoFromPS() function has already returned.

          The execution works like so:

          var myResult2 = infoFromPS();
          - this causes the infoFromPS() function to execute...

          infofromPS() creates a BT message, sets the properties including the onResult handler, and calls "bt.send()". It then completes, and returns nothing (undefined).

          The next line to execute (because infoFromPS() has compelted) is:

          $.writeln("myResult2 = " + myResult2);

          And since infoFromPS() returned noting, you get

          myResult = undefined

          in the ESTK.

          Then, at some time (depends on how long the script takes to execute in Photoshop - could be hours), a response message is received from Photoshop. At that time, your onResult handler executes:

          myResult1 is set to the response message body, the $.writeln writes the correct stuff into the ESTK console, and the onResult function returns myResult1 (which does nothing). You can't "return" something from an onResult handler.

          The correct way to use BridgeTalk is to write your script so that it sends the message, and then to write the onResult handler so it does what you need with the returning message.

          #target indesign;
          #targetengine "session"

          function infoFromPS() {
          var bt = new BridgeTalk();
          bt.target = "photoshop";
          bt.body = "app.colorSettings;"
          bt.onResult = function( msg ) {
          var myResult = msg.body;
          $.writeln( "BridgeTalk result = " + myResult );
          doSomethingNow( myResult );
          }
          bt.send();
          }

          doSomethingNow = function( result ) {
          $.writeln( "Now I am doing something with " + result );
          }

          infoFromPS();

          This *should* (I haven't tested it) write into the ESTK console:

          "BridgeTalk result..."
          "Now I am doing something with..."

          Regards

          Bob
          • 2. Re: How to get result from BridgeTalk message?
            Kasyan Servetsky Level 5
            Hi Bob,

            Thank you so much for the quick reply and intelligible explanation. You opened my eyes to this problem. I reached a deadlock and you showed me the way out of it. I wouldn't be able to solve this thing without your help. Now it works at last!
            Thank you again, Bob.

            Kasyan

            #target indesign-5.0
            
            #targetengine "session"

            function infoFromPS() {
               var bt = new BridgeTalk;
               bt.target = "photoshop";
               bt.body = "app.colorSettings;"
               bt.onResult = function(resObj) {
                  var myResult = resObj.body;
                  $.writeln( "BridgeTalk result = " + myResult );
                  doSomethingNow( myResult );
               }
               bt.send();
            }

            function doSomethingNow( result ) {
               if (result != "ISO Web Coated") {
                  alert( "Color Settings in Photoshop are set to \"" + result + "\"");
               }
            }

            infoFromPS();
            • 3. Re: How to get result from BridgeTalk message?
              dhishok Level 1

              Hi Bob & Kasyan,

               

              Currently i am working with InDesign CS3. I need to check whether the Object layered images preseneted in my InDesign document, if it is found i need to open the particular image (.ai or .psd) in the (Illustrator or Photoshop) applications and do some layer manipulation in it and do saveAs with different name. Finally i need to relink the image in InDesign.

               

              I have written the script for InDesign, Illustrator & Photoshop seperately for the above stuff. The only thing i need to do is combine these scripts and make them intermediate. Finally i have to run this script from InDesign Scripts palette.

               

              In a script, targetting the different applications is not work out i think so. Hence i tried with Bridge Talk() but facing difficulties on execution from ESTK.

               

              Below is my code:

              ---------------------------------------------------

              #target InDesign-5.0

              var doc = app.activeDocument;

              var docLinks = doc.links;

              var OLImage = [];

              var OLayer = [];

              var myCheck = 0;

               

              for (e=0; e<docLinks.length; e++){

                  var myLink = docLinks[e];

                  var myGLayer = myLink.parent.graphicLayerOptions.graphicLayers;

                  if (myGLayer.length > 1){

                      for (g=0; g<myGLayer.length; g++){

                          if (myGLayer[g].currentVisibility != myGLayer[g].originalVisibility){

                              OLayer.push(myGLayer[g].name);

                              OLayer.push(myGLayer[g].currentVisibility);

                              OLImage.push(OLayer);

                              myCheck = 1;

                          }

                      }

                  if (myCheck == 1){

                      var myUpdatedImage = setLayerVisibility(myLink.filePath, OLImage);

                      alert (myUpdatedImage);

                      }

                  }

              }

               

               

               

              function setLayerVisibility(myFile, ObjLayers){

               

                  if (myFile.toString().match(/\.ai$/gi) != null){

               

              //~         #target Illustrator-13.0

               

                      var doc = app.open(File(myFile));

                      var docPath = doc.path;

               

                      for (o=0; o<ObjLayers.length; o++){

                          if (ObjLayers[o][1])

                              doc.layers.getByName(ObjLayers[o][0]).visible = true;

                          else

                              doc.layers.getByName(ObjLayers[o][0]).remove();

                          }

               

                      var saveOptions = new IllustratorSaveOptions();

                      var aiCS4Doc = new File(docPath + "/" + doc.name.replace(".ai", "-b.ai"));

                      saveOptions.compatibility = Compatibility.ILLUSTRATOR13;

                      saveOptions.flattenOutput = OutputFlattening.PRESERVEAPPEARANCE;

                      doc.saveAs( aiCS4Doc, saveOptions );

                      return aiCS4Doc;

                  }   

               

                  else if (myFile.toString().match(/\.psd$/gi) != null){

               

              //~         #target Photoshop

               

                      var doc = app.open(File(myFile));

                      var docLayers = doc.layers;

                      var docPath = doc.fullName.toString().replace(/\.psd$/gi, "-b.psd");

               

                      for (p=0; p<ObjLayers.length; p++){

                          if (ObjLayers[p][1])

                              doc.layers.getByName(ObjLayers[p][0]).visible = true;

                          else

                              doc.layers.getByName(ObjLayers[p][0]).remove();

                          }

               

                      doc.saveAs (File(docPath));

                      return docPath;

                  }   

              }

               

               

              Can you please guide me in this regard.

               

               

              Thanks in advance

              Thiyagu

              • 4. Re: How to get result from BridgeTalk message?
                Gonterman1201 Level 1

                Can you call an error from the body of the string message your sending in the BridgeTalk?

                I need to make an error when my script errors.

                Thanks BG

                • 5. Re: How to get result from BridgeTalk message?
                  Kasyan Servetsky Level 5

                  Yes, here is an example:

                  #target indesign
                  CreateBridgeTalkMessage();
                  
                  function CreateBridgeTalkMessage() {
                      var bt = new BridgeTalk();
                      bt.target = "photoshop";
                      var myScript = "TestInPS = " + TestInPS.toSource() + "\r";
                      myScript += "TestInPS();";
                      bt.body = myScript;
                      
                      bt.onResult = function(resObj) {
                          alert("Done! - " +  resObj.body);
                      }
                  
                      bt.onError = function(msg) {
                          alert("Error: " + msg.body);
                      }
                  
                      bt.send(100);
                  }
                  
                  function TestInPS() {
                      var myPsDoc = app.activeDocument;
                      return myPsDoc.name;
                  }
                  

                   

                  If a document is open in Photoshop, it returns its name:

                  1.png

                  If no document is open, it can't get the name of non-existing activeDocument and returns the error:

                  2.png

                  • 6. Re: How to get result from BridgeTalk message?
                    Gonterman1201 Level 1

                    Thank you for your reply. I do get an error when the document doesn't open and that is what I want. However I would also like it to error when the script I run to save the file does not save. this error would have to be called in the string I believe.

                     

                    bt=new BridgeTalk();

                    bt.target="photoshop";

                    var myPsDoc = app.open(new File(input));

                    myMode=app.activeDocument.mode;//////ex;CMYK

                    myMode=myMode.toString();

                    myMode=myMode.substr(13);///tells us what color mode the file is in.

                    activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;

                    var w = app.activeDocument.width.as( 'px' );

                    var h = app.activeDocument.height.as( 'px' );

                    aspect=w/h;

                    bt.timeout = function( ) { while(bt.getStatus("photoshop") != "IDLE"){bt.timeout = 3;}};

                    bt.body = "myMode="+ myMode.toSource()+";"+"\r"+"toCfitFive="+ toCfitFive.toSource()+";"+"\r"+"pa="+ pa.toSource()+";"+"\r"+"aspect="+ aspect.toSource()+";"+"\r"+"fTyp="+ fType.toSource()+";"+"\r"+"fType="+ fType.toSource()+";"+"\r"+"fPath="+ myFolder .toSource()+";"+"\r"+"paPu="+ paPu.toSource()+";"+"\r"+"HJKC2015BW();"+HJKC2015BW.toString() ;

                    bt.onError = function( btErr ) { result = btErr.body };

                    bt.onResult = function( btRes ) { result = btRes.body  };

                    bt.onTimeout = function( btOut ) { result = btOut.body  };

                    bt.send(4);

                    ////////////// inside the string//////////////////////////////

                    try{

                    if (enabled != undefined && !enabled)

                          return;

                        var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

                        var desc1 = new ActionDescriptor();

                        var desc2 = new ActionDescriptor();

                        desc2.putInteger(cTID('EQlt'), 12);

                        desc2.putEnumerated(cTID('MttC'), cTID('MttC'), cTID('None'));

                        //if (aspect!=0.8) fPath="\\\\KCMS7\\Testing\\binuscan Test\\ePAGE-Test\\Hold";

                        desc1.putObject(cTID('As  '), sTID("JPEGFormat"), desc2);

                        desc1.putPath(cTID('In  '), new File(fPath));

                        desc1.putInteger(cTID('DocI'), 37);

                        desc1.putBoolean(cTID('LwCs'), true);

                        executeAction(cTID('save'), desc1, dialogMode);

                        }

                    catch(e) {

                        // Handle errors here

                    result ="error"; ///need help here on what to send even to fake it out that it's not open just to throw an error.

                    • 7. Re: How to get result from BridgeTalk message?
                      Kasyan Servetsky Level 5

                      I don't understand what your problem is.

                      Let's assume that I have a jpeg-file open in photoshop. The script triggered from InDesign saves it as tif-file in the "Test" folder on my drive "G" which is a removable card.

                      I run this script and it makes the tif-file as expected:

                      CreateBridgeTalkMessage();  
                        
                      function CreateBridgeTalkMessage() {  
                          var bt = new BridgeTalk();  
                          bt.target = "photoshop";  
                          var myScript = "TestInPS = " + TestInPS.toSource() + "\r";  
                          myScript += "TestInPS();";  
                          bt.body = myScript;  
                        
                          bt.onError = function(msg) {
                              alert("Error code#: " + parseInt(msg.headers["Error-Code"]) + "\r" + msg.body);  
                          }  
                        
                          bt.send(100);  
                      }  
                        
                      function TestInPS() {  
                          if (app.documents.length > 0) {
                              var doc = app.activeDocument;
                              
                              var tifFile = new File("/G/Test/" + doc.fullName.displayName.replace(/jpg$/, "tif"));
                              tiffSaveOptions = new TiffSaveOptions();
                              tiffSaveOptions.byteOrder = ByteOrder.IBM;
                              tiffSaveOptions.imageCompression = TIFFEncoding.TIFFLZW;
                              layers = false;
                      
                              app.activeDocument.saveAs(tifFile, tiffSaveOptions, true, Extension.LOWERCASE);
                          }
                          else {
                              alert("Please open a document and try again.", "Resave as TIF", true);
                          }
                      }  
                      

                       

                      Now I locked the card and run the script again. It returns an error message:

                      02-02-2016 16-28-43.png

                      A quote from the JS tools guide:

                      A callback function that the target application invokes to return an error

                      response to the sender. It can send JavaScript run-time errors or exceptions,

                      or C++ exceptions.

                      To define error-response behavior, set this to a function definition in the

                      following form:

                      bridgeTalkObj.onError = function( errorMsgObject ) {
                           // error handler defined here
                      };
                      

                      The body property of the received message object contains the error

                      message, and the headers property contains the error code in its

                      Error-Code property. See “Messaging error codes” on page 190.

                      The function returns undefined.

                      As far as I understand, the Adobe's JS inter-application communication has limitations. To overcome them use either AppleScript (on Mac) or Visual Basic (on Windows).

                       

                      P.S. In the future, please use syntax highlighting > javascript when you paste a code in advanced editor so that we could easily copy-paste it.

                      02-02-2016 16-47-26.png

                      • 8. Re: How to get result from BridgeTalk message?
                        Gonterman1201 Level 1

                         

                        Sorry about that Kasyan I wanted to but I could not find the tool for it in the menu. I just looked at the javascript guide that you showed.

                        I was thinking maybe having the function return a header bt.headers ["Error-Code"] = -29;

                        • 9. Re: How to get result from BridgeTalk message?
                          Kasyan Servetsky Level 5

                          Theoretically, you can set your own error code number (it's a read/write property), but in practice I've never done this. As far as I understand, this gives the user idea what sort of problem occurred in the sender application. I don't see the reason to change it.

                          • 10. Re: How to get result from BridgeTalk message?
                            Gonterman1201 Level 1

                            I inserted

                            function TestInPS() { 

                                    var myPsDoc = app.activeDocument;

                                    var test=bt.headers ["Error-Code"] = 8;

                                    return test; 

                                } 

                            into your script but bt is undefined.