Why Integrate?

With so many web applications floating around in the modern tech industry ether, it has become a difficult—and quite critical—process to identify and utilize the best ones for integration in your project. Some of the most useful applications are CRM integrations, payment integrations, video and chatting, and those that enable your app to connect with others in the same industry (such as Eventbrite integrations).

Writing your own wrapper for Zoho

Over here at Fyresite, we recently integrated two large applications into our latest project, AcmeLift. The Rental Results application had modules/gems ready to go, while Zoho was lacking in this area and we needed to write our own wrapper.

By exploring both of these routes (with modules/gems and without) simultaneously in the same project, we became privy to the pros and cons to each. When using another’s code for integration, you will need to heavily rely on what they have written with little flexibility. This can provide a great jumping-off point and crutch to fall back on, but also limits the scope of what you can accomplish with the project due to limitations in the code.

With AcmeLift in particular, we were using both Zoho and Rental Results to communicate with our website. All sites, including Fyresite’s, shared similar IDs that are used to look up important information.

Initially, we thought it would be useful and timesaving to include the node. Zoho module into our project. Little did we know the number of limitations that this module would have. Because this project involved numerous custom models created by our client, the Node Package was not capable of meeting our rigid requirements.

Due to this issue, we spent some time changing our current code to only use our Zoho API Wrapper. After looking into what it would take to create this wrapper, it became apparent that this would be the simplest option and we found it easy to implement.

For those interested in what we put together, the following code snippet will allow you to use any CRM call in Zoho, with the exception of file and photo uploading. Zoho’s support for uploading isn’t very straight forward, and we had to come up with a way to insert attachments into our Zoho Modules.

static URL(options) {
    var url = "https://crm.zoho.com/crm/private/json/"+options.object+"/"+options.actions+
    // If options has an object_id or attachment attached to the object we want to add
    if(options.query){url += "&"+options.query};
    if(options.object_id){url += "&id="+options.object_id};
    if(options.attachment){url += "&content="+options.attachment}
    return url;

static ZohoAPIWrapper(options){
        if(!options.query && options.json){ options.query = this.jsonToXML(options) };
        var url = this.URL(options);
        return fetch(url)
            if (response.status == 414) {
                return response.text()
            return response.json();
            return json.response;
            console.log("Error in handling Zoho Request");
            return false;
        return false;

// When the APIWrapper notices an attachment object this method is called to turn the attachment into a fileinputstream
static fileToStreamData(attachment){
    return AttachmentString(options)

// JSON to XML is used for Update/Insert records. Zoho only accepts XML Data so JSON has to be turned into XMl.
// This is a specially created method for the ZohoAPIWrapper. 
// <FL val> = (field level value) = Key
// The method can take both JSON as an object or JSON as an array.
// All products sent should be the same - This is the Zoho way of doing it.
static jsonToXML(options){
    // If the object is an array!
    var xml="xmlData=";
        // Start XML tags
        xml += "<"+options.object+">";
        // Loop through the objects
        for (var i = 0; i < options.length; i++) {
            // Open up row and give the row a number
            xml+="<row no='"+(i+1)+"'>";
            // loop through keys, and place Field Level Values with keys
            // Close Row
            xml +="</row>";
        // Log for Testing purpose
        // Close XML tag
        xml+= "</"+options.object+">"
        xml += "<"+options.object+"><row no='1'>"
        xml+=this.keysToXML(options.json) + "</row></"+options.object+">"
    return xml;

static keysToXML(dictionary){
    // loop through keys, and place Field Level Values with keys
    var stringToReturn = "";
    for(var key in dictionary) {
        if(dictionary.hasOwnProperty(key)) {
            stringToReturn+="<FL val='"+key+"'>"+dictionary[key]+"</FL>";
    return stringToReturn;


The main method here is the Zoho API Wrapper. The first line in this code checks to make sure there is a query variable. If there is no query key value pair, but instead a JSON key value pair, we send it directly to JSONToXML— which does exactly what you would expect. The returned XML has the required Zoho fields and values. After this method is complete, we are then ready to build the URL with the modified options variable.

Not every call needs and XML to JSON conversion, just the ones that require uploading information. GET routes only need criteria and ID.


Next, we identified the base URL for the project and found that the API calls were per individual module. This API Wrapper is less complex and can handle almost everything in the Zoho CRM. It’s worth noting that things become a bit more complex when sending attachments and files. We attempted to make the code as simple as possible by creating a variable that returns an attachmentString. By using Zoho, and not other wrappers, it was possible to add our data to the custom modules. Should you need help with one of your own Zoho integrations, please don’t hesitate to give us a call.