Cyclr supports JavaScript as its scripting language, allowing you to manipulate data before it’s sent as well as after it’s been retrieved. This can be useful when moving data between applications as what’s valid in one, may not be valid in another.
Also, sometimes data just doesn’t quite “fit”.
Inline Script #
Inline Script is used to make small changes to data, directly in a mapping field.
For Inline Script, you must prefix the JavaScript code with “=” (an equals sign), e.g.:=(100 * 2)
or
=`[Mergefield]` === '' ? 'no value' : `[Mergefield]`;
It’s best to use ` characters (backticks) around string values being merged in as that will prevent carriage returns and any quote characters from breaking your Script.
Note: [Mergefield] above represents fields inserted by Cyclr in Step Setup when choosing Type a Value and selecting from the dropdowns.
If you’re finding your inline script is becoming complex, or it’s being used on multiple fields, you may want to consider using Step Script instead. Beyond just the added readability, there may also be a performance advantage.
Step Script #
Step Script is used when you want to want to make more complex changes to data.
If you’re working on a Cycle in the Builder and need to perform a change to some data, click the Step Setup button on a Step then expand the Advanced Settings area and enter some Script to tie in to Cyclr’s Events as described below.
This is generally easier to read than multiple inline scripts and as mentioned above, there may be a performance advantage to using one set of Step Script instead of multiple inline scripts.
Connector Script #
If you’re building a Custom Connector you also have the option to add script directly to the Connector’s definition.
This is done in the Script section of the Connector builder, either at the top level or within individual methods.
Event Handlers #
Events are triggered at certain points when a Cycle runs, allowing you to modify data using “event handlers” which are simply JavaScript functions.
To add an event handler, put a JavaScript function at the Connector or Method level, or in the Advanced Settings area of a Step in the Cycle Builder, using the event name as the name of the function, e.g.:
function before_action() {
/* Handle event here */
return true;
}
When working on a Custom Connector, event handlers entered at the Connector level will be called for all of its Methods. Event handlers entered at the Method level will only be called for that Method. Event handlers entered through a Step’s Step Setup will only be called for that one Step.
If you need to pass a value from a before_action handler to an after_action handler and you’re not able to put it in the method_request object as part of the Request (the API being called might object to it), you can use the method_request_mergefields object as it’s persisted across those two events. The script_parameters object, for example, is not persisted across any events.
Event Handler Order #
If an event handler exists at more than one level for the same event, i.e. Connector level as well as Method level, all of those event handlers are called.
This is useful if common processing of the data is required across all Methods using a Connector level after_action handler, but some Methods need further processing so an additional Method level after_action handler can also be used.
The order that Cyclr calls handlers for the same event is as follows:
Events beginning with “before” (such as before_action
):
Method -> Connector -> Builder Step
All other events (such as after_action
):
Connector -> Method -> Builder Step
General Objects #
- script_execution_context: (string) Contains a value that can be used to identify the context your Script is being executed in. Its value will be
RUNNING_TRANSACTION
,CONNECTOR_TESTING
orSTEP_TESTING
depending on where it’s being executed. - method_response_fields: Array containing all the Response Fields defined on a Method.
- method_response_fields_in_use: Array containing the Response Fields defined on a Method that have been mapped on subsequent Steps.
Variables and Event Handler Functions #
This matrix shows the Script variables present in each Event Handler Function.

Events #
before_webhook #
Called when a webook request has been received and before anything else is done. Method is used to decide if the request should be continued or return a custom message to the caller.
Global objects
- method_endpoint: (string) The webhook request URL.
- method_request_headers: (object) The webhook request headers.
- method_request: (object) The received webhook request body.
- method_raw_request: (string) A string representing the received webhook request body exactly as Cyclr received it. Useful when writing Script to validate requests as genuine when a sending system has added a signature.
- method_request_parameters: (object) The webhook request parameters.
- method_response_headers: (object) The response headers for the request.
- method_response: (object) The response body for the request.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true for the webhook to continue normal execution, false to stop execution of the request and send the response body/headers to the caller
after_webhook #
Called immediately after a Request to a Webook has been received, whether the Cycle is currently running or stopped.
Global objects
- method_response: (object) The data that was POSTed to the Cyclr webhook
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- cycle_step_id: (string) ID of the step that is executing the script.
- cycle_id: (string) The ID of the cycle the script is running in
- cyclr_account_id: (string) The internal ID of the account the script is running in
- return: true for the webhook to continue normal execution, false to ignore the webhook request
before_action #
Called before Cyclr makes a request to an external API.
If a Method uses Paging, this function is called before each page is retrieved.
Global objects
- method_request_headers: (object) HTTP headers for the request.
- method_request_parameters: (object) Querystring parameters for the request.
- method_request: (object) Data that will be posted to the third party API.
- method_request_mergefields: (object) Mergefields for the request.
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- cycle_step_id: (string) ID of the step that is executing the script.
- cycle_id: (string) ID of the cycle the script is running in
- cyclr_account_id: (string) The internal ID of the account the script is running in
- external_account_id: (string) The external ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- last_successful_run_date: (string) Time value indicating when a Step last ran without error.
- action_data: (object) An object used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- script_parameters: (object) An object that contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true to continue with the request to the third party API, false to abort the request (use throw for a more useful step error message)
after_action #
Function is called when Cyclr has a response from an external API.
If a Method uses Paging, this function is called after each page is retrieved.
Global objects
- method_endpoint: (string) The URL of the original request
- method_request: (object) Data that was posted to the third party API
- method_request_mergefields: (object) Mergefields for the request
- method_response_headers: (object) Response headers for the request
- method_response: (object) Data that was received from the third party API. If the Method uses paging, this contains only the current page’s Response.
- method_raw_response: (string) A string representing the received Response Body exactly as Cyclr received it.
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- cycle_step_id: (string) ID of the step that is executing the script.
- cycle_id: (string) ID of the cycle the script is running in
- cyclr_account_id: (string) Internal ID of the account the script is running in
- external_account_id: (string) External ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- action_data: (object) An object used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- statusCode: (number) The response status code.
- reasonPhrase: (string) The response reason phrase.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true
after_action_paging #
If this function is provided, it is called once after all pages of data have been retrieved, whether Paging has been implemented or not.
The Paging referred to here is Inbound. This function doesn’t wait for Outbound paging to complete.
Global objects
- method_request_headers: (object) The response headers for the request
- method_request_parameters: (object) Parameters for the request
- method_request_mergefields: (object) Mergefields for the request
- method_response: (object) Contains all of the Response data.
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- cycle_step_id: (string) ID of the step that is executing the script.
- cycle_id: (string) ID of the cycle the script is running in
- cyclr_account_id: (string) Internal ID of the account the script is running in
- external_account_id: (string) External ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- next_last_successful_run_date: (string) Assign to this variable to set the last_successful_run_date value a Step will use on its next run.
- action_data: (object) Used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true
after_error #
Function is called when Cyclr received an error from an external API.
Global objects
- method_error: (object) Details of the error, see Handle Errors from Third Party APIs below for more information on handling errors.
- cycle_variables: (object)Allows access to Cycle variables. Changes are not persisted.
- cycle_step_id: (string) ID of the step that is executing the script.
- cycle_id: (string) ID of the cycle the script is running in
- cyclr_account_id: (string) Internal ID of the account the script is running in
- external_account_id: (string) External ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- action_data: (object) Used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true
action_condition #
Function is used to essentially combine a Method with a Decision Step, allowing a test to be performed that directs a Transaction down either the True or False exit points. If this function is included in a method, Cyclr will add True and False exit points.
Global objects
- method_response: (object) object that was received from the third party API.
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- cycle_step_id: (string) ID of the step that is executing the script.
- cycle_id: (string) ID of the cycle the script is running in
- cyclr_account_id: (string) Internal ID of the account the script is running in
- external_account_id: (string) External ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- action_data: (object) Used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true for the Transaction to exit on the “True Route”, false to exit on the “False Route”
before_oauth2_authorise #
Function is called before Cyclr makes an OAuth 2 authorise request.
Global objects
- method_endpoint: (string) URL for the OAuth authorise endpoint
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- action_data: (object) Used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- return: true
before_oauth2_token #
Called before Cyclr makes an OAuth 2 access token request.
Global objects
- method_request_headers: (object) HTTP headers for the request
- method_request: (object) Object that is going to be sent to the OAuth 2 access token endpoint
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- external_account_id: (string) External ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- action_data: (object) Used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true
after_oauth2_token #
Called after Cyclr makes an OAuth 2 access token request.
Global objects
- method_response: (object) response object that was received from the OAuth 2 access token request
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- action_data: (object) Used to persist data between some event handler functions, allowing data to be passed between them. Accessible in before_action, after_action, after_action_paging, action_condition, after_error, before_oauth2_authorise, before_oauth2_token and after_oauth2_token.
- return: true
before_oauth2_refresh #
Called before Cyclr makes an OAuth 2 refresh token request.
Global objects
- method_request_headers: (object) HTTP headers for the request
- method_request: (object) request object that is going to be sent to the OAuth 2 refresh token request
- external_account_id: (string) External ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true
after_oauth2_refresh #
Called after Cyclr makes an OAuth 2 refresh token request.
Global objects
- method_response: (object) response object that was received from the OAuth 2 refresh token request.
- external_account_id: (string) External ID of the account the script is running in
- cyclr_account_timezone: (string) The timezone set on the Cyclr Account as a “TZ identifier”, e.g. “America/New_York” or “Europe/London”. If used in a Template within the Console, it returns “Etc/UTC”.
- cycle_variables: (object) Allows access to Cycle variables. Changes are not persisted.
- script_parameters: (object) Contains any available script parameters from the connector and method. Note: Changes are not persisted.
- return: true
Functions #
http_request #
Function to make external HTTP requests.
When calling the http_request
function, you provide a JSON object with the following properties:
method
: HTTP method, e.g. GET, POST, DELETE, PUTurl
: URL for the HTTP requestparameters
: Querystring parametersbinary
: Defaults tofalse
. Boolean to indicate whether contents of the Response Body should be treated as binary (true
) or text (false
).headers
: HTTP headersdata
: HTTP request data. If sending JSON, you should use JSON.stringify() to serialize it.
Example:
function after_action() {
var response = http_request(
{
'method': 'POST',
'url': 'https://someapi.com/createsomething',
'binary': false,
'headers':
{
'Authorization': 'Bearer ' + method_auth_value,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
'data': JSON.stringify( { "MyData": "some value" } )
}
);
return true;
}
The Response from an http_request
call is returned as a JSON object with these properties:
- status_code: the HTTP Status code returned
- headers: any HTTP headers
- content: the Response body
- request: details of the Request that was made
btoa #
Function to encode a string to Base64 using a specified destination character set.
Note: If no character set is provided the default will be UTF-8
Supported character sets which can be supplied: ASCII
, ISO-8859-1
, UTF-7
, UTF-8
, UTF-16
, UTF-16LE
, UTF-16BE
, UTF-32
, UTF-32LE
, UTF-32BE
var Utf8Base64Encoded = btoa(“Hĕllō Wōrld”); // SMSVbGzFjSBXxY1ybGQ=
var AsciiBase64Encoded = btoa(“Hĕllō Wōrld”,”ascii”); // SD9sbD8gVz9ybGQ=
var IsoBase64Encoded = btoa(“Hĕllō Wōrld”,”iso-8859-1″); // SGVsbG8gV29ybGQ=
atob #
Function to decode a Base64 encoded string, using a specified source character set, back to its original value.
Note: If no character set is provided the default will be UTF-8
Supported character sets which can be supplied: ASCII
, ISO-8859-1
, UTF-7
, UTF-8
, UTF-16
, UTF-16LE
, UTF-16BE
, UTF-32
, UTF-32LE
, UTF-32BE
var Utf8Base64Decoded = atob("SMSVbGzFjSBXxY1ybGQ="); // Hĕllō Wōrld
var AsciiBase64Decoded = atob("SD9sbD8gVz9ybGQ=","ascii"); // H?ll? W?rld
var IsoBase64Decoded = atob("SGVsbG8gV29ybGQ=","iso-8859-1"); // Hĕllō Wōrld
cyclr_encrypt #
Function to generate a hash from a value.
Parameter | Description |
---|---|
algorithm | The hashing algorithm to use. String. Options are: * md5 * sha1 * sha256 * sha512 |
data | The input data to generate a hash from. |
base64Encoded | Whether the data parameter is base64 encoded.Boolean. Defaults to false if not set. |
Example:
var algorithm = 'sha512';
var valueToHash = 'This is the string to hash.';
var hash = cyclr_encrypt(algorithm, valueToHash);
cyclr_sign #
Function to sign a string.
Example:
var algorithm = 'HMAC-SHA1';
var signingKey = 'This is the signing key.';
var valueToSign = 'This is the string to sign.';
var signature = cyclr_sign(algorithm, signingKey, valueToSign, 'base64');
Supported algorithms are: HMAC-SHA1
, HMAC-SHA256
, HMAC-SHA512
, RSA-SHA1
, RSA-SHA224
, RSA-SHA256
, RSA-SHA384
, RSA-SHA512
.
If provided, the 4th parameter in the function call is the encoding type of the signingKey as a string. Possible values are:
UTF8
– the default if not provided.hex
base64
cyclr_csv_parse #
Function to parse a CSV string.
var csv = '1,2,3\na,b,c';
var delimiter = ',';
var hasHeader = false;
var csvRecords = cyclr_csv_parse(csv, delimiter, hasHeader);
cyclr_xml_serialize #
Function to convert JSON to XML.
var jsonObj = {
"note": {
"to": "Tove",
"from": "Jani",
"heading": "Reminder",
"body": "Dont forget me this weekend!"
}
};
var jsonObjAsXml = cyclr_xml_serialize(jsonObj);
// Output:
//<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Dont forget me this weekend!</body></note>
cyclr_xml_deserialize #
Function to convert XML to JSON.
var xmlStr = '<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Dont forget me this weekend!</body></note>';
var xmlAsJson = cyclr_xml_deserialize(example);
// Output:
// {
// "note": {
// "to": "Tove",
// "from": "Jani",
// "heading": "Reminder",
// "body": "Dont forget me this weekend!"
// }
// }
PGP Encryption #
Cyclr provides the following Script functions for use with Pretty Good Privacy (“PGP”) encryption:
cyclr_pgp_encrypt(textToEncrypt, pgpPublicKey)
cyclr_pgp_decrypt(encryptedPgpMessage, pgpPrivateKey[, passphrase])
These functions enable you to encrypt and decrypt data using PGP encryption and can be used on Connector Methods or directly on Steps within the Builder.
With PGP encryption, you generate a Public and a Private Key as a pair. You then encrypt text using the Public Key, and decrypt it using the Private Key and passphrase (if set).
cyclr_pgp_encrypt()
Simple Example:
function before_action() {
method_request.messageContent = cyclr_pgp_encrypt(method_response.messageContent, "myPublicKey");
return true;
}
Example showing realistic (but truncated) values:
var encryptedMsg = cyclr_pgp_encrypt(`A string to encrypt.`, `-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: OpenPGP.js v.1.20130420
Comment: http://openpgpjs.org
xk0EZ6OKXgECAM7iHQVl78y7/THrCBj+5+dRB3NFDcZcj4qI8//f3eg173CT
[...]
XyMhZhJGMH++oR2j/s0QW+yxR6Ac+PzC+1wDk8BUuw==
=MfCB
-----END PGP PUBLIC KEY BLOCK-----`);
cyclr_pgp_decrypt()
Simple Example:
function after_action() {
method_response.decryptedData = cyclr_pgp_decrypt(method_response.data, "myPrivateKey", "myPassphrase");
return true;
}
Example showing realistic (but truncated) values:
var decryptedMsg = cyclr_pgp_decrypt(`-----BEGIN PGP MESSAGE-----
Version: OpenPGP.js v4.10.10
wYwDbctZCAjZL9MBBAC1UOC/K1HC32gMlh1wQUT2B/CUwTBUJY9rGXCuZVuT
[...]
QIb6hK1SRamKnTK331X+WfNSChwV7lJiY8coJWBHpMNTaQ==
=OP5x
-----END PGP MESSAGE-----`, `-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: BCPG v1.58
lQH+BGeE6mABBADkWBXfayPtXYK8tobIxhNZRYi0Tz7EmQ6Kaj8XWoi3ypPYRxED
[...]
Oi8Y8uDjnnyj7msKTOHrGLiX4CovtmE/QfDTXtY0g/lwA5OPnQzb7O+tme+kJuT6
c3i7fg==
=Fixv
-----END PGP PRIVATE KEY BLOCK-----`, 'E*rtAZ9m-3Hs9FgjHEyk')
Storage Functions #
Cyclr provides several storage functions available for use in Script that can be used when developing a Connector, or on a Step in a Template or Cycle.
Data they work against is locked to the instance of a Connector they’re called on. i.e. if you write data using cyclr_storage_set()
on a Step from one installed Salesforce Connector, you cannot access that same data using cyclr_storage_get()
on a Step from a different Salesforce Connector.
The functions come in 2 flavours:
cyclr_storage_...()
and cycle_storage_...()
The cyclr_storage_...()
functions access the same data on any Steps in any Cycles for a particular instance of a Connector.
The cycle_storage_...()
functions work in the same way, but their data is further restricted to the context of a particular Cycle. If you write data in one Cycle, you cannot access it in another;
The storage functions available in their cyclr_
versions are shown below.
Change cyclr_
to cycle_
to use the versions that are further restricted to a particular Cycle:
- cyclr_storage_list_values()
- cyclr_storage_delete_all()
- cyclr_storage_delete(key)
- cyclr_storage_get(key)
- cyclr_storage_set(key, value)
- cyclr_storage_append(key, value)
- cyclr_storage_list_keys()
- cyclr_storage_increment(key, amount)
- cyclr_storage_decrement(key, amount)
Exceptions #
AuthRefreshException #
Exception to force the OAuth 2 authentication token to be refreshed.
This is useful when the OAuth 2 endpoint doesn’t return a definite token expiry time.
Upon getting this exception, Cyclr will call the OAuth 2 Access Token URL to get a new access token.
For example, an API returns 200 with an error code in the response when the token becomes invalid:
function after_action() {
if (typeof method_response.error !== 'undefined' &&
method_response.error === 'invalid_grant') {
throw new AuthRefreshException();
}
return true;
}
If an API returns a non-2xx HTTP status code when the auth token becomes invalid, you should throw AuthRefreshException
in after_error
:
function after_error() {
if (method_error.statusCode === 403) {
throw new AuthRefreshException();
}
return true;
}
AuthSessionException #
Exception to force the authentication session to be refreshed.
Upon getting this exception, Cyclr will call the Post Install Property Value Lookup Method to start a new session.
For example, an API returns 200 with an error code in the response when the session expires:
function after_action() {
if (typeof method_response.error_code !== 'undefined' &&
method_response.error_code === 'You are not logged on.') {
throw new AuthSessionException();
}
return true;
}
If an API returns a non-2xx HTTP status code when the auth session expires, you should throw AuthSessionException
in after_error
:
function after_error() {
if (method_error.statusCode === 403) {
throw new AuthSessionException();
}
return true;
}
Libraries #
The following libraries are available within Cyclr’s script engine:
Note: It is not necessary to load these with a require
call as they are automatically available.
Moment.js #
Library Name: moment
Description: Parse, validate, manipulate, and display dates and times in JavaScript. Cyclr also supports the Moment Timezone extension, which enables formatting and converting of dates in any timezone.
External Documentation: https://momentjs.com/ , https://momentjs.com/timezone/
CryptoJS #
Library Name: crypto-js
Description: JavaScript library of crypto standards.
Note: The output of encrypted data is always in a hex string. Formatting options CryptoJS.enc
are not supported when calling toString
.
External Documentation:
https://github.com/brix/crypto-js
https://cryptojs.gitbook.io/docs
Modules supported by Cyclr:
- MD5
- SHA1
- SHA256
- HmacSHA1
- HmacSHA256
- HmacSHA512
Example usage:
var md5Hash = CryptoJS.MD5("A string to hash.");
var sha256Hash = CryptoJS.SHA256("A string to hash.");
var hmacSha512Hash = CryptoJS.HmacSHA512("A string to hash.");
Connector scripting examples #
Make External Requests #
You can write a script to call external API endpoints. This is especially useful if the API returns a URL which contains the real response object.
For example, a webhook returns the following object to Cyclr:
{
"event": "object.updated",
"api_url": "http://httpbin.org/get"
}
Use http_request
to call api_url
and replace the webhook response with the updated object:
function after_webhook() {
var request = {
'method': 'GET',
'url': method_response.api_url,
'headers': {
'Accept': 'application/json'
}
};
var content = http_request(request).content;
method_response = content;
return true;
}
After calling api_url
, Cyclr will then replace method_response
with the content of the HTTP call.
Return false
in the after_webhook
function will stop Cyclr from running the webhook. You can use this trick to filter webhook events.
Transform Key Value Pairs #
Making use of key value pair responses requires the use of scripting, consider an API that returns the below representation of a contact.
{
"properties": [{
"key": "email",
"value": "example@example.com"
}]
}
To access the email field we would add a field in the method response with a connector location of properties.email. However this would not work as the Cyclr is looking in the response for a properties object with a property named email to get the value from. To solve the issue we would add the below function into the method scripts, this function will transform the properties array into an object with properties for each key value pair.
function after_action() {
var original = method_response.properties;
method_response.properties = {};
for (var i = 0; i < original.length; i++) {
var item = original[i];
if (item['key'] == void(0))
continue;
var val = item['value'];
if (val == void(0))
continue;
method_response.properties[item['key']] = val;
}
return true;
}
Now when Cyclr runs the method if will get the following result back and the properties.email field will work as expected.
{
"properties": {
"email": "example@example.com"
}
}
For a corresponding request method, e.g. adding a contact, we would need the below function in the method scripts to perform the data transformation in reverse.
function before_action() {
var original = method_request.properties;
method_request.properties = [];
for (var p in original) {
method_request.properties.push({
'key': p,
'value': original[p]
});
}
return true;
}
Modify Parameters #
Besides the HTTP request body, you can also use scripting to modify HTTP headers (method_request_headers
) and query string parameters (method_request_parameters
).
function before_action() {
var xmlData = '<Records><Record>';
for (var p in method_request) {
xmlData += '<Field val=""' + p + '"">' + method_request[p] + '</Field>';
}
xmlData += '</Record></Records>';
method_request_parameters.xmlData = xmlData;
return true;
}
In this example, we transformed the method request body to a XML string and saved the string as a new parameter called xmlData
.
Action Condition #
When working with a Custom Connector, you can add True/False Exits to a Step if you put an action_condition
event function on your Custom Connector’s Method.
Note: Adding an action_condition
function to a Step doesn’t have any effect.
// Any records that pass the condition will continue down the green "True" path.
// Those that do not will take the red "False" path.
function action_condition() {
if ([some test])
return true;
return false;
}
// If you want to send errored transactions (as opposed to successful calls that
// fail the condition) down the false path, you will need to add after_error script.
Handle Errors from Third Party APIs #
The scripting engine can be used to catch and handle errors returned from third party APIs.
Cyclr exposes a received error response in the after_error
function through the method_error
object, which has these properties:
- statusCode – (number) the HTTP status code returned by the third party API.
- reasonPhrase – (string) the reason phrase returned by the third party API.
- content – (string) the body content of the response from the third party API. Could contain JSON or XML.
- isError – indicates that the error is an error. default: true, set to false if using isWarning or isSuccess.
- isWarning – set to true for Cyclr to log the error as a warning.
- isSuccess – set to true to change the error to success. This will result in the value of
method_error.content
being provided as the data to be returned. Alternatively, you can assign a string to provide your own data as the response, e.g.:method_error.content = '{"result": "An error occurred."}'
Example: change an error to a warning
function after_error() {
if (method_error.statusCode != null &&
method_error.statusCode === 400 &&
method_error.reasonPhrase == 'Email Address not valid') {
method_error.isError = false;
method_error.isWarning = true;
}
return true;
}
Example: change an error to a success
function after_error() {
if (method_error.statusCode != null &&
method_error.statusCode === 400 &&
method_error.reasonPhrase == 'Email Address not valid') {
method_error.isError = false;
method_error.isSuccess = true;
method_error.content = '{}';
}
return true;
}
Limitations #
- Script used in Event Handler functions will execute for a maximum of 60 seconds before Cyclr times it out and returns an error.
Exceptions to this are:after_action
– times out after 90 seconds and runs separately for each page of data retrieved.after_action_paging
– times out after 90 seconds multiplied by the number of pages of data retrieved.
- External HTTP requests: for security reasons, we will use the same authentication method as the connector and the same authentication value when the connector was installed by the user. You cannot use the script to access or modify the authentication value.
- The cycle_variables object is only available through a Step’s Advanced Settings area, and not through Inline Script. Also, any changes made to it and its properties are not persisted.