# Java -------------------------------------------------------------------------------- title: "Introduction" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly." last_updated: "2026-03-18T07:41:08.683Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/introduction/" service: "All Services" related: - Project Directory Structure (/en/cli/v1/project-directory-structure/introduction/) - Java SDK (/en/sdk/java/v1/overview/) - Node.js SDK (/en/sdk/nodejs/v2/overview/) - Zoho CRM (https://www.zoho.com/in/crm/) -------------------------------------------------------------------------------- # Lead Manager App ### Introduction This tutorial will help you build a web application that can connect with your {{%link href="https://www.zoho.com/in/crm/" %}}Zoho CRM account{{%/link%}} and enable you to manage leads in your organization. You will be able to access, add, edit, or delete leads in the {{%link href="https://help.zoho.com/portal/en/kb/crm/sales-force-automation/leads" %}}Leads module{{%/link%}} in your CRM account, directly from this application. The connection to Zoho CRM is established using {{%link href="/en/api/oauth2/overview-and-terminology/#OverviewandTerminology" %}}OAuth 2.0 authentication protocol{{%/link%}}. We will generate an OAuth Access Token for the Lead Manager application and use it to authorize the connection to access CRM data. We will also implement a {{%bold%}}Catalyst connector{{%/bold%}} to manage this access to the CRM account. The connector will refresh the Access Token automatically each time it expires using a Refresh Token, and will maintain a constant connection between the client and the CRM account. These tokens can be generated after registering the client application in the Zoho API console and obtaining the required credentials. The client application will look like this: <br /> The Lead Manager application contains the following fundamental Catalyst components: 1. {{%link href="/en/serverless/getting-started/introduction/" %}}**Catalyst Serverless**{{%/link%}}: - {{%bold%}}{{%link href="/en/serverless/help/functions/advanced-io/" %}}Advanced I/O Function{{%/link%}}:{{%/bold%}} The Advanced I/O Function is coded in the {{%bold%}}Java{{%/bold%}} programming environment. The function defines the APIs that handle the CRUD actions of the CRM Leads module, such as adding or deleting a lead, from the client application. It also defines routes that handle the connection to CRM, authenticate the user, and generate the OAuth tokens. 2. {{%link href="/en/cloud-scale/getting-started/introduction/" %}}**Catalyst Cloud Scale**{{%/link%}}: - {{%bold%}}{{%link href="/en/cloud-scale/help/data-store/introduction" %}}Data Store{{%/link%}}:{{%/bold%}} To store the Refresh Token and {{%link href="/en/cloud-scale/help/authentication/user-management/users/introduction/" %}}UserID of the Catalyst user{{%/link%}} fetched by the Advanced I/O function. The Refresh Token is fetched from this table by the function, whenever a new Access Token needs to be generated. - {{%bold%}}{{%link href="/en/cloud-scale/help/zcql/introduction" %}}ZCQL{{%/link%}}{{%/bold%}}: To fetch data from the Data Store through querying. - {{%bold%}}Client:{{%/bold%}} This is the front end of the application that is hosted on Catalyst through {{%link href="/en/cloud-scale/help/web-client-hosting/introduction" %}}web client hosting{{%/link%}}. - {{%bold%}}{{%link href="/en/cloud-scale/help/authentication/introduction" %}}Authentication:{{%/link%}}{{%/bold%}} To implement a Zoho sign-in option in the client application's login page, in addition to the standard login option, we will be implementing {{%bold%}}{{%link href="/en/cloud-scale/help/authentication/native-catalyst-authentication/embedded-authentication/setup-embedded-auth/" %}}Embedded authentication{{%/link%}}{{%/bold%}} type in this tutorial. We will use the Catalyst web console and the Catalyst Command Line Interface (CLI) to build this application. You will be given the code for the files to be included in the function and client components in this tutorial. You will just need to copy the provided code and paste it into the appropriate files as directed. ### Application Architecture The Lead Manager application's architecture is depicted below: <br/> We will explain the architecture in detail in the {{%link href="/en/tutorials/leadmanager/java/configure-client-directory" %}}Configure Client section{{%/link%}}, after you configure the function and client components. -------------------------------------------------------------------------------- title: "Prerequisites" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.683Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/prerequisites/" service: "All Services" related: - Catalyst CLI Documentation (/en/cli/v1/cli-command-reference/) -------------------------------------------------------------------------------- # Prerequisites Before you begin building the application, you must have the following prerequisites installed on your system: 1. {{%bold%}}Catalyst CLI{{%/bold%}}<br /><br /> Catalyst CLI contains a host of tools that enable you to initialize, develop, test, and deploy the components of your application from your local machine. We will be working with Catalyst CLI in this tutorial. You must perform these actions: 1. {{%bold%}}Install Catalyst CLI:{{%/bold%}} Catalyst CLI is installed through NPM. You must therefore have NPM and Node.js installed on your system before you install the CLI. Refer to the {{%link href="/en/getting-started/installing-catalyst-cli/" %}}**Install Catalyst CLI help page**{{%/link%}} for details on the pre-requisites and the steps to install it. 2. {{%bold%}}Login Catalyst CLI:{{%/bold%}} After you install Catalyst CLI, you must authenticate the CLI with your Catalyst account before using it. Refer to the {{%link href="/en/cli/v1/login/login-from-cli/" %}}**CLI Login help page**{{%/link%}} for the steps to login from Catalyst CLI and the various options available for it. 2. {{%bold%}}Zoho CRM Account{{%/bold%}}<br /><br /> Because the Leads module is available in all editions of Zoho CRM, you can have a configured Zoho CRM account of any edition to establish a connection with the Lead Manager application. If you don't have a Zoho CRM account, you can sign up for it {{%link href="https://www.zoho.com/in/crm/" %}}here{{%/link%}}. 3. {{%bold%}}Any IDE tool for Node.js and client code development{{%/bold%}}<br /><br /> You can use any IDE to work with the function and the client code. Some popular choices include Visual Studio Code, IntelliJ IDEA, Eclipse, and Sublime Text. Download and install an IDE of your choice in your system. {{%info image="/images/tutorials/todo-list/vscode.png"%}}If you are a Visual Studio Code IDE user, you can install the {{%bold%}}Catalyst Tools{{%/bold%}} extension, and use your IDE itself in place of the CLI. You can find more details about the Catalyst VS Code extension from this {{%link href="/en/catalyst-extensions/vs-code-extension/introduction/" %}}help section{{%/link%}}.{{%/info%}} -------------------------------------------------------------------------------- title: "Create a project" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.684Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/create-project/" service: "All Services" related: - Project Directory (/en/cli/v1/project-directory-structure/introduction) - Setup Catalyst Projects (/en/getting-started/catalyst-projects) -------------------------------------------------------------------------------- # Create a Project Let's {{%link href="/en/getting-started/catalyst-projects" %}}create a Catalyst project{{%/link%}} from the Catalyst console. 1. Log in to the {{%link href="https://console.catalyst.zoho.com/baas/index" %}}Catalyst console{{%/link%}} and click {{%bold%}}Create a new Project{{%/bold%}}.<br /> <br /> 2. Enter the project's name as "{{%bold%}}LeadManager{{%/bold%}}" in the pop-up window. 3. Click {{%bold%}}Create{{%/bold%}}. Your project will be created and opened. <br /> -------------------------------------------------------------------------------- title: "Create a table" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.684Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/create-table/" service: "All Services" related: - Data Store (/en/cloud-scale/help/data-store/introduction) -------------------------------------------------------------------------------- # Create a Table in the Data Store Next, let's create a table in the Data Store. This table is used to store the Refresh Token and {{%badge%}}userID{{%/badge%}} values, which are retrieved whenever an Access Token needs to be generated. To create a table: 1. Navigate to **Catalyst Cloud Scale** service in the console and click **Data Store** under Storage. 2. Click **Create a new Table.** <br/> 3. Enter the table’s name as {{%bold%}}“Token”{{%/bold%}} and click **Create**. <br/> {{%note%}}{{%bold%}}Note:{{%/bold%}} Ensure that you enter the name exactly as instructed, because the application's code contains the same name. {{%/note%}} The table will be created and displayed in the **Data Store** page. Now, let’s create two columns in the table to store the **UserID** and the **Refresh Token** respectively. 1. Click {{%bold%}}New Column{{%/bold%}} in the **Schema View** section of the Data Store table. <br/> 2. Enter the column's name as "{{%bold%}}refresh\_token{{%/bold%}}". Select the data type as {{%bold%}}Encrypted Text{{%/bold%}} and click {{%bold%}}Create{{%/bold%}}. <br/> You can learn about the various data types supported by Catalyst and the other properties of a column from the {{%link href="/en/cloud-scale/help/data-store/introduction" %}}Data Store help page{{%/link%}}. {{%note%}}{{%bold%}}Note:{{%/bold%}} Ensure that you enter the name exactly as instructed, because the application's code contains the same name.{{%/note%}} 3. Create another column using the previous steps with the column name as "{{%bold%}}userId{{%/bold%}}" of the data type "{{%bold%}}BigInt{{%/bold%}}". You need not provide any other values. <br/> The columns will be created and listed in the Schema View section. #### Configure Scopes and Permissions To allow any user of the Lead Manager application to view or manage leads from the client application, you must enable an additional {{%link href="/en/cloud-scale/help/data-store/scopes-and-permissions" %}}table permission{{%/link%}} that will allow the user to fetch and store new Refresh Tokens, if needed. Click the {{%bold%}}Scopes and Permissions{{%/bold%}} tab for the **Token** table, then check the {{%bold%}}Insert{{%/bold%}} permission for the **App User** role under **Table Permissions** section. The {{%bold%}}Select{{%/bold%}} permission will already be checked by default. <br/> The Data Store is now configured for the application. -------------------------------------------------------------------------------- title: "Enable Zoho sign-in" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.684Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/enable-zoho-sign-in/" service: "All Services" related: - Authentication (/en/cloud-scale/help/authentication/user-management/users/introduction/) -------------------------------------------------------------------------------- # Enable Zoho Sign-in The Lead Manager application contains a login page where you must provide valid credentials to access your Zoho CRM account. You can implement a signup functionality for this application by yourself, if needed. Otherwise, you can also integrate the Zoho sign-in feature that will enable you to sign in to the client application directly using your Zoho account. To configure Zoho sign-in for the Lead Manager application from the console: 1. Navigate to **Authentication** under the **Security & Identity** section, click **Setup** in the **Native Catalyst Authentication** tab. <br/> 2. Select **Embedded Authentication**. Click **Next**. <br/> 3. In the Authentication Setup page, enable **Public Signup** and click **Zoho**. <br/> 4. In the dialog box that appears, click **Yes, proceed**. <br/> 5. Provide the Client Name as **"LeadManagerApp"** and click **Enable.** <br/> {{%note%}}{{%bold%}}Note:{{%/bold%}} You can enter any name you need. However, please make a note that we will be using {{%bold%}}"LeadManagerApp"{{%/bold%}} as the client name while initializing it in the CLI and while registering it in the Zoho API console.{{%/note%}} 6. We will not be configuring any additional authentication settings for our application. Click **Finish**. <br/> Zoho sign-in will now be available for the client application. -------------------------------------------------------------------------------- title: "Initialize the project" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.704Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/initialize-project/" service: "All Services" related: - Initialize CLI Resources (/en/cli/v1/initialize-resources/introduction) - Project Directory Structure (/en/cli/v1/project-directory-structure/introduction) -------------------------------------------------------------------------------- # Initialize the Project from the CLI You can now begin working on your Catalyst project from the CLI. The first step is to initialize the project in an empty directory. This will be the home directory of your project, where all of your project files are saved. You can learn more about this from the {{%link href="/en/cli/v1/project-directory-structure/introduction" %}}Project Directory Structure help page{{%/link%}}. You can learn about initializing a project in detail from the {{%link href="/en/cli/v1/initialize-resources/introduction/" %}}CLI help documentation{{%/link%}}. For the Lead Manager application, we will initialize the Advanced I/O function in the Java or Node.js environment, and the client component. 1. Create a folder for the project on your local machine and navigate to it from the terminal. 2. Initialize a project by executing the following command from that directory: {{%cli%}} catalyst init{{%/cli%}} 3. The CLI will now ask you to associate a Catalyst project with the directory. Associate it with the project that we created earlier from the console. Select **Lead Manager** from the list and click **Enter**. <br /> 4. Select {{%bold%}}Functions{{%/bold%}} and {{%bold%}}Client{{%/bold%}} using the space bar. Press the {{%bold%}}Enter{{%/bold%}} key to initialize. <br /> <br /> 5. The CLI will initiate the function setup. Select {{%bold%}}AdvancedIO{{%/bold%}} as the function type.<br /> <br /> 6. Select the latest runtime of **Java** as the function stack, and press {{%bold%}}Enter{{%/bold%}}.<br /> <br /> 7. Enter "{{%bold%}}crmCRUD{{%/bold%}}" as the folder name and "{{%bold%}}CRMCRUD{{%/bold%}}" as the class name. Press {{%bold%}}Enter{{%/bold%}} each time.<br /> <br /> The CLI will download and install the latest {{%link href="/en/sdk/java/v1/overview/" %}}Catalyst Java SDK{{%/link%}} package on your local system. {{%note%}}{{%bold%}}Note:{{%/bold%}} Ensure that you enter the package name, or class name and folder name, exactly as instructed, because the application's code contains the same names.{{%/note%}} 8. The CLI will initiate the client set up next. Select **Basic web app** as your client type. <br /> 9. Enter "{{%bold%}}LeadManagerApp{{%/bold%}}" as the name for the client package and press {{%bold%}}Enter{{%/bold%}}. <br /> <br /> You can enter any name you need. However, you can use the same name that you used while enabling Zoho sign-in to maintain standardization. <br /><br /> The client directory will be created in the standard structure. Catalyst initialization is now complete. Your project directory (CATALYST_PROJECT_HOME) is now set up with the {{%link href="/en/cli/v1/project-directory-structure/functions-directory"%}}client directory{{%/link%}} (CATALYST\_CLIENT\_HOME) and the {{%link href="/en/cli/v1/project-directory-structure/client-directory" %}}functions directory{{%/link%}} (CATALYST\_FUNCTIONS\_HOME) along with configuration files and dependencies. The project directory also contains the {{%badge%}}{{%link href="/en/cli/v1/project-directory-structure/catalyst-json" %}}catalyst.json{{%/link%}}{{%/badge%}} configuration file and a hidden {{%badge%}}.catalystrc{{%/badge%}} file. This is the structure of your project directory. <br /> {{%note%}}{{%bold%}}Note:{{%/bold%}} These images includes an additional file {{%badge%}}login.html{{%/badge%}}. This is the final directory of your project. We will create {{%badge%}}login.html{{%/badge%}} while configuring the client directory.{{%/note%}} -------------------------------------------------------------------------------- title: "Configure functions directory" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.705Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/configure-functions-directory/" service: "All Services" related: - Advanced I/O Functions (/en/serverless/help/functions/advanced-io/) - Functions Directory Structure (/en/cli/v1/project-directory-structure/functions-directory) -------------------------------------------------------------------------------- # Configure the Functions Directory We will now begin coding the Lead Manager application by configuring the Advanced I/O function. The functions directory{{%link href="/en/cli/v1/project-directory-structure/functions-directory" %}}{{%/link%}} {{%badge%}}functions/crmCRUD{{%/badge%}} contains: * The {{%badge%}}CRMCRUD.java{{%/badge%}} main function file * The {{%badge%}}catalyst-config.json{{%/badge%}} configuration file * Java library files in the {{%badge%}}lib{{%/badge%}} folder * {{%badge%}}.classpath{{%/badge%}} and {{%badge%}}.project{{%/badge%}} dependency files You will be adding code in {{%badge%}}CRMCRUD.java{{%/badge%}}. You can use any IDE to configure the function. {{%note%}}{{%bold%}}Note:{{%/bold%}} Please go through the code in this section to make sure you fully understand it. We will discuss the function and client code, after you configure the client.{{%/note%}} You can directly copy the code below and paste it in {{%badge%}}CRMCRUD.java{{%/badge%}} located in the {{%badge%}}functions/crmCRUD{{%/badge%}} directory and save the file. {{% panel_with_adjustment header="CRMCRUD.java" footer="button" class="language-java line-numbers" scroll="set-scroll" %}}import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.logging.Level; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.catalyst.advanced.CatalystAdvancedIOHandler; import com.zc.auth.connectors.ZCConnection; import com.zc.component.ZCUserDetail; import com.zc.component.object.ZCObject; import com.zc.component.object.ZCRowObject; import com.zc.component.object.ZCTable; import com.zc.component.users.ZCUser; import com.zc.component.zcql.ZCQL; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; public class CRMCRUD implements CatalystAdvancedIOHandler { private static final Logger LOGGER = Logger.getLogger(CRMCRUD.class.getName()); private String apiUrl = "https://www.zohoapis.com/crm/v2/Leads"; private String GET = "GET"; private String POST = "POST"; private String PUT = "PUT"; private String DELETE = "DELETE"; private String CLIENT_ID = "{{YOUR_CLIENT_ID}}"; //Add your client ID private String CLIENT_SECRET = "{{YOUR_CLIENT_SECRET}}"; //Add your client secret OkHttpClient client = new OkHttpClient(); @Override @SuppressWarnings("unchecked") public void runner(HttpServletRequest request, HttpServletResponse response) throws Exception { try { LOGGER.info("STARTED!!!"); String url = request.getRequestURI(); String method = request.getMethod(); String responseData = ""; String recordID = ""; Pattern p = Pattern.compile("([0-9]+)"); MediaType mediaType = MediaType.parse("application/json"); JSONParser jsonParser = new JSONParser(); JSONObject data = new JSONObject(); org.json.simple.JSONArray reqData = new org.json.simple.JSONArray(); //Fetches the Refresh Token by calling the getRefreshToken() function, and inserts it along with the userID in the Token table if (Pattern.matches("/generateToken", url) && method.equals(GET)) { LOGGER.info("generateToken!!!"); String code = request.getParameter("code"); String domain = (request.getHeader("host").contains("localhost") ? ("http://" + request.getHeader("host")) : ("https://") + request.getHeader("host").split(":")[0]); LOGGER.info("Domain: "+domain); LOGGER.info("Code: "+code); ZCUserDetail details = ZCUser.getInstance().getCurrentUser(); ZCObject object = ZCObject.getInstance(); ZCRowObject row = ZCRowObject.getInstance(); row.set("refresh_token", getRefreshToken(code, domain)); row.set("userId", details.getUserId()); ZCTable tab = object.getTable(1824000000686079L); //Replace this with the Table ID of your table tab.insertRow(row); response.setStatus(200); response.sendRedirect(domain + "/app/index.html"); //Fetches the user details by calling the getUserDetails() function } else if (Pattern.matches("/getUserDetails", url) && method.equals(GET)) { ArrayList&lt;ZCRowObject&gt; user = getUserDetails(); JSONObject resp = new JSONObject(); if (user.isEmpty()) { resp.put("userId", null); response.setContentType("application/json"); response.getWriter().write(resp.toJSONString()); response.setStatus(200); } else { resp.put("userId", user.get(0).get("Token", "userId")); response.setContentType("application/json"); response.getWriter().write(resp.toJSONString()); response.setStatus(200); } //Executes various APIs to access, add, or modify leads in CRM //Fetches all leads } else if (Pattern.matches("/crmData", url) && method.equals(GET)) { responseData = getResponse(GET, null); //Fetches a particular lead } else if (Pattern.matches("/crmData/([0-9]+)", url) && method.equals(GET)) { Matcher m = p.matcher(url); if (m.find()) { recordID = m.group(1); } apiUrl = apiUrl + "/" + recordID; responseData = getResponse(GET, null); //Adds a new lead } else if (Pattern.matches("/crmData", url) && method.equals(POST)) { ServletInputStream requestBody = request.getInputStream(); JSONObject jsonObject = (JSONObject) jsonParser.parse(new InputStreamReader(requestBody, "UTF-8")); reqData.add(jsonObject); data.put("data", reqData); RequestBody body = RequestBody.create(mediaType, data.toString()); responseData = getResponse(POST, body); //Deletes a lead } else if (Pattern.matches("/crmData/([0-9]+)", url) && method.equals(DELETE)) { Matcher m = p.matcher(url); if (m.find()) { recordID = m.group(1); } apiUrl = apiUrl + "/" + recordID; responseData = getResponse(DELETE, null); //Edits a lead } else if (Pattern.matches("/crmData/([0-9]+)", url) && method.equals(PUT)) { Matcher m = p.matcher(url); if (m.find()) { recordID = m.group(1); } apiUrl = apiUrl + "/" + recordID; ServletInputStream requestBody = request.getInputStream(); JSONObject jsonObject = (JSONObject) jsonParser.parse(new InputStreamReader(requestBody, "UTF-8")); reqData.add(jsonObject); data.put("data", reqData); RequestBody body = RequestBody.create(mediaType, data.toJSONString()); responseData = getResponse(PUT, body); } else { LOGGER.log(Level.SEVERE, "Error. Invalid Request"); //The actions are logged. You can check the logs from Catalyst response.setStatus(404); responseData = "Error. Invalid Request"; response.getWriter().write(responseData); } response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Exception in CRM Function ", e); response.setStatus(500); response.getWriter().write(e.toString()); } } @SuppressWarnings("unchecked") //Fetches an Access Token using the Refresh Token public String getAccessToken(Long userId) throws Exception { JSONObject authJson = new JSONObject(); JSONObject connectorJson = new JSONObject(); String query = "SELECT refresh_token FROM Token where UserId=" + userId; if (rowList.isEmpty()) { throw new RuntimeException("No token found for userId: " + userId); } Object refreshTokenObj = rowList.get(0).get("Token", "refresh_token"); if (refreshTokenObj == null) { throw new RuntimeException("Refresh token is null for userId: " + userId); } authJson.put("refresh_token", refreshTokenObj.toString()); ArrayList&lt;ZCRowObject&gt; rowList = ZCQL.getInstance().executeQuery(query); authJson.put("client_id", CLIENT_ID); authJson.put("client_secret", CLIENT_SECRET); authJson.put("auth_url", "https://accounts.zoho.com/oauth/v2/token"); authJson.put("refresh_url", "https://accounts.zoho.com/oauth/v2/token"); authJson.put("refresh_token", rowList.get(0).get("Token", "refresh_token")); connectorJson.put(userId.toString(), authJson); return ZCConnection.getInstance(connectorJson).getConnector(userId.toString()).getAccessToken(); } //Fetches the Refresh Token by passing the required details public String getRefreshToken(String code, String domain) throws Exception { HttpUrl.Builder urlBuilder = HttpUrl.parse("https://accounts.zoho.com/oauth/v2/token").newBuilder(); urlBuilder.addQueryParameter("code", code); urlBuilder.addQueryParameter("client_id", CLIENT_ID); urlBuilder.addQueryParameter("client_secret", CLIENT_SECRET); urlBuilder.addQueryParameter("grant_type", "authorization_code"); urlBuilder.addQueryParameter("redirect_uri", domain + "/server/crmcrud/generateToken"); String URL = urlBuilder.build().toString(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request getResponse = new Request.Builder().url(URL).method(POST, body).build(); JSONParser jsonParser = new JSONParser(); JSONObject data = (JSONObject) jsonParser.parse(client.newCall(getResponse).execute().body().string()); return data.get("refresh_token").toString(); } //Passes the Access Token fetched to obtain the authorization needed to perform each action on the CRM module public String getResponse(String METHOD, RequestBody body) throws Exception { Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String accessToken = getAccessToken(userId); Request getResponse = new Request.Builder().url(apiUrl).method(METHOD, body) .addHeader("Authorization", "Zoho-oauthtoken " + accessToken).build(); return client.newCall(getResponse).execute().body().string(); } //Fetches the record from the Token table that contains the Refresh Token, by passing the userID public ArrayList&lt;ZCRowObject&gt; getUserDetails() throws Exception { Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String query = "SELECT * FROM Token where UserId=" + userId; ArrayList&lt;ZCRowObject&gt; rowList = ZCQL.getInstance().executeQuery(query); return rowList; } } {{% /panel_with_adjustment %}} {{%note%}}{{%bold%}}Note:{{%/bold%}} After you copy and paste this code in your function file, ensure that you replace the following values in it: * {{%link href="/en/tutorials/leadmanager/java/register-client" %}}Client ID{{%/link%}} in line 32 * {{%link href="/en/tutorials/leadmanager/java/register-client" %}}Client Secret{{%/link%}} in line 33 * {{%link href="/en/tutorials/leadmanager/java/create-table" %}}Table ID{{%/link%}} in line 61 {{%/note%}} The functions directory is now configured. We will discuss the function and client code, after you configure the client. -------------------------------------------------------------------------------- title: "Register the client" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.706Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/register-client/" service: "All Services" related: - Catalyst CLI Documentation (/en/cli/v1/cli-command-reference/) -------------------------------------------------------------------------------- # Register the Client Application in Zoho API Console We must now register the client application in the Zoho API console, to generate the following credentials: * {{%bold%}}Client ID{{%/bold%}}: The unique key generated for a registered client * {{%bold%}}Client Secret{{%/bold%}}: The secret value generated for a registered client's Client ID The Client ID and Client Secret are added in the function and client code in several places. These values are necessary to generate the Access Token and Refresh Token initially, and later to refresh the Access Token using the Refresh Token. To register the client application in Zoho API console: 1. Visit the {{%link href="https://api-console.zoho.com/" %}}Zoho API Console{{%/link%}} and click {{%bold%}}Get Started{{%/bold%}}. 2. Select {{%bold%}}Server-based Applications{{%/bold%}} as the client type.<br /> <br /> 3. Enter "{{%bold%}}LeadManagerApp{{%/bold%}}" as the client name. <br /> <br /> Provide the other details in the following format: * Homepage URL: {{%bold%}}{APP\DOMAIN}/app/index.html{{%/bold%}} * Authorized Redirect URIs: {{%bold%}}{APP\DOMAIN}/server/crm_crud/generateToken{{%/bold%}} Replace {APP_DOMAIN} with the application URL value of the LeadManager project you created in Catalyst. The application URL follows the below syntax : **https:<span></span>//{project name}-{orgID}.development.catalystserverless.com** {{%note%}}{{%bold%}}Note:{{%/bold%}} 1. You can fetch the project name by navigating to **Settings** in the top right corner of the Catalyst console. Then go to **Project Settings->General**. Please make sure to enter your project name in small case without any spaces in the domain URL. 2. You can fetch the Org id value directly from the URL in the Catalyst console. Say for example in the below URL, **"687259092"** is the Org Id. <br> **https:<span></span>//console.catalyst.zoho.com/baas/687259092/project/11811000000477018/Development** {{%/note%}} For example, the homepage URL in this case will be: **https:<span></span>//leadmanager-687259092.development.catalystserverless.com/app/index.html.** And the redirect URL will be: **https:</span><span></span>//leadmanager-687259092.development.catalystserverless.com/server/crm_crud/generateToken** We enter the path to the index page of the client as the homepage URL, and a route defined in the Node.js function as an authorized redirect URI. We will discuss these steps in the next sections. * You must add another Authorized Redirect URI for the client. We will serve the app through a localhost to test it after configuring the code. Because this will be redirected to a local domain, we must add that as another authorized redirect URI. Click the {{%bold%}}(+) icon{{%/bold%}} under Authorized Redirect URIs and add: "{{%bold%}}http://localhost:3000/server/crm\_crud/generateToken{{%/bold%}}" <br/> {{%note%}}{{%bold%}}Note:{{%/bold%}} When you serve an application locally from the CLI, it is hosted from port 3000 by default. We are therefore adding the domain accordingly.{{%/note%}} 4. Click {{%bold%}}Create{{%/bold%}} after configuring these details. The API console will generate and display the Client ID and Client Secret values for the registered client. <br/> You will need to copy these values and paste them into the function and client files in your project directory. We will discuss this in the next section. -------------------------------------------------------------------------------- title: "Configure the client" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.706Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/configure-client-directory/" service: "All Services" related: - Client Directory Structure (/en/cli/v1/project-directory-structure/introduction) - Web Client Hosting (/en/cloud-scale/help/web-client-hosting/introduction/) -------------------------------------------------------------------------------- # Configure the Client Directory Let's now configure the client component. The {{%link href="/en/cli/v1/project-directory-structure/introduction" %}}client directory{{%/link%}} contains: * The {{%badge%}}index.html{{%/badge%}} file that contains the HTML code for the frontend application * The {{%badge%}}main.css{{%/badge%}} file that contains the CSS code * The {{%badge%}}main.js{{%/badge%}} file that contains the JavaScript code * The {{%badge%}}client-package.json{{%/badge%}} configuration file We will be coding {{%badge%}}index.html{{%/badge%}}, {{%badge%}}main.js{{%/badge%}} and {{%badge%}}main.css{{%/badge%}}. We will also create a new file {{%badge%}}login.html{{%/badge%}} in this directory and add code in it. {{%note%}}{{%bold%}}Note:{{%/bold%}} Please go through the code in this section to make sure you fully understand it. We will discuss the code at the end of this section.{{%/note%}} Copy the code below and paste it in the respective files located in the {{%badge%}}client/{{%/badge%}} directory of your project using an IDE and save the files. {{% panel_with_adjustment header="index.html" footer="button" class="language-xml line-numbers" scroll="set-scroll" %}}&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset="utf-8" /&gt; &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt; &lt;title&gt;CRM Lead Manager&lt;/title&gt; &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt; &lt;link rel="stylesheet" type="text/css" media="screen" href="main.css" /&gt; &lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"&gt; &lt;link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"&gt; &lt;link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet"&gt; &lt;script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"&gt;&lt;/script&gt; &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="main.js"&gt;&lt;/script&gt; &lt;script src="https://static.zohocdn.com/catalyst/sdk/js/2.0.0/catalystWebSDK.js"&gt;&lt;/script&gt; &lt;script src="/__catalyst/sdk/init.js"&gt;&lt;/script&gt; &lt;link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"&gt; &lt;style&gt; #connect { height: 260px; width: 500px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } &lt;/style&gt; &lt;/head&gt; &lt;body onload="getUserDetails()"&gt; &lt;br&gt; &lt;center&gt; &lt;h1&gt;CRM Lead Manager&lt;/h1&gt;&lt;br&gt; &lt;/center&gt; &lt;div id="connect"&gt; &lt;center&gt; &lt;p&gt;Click here to connect to Zoho CRM&lt;/p&gt; &lt;button onclick='navigate()'&gt; &lt;img src="https://www.zohowebstatic.com/sites/default/files/styles/product-home-page/public/icon-crm_blue.png" style="width: 180px;height: 130px;"&gt; &lt;/button&gt; &lt;/center&gt; &lt;/div&gt; &lt;div style="width: 200px;float: right; margin-right: 30px;"&gt;&lt;label for="logoutbtn" class="btn btn-success btn-block btn-outlined"&gt;Logout&lt;/label&gt; &lt;button id="logoutbtn" onclick="logout()" style="display: none;"&gt;&lt;/button&gt; &lt;/div&gt; &lt;div id="main"&gt; &lt;div class="container"&gt; &lt;ul class="nav nav-tabs nav-justified mb-3" id="myTab" role="tablist"&gt; &lt;li class="nav-item"&gt; &lt;a class="nav-link active" id="check-tab" data-toggle="tab" href="#check" role="tab" aria-controls="check" aria-selected="true"&gt;Add a Lead&lt;/a&gt; &lt;/li&gt; &lt;li class="nav-item"&gt; &lt;a class="nav-link" id="report-tab" data-toggle="tab" href="#report" onclick="getLeads()" role="tab" aria-controls="report" aria-selected="false"&gt;Manage Leads&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;&lt;br&gt; &lt;div class="tab-content" id="myTabContent"&gt; &lt;div class="tab-pane fade show active" id="check" role="tabpanel" aria-labelledby="check-tab"&gt; &lt;div class="tab-pane fade show active" id="ex3-tabs-1" role="tabpanel" aria-labelledby="ex3-tab-1"&gt; &lt;div style="margin-left: 100px; margin-right:100px;"&gt; &lt;form id="leads"&gt; &lt;!-- 2 column grid layout with text inputs for the first and last names --&gt; &lt;div class="row mb-4"&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example1"&gt;First name&lt;/label&gt; &lt;input type="text" id="firstName" class="form-control" /&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example2"&gt;Last name&lt;/label&gt; &lt;input type="text" id="lastName" class="form-control" required /&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example3"&gt;Company name&lt;/label&gt; &lt;input type="text" id="companyName" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Email input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example5"&gt;Email&lt;/label&gt; &lt;input type="email" id="email" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example4"&gt;State&lt;/label&gt; &lt;input type="text" id="state" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Number input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example6"&gt;Phone&lt;/label&gt; &lt;input type="number" id="phone" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Number input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example6"&gt;Lead Source&lt;/label&gt; &lt;input type="text" id="leadSource" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Submit button --&gt; &lt;center&gt;&lt;button type="submit" onclick="createLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;"&gt;Add Lead&lt;/button&gt; &lt;div id="loader" style="display: none;"&gt; &lt;div class="spinner-border" role="status"&gt; &lt;span class="sr-only"&gt;Loading...&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/center&gt; &lt;/form&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="tab-pane fade" id="report" role="tabpanel" aria-labelledby="report-tab"&gt; &lt;center&gt; &lt;div id="loaders" style="display: none; padding-top: 200px;"&gt; &lt;div class="spinner-border" role="status"&gt; &lt;span class="sr-only"&gt;Loading...&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/center&gt; &lt;p id="showData"&gt;&lt;/p&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Modal --&gt; &lt;div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"&gt; &lt;div class="vertical-alignment-helper"&gt; &lt;div class="modal-dialog vertical-align-center"&gt; &lt;div class="modal-content"&gt; &lt;center&gt; &lt;h4 class="modal-title" id="myModalLabel"&gt;&lt;/h4&gt; &lt;div class="modal-body" id="message"&gt;&lt;/div&gt; &lt;div class="modal-footer"&gt; &lt;button type="button" style="background-color: #007bff;color: white;" class="btn btn-default" data-dismiss="modal"&gt;Close&lt;/button&gt; &lt;/div&gt; &lt;/center&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="modal fade" id="editForm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"&gt; &lt;div class="vertical-alignment-helper"&gt; &lt;div class="modal-dialog vertical-align-center"&gt; &lt;div class="modal-content"&gt; &lt;div style="margin-left: 80px; margin-right:80px;"&gt; &lt;br&gt; &lt;center&gt; &lt;h2&gt;Edit Lead&lt;/h2&gt; &lt;/center&gt; &lt;br&gt; &lt;form id="editLeads"&gt; &lt;!-- 2 column grid layout with text inputs for the first and last names --&gt; &lt;div class="row mb-4"&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example1"&gt;First name&lt;/label&gt; &lt;input type="text" id="editfirstName" class="form-control" /&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example2"&gt;Last name&lt;/label&gt; &lt;input type="text" id="editlastName" class="form-control" required /&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example3"&gt;Company name&lt;/label&gt; &lt;input type="text" id="editcompanyName" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Email input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example5"&gt;Email&lt;/label&gt; &lt;input type="email" id="editemail" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example4"&gt;State&lt;/label&gt; &lt;input type="text" id="editstate" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Number input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example6"&gt;Phone&lt;/label&gt; &lt;input type="number" id="editphone" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Submit button --&gt; &lt;center&gt;&lt;button type="submit" id="editBtn" onclick="editLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;"&gt;Edit&lt;/button&gt; &lt;div id="loader" style="display: none;"&gt; &lt;div class="spinner-border" role="status"&gt; &lt;span class="sr-only"&gt;Loading...&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/center&gt; &lt;/form&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="modal fade right" id="ModalDanger" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"&gt; &lt;div class="modal-dialog modal-notify modal-danger modal-side modal-top-right" role="document"&gt; &lt;!--Content--&gt; &lt;div class="modal-content"&gt; &lt;!--Header--&gt; &lt;div class="modal-header"&gt; &lt;p class="heading"&gt;Lead Deletion&lt;/p&gt; &lt;button type="button" class="close" data-dismiss="modal" aria-label="Close"&gt; &lt;span aria-hidden="true" class="white-text"&gt;×&lt;/span&gt; &lt;/button&gt; &lt;/div&gt; &lt;!--Body--&gt; &lt;div class="modal-body"&gt; &lt;div class="row"&gt; &lt;div class="col-9"&gt; &lt;p&gt;Are you sure you want to delete the Lead?&lt;/p&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!--Footer--&gt; &lt;div class="modal-footer justify-content-center"&gt; &lt;a type="button" class="btn btn-danger" id="delete-btn" onclick="deleteLead()"&gt;Delete&lt;/a&gt; &lt;a type="button" class="btn btn-outline-danger waves-effect" data-dismiss="modal"&gt;Cancel&lt;/a&gt; &lt;/div&gt; &lt;/div&gt; &lt;!--/.Content--&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/body&gt; &lt;script&gt; //Add Your Client ID and Redirect URL here function navigate() { window.location.href = "https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.modules.ALL&client_id={{YOUR_CLIENT_ID}}&response_type=code&access_type=offline&redirect_uri="+location.protocol + '//' + location.host + "/server/crmcrud/generateToken"; } &lt;/script&gt; &lt;/html&gt; {{% /panel_with_adjustment %}} {{%note%}}{{%bold%}}Note:{{%/bold%}} After adding {{%badge%}}index.html{{%/badge%}} to your client folder, make sure to replace {{%bold%}}{{YOUR_CLIENT_ID}}{{%/bold%}} in the {{%badge%}}navigate(){{%/badge%}} function with your actual Zoho Client ID.{{%/note%}} {{% panel_with_adjustment class="language-javascript line-numbers" header="main.js" footer="button" scroll="set-scroll" %}}function createLead() { debugger; $("#loader").show(); var firstName = $("#firstName").val(); var lastName = $("#lastName").val(); if (lastName == "") { alert("Kindly Enter the Last Name"); $("#loader").hide(); return; } var companyName = $("#companyName").val(); var email = $("#email").val(); var state = $("#state").val(); var phone = $("#phone").val(); var leadSource = $("#leadSource").val(); $.ajax({ url: "/server/crmcrud/crmData", type: "post", contentType: "application/json", data: JSON.stringify({ "First_Name": firstName, "Last_Name": lastName, "Company": companyName, "Email": email, "State": state, "Phone": phone, "Lead_Source": leadSource, }), success: function (data) { debugger; $('#leads').trigger("reset"); $("#myModalLabel").html("<br>Success"); $("#message").html("Lead Created Successfully"); $("#loader").hide(); $('#myModal').modal('show'); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html("<br>Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function logout() { var redirectURL = "http://localhost:3000/app/login.html"; //Add your app domain var auth = catalyst.auth; auth.signOut(redirectURL); } function getUserDetails() { $("#main").hide(); $("#connect").hide(); catalyst.auth.isUserAuthenticated().then(result => { $("#loader").show(); $.ajax({ url: "/server/crmcrud/getUserDetails", type: "get", success: function (data) { $("#loader").hide(); if (data.userId) { $("#main").show(); $("#connect").hide(); } else { $("#connect").show(); $("#main").hide(); } }, error: function (error) { $("#myModalLabel").html("<br>Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); }).catch(err => { document.body.innerHTML = 'You are not logged in. Please log in to continue. Redirecting you to the login page..'; setTimeout(function () { window.location.href = "login.html"; }, 3000); }); } function getLeads() { debugger; var tableContainer = document.getElementById("showData"); tableContainer.innerHTML = ""; $("#loaders").show(); $.ajax({ url: "/server/crmcrud/crmData", type: "get", success: function (data) { debugger; var reqData = getRequiredData(data.data); $("#loaders").hide(); renderTable(reqData); }, error: function (error) { $("#myModalLabel").html("<br>Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function showDeletePopup(leadID) { $('#ModalDanger').modal('show'); var deleteBtn = document.getElementById("delete-btn"); deleteBtn.value = leadID; } function deleteLead() { var leadID = document.getElementById('delete-btn').value; $.ajax({ url: "/server/crmcrud/crmData/" + leadID, type: "delete", success: function (data) { debugger; $('#ModalDanger').modal('toggle'); $("#myModalLabel").html("<br>Success"); $("#message").html("Lead Deleted Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $("#myModalLabel").html("<br>Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function showEditPopup(leadID) { $.ajax({ url: "/server/crmcrud/crmData/" + leadID, type: "get", success: function (data) { debugger; var respData = data.data; $('#editfirstName').val(respData[0].First_Name); $('#editlastName').val(respData[0].Last_Name); $('#editcompanyName').val(respData[0].Company); $('#editemail').val(respData[0].Email); $('#editstate').val(respData[0].State); $('#editphone').val(respData[0].Phone); $('#editleadSource').val(respData[0].Lead_Source); $('#editBtn').val(respData[0].id); $('#editfirstName').html(respData[0].First_Name); $('#editlastName').html(respData[0].Last_Name); $('#editcompanyName').html(respData[0].Company); $('#editemail').html(respData[0].Email); $('#editstate').html(respData[0].State); $('#editphone').html(respData[0].Phone); $('#editleadSource').html(respData[0].Lead_Source); $('#editForm').modal('show'); }, error: function (error) { $("#myModalLabel").html("<br>Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function editLead() { var firstName = $("#editfirstName").val(); var lastName = $("#editlastName").val(); if (lastName == "") { alert("Kindly Enter the Last Name"); return; } var companyName = $("#editcompanyName").val(); var email = $("#editemail").val(); var state = $("#editstate").val(); var phone = $("#editphone").val(); var leadSource = $("#editleadSource").val(); var leadID = $("#editBtn").val(); $.ajax({ url: "/server/crmcrud/crmData/" + leadID, type: "put", contentType: "application/json", data: JSON.stringify({ "First_Name": firstName, "Last_Name": lastName, "Company": companyName, "Email": email, "State": state, "Phone": phone, "Lead_Source": leadSource }), success: function (data) { debugger; $('#editForm').modal('toggle'); $("#myModalLabel").html("<br>Success"); $("#message").html("Lead Edited Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html("<br>Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function getRequiredData(data) { var i; var resp = []; for (i = 0; i < data.length; i++) { var gulp = { "First Name": data[i].First_Name, "Last Name": data[i].Last_Name, "Phone": data[i].Phone, "Email": data[i].Email, "Company": data[i].Company, "Edit": '&lt;center&gt;&lt;a href=&quot;javascript:showEditPopup(\'' + data[i].id + '\')&quot;&gt;&#9998;︎&lt;/a&gt;&lt;/center&gt;', "Delete": '&lt;center&gt;&lt;a href=&quot;javascript:showDeletePopup(\'' + data[i].id + '\')&quot;&gt;&#128465;︎&lt;/a&gt;&lt;/center&gt;' } resp.push(gulp); } console.log(resp); return resp; } function renderTable(respData) { var col = []; for (var i = 0; i < respData.length; i++) { for (var key in respData[i]) { if (col.indexOf(key) === -1) { col.push(key); } } } var table = document.createElement("table"); table.id = "dataTable"; var tr = table.insertRow(-1); for (var i = 0; i < col.length; i++) { var th = document.createElement("th"); th.innerHTML = col[i]; tr.appendChild(th); } for (var i = 0; i < respData.length; i++) { tr = table.insertRow(-1); for (var j = 0; j < col.length; j++) { var tabCell = tr.insertCell(-1); tabCell.innerHTML = respData[i][col[j]]; } } var divContainer = document.getElementById("showData"); divContainer.innerHTML = ""; divContainer.appendChild(table); } {{% /panel_with_adjustment %}} {{% panel_with_adjustment class="language-css line-numbers" header="main.css" footer="button" scroll="set-scroll" %}}#dataTable { font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; } #dataTable td, #dataTable th { border: 1px solid #ddd; padding: 8px; } #dataTable tr:nth-child(even){background-color: #f2f2f2;} #dataTable tr:hover {background-color: #ddd;} #dataTable th { padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #007bff; color: white; } .vertical-alignment-helper { display: table; height: 100%; width: 100%; pointer-events: none; } .vertical-align-center { display: table-cell; vertical-align: middle; pointer-events: none; } .modal-content { width: inherit; max-width: inherit; height: inherit; margin: 0 auto; pointer-events: all; } {{% /panel_with_adjustment %}} {{% panel_with_adjustment class="language-xml line-numbers" header="login.html" footer="button" scroll="set-scroll" %}}&lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt; &lt;head&gt; &lt;meta charset=&quot;utf-8&quot; /&gt; &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt; &lt;title&gt;CRM Lead Manager&lt;/title&gt; &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt; &lt;!-- Bootstrap --&gt; &lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css&quot; integrity=&quot;sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T&quot; crossorigin=&quot;anonymous&quot;&gt; &lt;!-- Catalyst SDK --&gt; &lt;script src=&quot;https://static.zohocdn.com/catalyst/sdk/js/4.6.1/catalystWebSDK.js&quot;&gt;&lt;/script&gt; &lt;script src=&quot;/__catalyst/sdk/init.js&quot;&gt;&lt;/script&gt; &lt;style&gt; html, body { height: 100%; margin: 0; padding: 0; overflow: hidden; /* No page scroll */ background-color: #f8f9fa; font-family: &quot;Segoe UI&quot;, Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; flex-direction: column; justify-content: center; align-items: center; } h1 { margin-bottom: 30px; color: #333; } /* Bigger height to avoid internal iframe scroll */ #login { width: 90%; max-width: 500px; height: 500px; /* increased from 260px */ overflow: hidden; /* hides any internal scrollbars */ border-radius: 8px; background: #fff; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); padding: 20px; } &lt;/style&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;CRM Lead Manager&lt;/h1&gt; &lt;div id=&quot;login&quot;&gt;&lt;/div&gt; &lt;script&gt; // Initialize Catalyst login widget catalyst.auth.signIn(&quot;login&quot;); &lt;/script&gt; &lt;!-- Optional JS dependencies --&gt; &lt;script src=&quot;https://code.jquery.com/jquery-3.4.1.min.js&quot; integrity=&quot;sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt; &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js&quot; integrity=&quot;sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt; &lt;script src=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js&quot; integrity=&quot;sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt; &lt;/body&gt; &lt;/html&gt; {{% /panel_with_adjustment %}} The client directory is now configured. Let us quickly go through the working of the function and client components of the application: * The {{%badge%}}login.html{{%/badge%}} file in the client component enables Catalyst Authentication login. This does not handle the Zoho sign-in feature, only the Catalyst login. * {{%badge%}}index.html{{%/badge%}} contains the code for the front-end of the client. It defines a function {{%badge%}}navigate(){{%/badge%}} that enables the connection to the CRM account by passing the required authorization information such as the Client ID and the scope. * The Advanced I/O function defines the following APIs that perform various actions: * {{%bold%}}{{%badge%}}/generateToken{{%/badge%}}:{{%/bold%}} Obtains the Refresh Token by calling the {{%badge%}}getRefreshToken(){{%/badge%}} function, and inserts it along with the {{%badge%}}userID{{%/badge%}} of the current user in the _Token_ table in the Data Store. It then redirects to the index page of the client. * {{%bold%}}{{%badge%}}/getUserDetails{{%/badge%}}:{{%/bold%}} Fetches the user details by calling the {{%badge%}}getUserDetails(){{%/badge%}} function. If there is no record in the table, a JSON response with the {{%badge%}}userID{{%/badge%}} alone is sent. If the record exists in the table, it is sent along with the {{%badge%}}userID{{%/badge%}}. * {{%bold%}}{{%badge%}}/crmData{{%/badge%}}:{{%/bold%}} This route defines the path of all leads in the Leads module. The Node function executes the HTTP {{%badge%}}GET{{%/badge%}} and {{%badge%}}POST{{%/badge%}} operations to fetch all leads or create a new lead using this route respectively. * {{%bold%}}{{%badge%}}/crmData/:id{{%/badge%}}:{{%/bold%}} This route defines the path of a particular lead in the Leads module. The {{%badge%}}id{{%/badge%}} represents the unique ID of the lead in CRM. The function executes the HTTP {{%badge%}}PUT{{%/badge%}} and {{%badge%}}DELETE{{%/badge%}} operations to edit or delete a lead respectively using this route. * The Advanced I/O function contains the following functions that are called by the APIs: * {{%bold%}}{{%badge%}}getRefreshToken(){{%/badge%}}:{{%/bold%}} Fetches the Refresh Token by passing the Client ID, Client Secret, Redirect URI and other required values as query string parameters * {{%bold%}}{{%badge%}}getAccessToken(){{%/badge%}}:{{%/bold%}} Fetches the Access Token by passing the Refresh Token queried from the Token table using ZCQL, and other required parameters. The Access Token is fetched each time an operation needs to be performed on the CRM module, such as adding a lead or editing a lead. * {{%bold%}}{{%badge%}}getResponse(){{%/badge%}}:{{%/bold%}} Passes the Access Token fetched to obtain the authorization needed to perform each action on the CRM module. This function is called with each {{%badge%}}/crmData{{%/badge%}} and {{%badge%}}/crmData/:id{{%/badge%}} API to authorize the request. * {{%bold%}}{{%badge%}}getUserDetails(){{%/badge%}}:{{%/bold%}} Fetches the record from the _Token_ table that contains the Refresh Token, by passing the userID * {{%badge%}}main.js{{%/badge%}} is the JavaScript function in the client component that parses the JSON responses obtained from the function and renders them in the {{%badge%}}index.html{{%/badge%}} page. This function defines the actions for all the UI elements in the client application. For example, {{%badge%}}getLeads(){{%/badge%}} obtains all leads from the function response and renders them in the client, and {{%badge%}}showEditPopup(){{%/badge%}} defines the actions for editing a lead. -------------------------------------------------------------------------------- title: "Test the application" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.710Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/test-application/" service: "All Services" related: - Serve CLI Resources (/en/cli/v1/serve-resources/introduction) -------------------------------------------------------------------------------- # Test the Application Before you deploy the application to the remote console, you can {{%link href="/en/cli/v1/serve-resources/introduction" %}}test the application on a local server{{%/link%}} and check if everything works fine using the Catalyst CLI. To serve the Catalyst project locally, execute the following command from your project directory: {{%cli%}} catalyst serve{{%/cli%}} The Lead Manager application will now be served at default port 3000\. The local endpoint URLs of the components are displayed. {{%note%}}{{%bold%}}Note:{{%/bold%}} Every time you access the homepage or any of the sub-pages of your client, or the function, the CLI will display a live log of the URL accessed, along with the HTTP request method.{{%/note%}} <br /> You can now open the application in a browser using the local URL of the client displayed in the CLI. You will initially be redirected to the login page. If you configure a sign-up action on your own, you can sign up first, then log in to the application. Otherwise, you can log in using the Zoho sign-in icon. <br /> You will be redirected to the permissions page. Accept the permissions requested by the app to access your Zoho account details. <br /> You will then be redirected back to the application. Click the {{%bold%}}Zoho CRM icon{{%/bold%}} in this page to connect to Zoho CRM. <br /> You must now {{%bold%}}choose the CRM account{{%/bold%}} that you wish to connect with the Lead Manager app, then click {{%bold%}}Submit{{%/bold%}}. All your existing developer, sandbox, and production accounts will be listed. Click {{%bold%}}Accept{{%/bold%}} to allow the Lead Manager app to access your Zoho CRM modules. <br /> You will be redirected back to the application. You can now create and manage leads in your configured Zoho CRM account, directly from this application. To add a lead, enter the details of the lead in the _Add a Lead_ section and click {{%bold%}}Add Lead{{%/bold%}}. <br /> A confirmation pop-up will display the status every time you add, edit, or delete a lead. <br /> You can click the {{%bold%}}Manage Leads{{%/bold%}} tab to view all your leads from the Leads module. You can edit or delete any of them by clicking their respective icons in the table. <br /> You can update a lead's information, then click {{%bold%}}Edit{{%/bold%}}. <br /> If you click the delete icon, you must confirm the action in the confirmation pop-up. <br /> You can also check the Refresh Token and {{%badge%}}userID{{%/badge%}} values populated in the Data Store from your Catalyst console. Navigate to the {{%bold%}}Data View{{%/bold%}} section of the _Token_ table to view the record that was added. <br /> If you delete this entry, you will have to authenticate your credentials in the client application and establish a connection to your CRM account again. You can log out of the application by clicking {{%bold%}}Logout{{%/bold%}}. If this setup is working correctly, we can deploy the application to production. You can quit the {{%badge%}}serve{{%/badge%}} session in your terminal by executing the command to kill a running process, based on your OS. -------------------------------------------------------------------------------- title: "Deploy the project" description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: "2026-03-18T07:41:08.714Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/deploy-project/" service: "All Services" related: - Deploy CLI Resources (/en/cli/v1/deploy-resources/introduction) - Web Client Hosting (/en/cloud-scale/help/web-client-hosting/introduction/) -------------------------------------------------------------------------------- # Deploy the Project You can now deploy the application to the remote console. {{%note%}}{{%bold%}}Note:{{%/bold%}} Since you had already logged into the Lead Manager application from the local server, a Refresh Token would have already been generated. This token will continue to authenticate your access. {{%/note%}} To {{%link href="/en/cli/v1/deploy-resources/introduction" %}}deploy your Catalyst project from the CLI{{%/link%}}, run the following command in your terminal from your project directory: {{%cli%}} catalyst deploy{{%/cli%}} The function is deployed first, followed by the client component. The app URLs of the components will be displayed. <br /> You can now open the client component's URL in a browser to access the deployed application. Lead Manager application can now be accessed from its {{%link href="/en/cloud-scale/help/web-client-hosting/introduction" %}}web app URL{{%/link%}}. <br />