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 variables names will be in the exact case as the token name.

note

This action requires Microsoft Visual C++ Redistributable for Visual Studio 2019 be installed on the server to run properly. Download it from Visual Studio Downloads.

Input Parameter Reference

ParameterDescriptionSupports Tokens
Script NameA 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 GitHubNo
Local VariablesBy 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
CodeThe 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

ParameterDescription
Output TokenA 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 Token>:<Property Name>] syntax.

Events Reference

Event NameDescription
On ErrorIf 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:

NameDescription
UserExposes 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.
PageThe 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.
ModuleThe entry point from where the action was invoked. It can be a form, grid, API, a scheduled job, or another trigger or event.
Global TokensAll 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 ParametersIf 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 DataIf 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 TokensIn 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.

TypeDescriptionReference
WebClientProvides a more streamlined and powerful API to perform HTTP requests than the built-in XMLHttpRequest type.System.Net.WebClient
DateTimeClearScript does not support returning JavaScript Date objects back to the process. Use this type instead.System.DateTime
DateTimeOffsetSame 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": []
}
}
Last updated on by Patrick Anderson