# Script

The Tray Script connector can be used to add JavaScript functions to your workflows

## Overview

The Script connector can be used to add Script functions to your workflows.
The Script connector supports ES6.
The steps involved in using the Script connector are:

1. Optionally define **input variables** which can be pulled in from previous steps in your workflow. The below screenshot shows using `$.steps.loop-1.value` to pull in the **value variable** from the 'loop-1' workflow step.
   ![define-script-variable](https://tray.ai/documentation/images/connectors/core/script/9861b842-4c9e14bd_define-script-variable.png)
2. Your script must begin with the `exports.step = function()` line in order to function correctly. From within this you can create and return variables and work with objects. If you wish to use variables pulled in from previous steps, as mentioned in point 1, this should be `exports.step = function(input)`
3. In your script, 'input variables' are written in the format `input.NAME`
   So for example you could say `var message_object = input.message;` to create an object based on the above screenshot.
4. What you return in your script will determine what is available for subsequent connector steps to make use of, e.g. `return message_object;};`
   Please see our example workflow below for a simple demonstration of these points in action.

> **Warning:** **IMPORTANT!**: You can choose from the Operation dropdown options whether you want to execute your step synchronously or asynchronously. **You should nearly always choose synchronously**, unless you're planning to make HTTP requests in your script.

## JS Libraries

The following Javascript libraries come pre-installed and you can use them within your script:

* [lodash](https://lodash.com/)
* [moment-timezone](https://momentjs.com/timezone/)
  Following Node modules are pre-installed in **connector version >= 3.2**:
* [crypto](https://nodejs.org/api/crypto.html)
* [Buffer](https://nodejs.org/api/buffer.html)
* [URL](https://nodejs.org/api/url.html)
  Go through the section below on [Testing scripts locally\*\*.\*\*](#testing-scripts-locally)

## Notes on using the Script connector

The main property of the Script connector is the 'Script' input field. This is where you would typically write up the code needed.
One of the way your code can integrate with Tray.io features is through the use of Interpolated mode.
As this property is essentially a "text field", the use of interpolated mode within the Script connector itself is supported. Simply use the same curly brackets and jsonpath method as normal and the output should be the same.
Take for example a workflow that generates a random string.
![javascript-interpolated-mode-1](https://tray.ai/documentation/images/connectors/core/script/9861b842-beb86ec4_javascript-interpolated-mode-1.png)
Using some simple Javascript and the Script connector, we call the random string utilising interpolated mode:

```json
exports.step = function(input, fileInput) {
	return 'some value: ' + '{$.steps.random-helpers-1.result}';
};
```

![javascript-interpolated-mode-2](https://tray.ai/documentation/images/connectors/core/script/9861b842-555880ac_javascript-interpolated-mode-2.png)
The code will then be interpreted as the actual result of the jsonpath rather than the jsonpath itself as displayed in the Debug panels:

```json
{
	"file_output": false,
	"variables": [],
	"script": "exports.step = function(input, fileInput) \{\n\treturn 'some value: ' + 'w77io8pExkw';\n\};"
}
```

![javascript-interpolated-mode-3](https://tray.ai/documentation/images/connectors/core/script/9861b842-8f679e02_javascript-interpolated-mode-3.png)

> **Info:** **PLEASE NOTE**: We **don’t support Import statements** in script connectors

## Testing scripts locally

Although you can figure out what went wrong with your script code from your logs, you can save yourself some trouble by testing / debugging your code locally before adding it to the connector.
[Script connector tester](https://github.com/trayio/script-connector-tester) is a tool from Tray that you can use to quickly test / debug your code. It comes with loadash and moment libraries.
Fork the repo, clone it locally and run `npm install` to install libraries
Now you can follow the steps below to use it:

### 1. Run your workflow without code

Run the workflow with the script connector, no need to add the code in right now. As we will use this workflow run to grab the input data for Script step.

### 2 - Grab the input to Script

Open logs and grab the input from Script step. Paste this into the input.json file of your code locally.

```js
\{
	"variables": [
		\{
			"name": "data",
			"value": \{
				"name": "John",
				"age": 30,
				"car": "Audi"
			\}
		\}
	],
	"script": "// You can reference the input variables using input.NAME\n// Parsed JSON files could be referenced as fileInput\nexports.step = function(input, fileInput) \{\n\treturn input.foo\n\};",
	"file_output": false
\}
```

### 3 - Write code in the Script.js

Now write code in script.js file. You can use the [loadash](https://lodash.com/), [mout](http://moutjs.com/) and [moment](https://momentjs.com/) library functions.
Here's an example that uses [loadash keys function](https://lodash.com/docs/4.17.15#keys) to pluck the object keys:

```js
// You can reference the input variables using input.NAME
// Parsed JSON files could be referenced as fileInput
exports.step = function (input, fileInput) \{
  return _.keys(input.data);
\};
```

### 4 - Run code

Use `node run` in the terminal to run the code. The output of the script step function will be logged to the console.
![scipt result](https://tray.ai/documentation/images/connectors/core/script/4O8fvvIL5EADwNgaD8JSIr_scipt%20result.png)

### 5 - Debug code, verify and add back in the Script step

You can debug the code and fix easily now. When you are ready with the desired code, click on edit button on Script code and paste the code from your Script.js file.
![script add code back](https://tray.ai/documentation/images/connectors/core/script/3aYnfE178zdOTE6FT0Wah0_script%20add%20code%20back.png)

> **Info:** You may have to run `npm install` at regular intervals just to ensure your libraries are up to date with latest versions (for example if you are trying to use a function from a newer version of loadash or moment )

## Basic example

![script-example-workflow-2](https://tray.ai/documentation/images/connectors/core/script/9861b842-b0aee2b4_script-example-workflow-2.png)
The above example shows a manually triggered workflow which implements the following steps:

1. Use a script to create some dummy message values. In a live situation these messages would be pulled in from another connector step (e.g. intercom, ringcentral etc.). Manually creating these values is actually a nice demo of the basics of working with the Script connector:

```js
exports.step = function() {
  return {
    "messages": [
      \{"body": "Hello is there anybody there?", "phone_number": "+147438662", "id": 1052332004\},
      \{"body": "Anyone?", "phone_number": "+147438662", "id": 1052332004\},
      \{"body": "Ah there you are", "phone_number": "+147438662", "id": 1052332004\},
      \{"body": "empty", "phone_number": "+147438662", "id": 1052332004\}
    ]
  }
};
```

1. Use a Loop Helper to loop through the above. The 'Loop List' Operation can be used to deal with each message one by one.
   ![loop-messages](https://tray.ai/documentation/images/connectors/core/script/9861b842-a931cb11_loop-messages.png)
   In order to pull in the message for the script we use `$.steps.script-1.result.messages`.
   This is because, if we click on Debug and look at the output from the 'Execute Script' (script-1) step, it is in the format:
   ![script-1-output](https://tray.ai/documentation/images/connectors/core/script/9861b842-d77cc00a_script-1-output.png)
2. Then for each message that the loop helper processes, we can use another Script connector ('Check-message-Script' (script-2)) to check that the message fulfils certain criteria. We do this by first of all creating a 'message' input variable which pulls the message from Loop Collection (loop-1) with `$.steps.loop-1.value`:
   ![message-input-variable](https://tray.ai/documentation/images/connectors/core/script/9861b842-4be6f726_message-input-variable.png)
   We have to use 'value' here because the output log of a Loop Connector shows:
   ![loop-1-output](https://tray.ai/documentation/images/connectors/core/script/9861b842-0a8b3590_loop-1-output.png)
   The script itself then runs a check on each message fed by the loop, to see if the message itself was empty, in which case reformat it for the database. If it is not empty then it returns the message object unchanged:

```js
exports.step = function(input) {
  var message_object = input.message;

  if (message_object.body === "empty"){
    return \{
      "body": "empty",
      "phone_number": "---",
      "id": "000"
    \}
  } else \{
    return message_object;
  \}
};
```

1. Finally, the result of each loop and message check is fed into a Google Bigquery database (you will need to authenticate the Bigquery connector with your Bigquery account and setup a dataset and table), using the 'Insert Rows' Operation. The 'Project Id' and 'Dataset Id' are specified and then the result of the message is fed in:
   ![bigquery-input-data](https://tray.ai/documentation/images/connectors/core/script/9861b842-48ff2798_bigquery-input-data.png)
2. Once the workflow is setup, click 'Run Workflow Now'
   A successful run will then lead to your Bigquery dataset being updated so it will look something like this:
   ![bigquery-screenshot](https://tray.ai/documentation/images/connectors/core/script/9861b842-d2226550_bigquery-screenshot.png)
   And clicking on the Debug tab of will enable you to view the output logs of each stage of your workflow:
   ![script-docs-workflow-output-log](https://tray.ai/documentation/images/connectors/core/script/9861b842-65f80181_script-docs-workflow-output-log.png)
