アプリケーションのコーディング
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.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>
//クライアント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>
<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>
#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()はリードを編集するためのアクションを定義します。
最終更新日 2026-03-05 11:43:24 +0530 IST