No internet connection
  1. Home
  2. How to

Export Script Log to Text

By Mike Wax @mikewax
    2022-10-04 22:31:16.283Z

    Hello!

    I was wondering if there was a way to export the Script Log to TextEdit or a file or to the clipboard after a script has finished?

    I have a script that logs each file that successfully exported. It also logs if a file is not exported. So it would be nice to have a file that i can look at to determine which files didn't work.

    Ultimately this would get imported into a google sheet so that it's formatted to easily determine which files didn't get exported. Sometimes this could have up to 100 files in the log.

    Thank you so much!

    Solved in post #4, click to view
    • 6 replies
    1. Kitch Membery @Kitch2022-10-05 06:58:21.323Z

      Hi @mikewax,

      The best way to do this would be to append a new line to a text file.

      Here is a function to do that :-)

      const logFilePath = "~/Desktop/File Name Log.txt"
      
      function addToLogFile({ logFilePath, exportFileName, wasExportSuccessful }) {
          const wasSuccessful = wasExportSuccessful === true ? "Sucessful" : "Failed"
      
          sf.file.appendLines({
              path: logFilePath,
              lines: [`${exportFileName}\t${wasSuccessful}`],
          });
      }
      
      addToLogFile({
          logFilePath,
          exportFileName: "Take Number 1",
          wasExportSuccessful: true,
      });
      
      addToLogFile({
          logFilePath,
          exportFileName: "Take Number 2",
          wasExportSuccessful: false,
      });
      
      1. Mike Wax @mikewax
          2022-10-05 16:23:48.063Z

          Hey @Kitch ,

          Thank you so much for this. This is what i was looking for, but I am having a little trouble applying it my script in the correct way (please forgive me, I am VERY green to JavaScript, so my apologies ahead of time).

          I put my full script below. Here's a brief description:

          I am trying to upload exported files to a client upload site. Sometimes the client names don't match up to the file/export names, so I'm trying to "catch" any files that don't upload.

          The one's that are NOT successful, basically the script looks to see if the Cancel button was clicked. If if was, it moves to the next upload and flags it as "not uploaded".

          I'm trying to be able to get a log exported of all the files that were uploaded, and have it say "CLIENT_NAME was not uploaded" or "CLIENT_NAME was uploaded".

          It uses a repeater to go through however many files I need uploaded.

          My apologies again for the ignorance, I'm just a little lost on how to make this work.
          Thank you so much for the help!!!!

          var repeat = prompt("How many requests do you need opened?");
          
          sf.wait({
              intervalMs: 200
          })
          
          for (var i = 0; i < +repeat; i++) {
              sf.ui.app('com.google.Chrome').appActivateMainWindow();
              sf.ui.app('com.google.Chrome').appWaitForActive();
          
          
              sf.appleScript.googleChrome.windows.getByIndex(1).activeTab.execute(`
          
                  var BusinessName = document.querySelector("li.nlf-between-top > span.two-thirds").innerText;
                  
                  // Replace non-websafe characters.
                  var WebsafeName = BusinessName
                                  .replaceAll(' ', '_')
                                  .replaceAll('.', '')
                                  .replaceAll(',', '')
                                  .replaceAll('&', 'and')
                              ;
          
              // Copy Business Name to Clipboard.
                  navigator.clipboard.writeText(WebsafeName);
          
              `);
          
              sf.wait({
                  intervalMs: 500
              })
          
              // Save Clipboard (Business Name) to variable.
              var clipText = sf.clipboard.getText().text;
          
              // log(clipText);
          
              sf.keyboard.press({
                  keys: "end"
              })
          
              sf.appleScript.googleChrome.windows.getByIndex(1).activeTab.execute(`
          
                  document.getElementById("AddNewIVR").click();
          
              `);
          
              sf.wait({
                  intervalMs: 1000
              })
          
              sf.keyboard.press({
                  keys: "cmd+slash"
              })
          
              sf.wait({
                  intervalMs: 500
              })
          
              sf.keyboard.type({
                  text: "Users/mike.wax/Desktop/IVR Bounce"
              })
          
              sf.keyboard.press({
                  keys: "return"
              })
          
              sf.wait({
                  intervalMs: 500
              })
          
              sf.keyboard.press({
                  keys: "tab"
              })
          
              // Paster Client Name in Search field.
              sf.keyboard.type({
                  text: clipText
              })
          
              sf.keyboard.press({
                  keys: "return"
              })
          
              sf.wait({
                  intervalMs: 200
              })
          
              sf.keyboard.press({
                  keys: "tab",
                  repetitions: 2
              })
          
              sf.wait({
                  intervalMs: 200
              })
          
              sf.keyboard.press({
                  keys: "down"
              })
          
          
              var openActive = sf.ui.app("com.google.Chrome").mainWindow.sheets.whoseDescription.is("open").first.buttons.whoseTitle.is("Open").first;
          
          
              if (!openActive.isEnabled) {
                  sf.ui.app("com.google.Chrome").mainWindow.sheets.whoseDescription.is("open").first.buttons.whoseTitle.is("Cancel").first.elementClick();
                  log(clipText + " was not uploaded.");
              } else {
          
                  sf.wait({
                      intervalMs: 500
                  })
          
                  sf.keyboard.press({
                      keys: "return"
                  })
          
                  sf.wait({
                      intervalMs: 3000
                  })
          
                  sf.keyboard.press({
                      keys: "end"
                  })
          
                  sf.wait({
                      intervalMs: 200
                  })
          
                  log(clipText + " - Successfully Uploaded!");
          
                  sf.appleScript.googleChrome.windows.getByIndex(1).activeTab.execute(`
          
                      document.querySelector(".nlf-end > button").click();
          
                  `);
              };
          
              sf.wait({
                  intervalMs: 200
              })
          
              sf.keyboard.press({
                  keys: "cmd+w"
              })
          }
          
          // alert(" out of " + repeat + " files were successfully uploaded.");
          // Export file.
          
          1. Kitch Membery @Kitch2022-10-05 22:16:54.495Z

            Hi Mike,

            Obviously this is untested, as I'm not sure what web page you are trying to automate. However, check out the script below... Hopefully it works for you.

            const logFilePath = "~/Desktop/File Name Log.txt"
            
            function addToLogFile({ logFilePath, exportFileName, wasExportSuccessful }) {
                const wasSuccessful = wasExportSuccessful === true ? "Sucessful" : "Failed"
            
                sf.file.appendLines({
                    path: logFilePath,
                    lines: [`${exportFileName}\t${wasSuccessful}`],
                });
            }
            
            function main() {
                let repeatCount = prompt("How many requests do you need opened?");
                let successCount = 0;
            
            const googleChrome = sf.ui.app('com.google.Chrome');
            
                sf.wait({ intervalMs: 200 });
            
                for (let i = 0; i < Number(repeatCount); i++) {
                    googleChrome.appActivateMainWindow();
                    googleChrome.appWaitForActive();
            
                    sf.appleScript.googleChrome.windows.getByIndex(1).activeTab.execute(
                        `var BusinessName = document.querySelector("li.nlf-between-top > span.two-thirds").innerText;
                        
                        // Replace non-websafe characters.
                        var WebsafeName = BusinessName
                                .replaceAll(' ', '_')
                                .replaceAll('.', '')
                                .replaceAll(',', '')
                                .replaceAll('&', 'and');
                                
                        // Copy Business Name to Clipboard.
                        navigator.clipboard.writeText(WebsafeName);`
                    );
            
                    sf.wait({ intervalMs: 500 });
            
                    // Save Clipboard (Business Name) to variable.
                    let clipText = sf.clipboard.getText().text;
            
                    sf.keyboard.press({ keys: "end" });
            
                    sf.appleScript.googleChrome.windows.getByIndex(1).activeTab.execute(
                        `document.getElementById("AddNewIVR").click();`
                    );
            
                    sf.wait({ intervalMs: 1000 });
            
                    sf.keyboard.press({ keys: "cmd+slash" });
            
                    sf.wait({ intervalMs: 500 });
            
                    sf.keyboard.type({ text: "Users/mike.wax/Desktop/IVR Bounce" });
            
                    sf.keyboard.press({ keys: "return" });
            
                    sf.wait({ intervalMs: 500 });
            
                    sf.keyboard.press({ keys: "tab" });
            
                    // Paster Client Name in Search field.
                    sf.keyboard.type({ text: clipText });
            
                    sf.keyboard.press({ keys: "return" });
            
                    sf.wait({ intervalMs: 200 });
            
                    sf.keyboard.press({ keys: "tab", repetitions: 2 })
            
                    sf.wait({ intervalMs: 200 });
            
                    sf.keyboard.press({ keys: "down" });
            
                    let openActive = googleChrome.mainWindow.sheets.whoseDescription.is("open").first.buttons.whoseTitle.is("Open").first;
            
                    if (!openActive.isEnabled) {
            
                        googleChrome.mainWindow.sheets.whoseDescription.is("open").first.buttons.whoseTitle.is("Cancel").first.elementClick();
            
                        addToLogFile({
                            logFilePath,
                            exportFileName: clipText,
                            wasExportSuccessful: true
                        });
            
                        log(clipText + " was not uploaded.");
            
                    } else {
            
                        sf.wait({ intervalMs: 500 });
            
                        sf.keyboard.press({ keys: "return" });
            
                        sf.wait({ intervalMs: 3000 });
            
                        sf.keyboard.press({ keys: "end" });
            
                        sf.wait({ intervalMs: 200 });
            
                        addToLogFile({
                            logFilePath,
                            exportFileName: clipText,
                            wasExportSuccessful: true
                        });
            
                        log(clipText + " - Successfully Uploaded!");
            
                        sf.appleScript.googleChrome.windows.getByIndex(1).activeTab.execute(
                            `document.querySelector(".nlf-end > button").click();`
                        );
            
                        successCount++
                    }
            
                    sf.wait({ intervalMs: 200 });
            
                    sf.keyboard.press({ keys: "cmd+w" });
                }
            
                sf.file.open({ path: logFilePath });
            
                alert(`${successCount} out of ${repeatCount} files were successfully uploaded.`);
            }
            
            main();
            
            

            Note: There is a lot of keyboard simulation and manual waits being used in this script that may cause issues. If at all possible try to reduce them to make the script more robust. I'm not sure what each step does so I've left them all as is.

            Let me know how it runs :-)

            Reply1 LikeSolution
            1. Mike Wax @mikewax
                2022-10-06 00:48:19.085Z

                @Kitch.....I'm sending you a case of beer!!

                This worked perfectly! (i did make a few extra tweaks for formatting and such).

                I can't tell you how much i appreciate you taking the time to work this out and help me with this!

                The keyboard simulations are mostly just to control Chrome - things like close the tab, go to the bottom of the screen, etc. The waits are just to make sure the functions don't step over each other. Is there a way that you would suggest to make that better?

                Also, what is a good resource that you use for scripting? I would love to dive in and learn more to hopefully be able to do this on my own more.

                Thank you again. Your help and knowledge is invaluable.

                1. Kitch Membery @Kitch2022-10-06 02:17:53.419Z

                  You're welcome, Mike. It's always a pleasure helping you out :-)

                  Regarding making the script more stable, you could do the following;

                  Instead of using keyboard simulations, first try to use menu clicks wherever possible, for example, to close a tab in Chrome the best approach would be to use the "Click Menu Item" macro action to select "Close Tab" in the file menu;

                  The Script would look something like this.

                  sf.ui.app("com.google.Chrome").menuClick({
                      menuPath: ["File", "Close Tab"],
                  });
                  

                  And for scrolling to the bottom of the page, you could use something like this. (there may be a better way for doing this though, I'll have to do some research);

                  //Scroll to the bottom of the current web page.
                  sf.appleScript.googleChrome.windows.getByIndex(1).activeTab.execute(
                      `window.scrollTo(0,document.body.scrollHeight);`
                  );
                  

                  And here is a link to some good resources for learning Javascript;

                  https://soundflow.org/docs/how-to/custom-commands/javascript-resources

                  Also, be sure to join in on one of the SoundFlow Hangouts we hold every Wednesday.

                  https://soundflow.org/hangout

                  Rock on, Mike! :-)

                  1. Mike Wax @mikewax
                      2022-10-07 15:19:38.490Z

                      Thank you so much! I will definitely be joining the Hangout next week, i have bookmarked the resources page, and i will update my script with more menu functions.

                      I truly appreciate you, @Kitch!