Catalyst App within Zoho CRM by extension using Zoho Sigma Part 1

In this article, we will see how we can embed a Catalyst application handling a different business case in the Zoho CRM. This will be done by developing an extension using Zoho Sigma.

Published on February 22, 2024

Share This Post
AdobeStock 294312661 resized

The business world is complex and often has so many workflows that can be difficult to manage. You would find companies handling different services at different places requiring high context switching. This can frustrate the users and take a toll on the employees’ productivity. But Zoho CRM has always aimed for flexibility and the best user experience. In this article, we will see how we can embed a Catalyst application handling a different business case in the Zoho CRM. This will be done by developing an extension using Zoho Sigma.

The article will have a list of two blog posts handling the use case of an insurance company that needs a plugin in their CRM with custom permission access, SSO with Zoho’s OAuth, and running of catalyst functions. This extension will be used to manage their insurance policies which are currently being done by a separate system on Zoho Catalyst

Architecture Overview.

In this section, we will see how the data will flow for the business case that we are going to solve. The insurance application lives on the internet, developed in Zoho Catalyst. However, we require making it available inside the Zoho CRM for another newly created team which has more access and permission rights to the company’s data. They can view more modules than the insurance team which has a limited scope. The customer’s insurance policies are in the CRM but policy management is done from another application. A basic illustration for better understanding is given as follows.

flow

As you can see in the above illustrations, the insurance app will continue to work independently but it will also be accessible from the Zoho CRM with the Zoho Sigma plugin.

The Policy Manager app.

The first step is to have an application for the management of our insurance policies. For the sake of simplicity, we will keep the functionality very basic. We need a web app that allows us to add, edit, list, and delete the policies of the users. Let’s start developing it.

Prerequisites

– A Zoho account

– Zoho catalyst cli installed globally on your machine.

– An IDE for coding.

– Access to CRM.

Before we get started, there needs to be some data in our Zoho CRM with which we can work. For this purpose, we have created two records in the CRM that look as follows:

crm

This is dummy data for our sample project. Our policy manager can create policies based on the contacts in our Zoho CRM. For the catalyst app to get data from CRM, we will be using the REST API for Zoho CRM. There are some steps required for authentication which can be found here. For now, we will be registering our application self-client in the authentication part.

oauth console

Once you have your access token for the REST API, you can proceed.

Create a new catalyst project with the following command:

catalyst init

The project structure will be as follows.

file structure

Backend function

We will create an Advanced I/O function with a react frontend for our policy tracker. After the project is initialized, let us go into the function directory and install the following packages with the command below.

npm install axios express

Now that we have the right plugins, let us go to index.js and paste the following code inside.

const express = require("express");
const axios = require("axios");


const app = express();
const PORT = process.env.PORT || 3000;


// Middleware for parsing JSON requests
app.use(express.json());
// Zoho CRM API configuration
const ZOHO_API_ENDPOINT =
 "end_point";
const ZOHO_AUTH_TOKEN =
 "your_access_token";


let policyData = [];


// Function to fetch contacts from Zoho CRM
const fetchContacts = async () => {
 try {
   const response = await axios.get(ZOHO_API_ENDPOINT, {
     headers: {
       Authorization: `Bearer ${ZOHO_AUTH_TOKEN}`,
     },
   });
   console.log(response.data.data);
   return response.data.data;
 } catch (error) {
   console.error("Error fetching contacts from Zoho CRM:", error);
   return [];
 }
};


// 1. Fetch policies from Zoho CRM contacts
app.get("/policies", async (req, res) => {
 try {
   res.json(policyData);
 } catch (error) {
   res.status(500).send("Error fetching contacts from Zoho CRM");
 }
});


app.post("/policies", (req, res) => {
 const newPolicy = req.body;
 policyData.push(newPolicy);
 res.status(201).json(newPolicy);
});


app.get("/contacts", async (req, res) => {
 try {
   const contacts = await fetchContacts();
   res.json(contacts);
 } catch (error) {
   res.status(500).send("Error fetching contacts from Zoho CRM");
 }
});


// Start the server
app.listen(PORT, () => {
 console.log(`Server is running on http://localhost:${PORT}`);
});
module.exports = app;

We have two main endpoints here. The /contacts endpoint fetches the data from our CRM and /policies endpoint is responsible for creating and displaying all the available insurance policies on our front end.

React frontend

Since our backend is ready, let’s create a frontend for the policy manager. The app will allow users to create policies for clients that are registered in our CRM and display all available policies. A user can have multiple policies as well.

import React, { useState, useEffect } from "react";


interface Policy {
 id: number;
 Name: string;
 dateOfIssue: string;
 dateOfExpiration: string;
 type: string;
 amount: number;
 annualPremium: number;
 state: string;
}
interface Contact {
 Full_Name: string;
 id: number;
}


const App = () => {
 const [policies, setPolicies] = useState<Policy[]>([]);
 const [contacts, setContacts] = useState<Contact[]>([]);
 const [formData, setFormData] = useState<Policy>({
   Name: "",
   dateOfIssue: "",
   dateOfExpiration: "",
   type: "",
   amount: 0,
   annualPremium: 0,
   state: "",
   id: 0,
 });


 useEffect(() => {
   fetchData();
 }, []);


 const fetchData = async () => {
   try {
     const policiesResponse = await fetch(
       "/server/policy_tracker_function/policies",
       {
         method: "GET",
         headers: {
           "Content-Type": "application/json",
         },
       }
     );
     const policiesData = await policiesResponse.json();
     setPolicies(policiesData);
     const contactsResponse = await fetch(
       "/server/policy_tracker_function/contacts",
       {
         method: "GET",
         headers: {
           "Content-Type": "application/json",
         },
       }
     );
     const contactsData = await contactsResponse.json();
     console.log(contactsData);
     setContacts(contactsData);
   } catch (error) {
     console.error("Error fetching data:", error);
   }
 };


 const handleChange = (e: any) => {
   setFormData({ ...formData, [e.target.name]: e.target.value });
 };


 const handleSubmit = async (e: any) => {
   e.preventDefault();


   try {
     await fetch("/server/policy_tracker_function/policies", {
       method: "POST",
       headers: {
         "Content-Type": "application/json",
       },
       body: JSON.stringify(formData),
     });
     setFormData({
       Name: "",
       dateOfIssue: "",
       dateOfExpiration: "",
       type: "",
       amount: 0,
       annualPremium: 0,
       state: "",
       id: 0,
     });
     fetchData();
   } catch (error) {
     console.error("Error adding policy:", error);
   }
 };


 return (
   <div>
     <h1>Insurance Policies</h1>
     <div>
       {policies?.length === 0 && <p>No policies found. Add a new policy</p>}
       {policies?.map((policy) => (
         <div
           key={policy.id}
           style={{
             border: "1px solid black",
             padding: "10px",
             margin: "10px",
             borderRadius: "10px",
             width: "fit-content",
           }}
         >
           <h3>{contacts?.find((c) => c.id === policy.id)?.Full_Name}</h3>
           <p>
             <strong>Date of Issue:</strong> {policy.dateOfIssue}
           </p>
           <p>
             <strong>Date of Expiration:</strong> {policy.dateOfExpiration}
           </p>
           <p>
             <strong>Type:</strong> {policy.type}
           </p>
           <p>
             <strong>Amount:</strong> {policy.amount} $
           </p>
           <p>
             <strong>Annual Premium:</strong> {policy.annualPremium} $
           </p>
           <p>
             <strong>State:</strong> {policy.state}
           </p>
           <br />
         </div>
       ))}
     </div>
     <h2>Add Policy</h2>
     <form onSubmit={handleSubmit}>
       <label>
         Name:
         <select name="id" onChange={handleChange} value={formData.id}>
           <option value=""></option>
           {contacts?.map((contact) => (
             <option key={contact.id} value={contact.id}>
               {contact.Full_Name}
               {console.log(contact.Full_Name)}
             </option>
           ))}
         </select>
       </label>
       <br />


       <br />
       <label>
         Date of Issue:
         <input
           type="date"
           name="dateOfIssue"
           onChange={handleChange}
           value={formData.dateOfIssue}
         />
       </label>
       <br />
       <label>
         Date of Expiration:
         <input
           type="date"
           name="dateOfExpiration"
           onChange={handleChange}
           value={formData.dateOfExpiration}
         />
       </label>
       <br />
       <label>
         Type:
         <select onChange={handleChange} name="type" id="type">
           <option value=""></option>


           <option value="Term">Term</option>
           <option value="Whole">Whole</option>
         </select>
       </label>
       <br />
       <label>
         Amount:
         <input
           type="number"
           name="amount"
           onChange={handleChange}
           value={formData.amount}
         />
       </label>
       <br />
       <label>
         Annual Premium:
         <input
           type="number"
           name="annualPremium"
           onChange={handleChange}
           value={formData.annualPremium}
         />
       </label>
       <br />
       <label>
         State:
         <select onChange={handleChange} name="state" id="state">
           <option value="CA">California</option>
           <option value="TX">Texas</option>
           <option value="FL">Florida</option>
           <option value="NY">New York</option>
           <option value="PA">Pennsylvania</option>
           <option value="IL">Illinois</option>
           <option value="OH">Ohio</option>
           <option value="GA">Georgia</option>
           <option value="NC">North Carolina</option>
           <option value="MI">Michigan</option>
         </select>
       </label>
       <br />
       <button type="submit">Add Policy</button>
     </form>
   </div>
 );
};


export default App;

We are here handling the display of the insurance policies along with the creation. In the creation, a user of the policy app gets to select the user for whom the policy is being created and this user comes from our CRM. The policy will be created in our catalyst function. Hence we have achieved a two-way integration between CRM and Catalyst.

Now, with the following command, let us deploy the function.

catalyst deploy

If you get the following output in the terminal, the full-stack web application has been deployed.

results

To test it, you can head over to URL and see it in action.

results

As seen above, the users are from our CRM and the policy data is separate!

Conclusion

In this part, we were able to create our insurance policy manager with data from our CRM. In our next blog, we will install this Catalyst app as a plugin in our CRM with proper permission management and SSO login. Stay tuned!

Recent Posts
  • From Email to Purchase Order: Automating Order Processing with Zoho Flow and OpenAI
  • How to Create Custom Zoho Writer Documents with Conditions and Subforms
  • How to Create Macros to Automate Ticket Replies in Zoho Desk
  • Integrating Zoho Creator and Zoho Desk using a Widget Extension
Share This Post

Related Posts

Discover the latest news and updates on Zoho applications.

Unlock Your Knowledge Journey!

Get three articles for free, then enjoy unlimited access by registering.