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

    • Account blocked

      Yesterday I got my Zeptomail account blocked due to too many hard bounces. My account is used exclusively for sending transactional emails (eg. your order has been shipped, a form has been filled, etc) and the sudden blocking impacted hundreds of websites
    • IF Formula

      Hi, I'm having trouble setting up a custom formula in a field. Can you help me with it? The formula should do the following: If the created date is less or equal to 30 days the field should display a string New in pieline or Exisitng pipeline if above
    • View comprehensive logs of all actions in Custom Module History

      Hello everyone, We are happy to announce our new feature, Detail View in Custom Module History, which enhances visibility, control and accountability over your records. Users can now access a detailed timeline of every action that has been performed on
    • Track ZohoForm Conversion using Postmessage event

      Hi, I’ve been using a third-party lead tracking tool to capture leads from my website along with their source. Earlier, with the HubSpot form, the third-party script was able to detect the postMessage event that iframe forms typically send back to the
    • Email task creator when task is updated/marked complete

      I am looking for a way to notify the creator of a task in zoho todo when - Task is updated Task is closed Comments entered 1 and 2 are critical, and I cannot find a zoho flow to do this. There is no way that as a manager I will know when someone has completed
    • Email Recall Feature In Zoho Mail Which Should Also Work For Outside Organisation Members

      Add a feature to recall or undo sending an email within a configurable short time window (e.g., 30 seconds to 2 minutes) after hitting send, similar to Gmail’s undo send. Currently the sent email can not be recall If the recipient is not from within your
    • How to implement calculating average value of averaged values?

      Hi, I'm trying to implement a formula in my layout for a module that calculates the average of 2 averaged values, but I can't do so using the formula custom field. To calculate the 2 averaged values, I could use the formula custom field, but in the custom
    • Zoho Recruit update published job boards

      If we have a job thats already posted on several different job boards and we edit this job in zoho recruit (e.g. the description of the job), does this then automatically update this new information to all the published job boards?  If not, how does the
    • Narrative 14: The magic bazaar of Desk

      Behind the scenes of a successful ticketing system: BTS Series Narrative 14: The magic bazaar of Desk Marketplace is a centralized platform where users can discover Zoho and third-party applications that can be integrated with their Desk account to facilitate
    • Collections Management: #2 Late Payment Automation

      "Sir, I'll process the payment by evening, please don't apply any late payment charges", the customer said while arranging papers on his desk. Sanjay stood there with a tired smile. He had already visited twice that week. Payment collection was one thing.
    • Create a table in the layout section of modules

      Dear Sirs, I would like to know whether is possible to create a table under new fields in layouts section of modules. In fact in this section there are single line, multi line, pick list, multi-select, date, formula etc. but I am unable to add a table
    • Nimble enhancements to WhatsApp for Business integration in Zoho CRM: Enjoy context and clarity in business messaging

      Dear Customers, We hope you're well! WhatsApp for business is a renowned business messaging platform that takes your business closer to your customers; it gives your business the power of personalized outreach. Using the WhatsApp for Business integration
    • Power of Automation :: Automatic Task Status Handling for Users

      Hello Everyone, A custom function is a software code that can be used to automate a process and this allows you to automate a notification, call a webhook, or perform logic immediately after a workflow rule is triggered. This feature helps to automate
    • Question - why no way to input a 'tool description' and 'tree of 'tools'

      Every business is different, with different business processes. To be truly useful Zoho MCP needs to have user editable tool descriptions (or ruleset) and a 'tool tree' so that the LLM is context aware when being used. For example, the tool description
    • Develop Zoho Meeting as a Full Native Application (Not a Browser Wrapper)

      Hello Zoho Meeting Team, Hope you are doing well. We would like to suggest an important improvement regarding the Zoho Meeting desktop application. At the moment, the Zoho Meeting app feels more like a mini browser window or an iframe that loads the web
    • Error AS101 when adding new email alias

      Hi, I am trying to add apple@(mydomain).com The error AS101 is shown while I try to add the alias.
    • Suggestion to improve zoho writer

      I am using your product, I believe it is very useful, however, i was writing a note and I needed to draw an arrow in different angles to explain a point and I couldn't. it would be helpful, to add draw functions to the zoho writer. thanks
    • Two factor authentication for helpdesk users

      The company i work for wants use the helpdesk site in Zoho desk, as a place for their distribution partners to ask question and look for information about our product. The things there is suppose to go up there is somewhat confidential between my company
    • I Need Help Verifying Ownership of My Zoho Help Desk on Google Search Console

      I added my Zoho desk portal to Google Search Console, but since i do not have access to the html code of my theme, i could not verify ownership of my portal on Google search console. I want you to help me place the html code given to me from Google search
    • Can I create a custom function for chart of accounts?

      I'm trying to add a custom function that should run whenever a record in the Chart of Accounts module is edited, but on the form for creating a new function, the module dropdown does not include the chart of accounts as an option.
    • billing

      hi, I am being billed $12/year, and I can't remember why. My User ID is 691273115 Thanks for your help, --Kitty Pearl
    • Automatic Matching from Bank Statements / Feeds

      Is it possible to have transactions from a feed or bank statement automatically match when certain criteria are met? My use case, which is pretty broadly applicable, is e-commerce transactions for merchant services accounts (clearing accounts). In these
    • Unable to confirm Super Admin assignment — confirmation button not working

      I’m trying to change the roles within my organization. I am currently a super admin and would like to add another user as a super admin. When I attempt to confirm the action, a screen appears asking for my password to verify my identity. However, when
    • Inactive Items - Make Less Prominent by Default

      Currently, when one marks an Item as "Inactive", it really doesn't do much of anything to hide it or get it out of the way. Search and reporting within Finance should, by default, hide inactive Items from standard reports, searches, etc. If one specifically
    • How to unlink a SAML user from the existing Zoho Desk user (domain change case)

      Hi everyone, I’m trying to understand how to handle a situation where a customer changes their company domain. In our setup, users authenticate via SAML, so when the domain changes, the SAML system treats them as a new user. However, in Zoho Desk, I’d
    • Enable Screen Recording in Zoho WorkDrive Mobile Apps (Android & iOS)

      Hi Zoho WorkDrive Team, How are you? We are enthusiastic Zoho One users and rely heavily on Zoho WorkDrive for internal collaboration and content sharing. The screen-recording feature in the WorkDrive web app (similar to Loom) is extremely useful- however,
    • Automation#36: Auto-create time-entry after performing the Blueprint transition

      Hello Everyone, This week’s edition focuses on configuring a custom function within Zoho Desk to streamline time tracking within the Blueprint. In this case, we create a custom field, and request the agent to enter the spending time within the single
    • Feature Request: Reviews

      Any chance we could get a "Reviews" element to put on sites? It should be extremely simple to do. Basically just take the comments box and add an option for a star rating. At the very least, it would be nice to have more customization options for the comment box so the text could be changed from "Comments" to "Reviews". I've looked at a bunch of embeddable review widgets but nothing meets my needs so this would be a great feature to have added to the site builder.
    • Can we handle a support like (incident management) project in Zoho Projects?

      Hi, I have a new profile of a project whereby we provide "ticket" base support to a client. They have a request and ideally we would handle comms via a email exchange logged in Zoho. Today we use Zoho Projects for all out projects, which means that we
    • Trying to show the actual Terms & Conditions on PDF

      Hi, On Zoho forms I am trying to have the actual terms and conditions that the user needs to accept also show on the pdf that they receive after. Right now it only says "Agreed". Please help.
    • Installing EMAIL Setup in New Domain

      Respected Support team, I'm facing an issue with cloudflare in Pakistan, I want to setup Zoho Mail Setup but I Don't know how to enable Zoho mail setup without cloudflare. My Website https://stumbleguyzzapk.com/, https://fakservices.com/ is using CF,
    • Enhancements to Zoho Meeting Annotator

      Hello Zoho Meeting Team, Hope you are doing well. We would like to share a few improvement suggestions regarding the Zoho Meeting Annotator used during screen sharing. While the current version provides helpful annotation tools, there are several limitations
    • 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
    • Triggering rules on lead conversion

      There is no field on the Rule list for rule conversion to trigger an alert on liead conversion to a potential. I assigned a rule to file on any creation or update of a lead. The lead was changed a lead to a potential but no rule was fired. Rajesh Bhadra
    • How to calculate separate totals for Product Line Items filtered by category in Quotes?

      Hello! I'm working with Quotes in Zoho CRM and need help calculating conditional totals for line items. Current setup: I have two tables in my Quote template (Zoho Writer), both displaying Quoted Line Items Table 1 (top): Shows all products where Product
    • Add "Fetch Composite Item" Action for Inventory

      I want to make a Flow that uses information returned in the GET call for Composite Items, and it's not currently available in Zoho Flow. Please consider adding this functionality.
    • Zoho Social/Marketing Plus - Addition to "Monitor" function

      It would be very helpful if the Monitor function would allow us to add a column to monitor hashtags in addition to pages and mentions. This is a common and very valuable function in other social listening tools.
    • Almacenamiento

      Hola, Quisiera saber como podría hacer para bajar el almacenamiento de 5gb a mis usuarios, en otras palabras los quiero ir limitando de la cuota real, y luego ir agregando poco a poco la cantidad hasta llegar a los 5gb que me dan en el plan free. 
    • Zoho Invoice Now Supports VeriFactu for Businesses in Spain

      Starting from January 1, 2026, Spain requires real-time invoice reporting for all B2B transactions. From July 2026, this requirement will extend to B2C transactions as well. All reporting must be carried out through the VeriFactu to AEAT (Agencia Estatal
    • Will I Get a Refund If I Downgrade Zoho Mail?

      Hello, We upgraded an email account for our new employee. However, the employee left after one month, and now I've reduced the number of Zoho Mail users from 7 to 6. Can we get a refund for the remaining portion of our annual payment?
    • Next Page