Execute JavaScript (Server-side)
Audience:
Low-Code Engineer
Skill Prerequisites:
JavaScript
Executes JavaScript code on the server-side, optionally returning variables. This action is based on the Microsoft/ClearScript library that uses the Google V8 engine. It is a pure JavaScript framework, so there won't be access to the window or the document object. Other than that, it brings the full flexibility of JavaScript, plus some .net helpers to help write better code, faster.
All tokens that exist in the Execution Context when this action runs will be available inside the script as local variables. Note that JavaScript is a case-sensitive language, so variable names will be in the exact case as the token name.
This action requires minimum Microsoft Visual C++ Redistributable for Visual Studio 2019 or latest be installed on the server to run properly. Download it from Visual Studio Downloads.
IIS App Pool runtime (platform) needs to run under 64 bits for this action to run. Otherwise the execution will result in an error.
Input Parameter Reference
Parameter | Description | Supports Tokens |
---|---|---|
Script Name | A unique name that identifies what this script is about. It will be used for error and debug messages and logging and as the filename for the .js file exported to GitHub | No |
Local Variables | By default, all tokens in the context, as well as global tokens, are already available as local JavaScript variables. Additional variables can be created through this setting. It's useful, for example, to have non-developers control the flow of the code. Note that variables in JavaScript are case sensitive, so, when used, their names must match exactly the way they were defined in this setting. | Yes |
Code | The JavaScript code to run. It supports full syntax. To have the values exported back to the process, simply use return statements. | No |
Output Parameters Reference
Parameter | Description |
---|---|
Output Token | A token name to hold the result generated by the script so it can be used in subsequent actions. This parameter is optional. Note that if the return is a complex object, its properties will be accessible through the [<output>:<property name="">] syntax. |
Events Reference
Event Name | Description |
---|---|
On Error | If an error occurs in the script, it will trigger the execution of the list of actions specified for this event. |
Returning Data
Data can be returned from the script back to the process simply by issuing a return
statement. The returned value will be stored in the context under the name specified for the Output Token
setting above.
Given the example below, if the Output Token
was set to Sum
, then the result can be accessed in following actions by using the [Sum]
token.
// Example: return a primitive value (a number)
return a + b;
If the returned value is a complex object, the output token is expanded to include the first level properties as well. It's also common practice to return objects when the script must return multiple values.
Given the example below, if the Output Token
was set to Guest
, then the data will be accessible in the following actions by using the [Guest:Username]
and [Guest:VisitCount]
tokens. Accessing the root token, [Guest]
, would bring back the JSON for the entire object.
// Example: return an object with multiple properties
return {
username: 'john',
visitCount: 7
}
Note that some JavaScript types, such as Date
, can't be exported as tokens because of limitations with the ClearScript engine. In this case, use the DateTime
and DateTimeOffset
types. These are the .net classes that are injected and ready to use in the script.
// Example: return the current date
return {
username: 'john',
lastVisit: DateTime.Now
}
Available Variables
The following variables are automatically created and available in the script:
Name | Description |
---|---|
User | Exposes information about the current user. By default, this is the user running the workflow, but it can be changed through the Load User action for example. |
Page | The current page from where the workflow was triggered. In some cases, such as when running the action from a scheduler, this variable will be null. |
Module | The entry point from where the action was invoked. It can be a form, grid, API, a scheduled job, or another trigger or event. |
Global Tokens | All custom tokens that have been created in Plant an App Tokens will be available. Note that they always live under a namespace, so accessing them from the script needs to follow the syntax Namespace.TokenName . |
Workflow Parameters | If this action runs in a workflow, all input parameters are available as local variables. Note that if the inputs are Entities the variables are objects that contain all the properties of the respective entity. |
Module Data | If this action is invoked from a form, for example, then all the submitted fields will be available as variables. The variable name is exactly the string ID of each field. Same applies for grids and APIs which have inputs as well. |
Context Tokens | In Plant an App, it's common that actions generate new variables that are stored in the context for subsequent actions to use. All the tokens that were created by actions previous to the Execute Javascript will be available as local variables. |
Additional Objects
Besides the JavaScript built-in objects, the Execute JavaScript action exposes additional .net types to help write more efficient code, faster.
Type | Description | Reference |
---|---|---|
WebClient | Provides a more streamlined and powerful API to perform HTTP requests than the built-in XMLHttpRequest type. | System.Net.WebClient |
DateTime | ClearScript does not support returning JavaScript Date objects back to the process. Use this type instead. | System.DateTime |
DateTimeOffset | Same as the DateTime above, except it safer to use when users of the application are on various timezones. | System.DateTimeOffset |
Making HTTP Requests
There are two ways to perform HTTP requests to get or send data to remote servers. One is to use the JavaScript built-in XMLHttpRequest.
function get(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send();
if (xhr.status == 200)
return xhr.responseText;
throw new Error('Request failed: ' + xhr.status);
}
return get('https://example.com/api');
There is an easier way to accomplish the same by using the .net WebClient class that is injected into the script.
var client = new WebClient();
return client.DownloadString('https://example.com/api');
Example
1. Parse Returned Value from Server Request Action
Below you will find two actions that will make a call to the HubSpot API to get the contacts in a specified list and parse them to pull out just the First Name, Last Name, and Email address of each contact. To use these actions, you need to have a HubSpot account and have a HubSpot API Key saved in a Token in Plant an App. You must also have a HubSpot List created and know the list ID. Once you have these minimum requirements, you can import the actions into your application to see them in action.
This first action is a Server Request to HubSpot to get a list of contacts for the specified [ListID]
. The List ID is configured as an input parameter that you need to pass into this action by storing it in a Token named ListID. The action references a Token named [APIKeys:HubSpot]
to pass the API key on the URL. If you have your API key stored in a token already with a different NameSpace or Token Name, you will need to adjust the token reference. The return from the API call is stored in a token called ContactJSON to be used in the Execute JavaScript (Server-side) action.
{
"Id": -1,
"ActionErrorMessage": null,
"ActionType": "PostData",
"Condition": null,
"Description": null,
"IsDeleted": false,
"Parameters": {
"InputParameters": null,
"URL": "https://api.hubapi.com/contacts/v1/lists/[ListID]/contacts/all?hapikey=[APIKeys:Hubspot]",
"UrlTokenContext": "Url",
"UseSSL": null,
"Timeout": null,
"HttpMethod": "GET",
"Data": null,
"DoNotEscapeTokens": null,
"DisableReferer": null,
"Headers": null,
"UseDNNProxySettings": null,
"AddCurrentCookies": null,
"OutputParameters": null,
"CookieContainerToken": null,
"OutputTokenName": "ContactJSON",
"OutputHeaders": null,
"IgnoreErrors": null,
"Events": null,
"OnError": []
}
}
This second action is the Execute JavaScript (Server-side) action. It takes the value of the ContactJSON token stored in the last action and parses it to pull out only the First Name, Last Name, and Email address of each contact. It stores this information in an output token named ContactLIst to be used in subsequent actions.
{
"Id": -1,
"ActionErrorMessage": null,
"ActionType": "ExecuteJavascript",
"Condition": null,
"Description": null,
"IsDeleted": false,
"Parameters": {
"ScriptName": null,
"LocalVariables": [],
"Code": "var contactList = JSON.parse(ContactJSON);\n\nvar output = contactList.contacts.map(function(contact) {\n\treturn {\n \t'firstname': contact.properties.firstname.value,\n 'lastname': contact.properties.lastname.value,\n 'email' :contact['identity-profiles'][0].identities[0].value,\n }\n})\n\nreturn JSON.stringify(output);",
"OutputTokenName": "ContactLIst",
"OnError": []
}
}