Authenticate Zoho CRM in serverless
Firebase implementation
This serveless Zoho CRM authentication recipe is covered for Firebase functions using Node.js. After reading this article you will be able to use your serverless functions to make authentication using OAuth 2.0 and make simple calls using SDK for Node.js. To conduct authentication you need to have the Blaze plan activated in your firebase account. There is a simple solution to get the Blaze plan for free.
Prepare environment for Firebase functions
If you are familiar with creating Firebase functions you can skip this block and go directly to the next one.
Find a place in your system to create a new project for Firebase functions. Then install necessary official Firebase tools globally.
npm install -g firebase-tools
Then init Firebase project using the just installed tools.
firebase init
Select Functions: Configure and deploy Cloud Functions option using space.

Next select a project or create a new one. If you are already hosting your app in the Firebase it's good to select that project but it's not necessary. In the next step you will be asked to login. After successful authentication your Firebase project will be built. Open it in your IDE. The core folder is named functions and from there you will operate and create new functions so change to this folder if you use a IDE console. If not, remember to perform any console command from this folder.
Install Node.js SDK for Zoho CRM
It's a good idea to install the official Zoho SDK which will help you with authentication and API calls. Install the SDK in the functions folder.
npm install zcrmsdk
Then in the index.js file, require this module and add the config object.
// functions/index.js
const functions = require('firebase-functions');
const ZCRMRestClient = require('zcrmsdk')
const config = {
"client_id":"1000.BL2631QMU8G37XWUHUXOLZLRVVEJJH",
"client_secret":"d96679335576a4737f84b877a14079fa6f2f93b63d",
"redirect_url":"http://dummy_address.com",
"user_identifier":"dev@blowstack.com",
"tokenmanagement":"zohoAuth"
};
Provide your own data in the config object. If you don't know from where to get those values, please refer to my previous post about Zoho CRM authentication in Node.js and then having client id and client secret get back to this point of the article to follow next steps of Zoho serverless implementation.
The very important part of the config is tokenmanagemnt value. It should point to the object which implements three functions required by the SDK. Those functions control how tokens are saved, updated and retrieved when needed. In the next step you are going to create those functions and convert them into a node module.
Create oauth.js file
In the functions folder create a new one and name it i.e zohoAuth. Next in this folder create a file named oauth.js and paste the following code.
// functions/zohoAuth/oauth.js
let file_persistence = {};
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
file_persistence.saveOAuthTokens = function (tokenobject) {
return new Promise(function (resolve, reject) {
let tokens = {}
db.collection('zoho').doc('tokens').update({
access_token: tokenobject.access_token,
expires_in: tokenobject.expires_in,
refresh_token: tokenobject.refresh_token,
})
// eslint-disable-next-line promise/always-return
.then(function (docRef) {
resolve()
})
.catch(function (error) {
console.error("Error adding document: ", error);
})
})
}
file_persistence.getOAuthTokens = function (user_identifier) {
return new Promise(function (resolve, reject) {
let tokens = {}
// eslint-disable-next-line promise/always-return
db.collection('zoho').doc('tokens').get().then((snapshot) => {
let data = snapshot.data()
tokens.access_token = data.access_token
tokens.refresh_token = data.refresh_token
tokens.expires_in = data.expires_in
resolve(tokens)
}).catch((err) => {
console.log(err)
resolve()
})
})
}
file_persistence.updateOAuthTokens = function (tokenobject) {
return new Promise(function (resolve, reject) {
db.collection('zoho').doc('tokens').update({
access_token: tokenobject.access_token,
expires_in: tokenobject.expires_in,
})
// eslint-disable-next-line promise/always-return
.then(function (docRef) {
resolve()
})
.catch(function (error) {
console.error("Error adding document: ", error);
})
})
}
module.exports = file_persistence;
The implementation is based on the Firebase database. You don't need to provide any authentication values because it will be called from the Firebase servers. Take a look at the three methods. They operate on a database collection named zoho and documents named tokens. We will create them in a minute but first convert the functions into a node module.
Change the current folder to zohoAuth folder. Then generate the package.json file.
npm init -y
Check a newly created package.json file. It should have zohoAuth value in the name key. Get back to the functions folder. And create a local node module from the zohoAuth folder.
npm install --save ./zohoAuth
Now your config object points to the module that really exists. If you want to make any changes to the functions in the future do it in the zohoAuth folder inside the functions folder not in the node_modules folder.
Create a new collection
The newly created module refers to a database document and collection that doesn't exist. Let's fix this now!
Go to the Firebase panel and then to the database tab. Create a new collection named zoho and then a new document named tokens (tokens name instead of auto generated id). Newly created documents should have three String empty fields: access token, expires in and refresh token.

Let's make sure that only authorized services and develoipers can read and access tokens data. Go to the rules tab and make the tokens collection inaccessible for reading and writing.

The final result is as follows: the database is accessible for everyone but nobody can make changes to it (this way you can keep public data for your app in the database).

Create a function for serverless authentication
Time to pack all things up into the firebase function which generates access tokens for us. Go to the index.js file and paste the code posted below.
...
exports.renderTokens = functions.https.onRequest((request, response) => {
var grant_token = request.query.grant_token;
// eslint-disable-next-line promise/always-return
ZCRMRestClient.initialize(config).then(function () {
// eslint-disable-next-line promise/always-return
ZCRMRestClient.generateAuthTokens(config.user_identifier, grant_token).then(function (auth_response) {
console.log("access token :" + auth_response.access_token);
console.log("refresh token :" + auth_response.refresh_token);
console.log("expires in :" + auth_response.expires_in);
}).catch(e => {
console.log(e)
});
return response.send('OK')
}).catch(e => {
console.log(e)
})
});
This implementation is really straightforward and uses the SDK to generate tokens. Thanks to zohoAuth functions the process is fully covered. Time to test if the function triggered by i.e Postman generates our tokens correctly. But first deploy your work to the Firebase using the console.
firebase deploy
After deploying there will be shown a Function URL. Copy it and paste it to the Postman. Remember to generate a grant token, if you don't know what it is once again please refer to the previous article for Node.js implementation and get back with the grant token. In the postman make a call and add a key with the name grant_token and paste into the value of your previously generated grant token. The generating process can take a while. Check after a few minutes if the document in the database changed if so you can proceed to test the API using an example call.

Create a lead function
Let's create a second function to check whether our service inserts data to the Zoho CRM. In the index.js add the following function.
// functions/index.js
...
exports.lead = functions.https.onRequest((request, response) => {
// eslint-disable-next-line promise/always-return
ZCRMRestClient.initialize(config).then(function()//Use ZCRMRestClient.initialize(configJson).then(function() for configuration array
{
let input = {}
input.module = 'Leads';
input.body = {
"data": [{
"First_Name": 'My first name',
"Last_Name": 'Last name',
"Email": 'example@example.com',
"Description": 'description',
}]
};
// eslint-disable-next-line promise/always-return
ZCRMRestClient.API.MODULES.post(input).then(function(response){
console.log(response)
}).catch(e => {
return e;
})
console.log(response);
return response.send('OK')
}).catch(e => {
return e;
})
});
Then deploy your code to the firebase and call the URL in the Postman. Check your Zoho CRM account later to see if the lead has been inserted correctly.
Now that you understand how to authenticate and make the Zoho CRM API calls using a serverless environment you can easily expand the basic functionality using other functions. Remember that Postman by default doesn't use CORS so your calls won't be blocked but this can be an issue in your app. In such case you will have to pass proper header allowing executing url from firebase domain.