Code
The Code service allows custom JavaScript to be executed and the result passed back into the flow. Scripts are executed in the Node.js JavaScript runtime and have the Request library available to make it easy to make HTTP requests.
Environment
Scripts run in a strictly sandboxed environment, and have access to only certain resources and with some reasonable limits imposed.
- Scripts run in a Node.js v6 instance.
- Your script may run for up to 5 seconds (in real time).
- A memory limit of 64mb is in place (inclusive of memory allocated by Node.js).
- Scripts have access to all JavaScript's built-in objects, except for eval. We also provide access to some extra utils objects in order to interact with Flow XO and for utility, which we'll explain below.
- It's worth noting that there is no access to the Node.js API. For example, you can't use the fs module, nor can you require other modules. You may only write pure JavaScript, using the passed inputs and anything available in utils.
Running Scripts
When you configure your action, you'll be able to set up Inputs, which are key/value pairs which will be available to your script inside an inputs object.
For example, setting up these inputs:
Results in the script having access to an object like this:
inputs: { foo: "bar", a: "b" }
Of course, you'll probably want to use outputs from other tasks as your values, rather than a fixed string like "bar" or "b".
Your script then does its work, and either calls a function resolve with a string or object as the result, or reject with a string that will be written to the flow's log as an error. Like so:
resolve(answer);
reject("Error: " + errMsg);
If your script executes successfully (i.e. you call resolve), then subsequent actions can use the Result output to use the results of the script in future tasks. Result is a data output so you can access individual properties if you return a JS object.
Important: You must always call either resolve or reject in your script, or it will timeout and the action will be marked as failed.
Reference
- inputs: a plain JS object containing all the inputs configured in Inputs, as key/value pairs. Note that the values are always strings. The script may need to therefore convert into another type if necessary.
- resolve: a function which should be called at the end of a successful script execution. It accepts a single argument, which will be made available as an output to the script. Calling this function will pass the action, and provide the result as an output.
- reject: a function which should be called at the end of a failed script execution. It accepts a single argument, which should be a string explaining the failure. Calling this function will fail the action, and the passed string will be used as the error message for flow's log.
- utils: a JS object containing utility functions that can be used by the script. More about the available functions in the Utility Functions section below.
Utility Functions
The request function is not the raw Request library. The only format that will work is the request(opts, cb) form. No other functions listed on the request page will work, but it does return the request object, to support streaming.
Example Scripts
Example 1 (returns the result of a + b)
var a = inputs.a; var b = inputs.b; if(a == null || b == null) { return reject('inputs must not be null!'); } // We must cast the inputs to numbers, // as they will be passed as strings. resolve(Number(a) + Number(b));
Example 2 (uses the request library)
var url = inputs.url; var opts = { method: 'GET', url: url }; utils.request(opts, function(err, resp, body) { if(err) { return reject(err); } resolve(body); // NOTE: If you are having trouble // accessing the data returned from a JSON based API // you may need to parse the JSON string before resolving: // resolve(JSON.parse(body)); });
Example 3 (parsing JSON)
// Takes a JSON string array such as below // and returns a comma separated list // of names extracted from each item. // Uses new ES6 features. // Feeding this input: // [{"name":"Bob","age":42},{"name":"Lisa","age":29}] // // will result in: // Bob, Lisa let arr = []; try { arr = JSON.parse(inputs.arr); } catch(e) { return reject('Input must be valid JSON'); } const output = arr.map(item => item.name).join(', '); resolve(output);
Let us know how we can improve Flow XO on our feedback site.