Code Your Application
In the leadmanager/src/main/java/com/catalyst/appsail/leadmanager/ directory, create a Java code file and name it LeadmanagerApplication.java. This code file will contain the logic that will allow you to serve your application.
Along with this file, you need to create the following code files in the same directory:
- LeadManager.java: Will contain the business logic of your application.
- AuthProviderImpl.java: Will contain the logic to initialize the Catalyst SDK.
In the /src/main/resources/static directory, create the following files:
- index.html: The file that contains the HTML code for the front-end of the application.
- login.html: The file that contains the HTML code for the Embedded Authentication logic.
- main.css: The file that contains the styling elements of the application.
- main.js: The file that contains the JavaScript code that connects the front-end and backend.
The final structure of the leadmanager/ Spring Boot - JAR project directory is shown below:
You will be coding the LeadManager.java, LeadmanagerApplication.java, AuthProviderImpl.java, index.html, login.html, main.css, main.js, and pom.xml files.
Copy the code below and paste it into the respective files of your project using an IDE and save the files.
LeadmanagerApplication.javacopypackage com.catalyst.appsail.leadmanager; import java.util.Collections; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import jakarta.servlet.http.HttpServlet; @SpringBootApplication public class LeadmanagerApplication extends HttpServlet { public static void main(String[] args) { String port = System.getenv().getOrDefault("X_ZOHO_CATALYST_LISTEN_PORT","3000"); SpringApplication app = new SpringApplication(LeadmanagerApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port",port)); app.run(args); } }
LeadManager.javacopypackage com.catalyst.appsail.leadmanager; import java.util.*; import java.util.logging.Logger; import com.zc.auth.CatalystSDK; 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 org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @RestController class LeadManager { @SuppressWarnings("unused") private static final Logger LOGGER = Logger.getLogger(LeadManager.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 = ""; //Add your client ID private String CLIENT_SECRET = ""; //Add your client secret OkHttpClient client = new OkHttpClient(); String responseData = ""; MediaType mediaType = MediaType.parse("application/json"); org.json.simple.JSONArray reqData = new org.json.simple.JSONArray(); JSONObject data = new JSONObject(); JSONParser jsonParser = new JSONParser(); @GetMapping("/generateToken") public void generateToken(HttpServletRequest request, HttpServletResponse response) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); String code = request.getParameter("code"); String domain = (request.getHeader("host").contains("localhost") ? ("http://" + request.getHeader("host")) : ("https://") + request.getHeader("host").split(":")[0]); 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(********l); //Replace this with the Table ID of your table tab.insertRow(row); response.setStatus(HttpServletResponse.SC_OK); response.sendRedirect(domain + "/index.html"); } 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 + "/generateToken"); String URL = urlBuilder.build().toString(); MediaType mediaType = MediaType.parse("text/plain"); okhttp3.RequestBody body = okhttp3.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(); } @SuppressWarnings("unchecked") @GetMapping("/getUserDetails") public void getUserDetails(HttpServletRequest request, HttpServletResponse response) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String query = "SELECT * FROM Token where UserId="+userId; ArrayList
rowList = ZCQL.getInstance().executeQuery(query); JSONObject resp = new JSONObject(); if (rowList.isEmpty()) { resp.put("userId", null); response.setContentType("application/json"); response.getWriter().write(resp.toJSONString()); response.setStatus(200); } else { resp.put("userId", rowList.get(0).get("Token", "userId")); response.setContentType("application/json"); response.getWriter().write(resp.toJSONString()); response.setStatus(200); } } public ArrayList<ZCRowObject> getuserDetails(HttpServletRequest request) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String query = "SELECT * FROM Token where UserId="+userId; ArrayList rowList = ZCQL.getInstance().executeQuery(query); return rowList; } @GetMapping("/crmData") public void getAllLeads(HttpServletRequest request,HttpServletResponse response) throws Exception { responseData = getResponse(GET, null,request,apiUrl); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @GetMapping("/crmData/{id}") public void getLead(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception { String apiUri = apiUrl + "/" + id; responseData = getResponse(GET, null,request,apiUri); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @SuppressWarnings("unchecked") @PostMapping("/crmData") public void addLead(@RequestBody String leadData,HttpServletRequest request,HttpServletResponse response) throws Exception { JSONObject jsonObject = (JSONObject)jsonParser.parse(leadData); reqData.add(jsonObject); data.put("data", reqData); okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType,data.toString()); responseData = getResponse(POST, body,request,apiUrl); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @DeleteMapping("/crmData/{id}") public void deleteLead(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception { String apiUri = apiUrl + "/" + id; responseData = getResponse(DELETE, null,request,apiUri); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @SuppressWarnings("unchecked") @PutMapping("/crmData/{id}") public void editLead(@PathVariable Long id, @RequestBody String leadData,HttpServletRequest request,HttpServletResponse response) throws Exception { String apiUri = apiUrl + "/" + id; JSONObject jsonObject = (JSONObject)jsonParser.parse(leadData); reqData.add(jsonObject); data.put("data", reqData); okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType,data.toString()); responseData = getResponse(PUT, body,request,apiUri); reqData.remove(jsonObject); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } public String getResponse(String METHOD, okhttp3.RequestBody body,HttpServletRequest request,String apiUrl) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String accessToken = getAccessToken(userId,request); Request getResponse = new Request.Builder().url(apiUrl).method(METHOD, body) .addHeader("Authorization", "Zoho-oauthtoken " + accessToken).build(); String resp = client.newCall(getResponse).execute().body().string(); return resp; } @SuppressWarnings("unchecked") public String getAccessToken(Long userId,HttpServletRequest request) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); JSONObject authJson = new JSONObject(); JSONObject connectorJson = new JSONObject(); String query = "SELECT refresh_token FROM Token where UserId="+userId; ArrayList 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(); } } Note:
Ensure you add the Client ID and Client Secret values obtained after you registered the client in the Zoho API console to the lines 46 and 47 respectively, in the above code file.
Add the Table ID of the table you created in the Data Store in line 65.
AuthProviderImpl.javacopypackage com.catalyst.appsail.leadmanager; import com.zc.auth.AuthHeaderProvider; import jakarta.servlet.http.HttpServletRequest; public class AuthProviderImpl implements AuthHeaderProvider { private HttpServletRequest request; AuthProviderImpl(HttpServletRequest request) { this.request = request; } @Override public String getHeaderValue(String s) { return request.getHeader(s); } }
index.htmlcopy<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>CRM Lead Manager</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <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"> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet"> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"> </script> <script src="main.js"> </script> <script src="https://static.zohocdn.com/catalyst/sdk/js/4.4.0/catalystWebSDK.js"> </script> <script src="/__catalyst/sdk/init.js"> </script> <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <style> #connect { height: 260px; width: 500px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } </style> </head> <body onload="getUserDetails()"> <br> <center> <h1>CRM Lead Manager</h1> <br> </center> <div id="connect"> <center> <p>Click here to connect to Zoho CRM</p> <button onclick='navigate()'> <img src="https://www.zohowebstatic.com/sites/default/files/styles/product-home-page/public/icon-crm_blue.png" style="width: 180px;height: 130px;"> </button> </center> </div> <div style="width: 200px;float: right; margin-right: 30px;"> <label for="logoutbtn" class="btn btn-success btn-block btn-outlined">Logout</label> <button id="logoutbtn" onclick="logout()" style="display: none;"> </button> </div> <div id="main"> <div class="container"> <ul class="nav nav-tabs nav-justified mb-3" id="myTab" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="check-tab" data-toggle="tab" href="#check" role="tab" aria-controls="check" aria-selected="true">Add a Lead</a> </li> <li class="nav-item"> <a class="nav-link" id="report-tab" data-toggle="tab" href="#report" onclick="getLeads()" role="tab" aria-controls="report" aria-selected="false">Manage Leads</a> </li> </ul> <br> <div class="tab-content" id="myTabContent"> <div class="tab-pane fade show active" id="check" role="tabpanel" aria-labelledby="check-tab"> <div class="tab-pane fade show active" id="ex3-tabs-1" role="tabpanel" aria-labelledby="ex3-tab-1"> <div style="margin-left: 100px; margin-right:100px;"> <form id="leads"> <!-- 2 column grid layout with text inputs for the first and last names --> <div class="row mb-4"> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example1">First name</label> <input type="text" id="firstName" class="form-control" /> </div> </div> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example2">Last name</label> <input type="text" id="lastName" class="form-control" required /> </div> </div> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example3">Company name</label> <input type="text" id="companyName" class="form-control" /> </div> <!-- Email input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example5">Email</label> <input type="email" id="email" class="form-control" /> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example4">State</label> <input type="text" id="state" class="form-control" /> </div> <!-- Number input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example6">Phone</label> <input type="number" id="phone" class="form-control" /> </div> <!-- Number input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example6">Lead Source</label> <input type="text" id="leadSource" class="form-control" /> </div> <!-- Submit button --> <center> <button type="submit" onclick="createLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;">Add Lead</button> <div id="loader" style="display: none;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </center> </form> </div> </div> </div> <div class="tab-pane fade" id="report" role="tabpanel" aria-labelledby="report-tab"> <center> <div id="loaders" style="display: none; padding-top: 200px;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </center> <p id="showData"> </p> </div> </div> </div> <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="vertical-alignment-helper"> <div class="modal-dialog vertical-align-center"> <div class="modal-content"> <center> <h4 class="modal-title" id="myModalLabel"> </h4> <div class="modal-body" id="message"> </div> <div class="modal-footer"> <button type="button" style="background-color: #007bff;color: white;" class="btn btn-default" data-dismiss="modal">Close</button> </div> </center> </div> </div> </div> </div> <div class="modal fade" id="editForm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="vertical-alignment-helper"> <div class="modal-dialog vertical-align-center"> <div class="modal-content"> <div style="margin-left: 80px; margin-right:80px;"> <br> <center> <h2>Edit Lead</h2> </center> <br> <form id="editLeads"> <!-- 2 column grid layout with text inputs for the first and last names --> <div class="row mb-4"> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example1">First name</label> <input type="text" id="editfirstName" class="form-control" /> </div> </div> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example2">Last name</label> <input type="text" id="editlastName" class="form-control" required /> </div> </div> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example3">Company name</label> <input type="text" id="editcompanyName" class="form-control" /> </div> <!-- Email input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example5">Email</label> <input type="email" id="editemail" class="form-control" /> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example4">State</label> <input type="text" id="editstate" class="form-control" /> </div> <!-- Number input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example6">Phone</label> <input type="number" id="editphone" class="form-control" /> </div> <!-- Submit button --> <center> <button type="submit" id="editBtn" onclick="editLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;">Edit</button> <div id="loader" style="display: none;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </center> </form> </div> </div> </div> </div> </div> <div class="modal fade right" id="ModalDanger" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog modal-notify modal-danger modal-side modal-top-right" role="document"> <!--Content--> <div class="modal-content"> <!--Header--> <div class="modal-header"> <p class="heading">Lead Deletion</p> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true" class="white-text">×</span> </button> </div> <!--Body--> <div class="modal-body"> <div class="row"> <div class="col-9"> <p>Are you sure you want to delete the Lead?</p> </div> </div> </div> <!--Footer--> <div class="modal-footer justify-content-center"> <a type="button" class="btn btn-danger" id="delete-btn" onclick="deleteLead()">Delete</a> <a type="button" class="btn btn-outline-danger waves-effect" data-dismiss="modal">Cancel</a> </div> </div> <!--/.Content--> </div> </div> </div> </body> <script> //Add Your Client ID function navigate() { window.location.href = "https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.modules.ALL&client_id={{client_id}}&response_type=code&access_type=offline&redirect_uri=" + location.protocol + '//' + location.host + "/generateToken"; } </script> </html>
Note: Ensure you enter the Client ID in line 294login.htmlcopy<html> </html> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>CRM Lead Manager</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <script src="main.js"> </script> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <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"> <script src="https://js.zohostatic.com/catalystclient/1.0.0/catalystWebSDK.js"> </script> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"> </script> <script src="https://static.zohocdn.com/catalyst/sdk/js/4.4.0/catalystWebSDK.js"> </script> <script src="/__catalyst/sdk/init.js"> </script> <script> catalyst.auth.signIn("login"); </script> <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <style> #login { height: 100%; width: 100%; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } </style> <body> <br> <center> <h1>CRM Lead Manager</h1> </center> <div id="login"> </div> </body> </html>
main.csscopy#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; }
main.jscopyfunction 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: "/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("Success"); $("#message").html("Lead Created Successfully"); $("#loader").hide(); $('#myModal').modal('show'); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function logout() { var redirectURL = "/login.html"; //Add your app domain var auth = catalyst.auth; auth.signOut(redirectURL); } function getUserDetails() { $("#main").hide(); $("#connect").hide(); catalyst.auth.isUserAuthenticated().then(result => { console.log(result) $("#loader").show(); $.ajax({ url: "/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("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: "/crmData", type: "get", success: function (data) { debugger; var reqData = getRequiredData(data.data); $("#loaders").hide(); renderTable(reqData); }, error: function (error) { $("#myModalLabel").html("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: "/crmData/" + leadID, type: "delete", success: function (data) { debugger; $('#ModalDanger').modal('toggle'); $("#myModalLabel").html("Success"); $("#message").html("Lead Deleted Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function showEditPopup(leadID) { $.ajax({ url: "/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("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: "/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("Success"); $("#message").html("Lead Edited Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html("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": '<center> <a href="javascript:showEditPopup("' + data[i].id + '")">✎︎</a> </center>', "Delete": '<center> <a href="javascript:showDeletePopup("' + data[i].id + '")">🗑︎</a> </center>' } 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); }
pom.xmlcopy<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.12-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.catalyst.appsail</groupId> <artifactId>leadmanager</artifactId> <version>0.0.1-SNAPSHOT</version> <name>leadmanager</name> <description>Leadmanager Tutorial</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.zoho.catalyst</groupId> <artifactId>java-sdk</artifactId> <version>2.0.0-beta04</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.9.0</version> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> <repository> <id>java-sdk</id> <url>https://maven.zohodl.com</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </pluginRepository> </pluginRepositories> </project>
Addionally, you will also need to update the app-config.json file.
app-config.jsoncopy{ "command": "java -jar leadmanager-0.0.1-SNAPSHOT.jar", "build_path": "/", "stack": "java17", "env_variables": {}, "memory": 256, "scripts": { "preserve": "./mvnw clean package", "predeploy": "./mvnw clean package" }, "raw": {}, "platform": "javase", "catalyst_auth": true, "login_redirect": "/index.html" }
Note: Ensure you provide the right value for the buildpath key.Now let’s go over the logic and functionality of the application code.
The login.html file in the client component enables Catalyst Embedded Authentication login, allowing you to log in using the Zoho social login.
The index.html file contains the code for the front-end of the client. It defines a function navigate() that enables the connection to the CRM account by passing the required authorization information such as the Client ID and the scope.
The backend logic of the application defines the following APIs that perform various actions:
- /generateToken: Obtains the Refresh Token by calling the getRefreshToken() function, and inserts it along with the userID of the current user in the Token table in the Data Store. It then redirects to the index page of the client.
- /getUserDetails: Fetches the user details by calling the getUserDetails() function. If there is no record in the table, a JSON response with the userID alone is sent. If the record exists in the table, it is sent along with the userID.
- /crmData: This route defines the path of all leads in the Leads module. The Node function executes the HTTP GET and POST operations to fetch all leads or create a new lead using this route, respectively.
- /crmData/:id: This route defines the path of a particular lead in the Leads module. The id represents the unique ID of the lead in CRM. The function executes the HTTP PUT and DELETE operations to edit or delete a lead, respectively, using this route.
The backend logic is implemented using the following functions that are called by the APIs:
- getRefreshToken(): Fetches the Refresh Token by passing the Client ID, Client Secret, Redirect URI and other required values as query string parameters.
- getAccessToken(): 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.
- getResponse(): Passes the Access Token fetched to obtain the authorization needed to perform each action on the CRM module. This function is called with each /crmData and /crmData/:id API to authorize the request.
- getUserDetails(): Fetches the record from the Token table that contains the Refresh Token, by passing the userID.
main.js: It is the JavaScript function in the client component that parses the JSON responses obtained from the function and renders them in the index.html page. This function defines the actions for all the UI elements in the client application. For example, getLeads() obtains all leads from the function response and renders them in the client, and showEditPopup() defines the actions for editing a lead.
Last Updated 2025-01-31 19:19:27 +0530 +0530