Source: ZAnalyticsClient.js

/*$Id$*/
const https = require('https');
const fs = require('fs');
const path = require('path');
const querystring = require('querystring');
const request = require('request');
const analyticsURI = "@@REPORTS_URL";
const accountsURI = "@@ACCOUNTS_URL";
let encodedParams;

class ZAnalyticsClient
{
    constructor()
    {
        this.clientId;
        this.clientSecret;
        this.refreshtoken;
        this.accesstoken;
    }
    

    async initialize(clientId, clientSecret, refreshtoken)
    {
        this.clientId = clientId;
        this.clientSecret = clientSecret;
        this.refreshtoken = refreshtoken;
        this.accesstoken = await this.getOauth();
    }
    
    /**
     * Generate Request URI(Either User URI, Workspace URI or View URI) based on the arguments passed.
     * @method getUri
     * @param {String} emailId - EmailId of the user.
     * @param {String} workspaceName=null - Name of the workspace.
     * @param {String} viewName=null - Name of the view.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} User URI       - If emailId alone is passed as param
     *                   Workspace URI  - If emailId and workspaceName are passed as params.
     *                   View URI       - If emailId, workspaceName and viewName are passed as param.
     * @throws {Error} If the request failed due to some error.
     */
    getUri(emailId, workspaceName=null, viewName=null)
    {
        let uri =  "/api/" + encodeURIComponent(emailId);
        if(workspaceName != null)
        {
            uri +=  "/" + encodeURIComponent(workspaceName);
        }
        if(viewName != null)
        {
            uri +=  "/" + encodeURIComponent(viewName);
        }
        return uri;
    }
    
    /**
     * Adds a row to a specific table identified by the URI.
     * @method addRow
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} Column Names and Added Row Values.
     * @throws {Error} If the request failed due to some error.
     */
    async addRow(uriPath, params={}) {
        params.ZOHO_ACTION = 'ADDROW';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }


    /**
     * Delete rows on a specific table identified by the URI.
     * @method deleteData
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} Success Message and Deleted Rows Count.
     * @throws {Error} If the request failed due to some error.
     */
    async deleteData(uriPath, params={}) {
        params.ZOHO_ACTION = 'DELETE';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }


    /**
     * Update data on a specific table identified by the URI.
     * @method updateData
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} Updated Columns List and Updated Rows Count.
     * @throws {Error} If the request failed due to some error.
     */
    async updateData(uriPath, params={}) {
        params.ZOHO_ACTION = 'UPDATE';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }


    /**
     * Import data from a file to a specific table identified by the URI.
     * @method importData
     * @param {String} filepath - local path of the file where data is present.
     * @param {String} importType - The type of import.
            Can be one of
             1. APPEND
             2. TRUNCATEADD
             3. UPDATEADD
     * @param {Boolean} autoIdentify - If set to true, Import type is set to CSV (or) User need to send the 'ZOHO_IMPORT_FILETYPE' in params.
     * @param {String} onImportError - It controls the action to be taken incase there is an error during import.
            Can be one of
             1. ABORT
             2. SKIPROW
             3. SETCOLUMNEMPTY 
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} IMPORT Summary.
     * @throws {Error} If the request failed due to some error.
     */
    async importData(filepath, importType, autoIdentify, onImportError, uriPath, params={}) {
        params.ZOHO_ACTION = 'IMPORT';
        params.ZOHO_IMPORT_TYPE = importType;
        params.ZOHO_AUTO_IDENTIFY = autoIdentify;
        params.ZOHO_ON_IMPORT_ERROR = onImportError;

        var result = await this.handleImportRequest(filepath, uriPath, params);
        return result;
    }


    /**
     * Import data to a specific table identified by the URI.
     * @method importDataAsString
     * @param {String} importContent - holds the data to be imported.
     * @param {String} importType - The type of import.
            Can be one of
             1. APPEND
             2. TRUNCATEADD
             3. UPDATEADD
     * @param {Boolean} autoIdentify - If set to true, Import type is set to CSV (or) User need to send the 'ZOHO_IMPORT_FILETYPE' in params.
     * @param {String} onImportError - It controls the action to be taken incase there is an error during import.
            Can be one of
             1. ABORT
             2. SKIPROW
             3. SETCOLUMNEMPTY 
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} IMPORT Summary.
     * @throws {Error} If the request failed due to some error.
     */
    async importDataAsString(importContent, importType, autoIdentify, onImportError, uriPath, params={}) {
        params.ZOHO_ACTION = 'IMPORT';
        params.ZOHO_IMPORT_TYPE = importType;
        params.ZOHO_AUTO_IDENTIFY = autoIdentify;
        params.ZOHO_ON_IMPORT_ERROR = onImportError;

        params.ZOHO_IMPORT_DATA = importContent;

        if(params.ZOHO_CREATE_TABLE == null)
        {
          params.ZOHO_CREATE_TABLE = false;
        }


        var result = await this.handleRequest(uriPath, params);
        return result;
    }


    /**
     * Export data from a specific table identified by the URI.
     * @method exportData
     * @param {String} outputFormat - local path of the file where data is present.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Data in Specified output format.
     * @throws {Error} If the request failed due to some error.
     */
    async exportData(outputFormat, uriPath, params={}) {
        params.ZOHO_ACTION = 'EXPORT';
        params.ZOHO_OUTPUT_FORMAT = outputFormat;
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    
    /**
     * Get workspace/reports meta information.
     * @method getWorkspaceMetadata
     * @param {String} metadataType - Type of meta information.
            Can be one of
             1. ZOHO_CATALOG_LIST
             2. ZOHO_CATALOG_INFO
             3. ZOHO_DATATYPES
             4. ZOHO_TABLETYPES
     * @param {String} uriPath - Workspace URI (or) View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} Metadata of the workspace.
     * @throws {Error} If the request failed due to some error.
     */
    async getWorkspaceMetadata(metadataType, uriPath, params={}) {
        params.ZOHO_ACTION = 'DATABASEMETADATA';
        params.ZOHO_METADATA = metadataType;
        var result = await this.handleRequest(uriPath, params);
        return result;
    }
    
    /**
     * Get the list of all owned workspaces present in the ZohoAnalytics account identified by the URI.
     * @method myWorkspaceList
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} list of owned workspaces.
     * @throws {Error} If the request failed due to some error.
     */
    async myWorkspaceList(uriPath, params={}) {
        params.ZOHO_ACTION = 'MYWORKSPACELIST';
        var result = await this.handleRequest(uriPath, params);
        return result; 
    }
    
    /**
     * Get the list of all shared workspaces present in the ZohoAnalytics account identified by the URI.
     * @method sharedWorkspaceList
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} list of shared workspaces.
     * @throws {Error} If the request failed due to some error.
     */
    async sharedWorkspaceList(uriPath, params={}) {
        params.ZOHO_ACTION = 'SHAREDWORKSPACELIST';
        var result = await this.handleRequest(uriPath, params);
        return result; 
    }
    
    /**
     * Get the list of all available folders present in the workspace identified by the URI.
     * @method folderList
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} list of available folders.
     * @throws {Error} If the request failed due to some error.
     */
    async folderList(uriPath, params={}) {
        params.ZOHO_ACTION = 'FOLDERLIST';
        var result = await this.handleRequest(uriPath, params);
        return result; 
    }
    
    /**
     * Get the list of all available views present in the workspace identified by the URI.
     * @method viewList
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} list of available views.
     * @throws {Error} If the request failed due to some error.
     */
    async viewList(uriPath, params={}) {
        params.ZOHO_ACTION = 'VIEWLIST';
        var result = await this.handleRequest(uriPath, params);
        return result; 
    }

    /**
     * Get the name of workspace for the provided workspaceId.
     * @method getWorkspaceName
     * @param {String} workspaceId - Id of the workspace.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Name of the workspace.
     * @throws {Error} If the request failed due to some error.
     */
    async getWorkspaceName(workspaceId, uriPath, params={}) {
        params.ZOHO_ACTION = 'GETDATABASENAME';
        params.DBID = workspaceId;
        var result = await this.handleRequest(uriPath, params);
        return result.dbname; 
    }

    /**
     * Fetch the ID of provided workspace name.
     * @method getWorkspaceID
     * @param {String} workspaceName - name of the workspace.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Long} ID of the workspace.
     * @throws {Error} If the request failed due to some error.
     */
    async getWorkspaceID(workspaceName, uriPath, params={}) {
        params.ZOHO_ACTION = 'GETDATABASEID';
        params.ZOHO_DATABASE_NAME = workspaceName;
        var result = await this.handleRequest(uriPath, params);
        return result.dbid;
    }


    /**
     * Checks whether the workspace exist or not in the ZohoAnalytics account identified by URI.
     * @method isWorkspaceExist
     * @param {String} workspaceName - name of the workspace.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Boolean} 'true' if workspace exist 'false' otherwise.
     * @throws {Error} If the request failed due to some error.
     */
    async isWorkspaceExist(workspaceName, uriPath, params={}) {
        params.ZOHO_ACTION = 'ISDBEXIST';
        params.ZOHO_DB_NAME = workspaceName;
        var result = await this.handleRequest(uriPath, params);
        return result.isdbexist;
    }

    /**
     * Get copy workspace key for specified workspace identified by the URI.
     * @method getCopyDBKey
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} copy workspace key.
     * @throws {Error} If the request failed due to some error.
     */
    async getCopyDBKey(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETCOPYDBKEY';
        var result = await this.handleRequest(uriPath, params);
        return result.copydbkey;
    }

    /**
     * Fetch name of the view for the given view id.
     * @method getViewName
     * @param {String} viewId - name of the workspace.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} The View name.
     * @throws {Error} If the request failed due to some error.
     */
    async getViewName(viewId, uriPath, params={}) {
        params.ZOHO_ACTION = 'GETVIEWNAME';
        params.OBJID = viewId;
        var result = await this.handleRequest(uriPath, params);
        return result.viewname;
    }

    /**
     * Checks whether the view exist or not in the workspace identified by URI.
     * @method isViewExist
     * @param {String} viewName - name of the view.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Boolean} 'true' if view exist 'false' otherwise.
     * @throws {Error} If the request failed due to some error.
     */
    async isViewExist(viewName, uriPath, params={}) {
        params.ZOHO_ACTION = 'ISVIEWEXIST';
        params.ZOHO_VIEW_NAME = viewName;
        var result = await this.handleRequest(uriPath, params);
        return result.isviewexist;
    }

    /**
     * Checks whether the column exist or not in the view identified by URI.
     * @method isColumnExist
     * @param {String} columnName - name of the column.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Boolean} 'true' if column exist 'false' otherwise.
     * @throws {Error} If the request failed due to some error.
     */
    async isColumnExist(columnName, uriPath, params={}) {
        params.ZOHO_ACTION = 'ISCOLUMNEXIST';
        params.ZOHO_COLUMN_NAME = columnName;
        var result = await this.handleRequest(uriPath, params);
        return result.iscolumnexist;
    }
        
    /**
     * Gets the workspace ID (DBID) and View ID (OBJID) of the corresponding workspace.
     * @method getInfo
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} workspace id(DBID) and view id(OBJID).
     * @throws {Error} If the request failed due to some error.
     */
    async getInfo(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETINFO';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Fetch view details like view name,description,type from the the particular workspace identified by Workspace URI.
     * @method getViewInfo
     * @param {Long} viewId - Id of view for which info is needed.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} The meta information of the view.
     * @throws {Error} If the request failed due to some error.
     */
    async getViewInfo(viewId, uriPath, params={}) {
        params.ZOHO_ACTION = 'GETVIEWINFO';
        params.ZOHO_VIEW_ID = viewId;
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Get the details of recently accessed views from the ZohoAnalytics account identified by the URI.
     * @method recentItems
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} Recently modified views.
     * @throws {Error} If the request failed due to some error.
     */
    async recentItems(uriPath, params={}) {
        params.ZOHO_ACTION = 'RECENTITEMS';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Get the list of owned/shared dashboards present in the ZohoAnalytics account identified by the URI.
     * @method getDashboards
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} The list of dashboards present in the organization.
     * @throws {Error} If the request failed due to some error.
     */
    async getDashboards(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETDASHBOARDS';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Returns metainfo of the given view identified by the URI.
     * @method viewMetadata
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} metainfo of the view.
     * @throws {Error} If the request failed due to some error.
     */
    async viewMetadata(uriPath, params={}) {
        params.ZOHO_ACTION = 'VIEWMETADATA';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Create a blank workspace.
     * @method createWorkspace
     * @param {String} newWorkspaceName - Name of the workspace to be created.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Long} Newly created workspace id.
     * @throws {Error} If the request failed due to some error.
     */
    async createWorkspace(newWorkspaceName, uriPath, params={}) {
        params.ZOHO_DATABASE_NAME = newWorkspaceName;
        params.ZOHO_ACTION = 'CREATEBLANKDB';
        var result = await this.handleRequest(uriPath, params);
        return result.dbid;
    }

    /**
     * Copy a specific workspace identified by the URI.
     * @method copyWorkspace
     * @param {String} newWorkspaceName - Name of the workspace to be created.
     * @param {String} copydbkey - The key generated by GETCOPYDBKEY action for the source workspace.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Long} Copied workspace id.
     * @throws {Error} If the request failed due to some error.
     */
    async copyWorkspace(newWorkspaceName, copydbkey, uriPath, params={}) {
        params.ZOHO_DATABASE_NAME = newWorkspaceName;
        params.ZOHO_COPY_DB_KEY = copydbkey;
        params.ZOHO_ACTION = 'COPYDATABASE';
        var result = await this.handleRequest(uriPath, params);
        return result.dbid;
    }

    /**
     * Deletes a specific workspace.
     * @method deleteWorkspace
     * @param {String} workspaceName - Name of the workspace to be deleted.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async deleteWorkspace(workspaceName, uriPath, params={}) {
        params.ZOHO_DATABASE_NAME = workspaceName;
        params.ZOHO_ACTION = 'DELETEDATABASE';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Enable a workspace for custom domain.
     * @method enableDomainWorkspace
     * @param {String} workspaceName - Name of the workspace to be enabled for custom domain.
     * @param {String} domainName - Name of the custom domain for which the workspace has to be enabled.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async enableDomainWorkspace(workspaceName, domainName, uriPath, params={}) {
        params.DBNAME = workspaceName;
        params.DOMAINNAME = domainName;
        params.ZOHO_ACTION = 'ENABLEDOMAINDB';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }


    /**
     * Disable a workspace for custom domain.
     * @method disableDomainWorkspace
     * @param {String} workspaceName - Name of the workspace to be disabled for custom domain.
     * @param {String} domainName - Name of the custom domain for which the workspace has to be disabled.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async disableDomainWorkspace(workspaceName, domainName, uriPath, params={}) {
        params.DBNAME = workspaceName;
        params.DOMAINNAME = domainName;
        params.ZOHO_ACTION = 'DISABLEDOMAINDB';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Creates a table using the given configuration.
     * @method createTable
     * @param {String} config - Table Configuration.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async createTable(config, uriPath, params={}) {
        params.ZOHO_TABLE_DESIGN = config;
        params.ZOHO_ACTION = 'CREATETABLE';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Add a new column on the table identified by the URI.
     * @method addColumn
     * @param {String} columnName - Name of the column to be created.
     * @param {String} columnType - Type of the column to be created.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async addColumn(columnName, columnType, uriPath, params={}) {
        params.ZOHO_COLUMNNAME = columnName;
        params.ZOHO_DATATYPE = columnType;
        params.ZOHO_ACTION = 'ADDCOLUMN';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Delete a column from the table identified by the URI.
     * @method deleteColumn
     * @param {String} columnName - Name of the column to be deleted.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async deleteColumn(columnName, uriPath, params={}) {
        params.ZOHO_ACTION = 'DELETECOLUMN';
        params.ZOHO_COLUMNNAME = columnName;
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Rename a column with new name from the table identified by the URI.
     * @method renameColumn
     * @param {String} oldColumnName - Name of the column to be renamed.
     * @param {String} newColumnName - New Name of the column.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async renameColumn(oldColumnName, newColumnName, uriPath, params={}) {
        params.OLDCOLUMNNAME = oldColumnName;
        params.NEWCOLUMNNAME = newColumnName;
        params.ZOHO_ACTION = 'RENAMECOLUMN';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Hide columns on the table identified by the URI.
     * @method hideColumn
     * @param {String} columnNames - List of column names to be hide.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async hideColumn(columnNames, uriPath, params={}) {
        params.ZOHO_ACTION = 'HIDECOLUMN';
        params.ZOHO_COLUMNNAME = columnNames;
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Unhide columns from the table identified by the URI.
     * @method showColumn
     * @param {String} columnNames - List of column names to be unhide.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async showColumn(columnNames, uriPath, params={}) {
        params.ZOHO_ACTION = 'SHOWCOLUMN';
        params.ZOHO_COLUMNNAME = columnNames;
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Generate reports for the particular table or column.
     * @method autoGenReports
     * @param {String} source - Source should be column or table..
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async autoGenReports(source, uriPath, params={}) {
        params.ZOHO_SOURCE = source;
        params.ZOHO_ACTION = 'AUTOGENREPORTS';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Create a new view by copying the structure and data of existing view.
     * @method saveAs
     * @param {String} viewToCopy - Source view to be copied.
     * @param {String} newViewName - Name of the view to be created.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async saveAs(viewToCopy, newViewName, uriPath, params={}) {
        params.ZOHO_VIEWTOCOPY = viewToCopy;
        params.ZOHO_NEW_VIEWNAME = newViewName;
        params.ZOHO_ACTION = 'SAVEAS';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Generate reports from the table identified by the URI based on the reference table views.
     * @method createSimilarViews
     * @param {String} referenceView - Source view to be copied.
     * @param {String} folderName - Name of the view to be created.
     * @param {String} copyCustomFormula - Source view to be copied.
     * @param {String} copyAggregateFormula - Name of the view to be created.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async createSimilarViews(referenceView, folderName, copyCustomFormula, copyAggregateFormula, uriPath, params={}) {
        params.ZOHO_REFVIEW = referenceView;
        params.ZOHO_FOLDERNAME = folderName;
        params.ISCOPYCUSTOMFORMULA = copyCustomFormula;
        params.ISCOPYAGGFORMULA = copyAggregateFormula;
        params.ZOHO_ACTION = 'CREATESIMILARVIEWS';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Delete a table or report from the workspace identified by the URI.
     * @method deleteView
     * @param {String} viewName - Name of the view to be deleted.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async deleteView(viewName, uriPath, params={}) {
        params.ZOHO_VIEW = viewName;
        params.ZOHO_ACTION = 'DELETEVIEW';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Rename a table or report with a new name from the workspace identified by the URI.
     * @method renameView
     * @param {String} oldViewName - Name of the view to be renamed.
     * @param {String} newViewName - New name of the view.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async renameView(oldViewName, newViewName, uriPath, params={}) {
        params.ZOHO_VIEWNAME = oldViewName;
        params.ZOHO_NEW_VIEWNAME = newViewName;
        params.ZOHO_ACTION = 'RENAMEVIEW';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Copy one or more reports from one workspace to another within the same account or even across user accounts.
     * @method copyReports
     * @param {String} viewNames - Comma seperated view names to be copied.
     * @param {String} destWorkspaceName - Name of the desctination workspace.
     * @param {String} copydbkey - The key generated by GETCOPYDBKEY action for the source workspace.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async copyReports(viewNames, destWorkspaceName, copydbkey, uriPath, params={}) {
        params.ZOHO_VIEWTOCOPY = viewNames;
        params.ZOHO_DATABASE_NAME = destWorkspaceName;
        params.ZOHO_COPY_DB_KEY = copydbkey;
        params.ZOHO_ACTION = 'COPYREPORTS';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Copy one or more formula from one view to another within the same account or even across user accounts.
     * @method copyFormula
     * @param {String} formulaNames - Comma seperated formula names to be copied.
     * @param {String} destWorkspaceName - Name of the desctination workspace.
     * @param {String} copydbkey - The key generated by GETCOPYDBKEY action for the source workspace.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async copyFormula(formulaNames, destWorkspaceName, copydbkey, uriPath, params={}) {
        params.ZOHO_FORMULATOCOPY = formulaNames;
        params.ZOHO_DATABASE_NAME = destWorkspaceName;
        params.ZOHO_COPY_DB_KEY = copydbkey;
        params.ZOHO_ACTION = 'COPYFORMULA';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Add lookup in a specific child table.
     * @method addLookup
     * @param {String} columnName - Name of the column (Child column).
     * @param {String} referedTable - Name of the referred table (parent table).
     * @param {String} referedColumn - Name of the referred column (parent column).
     * @param {String} onError - This parameter controls the action to be taken In-case there is an error during lookup.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async addLookup(columnName, referedTable, referedColumn, onError, uriPath, params={}) {
        params.ZOHO_COLUMNNAME = columnName;
        params.ZOHO_REFERREDTABLE = referedTable;
        params.ZOHO_REFERREDCOLUMN = referedColumn;
        params.ZOHO_IFERRORONCONVERSION = onError;
        params.ZOHO_ACTION = 'ADDLOOKUP';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Remove the lookup for the given column.
     * @method removeLookup
     * @param {String} columnName - Name of the column for which lookup has to removed.
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async removeLookup(columnName, uriPath, params={}) {
        params.ZOHO_COLUMNNAME = columnName;
        params.ZOHO_ACTION = 'REMOVELOOKUP';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Updates cloud connection information of the given view identified by the URI.
     * @method updateCloudDBConnection
     * @param {String} uriPath - View URI.
     * @param {Object} config={} - Contains required details to construct the slide url.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async updateCloudDBConnection(uriPath, config={}, params={}) {
        params.ZOHO_ACTION = 'UPDATECLOUDDBCONNECTION';
        
        if((Object.keys(config).length) > 0)
        {
            params.ZOHO_CONNECTION_INFO = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Updates cloud connection information of the given live connect workspace identified by the URI.
     * @method updateRemoteDBConnection
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to construct the slide url.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async updateRemoteDBConnection(uriPath, config={}, params={}) {
        params.ZOHO_ACTION = 'UPDATEREMOTEDBCONNECTION';
        
        if((Object.keys(config).length) > 0)
        {
            params.ZOHO_CONNECTION_INFO = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Share the created views with users and also can update sharing permission granted.
     * @method shareViews
     * @param {String} viewNames - Comma seperated name of the views to be shared.
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async shareViews(viewNames, emailIds, uriPath, params={}) {
        params.ZOHO_VIEWS = viewNames;
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'SHARE';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Revoke permissions for the shared users.
     * @method removeShare
     * @param {String} emailIds - Comma seperated emailid of users, whose permission to be revoked.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async removeShare(emailIds, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'REMOVESHARE';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Grant admin permission to users for a specific workspace identified by the URI.
     * @method addWorkspaceAdmin
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async addWorkspaceAdmin(emailIds, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;  
        params.ZOHO_ACTION = 'ADDDBOWNER';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Revoke admin users for a specific workspace identified by the URI.
     * @method removeWorkspaceAdmin
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async removeWorkspaceAdmin(emailIds, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'REMOVEDBOWNER';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Fetch share info for a specific workspace identified by the URI.
     * @method getShareInfo
     * @param {String} uriPath - Workspace URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} Sharing details of the workspace.
     * @throws {Error} If the request failed due to some error.
     */
    async getShareInfo(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETSHAREINFO';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }
    
    /**
     * Fetch the meta information of groups present in the workspace identified by the URI.
     * @method getShareInfo
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains any additional control parameters.
     * @returns {Object} Meta information of groups present in the workspace.
     * @throws {Error} If the request failed due to some error.
     */
    async groupInfo(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'GROUPINFO';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        
        var result = await this.handleRequest(uriPath, params);
        return result;
    }
    
    /**
     * Create a new group in the workspace identified by the URI.
     * @method createGroup
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to create the group.
     * @returns {Long} Newly created group id.
     * @throws {Error} If the request failed due to some error.
     */
    async createGroup(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'CREATEGROUP';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result.groupId;
    }
    
    /**
     * Deletes groups from the workspace identified by the URI.
     * @method deleteGroup
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to delete groups.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async deleteGroup(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'DELETEGROUP';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }
    
    /**
     * Updates the specified group information present in the workspace identified by the URI.
     * @method updateGroupInfo
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains details on the group which has to be updated.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async updateGroupInfo(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'UPDATEGROUPINFO';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }
    
    /**
     * Add new members for the specified group present in the workspace identified by the URI.
     * @method addGroupMembers
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains the required information to add members into the group.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async addGroupMembers(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'ADDGROUPMEMBERS';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }
    
    /**
     * Remove members from the specified group present in the workspace identified by the URI.
     * @method removeGroupMembers
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains the required information to remove members from the group.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async removeGroupMembers(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'REMOVEGROUPMEMBERS';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Fetch users list for a specific account identified by the URI.
     * @method getUsers
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {JSONArray} User list information.
     * @throws {Error} If the request failed due to some error.
     */
    async getUsers(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETUSERS';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Add users to a specific account identified by the URI.
     * @method addUsers
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async addUsers(emailIds, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'ADDUSER';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Remove users from a specific account identified by the URI.
     * @method removeUsers
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async removeUsers(emailIds, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'REMOVEUSER';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }
    
    /**
     * Change the role of specified users with the new role provided.
     * @method changeUserRole
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} role - New role for the users. can be one of "ORGADMIN"/"USER".
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async changeUserRole(emailIds, role, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'CHANGEUSERROLE';
        params.ROLE = role;
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Activate users on a specific account identified by the URI.
     * @method activateUsers
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async activateUsers(emailIds, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'ACTIVATEUSER';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }


    /**
     * Deactivate users on a specific account identified by the URI.
     * @method deActivateUsers
     * @param {String} emailIds - Comma seperated emailid of users.
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async deActivateUsers(emailIds, uriPath, params={}) {
        params.ZOHO_EMAILS = emailIds;
        params.ZOHO_ACTION = 'DEACTIVATEUSER';
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    /**
     * Fetch the user plan info.
     * @method getPlanInfo
     * @param {String} uriPath - User URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {Object} User plan info.
     * @throws {Error} If the request failed due to some error.
     */
    async getPlanInfo(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETUSERPLANDETAILS';
        var result = await this.handleRequest(uriPath, params);
        return result;
    }

    /**
     * Get the standalone url to access a specific view identified by the URI.
     * @method getViewUrl
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Access URL for the view.
     * @throws {Error} If the request failed due to some error.
     */
    async getViewUrl(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETVIEWURL';
        var result = await this.handleRequest(uriPath, params);
        return result.viewurl;
    }

    /**
     * Get the embed url of a specific view identified by the URI. This API is available only for the White Label Administrator.
     * @method getEmbedUrl
     * @param {String} uriPath - View URI.
     * @param {Object} params={} - Contains any additional control parameters.
     * @returns {String} Embed URL for the view.
     * @throws {Error} If the request failed due to some error.
     */
    async getEmbedUrl(uriPath, params={}) {
        params.ZOHO_ACTION = 'GETEMBEDURL';
        var result = await this.handleRequest(uriPath, params);
        return result.embedurl;
    }
    
    /**
     * Get the list of all available slideshow present in the workspace identified by the URI.
     * @method getSlideList
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains any additional control parameters.
     * @returns {Object} Object having list of slideshows present in the workspace.
     * @throws {Error} If the request failed due to some error.
     */
    async getSlideList(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'GETSLIDELIST';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result;
    }
    
    /**
     * Get the meta-information of the provided slide present in the workspace identified by the URI.
     * @method getSlideInfo
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to get slideinfo.
     * @returns {Object} Object having meta-information of the provided slideshow.
     * @throws {Error} If the request failed due to some error.
     */
    async getSlideInfo(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'GETSLIDEINFO';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result;
    }
    
    /**
     * Get the URL to access the mentioned slide present in the workspace identified by the URI.
     * @method getSlideUrl
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to construct the slide url.
     * @returns {String} Access url of the slideshow.
     * @throws {Error} If the request failed due to some error.
     */
    async getSlideUrl(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'GETSLIDEURL';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result.slideUrl;
    }
    
    /**
     * Create a new slideshow in the workspace identified by the URI.
     * @method createSlideShow
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to create the slideshow.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async createSlideShow(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'CREATESLIDESHOW';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }
    
    /**
     * Update the mentioned slide information present in the workspace identified by the URI.
     * @method updateSlideShow
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to update the slideshow.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async updateSlideShow(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'UPDATESLIDESHOW';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }
    
    /**
     * Delete the mentioned slides present in the workspace identified by the URI.
     * @method deleteSlideShow
     * @param {String} uriPath - Workspace URI.
     * @param {Object} config={} - Contains required details to delete slideshows.
     * @returns {String} Success Message.
     * @throws {Error} If the request failed due to some error.
     */
    async deleteSlideShow(uriPath, config={}) {
        var params={};
        params.ZOHO_ACTION = 'DELETESLIDESHOW';
        
        if((Object.keys(config).length) > 0)
        {
            params.CONFIG = JSON.stringify(config);
        }
        var result = await this.handleRequest(uriPath, params);
        return result.message;
    }

    addQueryParams(params) 
    {
        let urlParams='';
        for (var key in params)
        {
            if(params[key] instanceof Array)
            {
                var array = params[key];
                for(var i in array)
                {
                    urlParams+= '&'+key+'='+encodeURIComponent(array[i]);
                }
                delete params[key];
            }
        }
        if(urlParams.length==0)
        {
            return querystring.stringify(params);
        }
        else
        {
            return querystring.stringify(params)+urlParams;
        }
    }

    async handleRequest(uriPath, params)
    {
        return await this.sendRequest(uriPath, params).catch(async error=>
        {
            if(error.code == "8535")
            {
                this.accesstoken = await this.getOauth();
                return await this.sendRequest(uriPath, params);
            }
            else
            {
                throw error;
            }
        });
    }
    
        sendRequest(uriPath, params){
            var action = params.ZOHO_ACTION;
            if(action != 'EXPORT')
            {
              params.ZOHO_OUTPUT_FORMAT= 'JSON';
            }
          params.ZOHO_ERROR_FORMAT= 'JSON';
          params.ZOHO_API_VERSION= '1.0';
          params.ZOHO_VALID_JSON= true;

          var header = {'User-Agent':'ZohoAnalytics NodeJS Library','Content-Type':'application/x-www-form-urlencoded'};
          header.Authorization = "Zoho-oauthtoken " + this.accesstoken;

          encodedParams = this.addQueryParams(params);
          var contentLength = 'Content-Length';
          header[contentLength] = encodedParams.length;
          var options = {
            host: analyticsURI,
            path: uriPath,
            headers: header,
            method: "POST",
            secureProtocol: 'TLSv1_2_method'
          };
        return new Promise(function(resolve, reject) {
          var req = https.request(options, (resp) => {
          let data = '';
            resp.on('data', (chunk) => {
            data += chunk;
            });

            resp.on('end', () => {

              var respJSON;
              if(resp.statusCode !=200)
              {
                respJSON = (JSON.parse(data)).response;
                reject(respJSON.error)
              }

              if(action == 'EXPORT')
              {
                resolve(data);
              }
              else
              {
                respJSON = (JSON.parse(data)).response;
                resolve(respJSON.result);
              }

            });
          }).on("error", (err) => {
            reject(JSON.parse(err))
          });
          req.write(encodedParams);
          req.end();

          });
        }


    async handleImportRequest(filepath, uriPath, params)
    {
        return await this.sendImportRequest(filepath, uriPath, params).catch(async error=>
        {
            if(error.code == "8535")
            {
                this.accesstoken = await this.getOauth();
                return await this.sendImportRequest(filepath, uriPath, params);
            }
            else
            {
                throw error;
            }
        });
    }

        sendImportRequest(filepath, uriPath, params){
          

          var headers = {'Content-Type': 'multipart/form-data','User-Agent':'ZohoAnalytics NodeJS Library'};

          params.ZOHO_OUTPUT_FORMAT= 'JSON';
          params.ZOHO_ERROR_FORMAT= 'JSON';
          params.ZOHO_API_VERSION= '1.0';
          params.ZOHO_VALID_JSON= true;
          if(params.ZOHO_CREATE_TABLE == null)
          {
            params.ZOHO_CREATE_TABLE = false;
          }

          headers.Authorization = "Zoho-oauthtoken " + this.accesstoken;

          encodedParams = querystring.stringify(params);

          return new Promise(function(resolve, reject) {

                var zohofile = fs.createReadStream(filepath);
                zohofile.on('error', err =>{reject(err);});
                zohofile.once('readable', function() {

                let formData = {  
                  'ZOHO_FILE': zohofile
                };


                var url = 'https://'+analyticsURI+uriPath+'?'+encodedParams;
                var req = request.post({url:url,headers:headers,formData: formData,secureProtocol: 'TLSv1_2_method'}, (err, resp, body)=> {
                if (err) {
                  reject(JSON.parse(err));  
                } else {
                    let respJSON = (JSON.parse(body)).response;
                    if(resp.statusCode!==200)
                    {
                        reject(respJSON.error)
                    }
                    else
                    {
                        resolve(respJSON.result);
                    }
                }
              });
              });
        
          });
    
    }
    
    
    getOauth() 
    {
        
            var oauthinfo = {};
            oauthinfo.client_id= this.clientId;
            oauthinfo.client_secret= this.clientSecret;
            oauthinfo.refresh_token= this.refreshtoken;
            oauthinfo.grant_type= 'refresh_token';

            encodedParams = querystring.stringify(oauthinfo);
            var options = {
              host: accountsURI,
              path: '/oauth/v2/token',
              headers: {
              'Content-Type': 'application/x-www-form-urlencoded',
              'User-Agent': 'ZohoAnalytics NodeJS Library',
              'Content-Length': encodedParams.length
              },
              method: "POST",
              secureProtocol: 'TLSv1_2_method'
            };
            
            return new Promise(function(resolve, reject) {
                
                var req = https.request(options, (resp) => {
                let data = '';
                // A chunk of data has been recieved.
                resp.on('data', (chunk) => {
                  data += chunk;
                });

                  // The whole response has been received. Print out the result.
                  resp.on('end', () => {
                  var respJSON = (JSON.parse(data));

                  if(!respJSON.error)
                  {
                    resolve(respJSON.access_token);
                  }
                  else
                  {
                    reject(respJSON.error);
                  }

                  });

                }).on("error", (err) => {
                  reject(err.message);
                });
                req.write(encodedParams);
                req.end();

        });
    }
  
};

module.exports = new ZAnalyticsClient();