- Print
- DarkLight
- PDF
Overview
The Code node provides a convenient way to add custom functionality to your Process by allowing you to access, modify, and create task parameters using JavaScript or Erlang. Although the Code node is highly efficient in speed, you may encounter a timeout error if your code is computationally intensive and takes an extended period to execute or if it includes an infinite loop. If your code requires extra processing power, you can create a dedicated microservice and call it from Corezoid. If you need further assistance, don't hesitate to contact us for custom solutions that will better fit your needs.
The Code node is specifically intended for handling simple code snippets. For more complex coding tasks, we recommend using the Git Call node as a better alternative.
Settings
The Code node has the following parameters:
- (Optional) Title and Description: Name and details of the node.
- Code editor: Supports following programming languages:
Javascript: Task parameters can be found within the data object, and you can access them using dot notation.
data.parameter_name
List of supported JavaScript libraries:
Available CryptoJS methods:
- Hashing: MD5, SHA-1, SHA-512, HMAC MD5, HMAC SHA-1, HMAC SHA-256
- Ciphers: AES, DES, Triple DES, Rabbit, RC4
- Encoders: base64
Below you can see an example of your code where Data is the task object, and param is one of its parameters.
-module(node). -export([main/1]). main(Data) -> [{<<"param">>, <<"Hello World!!!">>} | Data].
- XRegExp: XRegExp is an extensive regular expression library for JavaScript, enhancing native RegExp with new capabilities and syntaxes. It simplifies complex regex operations and supports Unicode matching.
Other:
- Alert if the number of tasks in the node queue reaches the following number: Helps monitor whether the number of tasks in the node exceeds the specified threshold. When selecting the checkbox, you have to enter the needed number of tasks in the field that appears below.
- Maximum interval, for which the task stays in the node before being forwarded: The amount of time a task is allowed to be in the node can be set in seconds, minutes, hours, and days.
Note: The checkbox has a minimum value of 30 seconds. You can set a shorter interval by using the Unixtime function.
Examples
Working with date/time using moment.js
In the Code editor form of the Code node details panel, you can write your code in JavaScript using the supported libraries.
You can see the example below.
require("libs/moment.js");
let datetime = moment().format('MMMM Do YYYY, h:mm a');
data.message = "Hi " + data.name + ". Today is " + datetime +". What a great time to learn Corezoid!" ;
require("libs/moment.js")
: Import the moment.js library used to obtain the current date and time.let datetime = moment().format('MMMM Do YYYY, h:mm a')
: Use the moment() method to obtain the current date and time and the format() method to convert it into a string. The resulting value is assigned to a local variable.data.message = "Hi " + data.name + ". Today is " + datetime +". What a great time to learn Corezoid!"
: Create a string using the value of the name parameter from the data object and the value of the datetime variable generated. Assign this string to data.message, which creates a new task parameter with the message key and the value of the string.
The data object stores the task parameters: name is an existing task parameter, and message is added as a new one. datetime is a local variable that will not be part of the task; it only exists temporarily while the node processes it.
Moment-timezone
require("libs/moment-timezone.js");
data.date = moment().tz('Europe/Kiev').format("DD-MM-YYYY HH:mm:ss");
require("libs/moment-timezone.js")
: Import the moment-timezone.js library used to convert and format dates for different time zones.data.date = moment().tz('Europe/Kiev').format("DD-MM-YYYY HH:mm:ss")
: Use the moment() method to obtain the current time, the format() method to define the desired format, and the tz() method to change the time zone to Europe/Kiev.
Hashing
MD5
require("libs/md5.js"); data.md5 = CryptoJS.MD5(data.variable).toString();
data.variable
: Task parameter that will be hashed.data.md5
: Task parameter that will store the hash.
SHA-1
require("libs/sha1.js"); data.sha1 = CryptoJS.SHA1(data.variable).toString();
data.variable
: Task parameter that will be hashed.data.sha1
: Task parameter that will store the hash.
SHA-512
require("libs/sha512.js"); data.sha512 = CryptoJS.SHA512(data.variable).toString();
data.variable
: Task parameter that will be hashed.data.sha512
: Task parameter that will store the hash.
HMAC SHA-1
require("libs/hmac-sha1.js"); var hash = CryptoJS.HmacSHA1(data.message, data.secret); data.hashInHex = hash.toString(CryptoJS.enc.Hex);
data.message
: Task parameter that will be hashed.data.secret
: Task parameter that stores the secret.data.hashInHex
: Task parameter that will store the hash as a hexadecimal string.
HMAC SHA-256
require("libs/hmac-sha256.js"); var hash = CryptoJS.HmacSHA256(data.message, data.secret); data.hashInHex = hash.toString(CryptoJS.enc.Hex);
data.message
: Task parameter that will be hashed.data.secret
: Task parameter that stores the secret.data.hashInHex
: Task parameter that will store the hash as a hexadecimal string.
Ciphers
AES
Encrypting
require("libs/aes.js"); data.encrypted = CryptoJS.AES.encrypt(data.message, data.password).toString();
data.message
: Task parameter that will be encrypted.data.password
: Task parameter that contains the password.data.encrypted
: Task parameter that will store the encrypted string.
Decrypting
require("libs/aes.js"); data.decrypted = CryptoJS.AES.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
data.encrypted
: Task parameter that will be decrypted.data.password
: Task parameter that contains the password.data.decrypted
: Task parameter that will store the decrypted string.
DES
Encrypting
require("libs/tripledes.js"); data.encrypted = CryptoJS.DES.encrypt(data.message, data.password).toString();
data.message
: Task parameter that will be encrypted.data.password
: Task parameter that contains the password.data.encrypted
: Task parameter that will store the encrypted string.
Decrypting
require("libs/tripledes.js"); data.decrypted = CryptoJS.DES.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
data.encrypted
: Task parameter that will be decrypted.data.password
: Task parameter that contains the password.data.decrypted
: Task parameter that will store the decrypted string.
Triple DES
Encrypting
require("libs/tripledes.js"); data.encrypted = CryptoJS.TripleDES.encrypt(data.message, data.password).toString();
data.message
: Task parameter that will be encrypted.data.password
: Task parameter that contains the password.data.encrypted
: Task parameter that will store the encrypted string.
Decrypting
require("libs/tripledes.js"); data.decrypted = CryptoJS.TripleDES.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
data.encrypted
: Task parameter that will be decrypted.data.password
: Task parameter that contains the password.data.decrypted
: Task parameter that will store the decrypted string.
Rabbit
Encryptingrequire("libs/rabbit.js"); data.encrypted = CryptoJS.Rabbit.encrypt(data.message, data.password).toString();
data.message
: Task parameter that will be encrypted.data.password
: Task parameter that contains the password.data.encrypted
: Task parameter that will store the encrypted string.
Decrypting
require("libs/rabbit.js"); data.decrypted = CryptoJS.Rabbit.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
data.encrypted
: Task parameter that will be decrypted.data.password
: Task parameter that contains the password.data.decrypted
: Task parameter that will store the decrypted string.
RC4
Encryptingrequire("libs/rc4.js"); data.encrypted = CryptoJS.RC4.encrypt(data.message, data.password).toString();
data.message
: Task parameter that will be encrypted.data.password
: Task parameter that contains the password.data.encrypted
: Task parameter that will store the encrypted string.
Decrypting
require("libs/rc4.js"); data.decrypted = CryptoJS.RC4.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
data.encrypted
: Task parameter that will be decrypted.data.password
: Task parameter that contains the password.data.decrypted
: Task parameter that will store the decrypted string.
Encoders
Base64
Encoding
require("libs/base64.js"); var wordArray = CryptoJS.enc.Utf8.parse(data.variable); data.base64 = CryptoJS.enc.Base64.stringify(wordArray);
data.variable
: Task parameter that will be encoded.wordArray
: Tocal variable that stores a wordArray representation ofdata.variable
.data.base64
: Task parameter that will store the encoded string.
Decoding
require("libs/base64.js"); var words = CryptoJS.enc.Base64.parse(data.base64); data.parsedStr = words.toString(CryptoJS.enc.Utf8);
data.base64
: Task parameter that will be decoded.words
: Tocal variable that stores a wordArray representation ofdata.base64
.data.parsedStr
: Task parameter that will store the decoded string.
Encoding
require("libs/hmac-sha256.js"); require("libs/base64.js"); // Custom function to base64URL encode a string manually (pure JS) function base64UrlEncode(input) { // Convert the input to a word array const wordArray = CryptoJS.enc.Utf8.parse(input); // Convert the word array to a base64 string let base64String = CryptoJS.enc.Base64.stringify(wordArray); // Perform base64URL encoding (replace characters and remove padding) base64String = base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); return base64String; } // Function to create a secure HMAC SHA-256 signature function createSignature(message, secret) { // Generate HMAC SHA-256 signature using the loaded library const hash = CryptoJS.HmacSHA256(message, secret); // Convert the hash to a base64-encoded string const base64 = CryptoJS.enc.Base64.stringify(hash); // Convert base64 to base64url return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); } // Function to generate the JWT token function generateJwtToken(header, payload, secret) { // Step 1: Encode the header and payload const encodedHeader = base64UrlEncode(JSON.stringify(header)); const encodedPayload = base64UrlEncode(JSON.stringify(payload)); // Step 2: Create the signature using HMAC-SHA256 const message = `${encodedHeader}.${encodedPayload}`; const signature = createSignature(message, secret); // Step 3: Return the final JWT return `${message}.${signature}`; } const header = { alg: "HS256", typ: "JWT" }; const payload = data.payload; const secret = data.secret; data.jwtToken = generateJwtToken(header, payload, secret);
Decoding
require("libs/base64.js"); require("libs/hmac-sha256.js"); // Base64Url encode function function base64UrlEncode(input) { return CryptoJS.enc.Base64.stringify(input) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); } // Base64Url decode function function base64UrlDecode(input) { let base64 = input.replace(/-/g, '+').replace(/_/g, '/'); while (base64.length % 4) { base64 += '='; } return CryptoJS.enc.Base64.parse(base64); } // Create HMAC SHA-256 signature function createSignature(message, secret) { const hash = CryptoJS.HmacSHA256(message, secret); return base64UrlEncode(hash); } // Decode and validate JWT token function decodeAndValidateJwtToken(token, secret) { const parts = token.split('.'); if (parts.length !== 3) { throw new Error('Invalid JWT token format'); } // Decode header and payload const header = JSON.parse(CryptoJS.enc.Utf8.stringify(base64UrlDecode(parts[0]))); const payload = JSON.parse(CryptoJS.enc.Utf8.stringify(base64UrlDecode(parts[1]))); const providedSignature = parts[2]; // Store decoded parts and original signature data.jwtHeader = header; data.jwtPayload = payload; data.jwtSignature = providedSignature; // Validate signature if secret is provided if (secret) { const message = `${parts[0]}.${parts[1]}`; const expectedSignature = createSignature(message, secret); data.signatureValidation = (expectedSignature === providedSignature) ? 'success' : 'failed'; } else { data.signatureValidation = 'not performed'; } // Validate token expiration const currentTime = Math.floor(Date.now() / 1000); if (payload.exp && payload.exp < currentTime) { data.tokenStatus = 'expired'; } else { data.tokenStatus = 'valid'; } } // Main execution try { const token = data.token; const secret = data.secret || null; // Optional secret for validation decodeAndValidateJwtToken(token, secret); } catch (error) { data.error = error.message; }
XRegExp
- Extended Syntax: This example demonstrates named capture groups for improved readability and maintainability.
Input (data.input - a text string):
[2024-11-06 14:23:00] INFO: User login successful, User ID: 12345, IP: 192.168.1.1
[2024-11-06 14:23:15] ERROR: Failed to load data, User ID: 12345
[2024-11-06 14:23:30] WARN: User requested invalid action, IP: 192.168.1.2
Code:
require("libs/xregexp.js");
// Define the complex multiline regex pattern
const logPattern = XRegExp(`
^ # Start of the line
(?<timestamp>\\[[^\\]]+\\]) # Capture timestamp in square brackets
\\s+ # Match one or more spaces
(?<level>\\w+) # Capture the log level (INFO, ERROR, etc.)
:\\s+ # Match colon and space after level
(?<action>[^,]+) # Capture the user action description (until the first comma)
(?:,\\s+User\\sID:\\s+(?<userId>\\d+))? # Optionally match User ID (if available)
(?:,\\s+IP:\\s+(?<ip>[^\\s,]+))? # Optionally match IP address (if available)
$ # End of the line
`, 'gm'); // Use 'g' for global matching and 'm' for multiline flag
data.output = [];
// Parse the log text using XRegExp.exec and iterate through matches
let match;
while ((match = XRegExp.exec(data.input, logPattern)) !== null) {
const logEntry = {
timestamp: match.timestamp,
level: match.level,
action: match.action,
};
if (match.userId) {
logEntry.userId = match.userId;
}
if (match.ip) {
logEntry.ip = match.ip;
}
// Output will now be stored in `data.output`
data.output.push(logEntry);
}
Output (data.output - a JSON array):
[
{
"timestamp": "[2024-11-06 14:23:00]",
"level": "INFO",
"action": "User login successful",
"userId": "12345",
"ip": "192.168.1.1"
},
{
"timestamp": "[2024-11-06 14:23:15]",
"level": "ERROR",
"action": "Failed to load data",
"userId": "12345"
},
{
"timestamp": "[2024-11-06 14:23:30]",
"level": "WARN",
"action": "User requested invalid action",
"ip": "192.168.1.2"
}
]
- Unicode Matching: This pattern matches any Unicode letter, showcasing XRegExp's Unicode property support.
require("libs/xregexp.js");
XRegExp('\\p{L}');
Error handling & troubleshooting
When an error occurs in the Code node, a task goes to the auxiliary Condition output node that
is used for storing error parameters.
When an error occurs during the task processing, you may see the following error parameter names in the task.
Error parameter name | Error type |
---|---|
__conveyor_code_return_type_error__ | Hardware (system error), Software (error in a node logic/settings). |
__conveyor_code_return_type_tag__ | *Error tag. |
__conveyor_code_return_type_description__ | Error description in human-readable language; can be static or dynamic. |
*The error tag __conveyor_code_return_type_tag__
may have the following values.
Value | Cause | Solution |
---|---|---|
code_timeout | Code has been running for too long. | Check if your program contains an infinite loop. |
code_executing_error | Your code contains an error. | Debug your code. |
code_return_format_error | Your code has a return statement that doesn't belong in a function and returns a value that isn't an object. The Code node wraps your code into a function, so an unexpected return statement can cause the program to end abruptly. | Remove the return statement to resolve the error. |
code_return_size_overflow | The size of your code exceeds the specified limit set for your environment. | Reduce the size of your code. |
code_fatal_error | A hardware error has occurred. | Contact the support team for further assistance. |
When working with your Process or State Diagram, you may encounter the following issues.
Issue | Cause | Solution |
---|---|---|
Failing to access task parameters. | The code refers to objects or object properties absent from the task. | Define the missing objects or object properties within the Code node or adjust the code to remove all references to them. |
A task parameter is referenced without using the data object. | Add a data object reference in front of the name of a task parameter. For example: data.amount = 1 is correct; amount = 1 is not correct. | |
Task parameters are gone. | The data object was assigned a new value in the Code node. | Data is a special object used by Corezoid to store task parameters. Therefore, access to task parameters will be removed if it is changed. You should avoid reassigning this object and use a different name for your variables instead. |