Automate Bulk Record Imports in Zoho CRM Using Bulk Write API and Deluge
Summary:
This article demonstrates how to use Zoho CRM’s Bulk Write API (v8) with Deluge scripts and Zoho WorkDrive to automate importing large volumes of records. The process is split across two custom functions, one for initiating the bulk import and another for tracking its status. Custom Function: Automate Bulk Record Imports from WorkDrive
Requirement Overview:
Businesses often deal with high-volume data entry operations such as customer databases. Uploading such data manually using the CRM UI is time consuming, error-prone, and inefficient.
This solution automates that workflow using:
- A .zip file with .CSV data uploaded in WorkDrive
- Two custom functions in Zoho CRM to:
a) Upload the file and trigger the Bulk Write API
b) Track the job status and retrieve the result
Deploy Custom Function in Zoho CRM
This use case requires two custom functions:
Function 1:
Function 2:
You can configure Function 2 to run after a delay using CRM's Schedules module.
Use Case
Scenario:
A real estate agency receives new property data daily in CSV format. The goal is to automate the bulk creation of “Floor Plan” records in CRM using this data. The CSV is zipped and stored in WorkDrive. This setup ensures data consistency and eliminates manual imports.
Configuration Steps:
1. Prepare a .csv file with the required module fields.
Example columns: Name, Email, etc.
Zip the file and upload it to a specific WorkDrive folder.
2. Create a CRM variable named Job_Id
API Name: Job_Id
Type: Text
3. Set up API Connections
The Code
Function 1: Initiate Bulk Write Job
(Download WorkDrive file → Upload to CRM → Start Bulk Write job → Store Job ID)
- // Fetch file from WorkDrive
- headerMap = Map();
- headerMap.put("Accept","application/vnd.api+json");
- fetchFiles = invokeurl
- [
- url :"https://www.zohoapis.com/workdrive/api/v1/files/<FOLDER_ID>/files"
- type :GET
- headers:headerMap
- connection:"workdrive"
- ];
- documentId = fetchFiles.getJSON("data").get(0).get("id");
- // Download file
- downloadFile = invokeurl
- [
- url :"https://download.zoho.com/v1/workdrive/download/" + documentId
- type :GET
- headers:headerMap
- connection:"workdrive"
- ];
- // Upload to CRM
- headerMap = Map();
- headerMap.put("feature", "bulk-write");
- headerMap.put("X-CRM-ORG", "<CRM ORG_ID>");
- uploadFile = invokeurl
- [
- url: "https://content.zohoapis.com/crm/v8/upload"
- type: POST
- headers: headerMap
- files: downloadFile
- connection: "crm"
- ];
- fileId = uploadFile.get("details").get("file_id");
- // Construct Bulk Write payload
- fieldMappings = list();
- fieldMappings.add({"api_name":"Name","index":0});
- fieldMappings.add({"api_name":"Email","index":1});
- resource = Map();
- resource.put("type","data");
- resource.put("module",{"api_name":"Floor_plans"});
- resource.put("field_mappings",fieldMappings);
- resource.put("file_id",fileId);
- data = list();
- data.add(resource);
- payload = Map();
- payload.put("operation","insert");
- payload.put("ignore_empty","true");
- payload.put("callback",{"url": "https://webhook.site/<your-id>","method":"post"});
- payload.put("resource",data);
- // Trigger Bulk Write API
- headerMap = Map();
- headerMap.put("Content-Type","application/json");
- bulkWrite = invokeurl
- [
- url :"https://www.zohoapis.com/crm/bulk/v8/write"
- type :POST
- parameters:payload.toString()
- headers:headerMap
- connection:"crm"
- ];
- jobId = createBulkWrite.getJSON("details").get("id");
- jobIdVariable = "<Add the ID of the Variable>";
- variableMap = Map();
- variableMap.put("id",jobIdVariable);
- variableMap.put("value",jobId);
- variablesList = List();
- variablesList.add(variableMap);
- param = Map();
- param.put("variables",variablesList);
// Update the variable with the Job ID value- updateVariable = invokeurl
- [
- url :"https://www.zohoapis.com/crm/v8/settings/variables"
- type :PUT
- parameters:param.toString()
- connection:"crm"
- ];
- info updateVariable;
Function 2: Track Job Status & Download Result
(Run using a Schedule – after 15-30 mins)
- // Get the Job ID variable info
- getVariableInfo = invokeurl
- [
- url: "https://www.zohoapis.com/crm/v8/settings/variables/3361723000088498029"
- type: GET
- connection:"stagehistory"
- ];
- info getVariableInfo;
- variableValue = getVariableInfo.getJSON("variables").get(0).get("value");
- info variableValue ;
// Call the Job details API to know the status- jobDetails = invokeurl
- [
- url: "https://www.zohoapis.com/crm/bulk/v8/write/"+jobId
- type: GET
- connection:"stagehistory"
- ];
- info jobDetails;
- jobStatus = jobDetails.getJSON("status");
// Check the status of the job- if(jobStatus == "success") {
- // Business logic to perform a task if the job status is success
- }
Custom Solution Created by Francis (Vishnu) | Zoho Partner Support
Tips : Avoid Common Errors
- Ensure to use the correct API Names for both Module & Fields in the script.
- To ensure you get the intended output, we would suggest you to use info() logs to each variable to check the output for seamless functionality under the Console section within Zoho CRM Function IDE.
- Since we have used the Connections within a function script, ensure to have the required scopes added in connection to perform the intended API action. Also, ensure to use the connection link name (i.e., crm_connection ) while passing on to Deluge Invoke URL or Integration Task.
- As a common practice, we have used US DC API end point. If you are using CRM account in a different DC (i.e., IN, EU, CA, AU, etc.), then we would recommend you to use the API end point URL according to your DC.
Refer to the following Guide - Article to learn the Best Practices for Optimising the Code and Various ways to Deploy Custom Function across Zoho CRM.