クライアントディレクトリの設定
クライアントコンポーネントを設定しましょう。クライアントディレクトリには以下が含まれています:
- フロントエンドアプリケーションのHTMLコードを含むindex.htmlファイル
- CSSコードを含むmain.cssファイル
- JavaScriptコードを含むmain.jsファイル
- client-package.json設定ファイル
index.html、main.js、main.cssのコーディングを行います。また、このディレクトリに新しいファイルlogin.htmlを作成してコードを追加します。
以下のコードをコピーして、IDEを使用してプロジェクトのclient/ディレクトリにある各ファイルに貼り付けて保存してください。
<!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.1/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とリダイレクトURLをここに追加してください
function navigate() {
window.location.href = "https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.modules.ALL&client_id={{YOUR_CLIENT_ID}}&response_type=code&access_type=offline&redirect_uri="+location.protocol + '//' + location.host + "/server/lead_manager_function/generateToken";
}
</script>
</html>
function createLead() {
debugger;
$("#loader").show();
var firstName = $("#firstName").val();
var lastName = $("#lastName").val();
if (lastName == "") {
alert("Kindly Enter the Last Name");
$("#loader").hide();
return;
}
var companyName = $("#companyName").val();
var email = $("#email").val();
var state = $("#state").val();
var phone = $("#phone").val();
var leadSource = $("#leadSource").val();
$.ajax({
url: "/server/lead_manager_function/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 = "http://localhost:3000/app/login.html"; //アプリドメインを追加
var auth = catalyst.auth;
auth.signOut(redirectURL);
}
function getUserDetails() {
$("#main").hide();
$("#connect").hide();
catalyst.auth.isUserAuthenticated().then(result => {
$("#loader").show();
$.ajax({
url: "/server/lead_manager_function/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: "/server/lead_manager_function/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: "/server/lead_manager_function/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: "/server/lead_manager_function/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: "/server/lead_manager_function/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);
}
#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;
}
<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.6.1/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: 260px;
width: 500px;
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>
クライアントディレクトリの設定が完了しました。
関数とクライアントコンポーネントの動作を簡単に確認しましょう:
-
クライアントコンポーネントのlogin.htmlファイルは、Catalyst Authentication ログインを有効にします。これはZohoサインイン機能ではなく、Catalystログインのみを処理します。
-
index.htmlはクライアントのフロントエンドのコードを含みます。Client IDや スコープなどの必要な認証情報を渡してCRMアカウントへの接続を可能にする navigate()関数を定義します。
-
Advanced I/O関数は、さまざまなアクションを実行する以下のAPIを定義します:
-
/generateToken: getRefreshToken()関数を呼び出してリフレッシュトークンを取得し、 Data Storeの_Token_テーブルに現在のユーザーの userIDとともに挿入します。その後、 クライアントのインデックスページにリダイレクトします。
-
/getUserDetails: getUserDetails()関数を呼び出してユーザー詳細を取得します。テーブルにレコードがない場合、 userIDのみを含むJSONレスポンスが送信されます。レコードがテーブルに存在する場合、 userIDとともに送信されます。
-
/crmData: このルートは、 リードモジュール内のすべてのリードのパスを定義します。Node関数はHTTP GETおよび POST操作を実行して、このルートを使用してそれぞれすべてのリードの取得または 新しいリードの作成を行います。
-
/crmData/:id: このルートは、 リードモジュール内の特定のリードのパスを定義します。idはCRM内のリードの一意のIDを 表します。関数はこのルートを使用してHTTP PUTおよび DELETE操作を実行し、それぞれリードの編集または削除を行います。
-
Advanced I/O関数には、APIから呼び出される以下の関数が含まれています:
-
getRefreshToken(): Client ID、Client Secret、 Redirect URIおよびその他の必要な値をクエリ文字列パラメータとして渡してリフレッシュトークンを取得します
-
getAccessToken(): ZCQLを使用してTokenテーブルから クエリされたリフレッシュトークンとその他の必要なパラメータを渡してアクセストークンを取得します。 アクセストークンは、リードの追加やリードの編集など、CRMモジュールで操作を実行する必要があるたびに取得されます。
-
getUserId(): userIDを渡して、リフレッシュトークンを含む _Token_テーブルのレコードを取得します
-
main.jsは、関数から取得したJSONレスポンスを解析して index.htmlページにレンダリングするクライアントコンポーネントのJavaScript関数です。 この関数は、クライアントアプリケーションのすべてのUI要素のアクションを定義します。 例えば、getLeads()は関数レスポンスからすべてのリードを取得してクライアントに レンダリングし、showEditPopup()はリードの編集アクションを定義します。
-
最終更新日 2026-03-05 11:43:24 +0530 IST