Before the examples, a brief walkthrough of where custom functions live and how to deploy them:
Problem: When a deal is created or when the linked account’s industry is updated, the deal record should automatically populate its “Account Industry” field from the account. This gives management the ability to filter and report on deals by industry without reps manually entering the same data twice.
Trigger: Workflow rule on the Deals module — fires when a deal is created or when the Account Name lookup field changes.
What the code does: fetches the deal, reads the linked account ID, fetches the account, reads its industry and writes it to a custom field on the deal. The guard on lines 10–13 prevents an error if the function fires on a deal with no linked account. The field API name “Account_Industry__c” is the internal name of the custom field — find it in Setup → Modules → Deals → Fields.
| // Function: copyAccountIndustryToDeal // Input parameter: dealId (Long) // 1. Fetch the deal record deal = zoho.crm.getRecordById(“Deals”, dealId); // 2. Get the linked Account ID from the deal accountId = deal.get(“Account_Name”).get(“id”); // 3. Guard: skip if no account is linked if(accountId == null ││ accountId == “”) { return; } // 4. Fetch the Account record account = zoho.crm.getRecordById(“Accounts”, accountId); // 5. Read the Industry field from the Account industry = account.get(“Industry”); // 6. Update the Deal record with the Account’s industry updateMap = Map(); updateMap.put(“Account_Industry__c”, industry); zoho.crm.updateRecord(“Deals”, dealId, updateMap); |
|---|
Problem: Sales deals need a human-readable reference number in the format DEAL-2026-0001, DEAL-2026-0002, etc. The CRM’s built-in auto-number field does not support year-prefixed sequential numbering.
Trigger: Workflow rule on the Deals module — fires only when a deal is created.
This example introduces two additional patterns: the invokeurl block for making API calls to Zoho’s own APIs (needed when the built-in Deluge functions do not provide the specific data point required) and a while loop for zero-padding the sequence number. The connection “zoho_crm_oauth” is a Connections entry created in Setup → Developer Space → Connections.
| // Function: generateDealNumber // Input parameter: dealId (Long) // 1. Get the current year currentYear = zoho.currentdate.getYear(); // 2. Search for existing deals this year to get the count criteria = “(Created_Time:greater_equal:” + currentYear + “-01-01T00:00:00+00:00)”; existingDeals = zoho.crm.searchRecords(“Deals”, criteria, 1, 1); // 3. Count deals created so far this year // Note: this uses a separate count query for accuracy countResp = invokeurl [ url: “https://www.zohoapis.com/crm/v2/Deals/count” type: GET connection: “zoho_crm_oauth” ]; totalCount = countResp.get(“count”).toLong(); // 4. Build the reference number with zero-padding sequenceNum = totalCount.toString(); while(sequenceNum.length() < 4) { sequenceNum = "0" + sequenceNum; } dealNumber = "DEAL-" + currentYear + "-" + sequenceNum; // 5. Write the reference number to the deal updateMap = Map(); updateMap.put("Deal_Number__c", dealNumber); zoho.crm.updateRecord("Deals", dealId, updateMap); |
|---|
Problem: When a deal is marked Closed Won, the account management team needs a standard set of onboarding tasks created automatically — Introduction call, Send welcome pack, System access setup, 30-day check-in. Creating these manually is time-consuming and inconsistent; different account managers create different tasks, some skip tasks and onboarding quality varies.
Trigger: Workflow rule on the Deals module — fires when Stage changes to “Closed Won”.
This example demonstrates list iteration (for each), date arithmetic (addDay), and creating records in a related module. The “What_Id” and “Who_Id” fields link each task to the deal and the primary contact respectively — so the tasks appear in both the deal’s activity timeline and the contact’s activity timeline.
For five more ready-to-use Deluge scripts, see the 5 Deluge scripts every CRM admin should know. For training on writing and maintaining these functions yourself, see the Deluge training programme.
| // Function: createOnboardingTasks // Input parameter: dealId (Long) // 1. Get the deal record to retrieve owner and linked contact deal = zoho.crm.getRecordById(“Deals”, dealId); ownerId = deal.get(“Owner”).get(“id”); contactId = deal.get(“Contact_Name”).get(“id”); dealName = deal.get(“Deal_Name”); // 2. Define onboarding tasks with offsets from today // Format: [Task Subject, Days from today] taskList = List(); taskList.add({“subject”:”Introduction call — ” + dealName, “offset”:1}); taskList.add({“subject”:”Send welcome pack — ” + dealName, “offset”:2}); taskList.add({“subject”:”System access setup — ” + dealName, “offset”:3}); taskList.add({“subject”:”30-day check-in — ” + dealName, “offset”:30}); // 3. Create each task in the Activities module for each task in taskList { dueDate = zoho.currentdate.addDay(task.get(“offset”)); taskData = Map(); taskData.put(“Subject”, task.get(“subject”)); taskData.put(“Due_Date”, dueDate.toString(“yyyy-MM-dd”)); taskData.put(“Status”, “Not Started”); taskData.put(“Priority”, “High”); taskData.put(“Owner”, {“id”: ownerId}); taskData.put(“What_Id”, {“id”: dealId, “type”: “Deals”}); taskData.put(“Who_Id”, {“id”: contactId, “type”: “Contacts”}); zoho.crm.createRecord(“Tasks”, taskData); } |
|---|
What is a Zoho CRM custom function?
Do I need to be a developer to write Zoho CRM custom functions?
What are the most common use cases for Zoho CRM custom functions?
How are custom functions triggered in Zoho CRM?
Can ABR write custom functions for our Zoho CRM?