Question about callback URLs

Hey, I’m fairly new to JavaScript. I would like to call one script from another, execute,
and return the output to continue.

I have a parent script that looks like:

   info=async (info) =>
   {
      var a= new Alert()
         a.title='INFO'
         a.message='\n'+info+'\n'
       a.addAction('OK')
      return await a.present()
   }

Var shortcutCb=async (name) =>
  {
    const XCBURL =  "shortcuts://x-callback-url/run-shortcut"
    let cb = new CallbackURL(XCBURL);
        cb.addParameter("name", (name));
    return await cb.open();
  } 

var scriptCb=async (name) =>
  {
    const XCBURL =  "scriptable:///run"
//     const XCBURL =  "scriptable://x-callback-url/run/"
    let cb = new CallbackURL(XCBURL);
        cb.addParameter("scriptName", encodeURI(name));
    return await cb.open();
  }

await shortcutCb(‘test’)
// Runs as expected

var return = await scriptCb (‘test2’) 
// Runs as expected (should return “return=true&string=sometext”
)

await info(return)
// Never executes

Is this the proper way to do this or should I be re-running the original script with a new function call?

The easiest way probably is to modify the script you want to call with:

// do your stuff ...
// and then assign the result you want to pass to the other script to module.exports
module.exports = result;

and where you want to call the other script simply write

const result = importModule("otherScriptName");

Note though that the called script can’t use async and await this way.

If you need async/await then you could export the async function in the called script with module.exports = myAsyncFunctionThatDoesTheWork; and call it in the calling script with

const myAsyncFunctionThatDoesTheWork = importModule("otherScriptName");
const result = await myAsyncFunctionThatDoesTheWork();

Another gotcha: If you do it this way then you can’t call the function in the first script otherwise it is called twice. Once during the import and the second time in the second script.

If you still want to execute the first script on its own, you need to check in the script if it is imported:

// module.filename contains the full path to the script.
// the regex removes everything from the beginning up to the last /
// and also the suffix ".js" at the very end
// the "g" at the end of /.../g means "global" so the regex is executed until it searched the whole string
if (module.filename.replace(/^.*\/|\.js$/g, "") === Script.name()) {
  // we are not imported because module.filename and Script.name() point to the same script
  await myAsyncFunctionThatDoesTheWork();
} else {
  // we are imported in another script, just "return" the function
  module.exports = myAsyncFunctionThatDoesTheWork;
}

I’ve not tested this code so there might be typing errors.

In your code example you assign some value to return but that is a reserved keyword in javascript. This will probably throw a syntax error.

1 Like

Awesome, thanks! Thats honestly a much better than the callbacks.

I already had those 3 functions importing from ‘library.js’.

I should be able figure it out from there.