As developers, we frequently switch between coding, debugging, and optimizing tasks. The last thing we want is to be burdened by manual user management. Adding users one by one to a channel is tedious and prone to errors, taking up more time than we could devote to actual development.
Let's explore how to create a custom workflow using Cliq's platform components to streamline the process of bulk-adding users to a channel via a Zoho Sheet or CSV file. This approach facilitates a smooth onboarding experience without the need for manual effort.
Pre-requisite :
Before beginning to script the code below, we must create a connection with Zoho Cliq. Once a connection is created and connected, you can use it in
Deluge integration tasks and
invoke URL scripts to access data from the required service.
Create a Zoho Oauth default connection with any unique name and the scopes - ZohoCliq.Channels.All and ZohoSheet.dataApi.ALL
Refer to the below links to learn more :
Step 1 : Creation of slash command
- After a successful login in Cliq, hover to the top right corner and click your profile. Post clicking, navigate to Bots & Tools > Commands.
- At your right, click the button - Create Command.
- To know more about slash commands and their purposes, refer to Introduction to slash commands.
- Create a slash command using your preferred name. Specify the following details: the command name, a hint (to give users an idea of what the command is for), and the access level.
- Finally, click "Save & edit code".

- inputs = List();
- inputs.add({"name":"channels","label":"Pick a channel","placeholder":"Choose a channel where you need to add members","max_selections":"1","multiple":false,"mandatory":true,"type":"native_select","data_source":"channels"});
- inputs.add({"name":"headername","label":"Header name","placeholder":"Email ID","hint":"In which the Email ID is present","min_length":"0","max_length":"25","mandatory":true,"type":"text"});
- inputs.add({"type":"radio","label":"Import type","name":"import_Type","hint":"Choose a type that you need to import users","options":[{"label":"CSV","value":"csv"},{"label":"Zoho sheet","value":"zohosheet"}],"trigger_on_change":"true"});
- return {"name":"addbulkuser","type":"form","title":"Add bulk users","hint":"To add maximum of upto 1000 users in a channel.","button_label":"Add Users","inputs":inputs,"action":{"type":"invoke.function","name":"addbulkusers"};
Step 2 : Scripting form function
- We need to create a function for the form that manages submission responses, including the Zoho Sheet link or CSV file, the name of the column containing the email addresses, and the channel details where users should be added in bulk.
- Hover to the top right corner and click your profile. After clicking, navigate to Bots & Tools > Functions.
- To your right, click the Create Function button.
- Name the function "addbulkusers," provide a description as desired, and select "form" as the function type. Then, click "Save and edit code," and paste the following code.
- emailIdList = list();
- successlist = list();
- failedlist = list();
- try
- {
- info form;
- formValues = form.get("values");
- columnName = formValues.get("headername");
- headerName = formValues.get("headername");
- if(formValues.get("import_Type").get("value") == "zohosheet")
- {
- url = formValues.get("url");
- spreadSheetId = url.getPrefix("?").getSuffix("open/");
- sheetName = url.getSuffix("?").getPrefix("&").getSuffix("=");
- worksheetname = sheetName.replaceAll(" ","%20");
- columnName = columnName.replaceAll(" ","%20");
- allDatas = list();
- params = Map();
- params.put("column_names",columnName);
- params.put("method","worksheet.records.fetch");
- params.put("worksheet_id",sheetName + "#");
- sheetDetails = invokeurl
- [
- url :"https://sheet.zoho"+environment.get("tld")+"/api/v2/" + spreadSheetId
- type :GET
- parameters:params
- connection:"addbulkusers"
- ];
- info sheetDetails;
- if(sheetDetails.get("status") == "success" && sheetDetails.get("records").size() <= 1000)
- {
- allDatas.addAll(sheetDetails.get("records"));
- }
- else if(sheetDetails.get("status") == "success" && sheetDetails.get("records").size() > 1000)
- {
- return {"type":"form_error","text":"I can only able to add 1000 user. Kindly try passing with 1000 records in the sheet!!!"};
- }
- else
- {
- return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
- }
- info "allData: " + allDatas.size();
- if(allDatas.size() > 1000)
- {
- return {"type":"form_error","text":"I can only able to add 1000 user. Kindly try passing with 1000 records in the sheet!!!"};
- }
- for each data in allDatas
- {
- if(data.get(formValues.get("headername")) == null)
- {
- return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
- }
- emailIdList.add(data.get(formValues.get("headername")));
- if(emailIdList.size() == 100)
- {
- channelID = formValues.get("channels").get("id");
- params = {"email_ids":emailIdList};
- info "Params: " + params;
- addUsers = invokeurl
- [
- url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
- type :POST
- parameters:params.toString()
- detailed:true
- connection:"addbulkusers"
- ];
- info "Adduser: " + addUsers;
- if(addUsers.get("responseCode") == "204")
- {
- successlist.addAll(emailIdList);
- }
- else
- {
- failedlist.addAll(emailIdList);
- }
- info "100: " + emailIdList.size();
- emailIdList = list();
- }
- }
- if(emailIdList.size() > 0)
- {
- channelID = formValues.get("channels").get("id");
- params = {"email_ids":emailIdList};
- info "Params: " + params;
- addUsers = invokeurl
- [
- url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
- type :POST
- parameters:params.toString()
- detailed:true
- connection:"addbulkusers"
- ];
- info "Adduser: " + addUsers;
- if(addUsers.get("responseCode") == "204")
- {
- successlist.addAll(emailIdList);
- }
- else
- {
- failedlist.addAll(emailIdList);
- }
- info "Email id: " + emailIdList;
- }
- info "Successlist: " + successlist;
- info "Failedlist: " + failedlist;
- if(successlist.size() > 0 && failedlist.size() > 0)
- {
- postMessage = {"text":"Successfully added " + successlist.size() + " member(s) and failed for " + failedlist.size() + " Member(s)"};
- }
- else if(successlist.size() > 0 && !failedlist.size() > 0)
- {
- postMessage = {"text":"Successfully added " + successlist.size() + " member(s)"};
- }
- else if(!successlist.size() > 0 && failedlist.size() > 0)
- {
- postMessage = {"text":"Adding members in channel failed for " + failedlist.size() + " member(s)"};
- }
- info zoho.cliq.postToChat(chat.get("id"),postMessage);
- }
- else
- {
- csvFile = formValues.get("csvFile");
- csvFile = csvFile.getfilecontent();
- allDatas = csvFile.toList("\n");
- i = 0;
- indexValue = 0;
- indexBoolean = false;
- for each data in allDatas
- {
- if(i == 0)
- {
- headers = data.toList(",");
- for each header in headers
- {
- info header;
- if(headerName == header)
- {
- indexBoolean = true;
- indexValue = headers.indexOf(headerName);
- }
- }
- if(indexBoolean == false)
- {
- return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
- }
- }
- else
- {
- emailIdList.add(data.get(indexValue));
- }
- i = i + 1;
- if(emailIdList.size() == 100)
- {
- channelID = formValues.get("channels").get("id");
- params = {"email_ids":emailIdList};
- info "Params: " + params;
- addUsers = invokeurl
- [
- url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
- type :POST
- parameters:params.toString()
- detailed:true
- connection:"addbulkusers"
- ];
- info "Adduser: " + addUsers;
- if(addUsers.get("responseCode") == "204")
- {
- successlist.addAll(emailIdList);
- }
- else
- {
- failedlist.addAll(emailIdList);
- }
- info "100: " + emailIdList.size();
- emailIdList = list();
- }
- }
- if(emailIdList.size() > 0)
- {
- channelID = formValues.get("channels").get("id");
- params = {"email_ids":emailIdList};
- info "Params: " + params;
- addUsers = invokeurl
- [
- url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
- type :POST
- parameters:params.toString()
- detailed:true
- connection:"addbulkusers"
- ];
- info "Adduser: " + addUsers;
- if(addUsers.get("responseCode") == "204")
- {
- successlist.addAll(emailIdList);
- }
- else
- {
- failedlist.addAll(emailIdList);
- }
- }
- info "Successlist: " + successlist;
- info "Failedlist: " + failedlist;
- if(successlist.size() > 0 && failedlist.size() > 0)
- {
- postMessage = {"text":"Successfully added " + successlist.size() + " member(s) and failed for " + failedlist.size() + " Member(s)"};
- }
- else if(successlist.size() > 0 && !failedlist.size() > 0)
- {
- postMessage = {"text":"Successfully added " + successlist.size() + " member(s)"};
- }
- else if(!successlist.size() > 0 && failedlist.size() > 0)
- {
- postMessage = {"text":"Adding members in channel failed for " + failedlist.size() + " member(s)"};
- }
- info zoho.cliq.postToChat(chat.get("id"),postMessage);
- }
- }
- catch (e)
- {
- info e;
- return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
- }
- return Map();
Step 3 : Configuring form change handler
- After copying and pasting the code into the form submission handler, navigate to the form change handler for the created form function.
- You can find this in the top left corner of the editor, where you will see an arrow next to the form submission handler. Clicking on this arrow will display the form change handler in a dropdown menu.
- Click it to edit the code in the form change handler, which is necessary for real-time modifications to a form's structure or behaviour based on user input in a specific field.
- targetName = target.get("name");
- info targetName;
- inputValues = form.get("values");
- info inputValues;
- actions = list();
- if(targetName.containsIgnoreCase("import_Type"))
- {
- fieldValue = inputValues.get("import_Type").get("value");
- info fieldValue;
- if(fieldValue == "csv")
- {
- actions.add({"type":"add_after","name":"import_Type","input":{"label":"CSV File","name":"csvFile","placeholder":"Please upload a zCSV File","mandatory":true,"type":"file"}});
- actions.add({"type":"remove","name":"url"});
- }
- else if(fieldValue == "zohosheet")
- {
- actions.add({"type":"add_after","name":"import_Type","input":{"name":"url","label":"Enter the sheet url","placeholder":"https://sheet.zoho.com/sheet/open/6xhgb324f142e91d845e5b4b472f7422379c9","min_length":"0","max_length":"400","mandatory":true,"type":"text","format":"url"}});
- actions.add({"type":"remove","name":"csvFile"});
- }
- }
- return {"type":"form_modification","actions":actions};

Business use cases:
- HR onboarding: Seamlessly add new employees to internal communication channels.
- Event management: Quickly invite attendees to event-specific channels.
- Education platforms: Enroll students in course groups in one go.
- Community building: Grow large communities by importing member lists effortlessly.
Bottom line
Bulk user addition in Cliq channels through Zoho Sheet or CSV files allows us to eliminate tedious tasks, reduce errors, and manage large-scale data effortlessly. Is onboarding consuming too much of your valuable development time? If so, it might be time to shake things up with a customized workflow!
We're here to help, so don't hesitate to reach out to support@zohocliq.com with any questions or if you need assistance in crafting even more tailored workflows.
Recent Topics
Auto-upload Creator Files to WorkDrive
Hi everyone, I’m working on a workflow that uploads files from Zoho Creator to specific subfolders in Zoho WorkDrive, as illustrated in the attached diagram. My Creator application form has two multi-file upload fields, and I want—on successful form submission—to
Add a Way to Duplicate Cards in the Same Canvas (Retain All Settings)
Dear Zoho SalesIQ Team, We would like to request a new feature in Zoho SalesIQ: the ability to duplicate an existing card within the same canvas while retaining all of its information and settings, including conditions, configurations, and display preferences.
Workdrive on Android - Gallery Photo Backups
Hello, Is there any way of backing up the photos on my android phone directly to a specific folder on Workdrive? Assuming i have the workdrive app installed on the phone in question. Emma
In arattai received message can't be deleted
The issue has been noticed in following: arattai app (Android) arattai app (Window) arattai web While the message posted by me may be deleted, the ones received from others can't be. The item <Delete> change to <Report> when the message is a received
Market cap
Market cap formula?? Kaise nikale
Zoho Sheet for Desktop
Does Zoho plans to develop a Desktop version of Sheet that installs on the computer like was done with Writer?
Option to Customize Career Site URL Without “/jobs/Careers”
Dear Zoho Recruit Team, I hope you are doing well. We would like to request an enhancement to the Career Site URL structure in Zoho Recruit. In the old version of the career site, our URL was simply: 👉 https://jobs.domain.com However, after moving to
SOME FEATURES ARE NOT IN THE ZOHO SHEET IN COMPARISION TO ZOHO SHEET
TO ZOHO sir/maam with due to respect i want to say that i am using ZOHO tool which is spreadsheet i want to say that some features are not there in zoho sheet as comparison to MS EXCEL like advance filter and other Features which should be there in ZOHO
Google enhanced conversions not working
Hi guys, I've connected Zoho CRM through Google Ads interface with the goal to setup the enhanced conversion tracking in Google Ads. I have to Zoho related conversion goals which you can see in the images below: For the conversion goal above I've setup
Need Help to setup plugs along with codeless bot buidler. To send sms OTPs to users via Zoho Voice and to verify it
Need Help to setup plugs along with codeless bot buidler. To send sms OTPs to users via Zoho Voice and to verify it. I get leads from our website and we need to make sure those are not junk. So we are using proactive chat bot and we need mobile OTPs to
Direct Integration Between Zoho Cliq Meetings and Google Calendar
Dear Zoho Team, We’d like to submit the following feature request based on our current use case and the challenges we’re facing: 🎯 Feature Request: Enable meetings scheduled in Zoho Cliq to be automatically added to the host's Google Calendar, not just
Cliq iOS can't see shared screen
Hello, I had this morning a video call with a colleague. She is using Cliq Desktop MacOS and wanted to share her screen with me. I'm on iPad. I noticed, while she shared her screen, I could only see her video, but not the shared screen... Does Cliq iOS is able to display shared screen, or is it somewhere else to be found ? Regards
Zoho Desk - Cannot Invite or Register New User
Hi who may concern, we encountered a problem that we cannot invite user or the visitor cannot register for a user at all through our help center portal, with the snapshot shown as below and the attachement. It always pops up that "Sorry, Unable to process
Zoho sheet
Unable to share zoho sheet with anyone on internet with editer option only view option is show
Allocating inventory to specific SO's
Is there a way that allocate inventory to a specific sales order? For example, let's say we have 90 items in stock. Customer 1 orders 100 items. This allocates all 90 items to their order, and they have a back order for the remaining 10 items which could
Mail and OS
Jai Hind! Zoho is doing good by creating good software (made in india) on par with other tech giants. 🥰 Suggestion: 1. Whenever we sign up on zoho mail its asking for other mail id. It shouldn't be like that. You should ask general details of a user
Personal account created under org account
Hi there, I am Jayesh. We are using ME Central, and we have an account by the email ID soc@kissht.com.. Now I have created a personal account., jayesh.auti@zohomail.in, accidentally. Can you help me to remove this jayesh.auti@zohomail.in from my organization
Add another account
How to add another mail account to my zoho mail.
Recover deleted user
Hi by mistake i have deleted an added user and his email associated. Please help me recover it thank you.
No connection to the server
Hello! I can't add a new email address to my mailbox because your server is rejecting me. Please help. I took and added a screenshot of this problem Marek Olbrys
URGENT: Business Email Disruption – SMTP Authentication Failed
Dear Zoho Support, I am writing to escalate a critical issue with my business email account: 📧 marek@olbrys.de My domain olbrys.de is fully verified in Zoho (MX, SPF, DKIM, DMARC all valid – green status). I am using the correct configuration: smtp.zoho.eu
Emails missing from desktop but visible on phone
Subject says it all. Windows 11 laptop. Apple phone. all systems up to date.
Website Hosting
Hello, I want to host my domain on Hostinger, and I want my emails to run through Zoho Mail. Please provide me with the SPF record, MX record (Type: TXT), and A record, so that I don’t face any issues with my emails. My website is on Hostinger hosting,
Can not search zoho mail after update V.1.7.0
i can not search mail on to and cc box from attached picture and then search contacts box can't click or use anything. include replay mail too.
Urgent Security Feature Request – Add MFA to Zoho Projects Client Portal Hello Zoho Projects Team,
Hello Zoho Projects Team, We hope you are doing well. We would like to submit an urgent security enhancement request regarding the Zoho Projects Client Portal. At this time, as far as we are aware, there is no Multi-Factor Authentication (MFA) available
How to retreive the "To be received" value of an Item displayed in Zoho inventory.
Hi everyone, We have our own Deluge code to generate a PO according to taget quantity and box quantity, pretty usefull and powerful! However, we want to reduce our quantity to order according to "To be received" variable. Seems like this might not even
Add Support for Authenticator App MFA in Zoho Desk Help Center
Hello Zoho Desk Team, We hope you are doing well. We would like to request an enhancement related to security for the Zoho Desk Help Center (customer portal). Currently, the Help Center supports MFA for portal users via SAML, JWT, SMS authentication,
Payment on a past due balance
Scenario: Customer is past due on their account for 4 months. We suspend their billing in Zoho books. Customer finally logs into the portal and enters a new credit card. We associate that cardwith their subscription, which will permit the card to be used
Instant Sync of Zoho CRM Data?
With how valuable Zoho Analytics is to actually creating data driven dashboards/reports, we are surprised that there is no instant or near instant sync between Zoho CRM and Zoho Analytics. Waiting 3 hours is okay for most of our reports, but there are
Kaizen #211 - Answering your Questions | Using Canvas and Widgets to Tailor CRM for Mobile
Howdy, tech wizards! We are back with the final post in addressing the queries you shared for our 200th milestone. This week, we are focusing on a couple of queries on Zoho CRM mobile configurations and custom payment gateway integration. 1. Mobile SDK
Remove "Invalid entries found. Rectify and submit again" modal
Following up on a post from a few years back, but can the Zoho team consider either removing the 'Invalid entries found. Rectify and submit again' modal that displays for empty mandatory fields OR allow an admin to change it? I've built a custom error
Validation function not preventing candidates under 18 or over 30 from submitting the web form
Hello everyone, I’m trying to create a validation rule for the Candidate Webform in Zoho Recruit. I added a custom field called “Date of Birth”, and I want to make sure that candidates cannot submit the form unless their age is between 18 and 30 years.
Remember all the ways we've posted?
The world celebrates World Postal Day in 2025 with the theme “#PostForPeople: Local Service. Global Reach". The story of the “post” is a story of human connection itself, evolving from simple handwritten notes carried over long distances to instant digital
Custom domain issue
I recently changed records for my support area custom domain for a few months, I then wanted to come back to Zoho, but now I can't connect it and I can't login as it's having an SSL issue. I cannot get a good response from support, as I've been notified
Cadence reports as front-end reports
Hello everyone, We have built a cadence which is connected to the Leads module. There are 11 steps in total, 7 are automatic emails and 4 are tasks for the Lead owners. As admins, we have access to this (very nicely made) 'View Reports' tab where we can
Zoho Commerce in multiple languages
When will you be able to offer Zoho Commerce in more languages? We sell in multiple markets and want to be able to offer a local version of our webshop. What does the roadmap look like?
Show elapsed time on the thank-you page?
Is it possible to display the total time a user spent filling out a Zoho Form on the thank-you? I’d like to show the difference between the `form submission timestamp` and the `start time` (currently have a hidden Date-Time field set to autofill the date
The present is a "present"
The conversation around mental health has been gaining attention in recent years. Even with this awareness, we often feel stuck; the relentless pace of modern life makes us too busy to pause, reflect, and recharge. In the world of customer support, this
Kaizen# 209 - Answering Your Questions | All About Client Script
Hello everyone! Welcome back to another exciting Kaizen post! Thanks for all your feedback and questions. In this post, let's see the answers to your questions related to Client Script. We took the time to discuss with our development team, carefully
Email Integration - Zoho CRM - OAuth and IMAP
Hello, We are attempting to integrate our Microsoft 365 email with Zoho CRM. We are using the documentation at Email Configuration for IMAP and POP3 (zoho.com) We use Microsoft 365 and per their recommendations (and requirements) for secure email we have
Next Page