Skip to content

dragonxsx/zoho-desk-nodejs-sdk

Repository files navigation

@banana.inc/zoho-desk-nodejs-sdk

npm version Node.js TypeScript License: MIT

A comprehensive, type-safe TypeScript SDK for the Zoho Desk API with OAuth 2.0, multi-data-center support, and token persistence.

Philosophy

This SDK is built on four core principles:

  • Spec-driven — API clients are auto-generated from Zoho's official OpenAPI specs using Microsoft Kiota. Every endpoint, model, and parameter stays in sync with the source of truth. No hand-written API wrappers to maintain or fall out of date.

  • Type-safe by default — Strict TypeScript throughout. Builder patterns for fluent, discoverable configuration. Full autocompletion and compile-time validation so issues surface in your editor, not at runtime.

  • Batteries-included but extensible — Ships with sensible defaults (file-based token store, configurable logging, proxy support) while keeping every component pluggable. Swap in your own token store, adjust SDK behavior, or route through a corporate proxy — all through clean interfaces.

  • Modern ESM stack — ESM-only with ES2022 target and NodeNext module resolution. No CommonJS baggage, no dual-package hazards. Designed for the Node.js ecosystem as it is today.

Features

  • 126 API modules auto-generated from official Zoho Desk OpenAPI specs
  • OAuth 2.0 with 7 grant types: refresh token, authorization code, client credentials, device code, implicit, direct access token, and stored token
  • PKCE support (RFC 7636) for secure public client flows
  • Authorization URL builder for constructing OAuth consent screens
  • Device authorization flow for headless/IoT devices
  • Automatic token refresh with 5-second expiry buffer
  • 7-region data center support — US, EU, IN, AU, CA, CN, JP
  • Pluggable token persistence with built-in CSV file store
  • Structured error handling with ZohoApiError and SDKException
  • Automatic retry with configurable max retries and delay
  • HTTP proxy support via undici ProxyAgent
  • Configurable logging powered by Winston
  • Lazy-loaded API clients for minimal startup overhead
  • TypeScript strict mode with full declaration maps

Installation

npm install @banana.inc/zoho-desk-nodejs-sdk

Requires Node.js >= 18. This package is ESM-only ("type": "module").

Quick Start

import {
  InitializeBuilder,
  OAuthBuilder,
  USDataCenter,
  FileStore,
  createDeskClient,
} from "@banana.inc/zoho-desk-nodejs-sdk";

// 1. Build the OAuth token
const token = new OAuthBuilder()
  .clientId("your-client-id")
  .clientSecret("your-client-secret")
  .refreshToken("your-refresh-token")
  .build();

// 2. Initialize the SDK
await new InitializeBuilder()
  .environment(USDataCenter.PRODUCTION())
  .token(token)
  .store(new FileStore("./tokens.csv"))
  .initialize();

// 3. Create the client and call APIs
const client = createDeskClient();
const tickets = await client.tickets.get();

Authentication

The SDK supports seven OAuth grant types through OAuthBuilder:

Refresh Token

For server-side applications with long-lived access.

const token = new OAuthBuilder()
  .clientId("your-client-id")
  .clientSecret("your-client-secret")
  .refreshToken("your-refresh-token")
  .build();

Grant Token (Authorization Code)

For exchanging a one-time authorization code for tokens.

const token = new OAuthBuilder()
  .clientId("your-client-id")
  .clientSecret("your-client-secret")
  .grantToken("your-grant-token")
  .redirectURL("https://your-app.com/callback")
  .build();

Direct Access Token

For quick testing or short-lived scripts where you already have an access token.

const token = new OAuthBuilder()
  .accessToken("your-access-token")
  .build();

Client Credentials

For server-to-server applications without user context.

const token = new OAuthBuilder()
  .clientId("your-client-id")
  .clientSecret("your-client-secret")
  .scope("Desk.tickets.ALL")
  .orgId("your-org-id")
  .clientCredentials()
  .build();

Stored Token by ID

For resuming a previously persisted token session.

const token = new OAuthBuilder()
  .id("stored-token-id")
  .build();

Authorization URL Builder

Build OAuth authorization URLs for redirecting users to the Zoho consent screen.

import { AuthorizationUrlBuilder, USDataCenter } from "@banana.inc/zoho-desk-nodejs-sdk";

const authUrl = new AuthorizationUrlBuilder()
  .clientId("your-client-id")
  .scope("Desk.tickets.ALL")
  .redirectUri("https://your-app.com/callback")
  .responseType("code")     // "code" (default) or "token" for implicit flow
  .accessType("offline")    // "offline" (default) or "online"
  .state("csrf-token")      // optional CSRF protection
  .prompt("consent")        // optional
  .build(USDataCenter.PRODUCTION());

PKCE (Proof Key for Code Exchange)

Secure authorization code flows for public clients (RFC 7636).

import {
  generatePKCEPair,
  AuthorizationUrlBuilder,
  OAuthBuilder,
  USDataCenter,
} from "@banana.inc/zoho-desk-nodejs-sdk";

// Generate a PKCE pair
const pkce = await generatePKCEPair();

// Include in authorization URL
const authUrl = new AuthorizationUrlBuilder()
  .clientId("your-client-id")
  .scope("Desk.tickets.ALL")
  .redirectUri("https://your-app.com/callback")
  .pkce(pkce)
  .build(USDataCenter.PRODUCTION());

// Exchange the code with the verifier
const token = new OAuthBuilder()
  .clientId("your-client-id")
  .clientSecret("your-client-secret")
  .grantToken("authorization-code-from-callback")
  .redirectURL("https://your-app.com/callback")
  .codeVerifier(pkce.codeVerifier)
  .build();

Device Authorization (Device Flow)

For devices without a browser (IoT, CLI tools, smart TVs).

import {
  requestDeviceCode,
  pollForDeviceToken,
  USDataCenter,
} from "@banana.inc/zoho-desk-nodejs-sdk";

// Step 1: Request a device code
const deviceCode = await requestDeviceCode(
  USDataCenter.PRODUCTION(),
  "your-client-id",
  "Desk.tickets.ALL",
);

// Step 2: Show the user where to authorize
console.log(`Visit ${deviceCode.verification_url} and enter code: ${deviceCode.user_code}`);

// Step 3: Poll until the user authorizes (supports cancellation)
const controller = new AbortController();
const token = await pollForDeviceToken(
  USDataCenter.PRODUCTION(),
  deviceCode,
  {
    clientId: "your-client-id",
    clientSecret: "your-client-secret",
    signal: controller.signal,
    onPoll: (status) => console.log(`Status: ${status}`),
  },
);

Implicit Flow

Parse tokens from URL fragments after an implicit OAuth redirect.

import { parseImplicitFragment } from "@banana.inc/zoho-desk-nodejs-sdk";

// Build the authorization URL with responseType("token") first,
// then parse the redirect fragment:
const fragment = "access_token=1000.abc...&expires_in=3600&token_type=Bearer";
const token = parseImplicitFragment(fragment);

Data Centers

The SDK supports all 7 Zoho Desk data center regions:

Region Class Production Environment
US USDataCenter USDataCenter.PRODUCTION()
EU EUDataCenter EUDataCenter.PRODUCTION()
IN INDataCenter INDataCenter.PRODUCTION()
AU AUDataCenter AUDataCenter.PRODUCTION()
CA CADataCenter CADataCenter.PRODUCTION()
CN CNDataCenter CNDataCenter.PRODUCTION()
JP JPDataCenter JPDataCenter.PRODUCTION()

Configuration

SDK Config

Customize SDK behavior with SDKConfigBuilder:

import { SDKConfigBuilder } from "@banana.inc/zoho-desk-nodejs-sdk";

const config = new SDKConfigBuilder()
  .autoRefreshFields(true)
  .pickListValidation(true)
  .timeout(30000)    // request timeout in ms
  .maxRetries(5)     // 0–10, default 3
  .retryDelay(10)    // seconds, 0–180, default 3
  .build();

await new InitializeBuilder()
  .environment(USDataCenter.PRODUCTION())
  .token(token)
  .SDKConfig(config)
  .initialize();

Logging

Enable Winston-based logging with LogBuilder:

import { LogBuilder, Levels } from "@banana.inc/zoho-desk-nodejs-sdk";

const logger = new LogBuilder()
  .level(Levels.INFO)
  .filePath("./sdk.log")
  .build();

await new InitializeBuilder()
  .environment(USDataCenter.PRODUCTION())
  .token(token)
  .logger(logger)
  .initialize();

Available levels: INFO, DEBUG, WARN, VERBOSE, ERROR, SILLY, OFF

HTTP Proxy

Route requests through a proxy with ProxyBuilder:

import { ProxyBuilder } from "@banana.inc/zoho-desk-nodejs-sdk";

const proxy = new ProxyBuilder()
  .host("proxy.example.com")
  .port(8080)
  .user("proxy-user")       // optional
  .password("proxy-pass")   // optional
  .build();

await new InitializeBuilder()
  .environment(USDataCenter.PRODUCTION())
  .token(token)
  .requestProxy(proxy)
  .initialize();

Token Persistence

The SDK persists tokens via the TokenStore interface. The built-in FileStore saves tokens to a CSV file:

import { FileStore } from "@banana.inc/zoho-desk-nodejs-sdk";

const store = new FileStore("./zoho_desk_tokens.csv");

To implement a custom store (e.g., database-backed), implement the TokenStore interface:

import type { TokenStore, Token } from "@banana.inc/zoho-desk-nodejs-sdk";

class DatabaseStore implements TokenStore {
  async findToken(token: Token): Promise<Token | null> { /* ... */ }
  async findTokenById(id: string): Promise<Token | null> { /* ... */ }
  async saveToken(token: Token): Promise<void> { /* ... */ }
  async deleteToken(id: string): Promise<void> { /* ... */ }
  async getTokens(): Promise<Token[]> { /* ... */ }
  async deleteTokens(): Promise<void> { /* ... */ }
}

Error Handling

The SDK provides two structured error types:

ZohoApiError

Thrown when the Zoho Desk API returns a non-2xx response. Contains the HTTP status, Zoho error code, response body, and request URL.

import { ZohoApiError } from "@banana.inc/zoho-desk-nodejs-sdk";

try {
  const tickets = await client.tickets.get();
} catch (err) {
  if (err instanceof ZohoApiError) {
    console.log(err.responseStatusCode); // e.g. 403
    console.log(err.errorCode);          // e.g. "INVALID_OAUTH"
    console.log(err.message);            // Human-readable message
    console.log(err.requestUrl);         // The URL that was called
    console.log(err.responseBody);       // Full parsed JSON body
  }
}

SDKException

Thrown for SDK-level errors (invalid configuration, missing parameters, etc.).

import { SDKException } from "@banana.inc/zoho-desk-nodejs-sdk";

try {
  await new InitializeBuilder().initialize();
} catch (err) {
  if (err instanceof SDKException) {
    console.log(err.code);    // e.g. "MANDATORY_VALUE_ERROR"
    console.log(err.message);
    console.log(err.details); // Optional structured details
    console.log(err.cause);   // Optional root cause Error
  }
}

Code Generation Pipeline

The SDK's 126 API modules are generated from Zoho's official OpenAPI specifications through a four-stage pipeline:

Pull OAS specs ──> Bundle per module ──> Kiota generate ──> Generate facade
  1. Pull — Clones the latest OpenAPI specs from zoho/zohodesk-oas
  2. Bundle — Creates self-contained spec bundles per API module with a manifest
  3. Generate — Runs Microsoft Kiota (via Docker) to produce TypeScript clients for each module
  4. Facade — Scans all generated clients and produces a unified ZohoDeskClient with lazy-loaded getters

To regenerate:

npm run generate

Note: Files under src/generated/ and src/client/zoho-desk-client.ts are auto-generated. Do not edit them by hand.

License

MIT

About

The first Node.js client for the Zoho Desk REST API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors