Is there a way to create a UXP plugin to run psjs scripts that run actions?

Hello everyone,
This is my first post and I hope that I am doing a good job at it.
I want to automate my action scripts, and I am looking for a way to let them run on a whole folder. Currently I would think the best way would be to write a Script using the new .psjs version for each action. What I wonder is if there is a good way to translate/run the actions via .psjs? I believe that this is done via batch play and I am still looking for examples that others have already posted. My endgoal would be to create a UXP plugin framework to add a radio button for each psjs and a button that would execute this script upon the source folder → target folder. I will continue to look for solutions and add on this post as I get closer to the goal, but I thought starting early to describe the problem would be the best way. Looking forward to be part of this community and this forum in particular! Cheers, Oliver

Looking for answers I stumbled upon a post from 2 and 3 years ago, that I want to share here, it is still not solving the issue, but I believe this topic is still hot, so collecting some posts while searching, may help others too.

Action can be executed directly from the UXP plugin. Why via psjs?

2 Likes

Hi @sttk3 thank you for asking,

The reason is that currently I am still looking for the best option.
I haven’t yet programmed a plugin and I had problems setting up the modal execution. I found some information that running .psjs was running faster than running it through an UXP plugin. My goal is to be able to run my actions on demand, but using a source and a target folder. If there is a good way to do it just in the plugin from UXP I would do just that, but I need to understand better the modal input /open and save in a silent way, as I am really struggling with this part right now.

Cheers!
Oliver

Given what you want to do,
I think you need to create a dedicated uxp panel.

Thank you @haller!
I will look into it then :slight_smile: !
Thank you for taking the time to read through my stuff and give me a direction to look into. I will update this post while I keep collecting, maybe it will help others in a similar situation.

Cheers,
Oliver

See if this works for you.

async function executarJSXfile(jsxFile) {  
  var pluginFolder = await fs.getPluginFolder()
  try {  var filetoken = await fs.createSessionToken(await pluginFolder.getEntry(jsxFile)); }
  catch (e) { app.showAlert("Script nĂŁo localizado!");}
  await app.batchPlay([{ "_obj": "AdobeScriptAutomation Scripts","javaScript": {"_path": filetoken,"_kind": "local"},"javaScriptMessage": "JSM","_isCommand": true,}], {});
}

 async function savePNG(params) {
  await core.executeAsModal(async () => {			
    var jsxArquivos = "jsx/salvarpng.jsx" 
    await executarJSXfile(jsxArquivos)
  })  
 }

running .psjs was running faster than running it through an UXP plugin

Perhaps it’s about InDesign. Those are the observations made.

InDesign can execute .idjs directly via the doScript command, passing arguments, and moreover, the UXP plugin system of InDesign is still in its infancy. Those options would be a good idea.

However in Photoshop, executing .psjs is a tricky task, and there is no easy way to pass arguments. It is easier and faster to get to the point where you can develop a UXP plugin than becoming a circus master who can execute .psjs.

@ Ancelmoa
Sorry but it seems to me that you asked for info on psjs,
is your script for .jsx files?

I am a bit confused as to what you are asking…

Are you wanting to run a Photoshop Action on a group of files (whole folder)? If so, you can simply use the built-in File > Automate > Batch… functionality. If you want to run multiple actions on a group of files, you could write a script that uses the play method from the Action class that @sttk3 linked to above.

Or, do you want to run a set of script files (either jsx or psjs) on a group of files? This can be done but executing jsx and psjs scripts from within another script is very inconsistent.

If you can provide a little more clarity, I’m pretty sure we can help with a solution. Cheers!

The principle is very similar. However, since there is no need for such a function, I did not study the case. But this script finds the .psjs file.

async function FileList() {
    const fs = require("uxp").storage.localFileSystem;
    var pluginFolder = await fs.getPluginFolder();
    
    try {
        let scriptsFolder = await pluginFolder.getEntry("scripts"); // Trying to access the"
        let entries = await scriptsFolder.getEntries(); // Getting the files from the folder

        for (let entry of entries) {
           alert(entry.name ); // Listing the files inside the "scripts" folder"
        }
    } catch (e) {
        alert("The 'scripts' folder does not exist or could not be accessed.");
    }
}

FileList();

Hi Ancelmoa, thank you for taking the time and providing a script snip.
Greatly appreciated! I am indeed looking for .psjs execution, simply because this will hopefully be future proof, but I also have to consider what sttk3 wrote in his post.
My journey is still at its starting point and I am struggling already just with modal executions.

Cheers,
Oliver

Hi sttk3,

thank you for your comment and advice. I understand that from the point of simplicity it might be easier to “just” write one plugin to encompass everything already, but I was thinking of having a modular approach, that may support also in the future other uses.
Right now I am already struggling with writing simple plugins that use modal mode to write and open documents.

Thank you for your support! Greatly appreciated.

Cheers,
Oliver

Hi jduncan,

Thank you for asking.
The idea is to have a battery of different scripts or functions (the internal logic is not important in this case) to be able to run the actions that I have created last year in a way that you can just trigger them with a button. The problem is that the run as batch mode does not work in silent mode, so I would have to push everytime again “save as”…this is why I am looking for a way to make it simpler. Currently when I run the action I can only do it one by one, but I need to run it over a collection in a folder for about 80 different entries.
I was thinking that this way I could create a modular framework to add more and more scripts / functions over time. Adding another button and create a json entry to link it is not that difficult, but this is the motivation behind my question.

Cheers,
Oliver

back to your initial question
can i execute an action from psjs
this psjs script allows you to execute an action or multiple actions

async function playAction() {
    let result;
    let psAction = require("photoshop").action;

    let command = [
        {"_obj":"play","_target":[{"_name":"action set name","_ref":"action"},{"_name":"action name","_ref":"actionSet"}]}
    ];
    result = await psAction.batchPlay(command, {});
}

async function action_play() {
    await require("photoshop").core.executeAsModal(playAction, {"commandName": "Action Commands"});
}

await action_play();

Everything you want to do seems doable, I just think it is overly complex and deemed to fail (sometimes)…

I tested executing psjs scripts from inside of my UXP command palette plugin and couldn’t get consistent results. Sometimes the script doesn’t run at all, and most times, the history doesn’t reflect any changes made by the script. I actually found executing jsx scripts more reliable.

How about a simple psjs script that allows you to select a folder to operate on and a selection of actions to run?

Hey Haller! thank you for the script snippet.
I am struggling with the batch part but this is definitely a part issue that I can use!
I also looked into the comments from sttk3 and worked on my “plugin” skills.
What I struggle most with is the “open a file silently” and go through all the files in the folder and save them silently. I hoped that the get a file would be silent, but it is actually a “filepicker” so I will have to see how to get around this. Also it took me quite a while to find out about the crucial importance of the “Required Permissions” entry in the manifest file.
Thanks again for your support!

Cheers,
Oliver

Hey Jduncan,
thank you again for checking in on me. I am also looking into the “only” plugin way. I just want to make it as modular as possible and I do have my actionscripts from before, but maybe I will have to re-write them in the future. What I found out about the manifest file was really important to be able to access files, So at least there I am getting closer to my main goal.

The problem is that I want to have a “silent” approach, means that the files need to be picked up one by one (just like batch process") once I have picked the source and the target folder. I wanted to call the folder picker also in a special way, having “pick source folder” for the source folder in the folder picker and a “pick target folder” as a title for the target picker window, but it seems that there are no options available I clicked on the link for “getFolder()” options and I got a 404 :slight_smile: …(https://developer.adobe.com/indesign/uxp/reference/uxp-api/reference-js/Modules/uxp/Persistent%20File%20Storage/Folder/storage#getfolderoptions)
maybe there is another way, but I have not yet found it.
I will keep digging.

Cheers,
Oliver

I have finally got the opening the file using the example from @jduncan , thank you for this! I do not fully understand, why it has to be done like it is done, but I am adapting it to my use and working on this now.