--- title: "アプリケーションのコーディング" url: https://docs.catalyst.zoho.com/ja/tutorials/leadmanager-appsail/springboot/code-app/ service: All Services type: tutorial related_links: - name: "認証用Web SDK" url: /ja/sdk/web/v4/cloud-scale/authentication/get-auth-instance/ --- # アプリケーションのコーディング leadmanager/src/main/java/com/catalyst/appsail/leadmanager/ディレクトリに、Javaコードファイルを作成し、**LeadmanagerApplication.java**と名付けます。このコードファイルには、アプリケーションを提供するためのロジックが含まれます。 このファイルに加えて、同じディレクトリに以下のコードファイルを作成する必要があります: * **LeadManager.java**: アプリケーションのビジネスロジックを含みます。 * **AuthProviderImpl.java**: Catalyst SDKを初期化するためのロジックを含みます。 /src/main/resources/staticディレクトリに、以下のファイルを作成します: * **index.html**: アプリケーションのフロントエンドのHTMLコードを含むファイルです。 * **login.html**: Embedded AuthenticationロジックのHTMLコードを含むファイルです。 * **main.css**: アプリケーションのスタイリング要素を含むファイルです。 * **main.js**: フロントエンドとバックエンドを接続するJavaScriptコードを含むファイルです。 leadmanager/ **Spring Boot - JAR**プロジェクトディレクトリの最終的な構造を以下に示します:
LeadManager.java、LeadmanagerApplication.java、AuthProviderImpl.java、index.html、login.html、main.css、main.js、およびpom.xmlファイルのコーディングを行います。 注意: このセクションのコードを十分に理解するために、必ず確認してください。 以下のコードをコピーして、IDEを使用してプロジェクトのそれぞれのファイルに貼り付け、ファイルを保存してください。 package 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); } } package 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 = ""; //クライアントIDを追加してください private String 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); //テーブルのTable IDに置き換えてください 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<ZCRowObject> 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<ZCRowObject> 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<ZCRowObject> 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(); } } 注意:
* Zoho APIコンソールでクライアントを登録した際に取得したClient IDとClient Secretの値を、上記のコードファイルのそれぞれ46行目と47行目に必ず追加してください。 * Data Storeで作成したテーブルのTable IDを65行目に追加してください。 package 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); } } <!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.6.2/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> //クライアント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> 注意: 252行目にClient IDを必ず入力してください。 <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://static.zohocdn.com/catalyst/sdk/js/4.6.2/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.6.2/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> #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; } 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: "/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); } <?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> さらに、**app-config.json**ファイルも更新する必要があります。 { "command": "java -jar leadmanager-0.0.1-SNAPSHOT.jar", "build_path": "./target", "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" } それでは、アプリケーションコードのロジックと機能について見ていきましょう。 * クライアントコンポーネントのlogin.htmlファイルは、Catalyst Embedded Authenticationログインを有効にし、Zohoソーシャルログインを使用してログインできるようにします。 * index.htmlファイルには、クライアントのフロントエンドのコードが含まれています。navigate()関数を定義しており、Client IDやスコープなどの必要な認証情報を渡すことでCRMアカウントへの接続を可能にします。 * アプリケーションのバックエンドロジックは、さまざまなアクションを実行する以下のAPIを定義しています: - **/generateToken**: getRefreshToken()関数を呼び出して*Refresh Token*を取得し、現在のユーザーのuserIDとともに*Data Store*のTokenテーブルに挿入します。その後、クライアントのインデックスページにリダイレクトします。 - **/getUserDetails**: getUserDetails()関数を呼び出してユーザーの詳細を取得します。テーブルにレコードがない場合は、userIDのみを含むJSONレスポンスが送信されます。テーブルにレコードが存在する場合は、userIDとともに送信されます。 - **/crmData**: このルートは、Leadsモジュールのすべてのリードのパスを定義します。Nodeファンクションは、このルートを使用してHTTP GETおよびPOST操作を実行し、すべてのリードの取得または新しいリードの作成を行います。 - **/crmData/:id**: このルートは、Leadsモジュールの特定のリードのパスを定義します。idはCRMにおけるリードの一意のIDを表します。ファンクションは、このルートを使用してHTTP PUTおよびDELETE操作を実行し、リードの編集または削除を行います。 * バックエンドロジックは、APIによって呼び出される以下の関数を使用して実装されています: - **getRefreshToken()**: Client ID、Client Secret、*Redirect URI*、およびその他の必要な値をクエリ文字列パラメータとして渡して、*Refresh Token*を取得します。 - **getAccessToken()**: ZCQLを使用してTokenテーブルからクエリされた*Refresh Token*およびその他の必要なパラメータを渡して、*Access Token*を取得します。Access Tokenは、リードの追加やリードの編集など、CRMモジュールで操作を実行する必要があるたびに取得されます。 - **getResponse()**: 取得した*Access Token*を渡して、CRMモジュールで各アクションを実行するために必要な認証を取得します。この関数は、各/crmDataおよび/crmData/:id APIで呼び出され、リクエストを認証します。 - **getUserDetails()**: userIDを渡して、*Refresh Token*を含む*Token*テーブルからレコードを取得します。 * **main.js**: ファンクションから取得したJSONレスポンスを解析し、index.htmlページにレンダリングするクライアントコンポーネントのJavaScript関数です。この関数は、クライアントアプリケーションのすべてのUI要素のアクションを定義します。たとえば、getLeads()はファンクションのレスポンスからすべてのリードを取得してクライアントにレンダリングし、showEditPopup()はリードを編集するためのアクションを定義します。