Bulk user onboarding for Cliq Channels in a jiffy

Bulk user onboarding for Cliq Channels in a jiffy

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".

  1. inputs = List();
  2. 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"});
  3. 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"});
  4. 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"});
  5. 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.
  1. emailIdList = list();
  2. successlist = list();
  3. failedlist = list();
  4. try 
  5. {
  6. info form;
  7. formValues = form.get("values");
  8. columnName = formValues.get("headername");
  9. headerName = formValues.get("headername");
  10. if(formValues.get("import_Type").get("value") == "zohosheet")
  11. {
  12. url = formValues.get("url");
  13. spreadSheetId = url.getPrefix("?").getSuffix("open/");
  14. sheetName = url.getSuffix("?").getPrefix("&").getSuffix("=");
  15. worksheetname = sheetName.replaceAll(" ","%20");
  16. columnName = columnName.replaceAll(" ","%20");
  17. allDatas = list();
  18. params = Map();
  19. params.put("column_names",columnName);
  20. params.put("method","worksheet.records.fetch");
  21. params.put("worksheet_id",sheetName + "#");
  22. sheetDetails = invokeurl
  23. [
  24. url :"https://sheet.zoho"+environment.get("tld")+"/api/v2/" + spreadSheetId
  25. type :GET
  26. parameters:params
  27. connection:"addbulkusers"
  28. ];
  29. info sheetDetails;
  30. if(sheetDetails.get("status") == "success" && sheetDetails.get("records").size() <= 1000)
  31. {
  32. allDatas.addAll(sheetDetails.get("records"));
  33. }
  34. else if(sheetDetails.get("status") == "success" && sheetDetails.get("records").size() > 1000)
  35. {
  36. return {"type":"form_error","text":"I can only able to add 1000 user. Kindly try passing with 1000 records in the sheet!!!"};
  37. }
  38. else
  39. {
  40. return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
  41. }
  42. info "allData: " + allDatas.size();
  43. if(allDatas.size() > 1000)
  44. {
  45. return {"type":"form_error","text":"I can only able to add 1000 user. Kindly try passing with 1000 records in the sheet!!!"};
  46. }
  47. for each  data in allDatas
  48. {
  49. if(data.get(formValues.get("headername")) == null)
  50. {
  51. return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
  52. }
  53. emailIdList.add(data.get(formValues.get("headername")));
  54. if(emailIdList.size() == 100)
  55. {
  56. channelID = formValues.get("channels").get("id");
  57. params = {"email_ids":emailIdList};
  58. info "Params: " + params;
  59. addUsers = invokeurl
  60. [
  61. url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
  62. type :POST
  63. parameters:params.toString()
  64. detailed:true
  65. connection:"addbulkusers"
  66. ];
  67. info "Adduser: " + addUsers;
  68. if(addUsers.get("responseCode") == "204")
  69. {
  70. successlist.addAll(emailIdList);
  71. }
  72. else
  73. {
  74. failedlist.addAll(emailIdList);
  75. }
  76. info "100: " + emailIdList.size();
  77. emailIdList = list();
  78. }
  79. }
  80. if(emailIdList.size() > 0)
  81. {
  82. channelID = formValues.get("channels").get("id");
  83. params = {"email_ids":emailIdList};
  84. info "Params: " + params;
  85. addUsers = invokeurl
  86. [
  87. url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
  88. type :POST
  89. parameters:params.toString()
  90. detailed:true
  91. connection:"addbulkusers"
  92. ];
  93. info "Adduser: " + addUsers;
  94. if(addUsers.get("responseCode") == "204")
  95. {
  96. successlist.addAll(emailIdList);
  97. }
  98. else
  99. {
  100. failedlist.addAll(emailIdList);
  101. }
  102. info "Email id: " + emailIdList;
  103. }
  104. info "Successlist: " + successlist;
  105. info "Failedlist: " + failedlist;
  106. if(successlist.size() > 0 && failedlist.size() > 0)
  107. {
  108. postMessage = {"text":"Successfully added " + successlist.size() + " member(s) and failed for " + failedlist.size() + " Member(s)"};
  109. }
  110. else if(successlist.size() > 0 && !failedlist.size() > 0)
  111. {
  112. postMessage = {"text":"Successfully added " + successlist.size() + " member(s)"};
  113. }
  114. else if(!successlist.size() > 0 && failedlist.size() > 0)
  115. {
  116. postMessage = {"text":"Adding members in channel failed for " + failedlist.size() + " member(s)"};
  117. }
  118. info zoho.cliq.postToChat(chat.get("id"),postMessage);
  119. }
  120. else
  121. {
  122. csvFile = formValues.get("csvFile");
  123. csvFile = csvFile.getfilecontent();
  124. allDatas = csvFile.toList("\n");
  125. i = 0;
  126. indexValue = 0;
  127. indexBoolean = false;
  128. for each  data in allDatas
  129. {
  130. if(i == 0)
  131. {
  132. headers = data.toList(",");
  133. for each  header in headers
  134. {
  135. info header;
  136. if(headerName == header)
  137. {
  138. indexBoolean = true;
  139. indexValue = headers.indexOf(headerName);
  140. }
  141. }
  142. if(indexBoolean == false)
  143. {
  144. return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
  145. }
  146. }
  147. else 
  148.             {
  149. emailIdList.add(data.get(indexValue));
  150.             }
  151. i = i + 1;
  152. if(emailIdList.size() == 100)
  153. {
  154. channelID = formValues.get("channels").get("id");
  155. params = {"email_ids":emailIdList};
  156. info "Params: " + params;
  157. addUsers = invokeurl
  158. [
  159. url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
  160. type :POST
  161. parameters:params.toString()
  162. detailed:true
  163. connection:"addbulkusers"
  164. ];
  165. info "Adduser: " + addUsers;
  166. if(addUsers.get("responseCode") == "204")
  167. {
  168. successlist.addAll(emailIdList);
  169. }
  170. else
  171. {
  172. failedlist.addAll(emailIdList);
  173. }
  174. info "100: " + emailIdList.size();
  175. emailIdList = list();
  176. }
  177. }
  178. if(emailIdList.size() > 0)
  179. {
  180. channelID = formValues.get("channels").get("id");
  181. params = {"email_ids":emailIdList};
  182. info "Params: " + params;
  183. addUsers = invokeurl
  184. [
  185. url :environment.get("base_url") + "/api/v2/channels/" + channelID + "/members"
  186. type :POST
  187. parameters:params.toString()
  188. detailed:true
  189. connection:"addbulkusers"
  190. ];
  191. info "Adduser: " + addUsers;
  192. if(addUsers.get("responseCode") == "204")
  193. {
  194. successlist.addAll(emailIdList);
  195. }
  196. else
  197. {
  198. failedlist.addAll(emailIdList);
  199. }
  200. }
  201. info "Successlist: " + successlist;
  202. info "Failedlist: " + failedlist;
  203. if(successlist.size() > 0 && failedlist.size() > 0)
  204. {
  205. postMessage = {"text":"Successfully added " + successlist.size() + " member(s) and failed for " + failedlist.size() + " Member(s)"};
  206. }
  207. else if(successlist.size() > 0 && !failedlist.size() > 0)
  208. {
  209. postMessage = {"text":"Successfully added " + successlist.size() + " member(s)"};
  210. }
  211. else if(!successlist.size() > 0 && failedlist.size() > 0)
  212. {
  213. postMessage = {"text":"Adding members in channel failed for " + failedlist.size() + " member(s)"};
  214. }
  215. info zoho.cliq.postToChat(chat.get("id"),postMessage);
  216. }
  217. }
  218. catch (e)
  219. {
  220. info e;
  221. return {"type":"form_error","text":"I can't find any email ids. Kindly re-check the column name and header row!!!"};
  222. }
  223. 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. 
  1. targetName = target.get("name");
  2. info targetName;
  3. inputValues = form.get("values");
  4. info inputValues;
  5. actions = list();
  6. if(targetName.containsIgnoreCase("import_Type"))
  7. {
  8. fieldValue = inputValues.get("import_Type").get("value");
  9. info fieldValue;
  10. if(fieldValue == "csv")
  11. {
  12. actions.add({"type":"add_after","name":"import_Type","input":{"label":"CSV File","name":"csvFile","placeholder":"Please upload a zCSV File","mandatory":true,"type":"file"}});
  13. actions.add({"type":"remove","name":"url"});
  14. }
  15. else if(fieldValue == "zohosheet")
  16. {
  17. 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"}});
  18. actions.add({"type":"remove","name":"csvFile"});
  19. }
  20. }
  21. 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.

    • Sticky Posts

    • Customer payment alerts in Zoho Cliq

      For businesses that depend on cash flow, payment updates are essential for operational decision-making and go beyond simple accounting entries. The sales team needs to be notified when invoices are cleared so that upcoming orders can be released. In contrast,
    • Automating Employee Birthday Notifications in Zoho Cliq

      Have you ever missed a birthday and felt like the office Grinch? Fear not, the Cliq Developer Platform has got your back! With Zoho Cliq's Schedulers, you can be the office party-cipant who never forgets a single cake, balloon, or awkward rendition of
    • Accelerate Github code reviews with Zoho Cliq Platform's link handlers

      Code reviews are critical, and they can get buried in conversations or lost when using multiple tools. With the Cliq Platform's link handlers, let's transform shared Github pull request links into interactive, real-time code reviews on channels. Share
    • App Spotlight : PagerDuty for Zoho Cliq

      App Spotlight brings you hand-picked apps to enhance the power of your Zoho apps and tools. Visit the Zoho Marketplace to explore all of our apps, integrations, and extensions. In today's fast-paced world, seizing every moment is essential for operational
    • Automate your status with Cliq Schedulers

      Imagine enjoying your favorite homemade meal during a peaceful lunch break, when suddenly there's a PING! A notification pops up and ruins your moment of zen. Even worse, you might be in a vital product development sprint, only to be derailed by a "quick
      • Recent Topics

      • [Free Webinar] Learning Table Series – Education Management in Zoho Creator

        Hello Everyone! We’re excited to invite you to another edition of Learning Table Series, where we showcase how Zoho Creator empowers industries with innovative and automated solutions. About the Learning Table Series The Learning Table Series is a free,
      • Adding Multiple Files to a Zoho Vault Entry

        There is a old blog post talking about adding multiple file attachments to one Zoho Vault Secret: https://www.zoho.com/blog/vault/introducing-new-features-in-zoho-vault-powerful-password-sharing-wider-storing.html Is that still possible, I can see how
      • Channel Configuration and Default Channels

        There are some of the default fields that cannot be removed or changed. Examples are the social media ones, such as Facebook. It would be nice to be able to remove these fields as it would be confusing if someone selected this but it's not configure
      • CRM x WorkDrive: File storage for new CRM signups is now powered by WorkDrive

        Availability Editions: All DCs: All Release plan: Released for new signups in all DCs. It will be enabled for existing users in a phased manner in the upcoming months. Help documentation: Documents in Zoho CRM Manage folders in Documents tab Manage files
      • Move attachments from one module to another with Deluge

        I have created a button that works just like the convert button for my custom modules. I would like this custom function to move any attachments in this record to the new module. I can't seem to find any documentation on how this can be accomplished.
      • Help in function code

        Hi, could someone look at the code below and tell me what 's wrong with it? After a deal creation or edition the code should find the related Account, than all open Deals for that Account and copy the field Total_Open_Deals from the Account record to
      • Automation Series: Auto-update Phase Status

        Hello Folks! You can auto-update your phase's status based on status of underlying tasks using custom functions. In this series, we will showcase how to create and run custom functions, using Deluge, with ease. Follow the steps below and automate your
      • Zoho CRM for Everyone's NextGen UI Gets an Upgrade

        Hello Everyone We've made improvements to Zoho CRM for Everyone's Nextgen UI. These changes are the result of valuable feedback from you where we’ve focused on improving usability, providing wider screen space, and making navigation smoother so everything
      • Is it possible to sync data every 5–10 minutes in Zoho Analytics (CRM or Excel imports)?

        Hello Team, I want to know if Zoho Analytics supports near real-time syncing of data from different sources. My requirements: I am importing data from Zoho CRM → Zoho Analytics I also have some datasets maintained in Excel/CSV I want both data sources
      • how to add subform over sigma in the CRM

        my new module don't have any subform available any way to add this from sigma or from the crm
      • Reporting Limitation on Lead–Product Relation in Zoho CRM

        I noticed that Zoho CRM has a default Products related list under Leads. However, when I try to create a report for Lead–Product association, I’m facing some limitations. To fix this, I’m considering adding a multi-lookup field along with a custom related
      • Zoho Projects - Project Details on the Project Menu

        Hi Project's team, I've helped may businesses setup and use Zoho Project and one thing I see time and time again is confusion on where to find the Project Details information. I would be much more intuitive if Project Details was on the menu before Dashboard.
      • Zoho Projects - Add Feed to Project Tabs

        Hi Projects Team, I'm working on a lightweight communications requirement for one of my customers in relation to communicating with their client users via Zoho Projects. I noticed that the Feed is only available in the Collaboration section, but you can
      • Zoho Projects - Visual improvement to parent and sub-task relationship

        Hi Projects Team, My feature request is to improve sub-task visibility. Please see screenshot below. I really think parent child relationships could be visually improved. Even if the first letter of the parent task was inline with other same level tasks
      • Zoho Logs - Not seeing logs since 30 Nov

        Hi, we have a few functions running, I am testing some new ones and noticed that although I can see executions, I cannot see any logs, even when the first line on the functions is a log. I reviewed some existing functions, one of which is invoked on a
      • Flow - Fetch info from drop down in another module

        I am running into a road block which I thought would be a simple task. My goal - The account is assigned to a "route" which can be selected from a drop down menu and adds a tag to the account accordingly (easy enough). Now when I create a task for this
      • Problem with signature on zoho survey

        Hello, I'm trying to export individual responses with signatures on zoho survey. But the signatures on some of my surveys are not exported as the original image, but as a generic image, same for all (screen joins). Is there a solution to have the signatures
      • Show unsubscribed contacts ?

        Hello, I would like to display the unsubscribed contacts. Unfortunately, I do not have this subscription type as described in the documentation (https://help.zoho.com/portal/en/kb/marketing-automation-2-0/user-guide/contacts/contact-management/articles/subscription-type-24-1-2024#Subscription_Type_field.)
      • Widget shows error

        Hi, May I ask why below characters will be auto added into the widget link and how to solve this error? As my widget shows 404 error now. ?serviceOrigin=https%3A%2F%2Fcrm.zoho.com&frameorigin=https%3A%2F%2Fcrm.zoho.com
      • Zoho Developer Community Hackathon 2025 is LIVE!

        Hey developers! It’s that time of the year again — the Zoho Developer Community Hackathon 2025 is officially open for registrations! If you’ve been waiting for a chance to stretch your skills, try something new, or finally bring that idea to life, this
      • Converted Leads Not Showing in Lead Reports

        Converted leads are not showing in the Lead reports. How can I make converted leads visible in the report,
      • Can I open PST file on Windows without Outlook?

        Yes, you can open PST file on Windows even if Outlook isn’t installed by using a dedicated MSOutlookHelp PST viewer tool. These programs are designed to work independently of Outlook and let you read the entire contents of a PST file, including emails,
      • Text widgets in dashboards

        Having a text widget in a dashboard would help immensely. It would allow adding links to related documents, relevant CRM views, etc. It would allow adding explanations of the data displayed in the other widgets, about how to interpret them or about filtering.
      • Read webpage - MSXML2.ServerXMLHTTP

        I have the following VBA script, put together from various sources (mainly zoho forum/help/support, so it once worked, I guess): private Sub GetListOfSheets() Dim url As String Dim xmlhttp As Object Dim parameters As String Dim html As String range("B1").value
      • [Webinar] Zoho Writer for content creators and publishing houses

        Managing multiple drafts, edits, and client reviews doesn't have to slow you down. Join our upcoming webinar to see how Zoho Writer helps content creators and publishing houses create, edit, and publish seamlessly—all in one place. You'll learn how to:
      • Adding Reports to Portals

        Is there a way to add Reports to portals so only the user can see report templates relevant to them?
      • How to assign one Manual to multiple Spaces?

        Hello, I have two spaces, one called tech knowledge and the other one called HR knowledge. I have a manual that is called HR tech. I want to assign this manual to HR knowledge and tech knowledge. How should I do that?
      • How can I assign courses to Spaces?

        How can I make courses show up here in this space?:
      • When will Zoho Learn be able to support SCORM files on the mobile app?

        When I click the SCORM content, I just get a message saying it's not possible yet. Yet implies that it will be coming soon. All I'm asking for is a realistic timeline so I know whether or not to invest my time in using it. If it will be soon, then I will
      • Announcing new features in Trident for Windows (v.1.35.6.0)

        Hello Community! Trident for Windows just got better with an update that makes working with your emails even more efficient. Let’s dive into what’s new! Work with PST files more efficiently. You can now do more than just view mounted PST files. You can
      • AI feature in Zoho Desk suggesting answers based on past ticket threads

        Hi I would like to suggest something that would be very useful : instead of suggesting answers based on the Knowledge Base, I think it would be great if Zia could analyze the history of all customer and agents threads, to suggest answers in new tickets.
      • Work Order Assignment for Engineers Handling Their Own Requests

        I’m setting up FSM for a business where there are multiple engineers, but each engineer handles their own process end-to-end receiving the service request, creating the work order, and completing the field service job. I noticed that I must create an
      • Looking for best practices to import data from SAP Business One (on-prem) into Zoho Analytics via Zoho DataPrep / Databridge — daily automated schedule

        Hi all, I’m using SAP Business One on-prem (SQL Server / or HANA — depending on DB backend) as our ERP. I want to build a pipeline that, every morning at 9:00 AM IST: pulls transactional data (invoices, customers, products, stock, etc.) from SAP B1, loads
      • Marketing Tip #9: Track your traffic sources

        Not all marketing channels work equally well. Knowing whether your visitors come from Google, Instagram, or email helps you focus on what actually drives sales. Try this today: Check your Zoho Commerce reports or connect Zoho PageSense to see your top
      • Google Analytics import data inaccurate (as of October 11, 2025)

        We have Zoho Analytics connected to GA4 to import daily event data. This has been running without issue for a couple of years. However, a month ago we started noticing discrepancies. All data until October 10 lines up perfectly - October 11 onward is
      • Can't make a document editable to anyone

        Hey everyone, I am using Zoho Workdrive and trying to share a document so that it is editable by anyone with the link. I am trying to convince people to shift from Google to Zoho, but they don't have accounts yet. When I try to change the share settings
      • E-Invoicing in Belgium with Zoho Billing

        Starting January 1, 2026, Belgium is introducing mandatory electronic invoices (e-invoicing) for all B2B transactions between VAT-registered businesses. Invoices and credits notes must be exchanged in a prescribed digital format. How E-Invoicing works
      • Zoho Voice lance BYOC (Bring Your Own Carrier) : intégrez votre opérateur

        Pour accompagner sa croissance, une entreprise a besoin d’une infrastructure téléphonique flexible et évolutive. Les solutions de téléphonie s’adaptent aux exigences du centre de contact, tout en intégrant aisément les opérateurs locaux de votre choix.
      • Synchronise item image between Zoho Commerce and Zoho Books/Inventory/CRM

        Here is a blindingly simple idea to tie several Zoho products together. Zoho - please include a method to synchronise the item image (or images) from one Zoho application to another. For example, if you upload an item image in Zoho Inventory, a user should
      • Zoho Recruit Slow and Freezing on all screens

        We have had an issue with Zoho Recruit for weeks being extremely slow and at times freezing.  We have 100 mega internet, and I went into each computer and updated the virtual memory so there is more available.  Also restarted all computers daily.  Still having the issues.  Almost unable to work.
      • Next Page