お知らせ:

当社は、お客様により充実したサポート情報を迅速に提供するため、本ページのコンテンツは機械翻訳を用いて日本語に翻訳しています。正確かつ最新のサポート情報をご覧いただくには、本内容の英語版を参照してください。

アプリケーションのコーディング

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プロジェクトディレクトリの最終的な構造を以下に示します: catalyst_tutorials_leadmanager_appsail_complete_directory

LeadManager.javaLeadmanagerApplication.javaAuthProviderImpl.javaindex.htmllogin.htmlmain.cssmain.js、およびpom.xmlファイルのコーディングを行います。

注意: このセクションのコードを十分に理解するために、必ず確認してください。

以下のコードをコピーして、IDEを使用してプロジェクトのそれぞれのファイルに貼り付け、ファイルを保存してください。

LeadmanagerApplication.java
copy
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);
	}
}

View more

LeadManager.java
copy
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();
	}
}

View more

注意:
  • Zoho APIコンソールでクライアントを登録した際に取得したClient IDClient Secretの値を、上記のコードファイルのそれぞれ46行目と47行目に必ず追加してください。

  • Data Storeで作成したテーブルのTable ID65行目に追加してください。

AuthProviderImpl.java
copy
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);
    }
}

View more

index.html
copy
<!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>

View more

注意: 252行目にClient IDを必ず入力してください。
login.html
copy
<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>

View more

main.css
copy
#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; }

View more

main.js
copy
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);
  }

View more

pom.xml
copy
<?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>

View more

さらに、app-config.jsonファイルも更新する必要があります。

app-config.json
copy
{
	"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"
}
View more

それでは、アプリケーションコードのロジックと機能について見ていきましょう。

  • クライアントコンポーネントのlogin.htmlファイルは、Catalyst Embedded Authenticationログインを有効にし、Zohoソーシャルログインを使用してログインできるようにします。

  • index.htmlファイルには、クライアントのフロントエンドのコードが含まれています。navigate()関数を定義しており、Client IDやスコープなどの必要な認証情報を渡すことでCRMアカウントへの接続を可能にします。

  • アプリケーションのバックエンドロジックは、さまざまなアクションを実行する以下のAPIを定義しています:

    • /generateToken: getRefreshToken()関数を呼び出してRefresh Tokenを取得し、現在のユーザーのuserIDとともにData StoreTokenテーブルに挿入します。その後、クライアントのインデックスページにリダイレクトします。
    • /getUserDetails: getUserDetails()関数を呼び出してユーザーの詳細を取得します。テーブルにレコードがない場合は、userIDのみを含むJSONレスポンスが送信されます。テーブルにレコードが存在する場合は、userIDとともに送信されます。
    • /crmData: このルートは、Leadsモジュールのすべてのリードのパスを定義します。Nodeファンクションは、このルートを使用してHTTP GETおよびPOST操作を実行し、すべてのリードの取得または新しいリードの作成を行います。
    • /crmData/:id: このルートは、Leadsモジュールの特定のリードのパスを定義します。idはCRMにおけるリードの一意のIDを表します。ファンクションは、このルートを使用してHTTP PUTおよびDELETE操作を実行し、リードの編集または削除を行います。
  • バックエンドロジックは、APIによって呼び出される以下の関数を使用して実装されています:

    • getRefreshToken(): Client IDClient SecretRedirect 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

関連リンク

認証用Web SDK