--- title: "Configure functions directory" url: https://docs.catalyst.zoho.com/en/tutorials/leadmanager/nodejs/configure-functions-directory/ description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: 2026-08-17T12:16:04Z service: All Services type: tutorial related_links: - name: "Advanced I/O Functions" url: /en/serverless/help/functions/advanced-io/ - name: "Functions Directory Structure" url: /en/cli/v1/project-directory-structure/functions-directory --- # Configure the Functions Directory We will now begin coding the Lead Manager application by configuring the Advanced I/O function. The functions directory [](https://docs.catalyst.zoho.com/en/cli/v1/project-directory-structure/functions-directory) `functions/crm\_crud` contains: * The `index.js` main function file * The `catalyst-config.json` configuration file * Node modules * `[package.json](https://docs.npmjs.com/files/package.json)` and `[package-lock.json](https://docs.npmjs.com/configuring-npm/package-lock-json.html)` dependency files You will be adding code in `index.js`. You can use any IDE to configure the function. > **Note:** Please go through the code in this section to make sure you fully understand it. We will discuss the function and client code, after you configure the client. ### Install Express and Node Fetch Frameworks for Node.js The Node.js function requires three frameworks to be installed. You must install the [express](https://expressjs.com/), [node-fetch](https://www.npmjs.com/package/node-fetch), and [axios](https://www.npmjs.com/package/axios) dependencies to import those packages in your code. #### `express` To install `Express.js`, navigate to the Node function's directory (`functions/crm\_crud`) in your terminal and execute the following command: ```sh npm install express --save ``` This will install the Express module and save the dependencies. ![catalyst_leadmanager_install_express](https://catalyst-docs-development.zohostratus.in/images/tutorials/leadmanager/catalyst_leadmanager_install_express.webp) #### `node-fetch` To install `node-fetch`, execute the following command from the Node function's directory navigate to the Node function's directory (`functions/crm\_crud`): ```sh npm install node-fetch ``` This will install the module. ![catalyst_leadmanager_install_node_fetch](https://catalyst-docs-development.zohostratus.in/images/tutorials/leadmanager/catalyst_leadmanager_install_node_fetch.webp) #### `axios` To install `axios`, execute the following command from the Node function's directory navigate to the Node function's directory (`functions/crm\_crud`): ```sh npm install axios ``` This will install the module. ![catalyst_leadmanager_install_axios](https://catalyst-docs-development.zohostratus.in/images/tutorials/leadmanager/catalyst_leadmanager_install_axios.webp) This information will also be updated in the [package.json](https://docs.npmjs.com/files/package.json) file. ```json { "name": "crm_crud", "version": "1.0.0", "main": "index.js", "author": "amelia.burrows@zylker.com", "dependencies": { "axios": "^0.27.2", "express": "^4.18.1", "node-fetch": "^3.2.6", "zcatalyst-sdk-node": "latest" } } ``` You can now add the code in the function file. Copy the code below and paste it in `index.js` located in `functions/crm\_crud` directory and save the file. **index.js** ```javascript "use strict"; const express = require("express"); const http = require("https"); const app = express(); app.use(express.json()); const catalyst = require("zcatalyst-sdk-node"); const HOST = "www.zohoapis.com"; const AUTH_HOST = "https://accounts.zoho.com/oauth/v2/token"; const PORT = 443; const axios = require("axios"); const CLIENTID = '{{YOUR_CLIENT_ID}}'; //Add your client ID const CLIENT_SECRET = '{{YOUR_CLIENT_SECRET}}'; //Add your client secret app.get("/generateToken", async (req, res) => { try { const catalystApp = catalyst.initialize(req); const code = req.query.code; let userManagement = catalystApp.userManagement(); let userDetails = await userManagement.getCurrentUser(); const domain = `${process.env.X_ZOHO_CATALYST_IS_LOCAL === 'true' ? "http" : "https"}://${process.env.X_ZOHO_CATALYST_IS_LOCAL === 'true' ? req.headers.host : req.headers.host.split(':')[0]}` const refresh_token = await getRefreshToken(code, res, domain); const userId = userDetails.user_id; const catalystTable = catalystApp.datastore().table("Token"); await catalystTable.insertRow({ refresh_token, userId, }); res.status(200).redirect(`${domain}/app/index.html`); } catch (err) { console.log(err); res .status(500) .send({ message: "Internal Server Error. Please try again after sometime.", error: err, }); } }); app.get("/getUserDetails", async (req, res) => { try { const catalystApp = catalyst.initialize(req); const userDetails = await getUserDetails(catalystApp); if (userDetails.length !== 0) { res.status(200).send({ userId: userDetails[0].Token.userId }); } else { res.status(200).send({ userId: null }); } } catch (err) { console.log(err); res .status(500) .send({ message: "Internal Server Error in Getting User Details. Please try again after sometime.", error: err, }); } }); app.get("/crmData", async (req, res) => { try { console.log(); const catalystApp = catalyst.initialize(req); const userDetails = await getUserDetails(catalystApp); const accessToken = await getAccessToken(catalystApp, userDetails); const options = { hostname: HOST, port: PORT, method: "GET", path: `/crm/v2/Leads`, headers: { Authorization: `Zoho-oauthtoken ${accessToken}`, }, }; var data = ""; const request = http.request(options, function (response) { response.on("data", function (chunk) { data += chunk; }); response.on("end", function () { console.log(response.statusCode); res.setHeader("content-type", "application/json"); res.status(200).send(data); }); }); request.end(); } catch (err) { console.log(err); res .status(500) .send({ message: "Internal Server Error. Please try again after sometime.", }); } }); app.get("/crmData/:id", async (req, res) => { try { const catalystApp = catalyst.initialize(req); const userDetails = await getUserDetails(catalystApp); const accessToken = await getAccessToken(catalystApp, userDetails); const options = { hostname: HOST, port: PORT, method: "GET", path: `/crm/v2/Leads/${req.params.id}`, headers: { Authorization: `Zoho-oauthtoken ${accessToken}`, }, }; var data = ""; const request = http.request(options, function (response) { response.on("data", function (chunk) { data += chunk; }); response.on("end", function () { res.setHeader("content-type", "application/json"); res.status(200).send(data); }); }); request.end(); } catch (err) { console.log(err); res.status(500).send({ message: "Internal Server Error. Please try again after sometime.", }); } }); app.post("/crmData", async (req, res) => { try { const catalystApp = catalyst.initialize(req); const createData = req.body; const reqData = []; reqData.push(createData); const data = { data: reqData, }; if (!createData) { res.status(400).send({ message: "Data Not Found" }); } const userDetails = await getUserDetails(catalystApp); const accessToken = await getAccessToken(catalystApp, userDetails); const options = { hostname: HOST, port: PORT, method: "POST", path: `/crm/v2/Leads`, headers: { Authorization: `Zoho-oauthtoken ${accessToken}`, "Content-Type": "application/json", }, }; const request = http.request(options, function (response) { res.setHeader("content-type", "application/json"); response.pipe(res); }); request.write(JSON.stringify(data)); request.end(); } catch (err) { console.log(err); res .status(500) .send({ message: "Internal Server Error. Please try again after sometime.", }); } }); app.put("/crmData/:id", async (req, res) => { try { const catalystApp = catalyst.initialize(req); const updateData = req.body; const reqData = []; reqData.push(updateData); const data = { data: reqData, }; if (!updateData) { res.status(400).send({ message: "Update Data Not Found" }); } const userDetails = await getUserDetails(catalystApp); const accessToken = await getAccessToken(catalystApp, userDetails); const options = { hostname: HOST, port: PORT, method: "PUT", path: `/crm/v2/Leads/${req.params.id}`, headers: { Authorization: `Zoho-oauthtoken ${accessToken}`, "Content-Type": "application/json", }, }; const request = http.request(options, function (response) { res.setHeader("content-type", "application/json"); response.pipe(res); }); request.write(JSON.stringify(data)); request.end(); } catch (err) { console.log(err); res .status(500) .send({ message: "Internal Server Error. Please try again after sometime.", }); } }); app.delete("/crmData/:id", async (req, res) => { console.log(`/crm/v2/Leads/${req.params.id}`); try { const catalystApp = catalyst.initialize(req); const userDetails = await getUserDetails(catalystApp); const accessToken = await getAccessToken(catalystApp, userDetails); const options = { hostname: HOST, port: PORT, method: "DELETE", path: `/crm/v2/Leads/${req.params.id}`, headers: { Authorization: `Zoho-oauthtoken ${accessToken}`, "Content-Type": "application/json", }, }; const request = http.request(options, function (response) { res.setHeader("content-type", "application/json"); response.pipe(res); }); request.end(); } catch (err) { console.log(err); res.status(500).send({ message: "Internal Server Error. Please try again after sometime.", }); } }); async function getAccessToken(catalystApp, userDetails) { const refresh_token = userDetails[0].Token.refresh_token; const userId = userDetails[0].Token.userId; const credentials = { [userId]: { client_id: CLIENTID, client_secret: CLIENT_SECRET, auth_url: AUTH_HOST, refresh_url: AUTH_HOST, refresh_token, }, }; const accessToken = await catalystApp.connection(credentials).getConnector(userId).getAccessToken(); return accessToken; } async function getRefreshToken(code, res, domain) { try { const url = `${AUTH_HOST}?code=${code}&client_id=${CLIENTID}&client_secret=${CLIENT_SECRET}&grant_type=authorization_code&redirect_uri=${domain}/server/crm_crud/generateToken`; const response = await axios({ method: "POST", url }); return response.data.refresh_token; } catch (err) { console.log(err); res.status(500).send({ message: "Internal Server Error. Please try again after sometime.", error: err, }); } } async function getUserDetails(catalystApp) { let userDetails = await catalystApp.userManagement().getCurrentUser(); let userDetail = await catalystApp.zcql().executeZCQLQuery(`SELECT * FROM Token where UserId=${userDetails.user_id}`); return userDetail; } module.exports = app; ``` > **Note:** After you copy and paste this code in your function file, ensure that you replace the following values in it: * [Client ID](https://docs.catalyst.zoho.com/en/tutorials/leadmanager/nodejs/register-client) in line 11 * [Client Secret](https://docs.catalyst.zoho.com/en/tutorials/leadmanager/nodejs/register-client) in line 12 The functions directory is now configured. We will discuss the function and client code, after you configure the client.