Functions | Online Help | Qntrl

Functions

Early Access  
Functions are not enabled for all users. If you have enabled Circuit in your organization, all your custom functions will be migrated as functions. If you’d like to try out Circuit, please email our support team for early access. 

Functions allow users to program a set of operations and execute them when invoked from an application. Users can automate processes or integrate with Zoho and other third- party applications using functions.

Functions in Qntrl allow you to write your own scripts in a language that you are comfortable with. These are serverless functions, where the cloud provider allocates machine resources dynamically. You can write your code in Qntrl without having to worry about server management while running the code.

Qntrl supports multiple programming languages for writing functions:

  • Zoho Deluge

  • JavaScript

  • Python

  • Python 3

  • Java

  • Node.js

Info

The supported languages vary depending on the module type selected.


Business uses cases

  1. Write a Java function that allows you to create a Qntrl card or send an SMS to a contact listed on a Qntrl card.
  2. Create a Python function in Qntrl that can validate an email address or determine the strength of a password.
  3. Write a Node JS function in Qntrl to hide passwords with asterisks (***) when entered or retrieve the current date and time.   

Create and Configure a Function 

1. Create a Function

  1. Navigate to(settings) and select Functions under Advanced.
  2. Click New Function from the top right corner of the page. 
  3. Enter the following details:
    1. NameProvide a unique name (no spaces or special characters). This name will serve as an identifier when invoking the function.
    2. Module TypeChoose the appropriate module (Default: Cards). See Module Type section for more information.  
    3. Boards(Only for Cards module) Select the relevant board. This field is disabled for other module types.
    4. Language:  Select a supported language based on the chosen module. For details, refer to the Languages section.
    5. Description: Add a description for the function.
  4. Click Save to proceed to the function editor.
    

Module Types and Language Compatibility  

Module Type

Purpose

Supported Languages

Cards

Automate card field logic or business rules

Zoho Deluge (Only)

Standalone

Custom scripts triggered manually or used in Circuits/Schedules

Deluge, Java, Python, Python 3, Node.js, Java Script

Web Service REST

Used in inbound and outbound REST API calls

JavaScript

Web Service SOAP

Used in inbound and outbound SOAP API calls

JavaScript


2. Write and Deploy the Function

Once in the editor:

  1. Write your logic using the selected language.

    1. Refer to the Languages section for guidance on configuring the chosen language.

    2. Refer to the Configure Functions by Modules section to configure functions for different modules.

  2. Configure the required parameters in the right panel.

  3. Once your function is ready and the parameters are configured, click Save to store the function.

  4. Click Save and Execute to test it with sample input. 


  1. If there are no errors, the Input dialog will open.

  2. Whenever a function is executed, there will be some values passed with the function. These values are called arguments. Specify the arguments based on which your function runs in the dialog and click Execute.



  1. The function will execute and render an Output in the Execution Status dialog box. This output will have two keys:

    1. Output key with a value, which is the output data.

    2. Log key has log data which the user prints using statement. 


  1. Click Deploy to bring it live and available for use.

NotesFor functions to be available inside Circuits, they must be deployed first.

 Other Actions in Functions 

  1. Navigate to(settings) Advanced and click Functions.
  2. In the list of functions, hover over the desired function and click the action menu (...).

  3. The following actions are available:

    1. Edit: Modify the function’s name and configuration settings.

    2. Preview: View the function’s code without opening the editor.

    3. REST API: Access the REST API link secured with OAuth credentials.

    4. Delete: Permanently remove the function from your system.


Languages     

Zoho Deluge        

Deluge functions is a native scripting language in Qntrl. No external packages are needed. It can be configured in Qntrl and linked to circuits, workflows, business rules, schedules, orchestrations, or used as standalone functions. Learn more about Zoho Deluge.

Use Case: Retrieve User's Geolocation Based on IP    

This function retrieves a user's IP-based geolocation details such as IP address, city, region, country, coordinates, and internet service provider (ISP). Businesses can use this data to personalize content, detect suspicious activity, or enhance user experience by adapting services based on location.
How It Works:  
  1. The function calls the public ipinfo.io API to retrieve geolocation details of the client based on their IP address.

  2. The API returns information including IP, city, region, country, latitude-longitude coordinates, and organization/ISP.

  3. The function extracts and displays these values for further use in applications like:

    • Location-based personalization (language, currency, offers).

    • Fraud detection (suspicious logins from unusual regions).

    • Logging and auditing user access.

  1. If the request fails, an error message is logged for debugging.

Sample Deluge Code Snippet

void getUserGeoInfo() { api_url = "https://ipinfo.io/json"; response = invokeurl [ url :api_url type :GET ]; try { ip = response.get("ip"); city = response.get("city"); region = response.get("region"); country = response.get("country"); org = response.get("org"); loc = response.get("loc"); info "IP: " + ip; info "Location: " + city + ", " + region + ", " + country; info "Coordinates: " + loc; info "ISP/Org: " + org; } catch (e) { info "Error getting IP info: " + e.toString(); } }
Upon successful execution, the function displays the user's IP address and geolocation details retrieved from the API.

JavaScript     

Alert

Early Access  

This feature is not enabled for all users. If you’d like to try it out, please email our support team for early access.

Write your functions in JavaScript and associate them with workflows, business rules, schedules, orchestrations, circuits, or use them as standalone functions. External packaged files are not supported.

Use Case: Creating a Folder and Uploading a File with a JavaScript Function 

This function automates file management in Qntrl by creating a new folder at a specified path and uploading a file with the provided content.  

How It Works:  
  • Parse the input data to extract folder name, file path, and file content.
  • Create a folder at the specified path.
  • Upload a text file into the newly created folder.
  • Return a success message if the operation is completed, or an error message if any step fails.

Sample JavaScript Code Snippet
function execute(data) {
  try {
      let jsonData = JSON.parse(data);
 
    if (!jsonData.folderName || !jsonData.filePath || !jsonData.fileContent) {
      console.error("Incomplete data provided.");
      return JSON.stringify({ success: false, message: "Incomplete data provided." });
    }
    let folderCreationResponse = OntrlFile.createFolder(jsonData.folderName, jsonData.filePath);
    folderCreationResponse
      .ifFailed(message => {
        console.error('Failed to create folder:', message);
        return JSON.stringify({ success: false, message: 'Failed to create folder.' });
      })
      .ifSuccess(() => {
        console.log('Folder created successfully.');
        let file = new File([jsonData.fileContent], 'uploaded_file.txt', { type: 'text/plain' });
        let uploadResult = OntrlFile.upload(file, {
          path: jsonData.filePath + '/' + jsonData.folderName,
          overwrite: true
        });
        console.log('Upload Result:', uploadResult);
        return JSON.stringify({ success: true, message: "Folder created and file uploaded successfully." });
      });
  } catch (error) {
    console.error('Error during execution:', error);
    return JSON.stringify({ success: false, message: "Error during execution." });
  }
}
Once you execute this function, you will be prompted to provide the input details.

Sample Input

{
  "folderName": "ProjectDocs",
  "filePath": "/user/uploads",
  "fileContent": "Initial project requirements and specifications."
}

Upon successful execution, a success message will be displayed, and the file will be uploaded to the newly created folder. If the execution is unsuccessful, an error message will be displayed. 


Node JS       

Node.js functions can be created and configured in Qntrl with auto-packaging support. These functions can be associated with workflows, business rules, schedules, or orchestrations, or used as stand-alone functions.

Use Case: Validating Email Input  

This function validates whether the user-provided input is in a proper email format. It ensures only correctly structured email addresses are accepted before proceeding with further processing. This is particularly useful for input validation in workflows, forms, and user onboarding scenarios.

How It Works:

  • Read the input parameter email.
  • If no email is provided, return an error message.
  • Apply a regex pattern to check if the email format is valid.
  • If valid, log and return a confirmation message.
  • If invalid, log and return an error message.

 

Sample Node JS Code Snippet
module.exports = async function(context, basicIO) { const input = basicIO.getParameter("email"); if(input === null) { basicIO.write(" provide a email paramter"); return; } const email = input.toString().trim(); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const isValid = emailRegex.test(email); if (isValid) { basicIO.write("Valid email: " + email); context.log.INFO("Validated email: " + email); } else { basicIO.write("Invalid email format."); context.log.INFO("Email validation failed for input: " + email); } }


Packaged Files Support:
Qntrl automatically packages your Node JS function and creates config.json and library files.
In the left panel, you can view the config.json and lib files.
  • config.json is a configuration file
  • lib is the library to which you can upload your third-party packages. Right-click on the folder to upload files.
Specify the values of the following keys:
  1. path: The .js file path contains the function code.
  2. action: Contains the action that your code performs. This is also the name of the main class in your .js file.
  3. connector: Contains the name of the connection that your function calls, if any.
Notes

The input body must be a JSON object with values for the arguments used in the code.


Sample Input
{
}

Once executed, the given email format will be validated and returns either a success message with the email or an error message if the format is invalid.


Python       

Write your functions in Python and link them to workflows, business rules, schedules, and orchestrations, or use them as standalone logic. The code runs in a Python 2 environment. You should follow Python 2 syntax while using any features supported by Python 2.

Use Case : Password Strength Validation

This function validates the strength of a user-provided password. It ensures that the password meets standard security requirements such as minimum length, presence of uppercase and lowercase letters, numbers, and special characters. This can be useful for enforcing password policies in workflows or during user onboarding.

How It Works:

  • Reads the password input.
  • Checks if it contains:
    • At least one uppercase letter
    • At least one lowercase letter
    • At least one number
    • At least one special character
    • Minimum length of 8 characters
  • Returns True if all conditions are met; otherwise, returns False. 
Sample Python Code Snippet
import re def check_password_strength(password): # Define regular expression patterns for strong passwords has_uppercase = re.compile(r'[A-Z]') has_lowercase = re.compile(r'[a-z]') has_number = re.compile(r'[0-9]') has_special = re.compile(r'[!@#$%^&*()_+{}\[\]:";\'<>?,./]') # Check if password meets all requirements if (has_uppercase.search(password) and has_lowercase.search(password) and has_number.search(password) and has_special.search(password) and len(password) >= 8): return True return False def runner(context, basicI0): password = basicI0.getParameter("password") is_strong = check_password_strength(password) basicI0.write(str(is_strong))

 

Packaged Files:

Qntrl automatically packages your Python function and creates config.json and library files.
In the left panel, you can view the config.json and lib files.
  • config.json is a configuration file
  • lib is the library to which you can upload your third-party packages. Right-click the folder to upload files.

Configuration Keys

  • path: The .js file path that contains the function code.

  • action: Contains the action that your code performs. This is also the name of the main class in your .js file.

  • connector: Contains the name of the connection that your function calls, if any.

The input body must be a JSON object with values for the arguments used in the code as shown below.  


Sample Input

{
    "password": "James@19189#"
}

The function executes and displays the response in the console.


Java      

Java functions allow strong typing and are ideal for more structured automation.

Code your functions in Java and associate them with workflows, business rules, schedules, orchestrations, circuits, or have them as standalone functions.

Use Case: Currency Conversion Function 

This function converts amounts between currencies using live exchange rates from an external API. It helps automate quick financial calculations within workflows, avoiding manual conversions. For example, businesses can instantly convert an invoice in INR to its USD equivalent during transactions.

How It Works:  
  1. Reads the input parameters:
    • from → Source currency (e.g., INR)
    • to → Target currency (e.g., USD)
    • amount → Amount to be converted (e.g., 100)
  1. Validates the inputs:
    • Ensures that all parameters are provided.
    • Confirms that the amount is a valid number.
  1. Connects to the exchange rate API:
    • Retrieves the latest exchange rate for the given currencies.
    • Handles cases where exchange rates are not available.
  1. Calculates the converted value.
  2. Returns the result in a clear format (e.g., 100 INR = 1.20 USD).

Sample Java Code Snippet

import com.zoho.cloud.function.Context; import com.zoho.cloud.function.basic.*; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import org.json.JSONObject; public class Java_doc1 implements ZCFunction { public void runner(Context context, BasicIO basicIO) throws Exception { String from = (String) basicIO.getParameter("from"); String to = (String) basicIO.getParameter("to"); String amountStr = (String) basicIO.getParameter("amount"); if (from == null || to == null || amountStr == null) { basicIO.write("Missing parameters: 'from', 'to', or 'amount'."); return; } double amount; try { amount = Double.parseDouble(amountStr); } catch (NumberFormatException e) { basicIO.write("Invalid amount. Please enter a valid number."); return; } // Call exchange rate API String apiUrl = String.format("https://free.ratesdb.com/v1/rates?from=%s&to=%s", from, to); URL url = new URL(apiUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("User-Agent", "Java"); int responseCode = conn.getResponseCode(); if (responseCode != 200) { basicIO.write("Failed to fetch exchange rate. HTTP code: " + responseCode); return; } BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; StringBuffer responseData = new StringBuffer(); while ((inputLine = in.readLine()) != null) { responseData.append(inputLine); } in.close(); // Parse JSON response JSONObject json = new JSONObject(responseData.toString()); JSONObject rates = json.getJSONObject("data").getJSONObject("rates"); if (!rates.has(to)) { basicIO.write("Exchange rate not available for currency: " + to); return; } double rate = rates.getDouble(to); double convertedAmount = amount * rate; String result = String.format("%.2f %s = %.2f %s", amount, from, convertedAmount, to); basicIO.write(result); } }


Packaged Files:
Qntrl automatically packages your Java function and creates config.json and library files.
You can view the config.json and library files in the left panel.
  • config.json is a configuration file
  • lib is the library to which you can upload your third-party packages. Right-click the folder to upload files.
Notes
  • Only .jar files can be uploaded in the lib folder.

  • Files up to 10 MB are only allowed.                                       

To pass the arguments of your function in the body, use the below code.   


Sample Input

{
  "from": "INR",
  "to": "USD",
  "amount": "100"
}

The function executes and displays the response in the console.

Notes
  • You can upload only one zip file per function.

  • The maximum allowed size of the zip file is 10MB.

 

Python 3 

Write your functions in Python and link them to workflows, business rules, schedules, and orchestrations, or use them as standalone logic. The code runs in a 3.9.16. version of the Python 3 environment. You should follow Python 3 syntax while using any features supported by Python 3.

Use Case: Password strength Checker 

This function evaluates the strength of a given password by checking its compliance with common security standards such as length, uppercase/lowercase letters, digits, and special characters.

How It Works:

  1. The user inputs a password.

  2. The function checks the following criteria:

    • Minimum length of 8 characters

    • At least one uppercase letter

    • At least one lowercase letter

    • At least one digit

    • At least one special character (!@#$%^&*(),.?":{}|<>)

  1. Based on the evaluation, it returns:

    • Strong password if all conditions are met.

    • Moderate password if some conditions are missing.

    • Error message pointing out what is missing.

  1. If the password is weak, the function suggests a randomly generated secure password.

 

Sample Python 3 Code Snippet

import re import secrets import string def runner(context, basicIO): context.log.INFO("log") password = basicIO.getParameter("password"); basicIO.write(check_password_strength(password)); def check_password_strength(password: str) -> None: strength = 0 if len(password) >= 8: strength += 1 else: return "Password should be at least 8 characters long." if re.search(r'[A-Z]', password): strength += 1 else: return "Password should include at least one uppercase letter." if re.search(r'[a-z]', password): strength += 1 else: return "Password should include at least one lowercase letter." if re.search(r'\d', password): strength += 1 else: return "Password should include at least one digit." if re.search(r'[!@#$%^&*(),.?":{}|<>]', password): strength += 1 else: return "Password should include at least one special character (!@#$%^&*(),.?\":{}|<>)" if strength == 5: return "Strong password!" elif 3 <= strength < 5: return "Moderate password. Try to include all types of characters." else: basicIO.write("Weak password. Consider using a stronger one.") suggestion = generate_secure_password() basicIo.write(f"Suggested strong password: {suggestion}") def generate_secure_password(length: int = 12) -> str: characters = string.ascii_letters + string.digits + "!@#$%^&*()?" return ''.join(secrets.choice(characters) for _ in range(length)) if __name__ == "__main__": pwd = input("Enter a password to check its strength: ") check_password_strength(pwd)


Packaged Files:

Qntrl automatically packages your Python function and creates config.json and library files.

In the left panel, you can view the config.json and lib files.

  • config.json is a configuration file

  • lib is the library to which you can upload your third-party packages. Right-click the folder to upload files.

Specify the values of the following keys:

  • path: The .js file path that contains the function code.

  • action: Contains the action that your code performs. This is also the name of the main class in your .js file.

  • connector: Contains the name of the connection that your function calls, if any.

Use the code below to pass the arguments of your function in the body.


Sample Input

"password": "sweri025377A"
The function executes and displays the response in the console.

Configuring Functions by Module    

Card based Function (Deluge Only)   

  • The functions can be used in Cards and Business Rules.
  • Use drag-and-drop Deluge scripting interface.
  • Once associated with a board, the board cannot be changed.

Adding Parameters:  
  • Under the Parameters section:
    • Board: Choose fields from the card.
    • Custom: Create new fields manually.
  • These parameters can be passed dynamically during function execution by providing the job ID.

Standalone Functions   

  • The functions can be used in Circuits and Schedules.

  • Can be written in any supported language.

  • Must be deployed to be used.

  • Client Callable: Turn this on to allow the function to be called from browsers, widgets, and other backend functions.Turn it off to allow only backend functions to call it.


Adding Parameters:  
  • Manually define key-value parameters in the editor.

  • These values are passed during execution.


Deployment Package Structure (Standalone)   

Each function should be packaged in a specific directory structure depending on the language used.

Depending on the selected language, the deployment package must be structured as follows:

Java   

FunctionName (root folder)

|

|---- FunctionName.java // Runner file

|---- lib // Folder for for dependent .jar files

        |---- <dependent .jar files>

|---- classes // Compiled class files in package structure

        |---- <compiled dependent .class files in package structure>

Notes

Any .java files placed directly in the root folder (not within packages) will also be compiled.

To build Java functions using a custom IDE, download the zc-server-sdk-core.jar file and include it in your project setup.

 

Node.js   

FunctionName (root folder)

|

|---- FunctionName.js // Runner file

|---- node_modules // Dependency folder

      |-- <dependent js files & folders>

 

Python / Python 3
FunctionName (root folder)

|

|---- FunctionName.py // Runner file

|---- <dependent.py files> // Additional modules or scripts

 

Uploading Dependencies   

To include third-party libraries with your function, follow the enhanced deployment structure described below for supported languages.

Java (with Dependencies) 

FunctionName(root folder)

|

| - - - - FunctionName.java // Main runner file

| - - - - config.json // Function configuration

| - - - - lib // Third-party JARs

| - - - - <dependent .jar files>

| - - - - classes

| - - - - <compiled dependent .class files in package structure>    

File Descriptions:  
  • FunctionName.java: Entry point of the function. You may define multiple runner files and configure them in config.json.

  • config.json: Contains metadata and execution settings for the function.

  • lib/: Place all third-party .jar files here.

  • classes/: Add your compiled .class files following the Java package structure.

Download Sample Java Deployment Zip

 

NodeJS   (with Dependencies) 

FunctionName(root folder)

|

| - - - - FunctionName.js // Main runner file

| - - - - config.json // Function configuration

| - - - - node_modules // Installed dependencies

| - - - - <third-party modules>

File Descriptions:  

  • FunctionName.js: Primary script that executes the logic. Users can add multiple runners that can be configured in config.json.

  • config.json: Used to define runners and execution parameters.

  • node_modules/: This directory should have all third-party dependencies needed.

Download Sample Node.js Deployment Zip

 

Python   / Python 3(with Dependencies) 

FunctionName(root folder)

|

| - - - - FunctionName.py // Main runner file

| - - - - config.json // Function configuration

| - - - - lib // Third-party libraries

| - - - - <third-party modules>

File Descriptions:  

  • FunctionName.py: Primary script that executes the logic. Users can add multiple runners that can be configured in config.json.

  • config.json: Defines runner configuration and dependencies.

  • lib/: Contains additional Python modules used by the function.

 

Web Service Functions

Functions created for web services support only JavaScript and are used in:

  • Inbound/Outbound REST APIs

  • Inbound/Outbound SOAP APIs 

Use Codex SDK for script creation and refer to Codex documentation for schema references.


Key Configurations:  

  • Module type must be set as Web Service REST or Web Service SOAP.

  • Scope (admin/user) defines execution privileges.    


    • Related Articles

    • Manage Custom Functions

      Custom functions allow users to develop and execute user-defined functions using Deluge. You can execute simple program snippets to automate processes, or integrate with third-party or Zoho applications. Business Uses for Custom Functions Use Custom ...
    • Configure Schedules

      Qntrl allows users to trigger custom functions periodically or at defined time intervals using Schedules. It can be used to obtain automated updates, weekly notifications, or monthly reports in an organization. Business Scenarios Schedule recurring ...
    • Custom Function: Move_Job_to_other_Stage

      This custom function can be used to move a card to any stage in the blueprint automatically. Cards can be moved to previous stages or upcoming stages. Business Scenario Mark, the head of Marketing, reviews all the marketing articles in his ...
    • Configuring Additional Components

      Early Access Circuit Templates in Qntrl Studio is not enabled for all users. If you’d like to try it out, please email our support team for early access. Webhooks Webhooks enable automated HTTP notifications that are sent to third-party applications ...
    • Features of Circuit

      Configure with or without code Circuit provides a platform to build workflow orchestrations with or without code. You can either visually design the Circuit schematics by dragging and dropping its elements in Builder View, or build its JSON code in ...

    You are currently viewing the help articles of Qntrl 3.0. If you are still using our older version and require guidance with it, Click here.