JSPM

@spektra-cloudevents/zoho-asap-widget

2.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 21
  • Score
    100M100P100Q71586F
  • License MIT

Standalone Angular library for Zoho Desk ASAP widget with JWT token authentication and session management

Package Exports

  • @spektra-cloudevents/zoho-asap-widget
  • @spektra-cloudevents/zoho-asap-widget/package.json

Readme

Zoho Desk ASAP Widget - Standalone Angular Library

A completely standalone Angular library (10+) that wraps the Zoho Desk ASAP 2.0 widget. This library handles everything internally: authentication, session management, and storage clearing. Your app only needs to pass a JWT token - no Zoho-specific code required.

๐ŸŽฏ Key Features

  • โœ… Truly Standalone: Accepts JWT token, handles authentication internally
  • โœ… Zero Zoho Dependencies in App: No AsapService, no additional authentication code needed
  • โœ… Multi-User Safe: Automatically detects user changes and clears sessions
  • โœ… Smart Token Refresh: Distinguishes token refresh (same user) from user switch (different user)
  • โœ… Automatic Session Management: Clears localStorage, sessionStorage, and cookies on logout
  • โœ… Prefill Support: Automatic form prefilling with dynamic values
  • โœ… Angular 10-18+ Compatible: Works with all modern Angular versions
  • โœ… Production Ready: Clean code, no console logs, robust error handling

๐Ÿ“ฆ Installation

npm install @cloudlabs/zoho-asap-widget

Import the module in your app:

import { ZohoAsapWidgetModule } from '@cloudlabs/zoho-asap-widget';

@NgModule({
  imports: [ZohoAsapWidgetModule],
  // ...
})
export class AppModule { }

๐Ÿš€ Basic Usage

Prerequisites: Your app must have a JWT token for authenticating users with Zoho Desk ASAP.

<!-- Simply pass your JWT token to the widget -->
<zoho-asap-widget
  *ngIf="jwtToken"
  [appId]="'YOUR_ZOHO_APP_ID'"
  [orgId]="'YOUR_ZOHO_ORG_ID'"
  [jwtToken]="jwtToken"
  [enabled]="true">
</zoho-asap-widget>

That's it! The widget handles:

  • User authentication with Zoho
  • Session management
  • Storage cleanup on logout
  • User switching detection

With Form Prefill

<zoho-asap-widget
  *ngIf="jwtToken"
  [appId]="'YOUR_ZOHO_APP_ID'"
  [orgId]="'YOUR_ZOHO_ORG_ID'"
  [jwtToken]="jwtToken"
  [enabled]="true"
  [prefillFields]="prefillData"
  [departmentId]="'YOUR_DEPT_ID'"
  [layoutId]="'YOUR_LAYOUT_ID'">
</zoho-asap-widget>

Where prefillData is an object in your component:

prefillData: any = {
  subject: 'Support Request',              // Standard Zoho field
  cf_event_request_id: 'MS012345678910',  // Custom field
};

Dynamic prefill example:

// Set subject dynamically with user name
this.prefillData.subject = `Support Request from ${this.userDisplayName}`;

// Update prefill based on user context
if (isPremiumUser) {
  this.prefillData = {
    subject: `Priority Support - ${userName}`,
    cf_priority: 'High',
    cf_user_type: 'Premium'
  };
}

๐Ÿ”ง Component Inputs

interface ZohoAsapWidgetInputs {
  // Required
  appId: string;              // Zoho ASAP application ID
  orgId: string;              // Zoho organization ID
  jwtToken: string;           // JWT token for Zoho authentication
  
  // Optional
  enabled?: boolean;          // Enable/disable widget (default: true)
  nonce?: string;             // Security nonce for script loading
  
  // Prefill (optional)
  prefillFields?: {           // Object with field names and values
    [fieldName: string]: any; // e.g., { cf_event_request_id: '12345', cf_priority: 'High' }
  };
  departmentId?: string;      // Department ID (required for prefill)
  layoutId?: string;          // Form layout ID (required for prefill)
}

๐Ÿ” How It Works

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Your App      โ”‚
โ”‚  (JWT Token)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚ JWT Token
         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Zoho Widget    โ”‚ โ”€โ”€โ–บ Authenticate with JWT
โ”‚   (Library)     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚
         โ–ผ Login with JWT
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Zoho Desk      โ”‚
โ”‚   ASAP API      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Flow

  1. App authenticates user and obtains JWT token
  2. App passes JWT token to widget via [jwtToken] input
  3. Widget handles everything:
    • Logs into Zoho Desk ASAP with JWT token
    • Manages session lifecycle
  4. On logout: Widget clears all Zoho storage/cookies automatically

๐Ÿง  Smart User Detection

The widget intelligently handles two scenarios:

Scenario 1: Same User, Token Refresh

// User's JWT token expires and gets refreshed
// Old: eyJhbGc...user@example.com...abc
// New: eyJhbGc...user@example.com...xyz

// Widget: Extracts user identity (email/oid)
// โ†’ Same user detected
// โ†’ Updates JWT without logout
// โ†’ User keeps their session state

Scenario 2: Different User Login

// User A logs out, User B logs in
// Old: eyJhbGc...userA@example.com...
// New: eyJhbGc...userB@example.com...

// Widget: Extracts user identity
// โ†’ Different user detected
// โ†’ Fully logs out User A
// โ†’ Clears all storage/cookies
// โ†’ Logs in User B with clean session

This prevents unnecessary session disruption while ensuring complete isolation between users.


## ๐Ÿงน Session Management (Automatic)

The widget handles **everything automatically** when component lifecycle changes:

```typescript
// When widget is destroyed (*ngIf becomes false):
// - Detects ngOnDestroy
// - Calls Zoho logout
// - Clears ALL Zoho storage (localStorage, sessionStorage, cookies)
// - Waits for logout confirmation event

// When widget is created fresh (*ngIf becomes true):
// - Clears any residual Zoho storage (safety check)
// - Loads Zoho script
// - Logs into Zoho with JWT token
// - Establishes fresh session

Your app just controls the *ngIf condition - widget does the rest!

๐Ÿ”„ Multi-User Scenarios

Perfect for applications where users switch accounts:

// User A logged in
this.jwtToken = 'eyJhbGc...userA@example.com...';
// Widget: Logs in User A

// User A logs out
this.jwtToken = null;
// Widget: Detects token removal, logs out, clears all Zoho data

// User B logs in (component recreated)
this.jwtToken = 'eyJhbGc...userB@example.com...';
// Widget: Fresh component โ†’ clears storage โ†’ new session
// User B sees ONLY their data, never User A's

๐Ÿ“ Form Prefilling

To prefill ticket fields when opening the widget, pass an object with field names and values:

<zoho-asap-widget
  [appId]="'202588000344171472'"
  [orgId]="'649984843'"
  [jwtToken]="jwtToken"
  [prefillFields]="{
    subject: 'Technical Support Request',        // Standard field
    description: 'Issue details here',           // Standard field
    cf_event_request_id: 'EVENT-12345',         // Custom field
    cf_priority: 'High',                         // Custom field
    cf_category: 'Technical Issue',              // Custom field
    cf_user_email: userEmail,                    // Custom field with dynamic value
    cf_location: 'Building A'                    // Custom field
  }"
  [departmentId]="'202588000019741045'"
  [layoutId]="'202588000019743298'">
</zoho-asap-widget>

Field Types:

Standard Zoho Fields (no prefix needed):

  • subject - Ticket subject/title
  • description - Ticket description/body
  • email - Contact email
  • phone - Contact phone

Custom Fields (require cf_ prefix):

  • cf_event_request_id - Your custom event ID field
  • cf_priority - Your custom priority field
  • cf_category - Your custom category field
  • cf_* - Any other custom field you've created

Requirements:

  • prefillFields: Object where keys are field names (standard or custom)
  • departmentId: Zoho department ID (required for prefill)
  • layoutId: Zoho form layout ID (required for prefill)

How to find field API names:

  1. Go to Zoho Desk > Setup > Channels > ASAP
  2. Click on your department's form layout
  3. Standard fields: Use lowercase names (subject, description, email)
  4. Custom fields: Will have API names like cf_event_request_id, cf_priority

Dynamic prefill with user context:

// Construct prefill data with user information
prefillData = {
  subject: `Support Request from ${userName}`,
  email: userEmail,
  cf_event_request_id: ticketId,
  cf_user_type: userType,
  cf_priority: priority
};

// Update specific fields dynamically
this.prefillData.cf_event_request_id = newTicketId;
this.prefillData.subject = `Updated Request - ${newTicketId}`;

// Widget automatically reloads when prefillFields object reference changes
this.prefillData = { ...this.prefillData };

The widget automatically:

  • Configures prefill before loading the Zoho script
  • Reapplies prefill after user login
  • Reloads widget when prefillFields object changes

Important: What Your App Needs vs. Doesn't Need

โœ… Your App Needs to Provide

  1. JWT Token - For Zoho Desk ASAP authentication

    • Get this from your authentication service/backend
    • Pass it to the widget: [jwtToken]="yourToken"
  2. Zoho Configuration - Your Zoho Desk ASAP credentials

    • appId: From Zoho Desk ASAP setup
    • orgId: Your Zoho organization ID
  3. Optional: Prefill Data - Custom field values for ticket forms

    • prefillFields: Object with field names and values
    • departmentId & layoutId: Required if using prefill

โŒ Your App Does NOT Need

  • Any Zoho-specific services or logic
  • Additional authentication code (widget handles JWT authentication)
  • Session management code
  • Storage/cookie clearing logic
  • Logout/login event handlers
  • User switching detection
  • Import anything except ZohoAsapWidgetModule

Summary: Just provide the JWT token and Zoho config - the widget handles all authentication and session management internally!

๐Ÿ—๏ธ Building & Publishing

# Build the library for production
ng build zoho-asap-widget --configuration production

# Navigate to dist folder
cd dist/zoho-asap-widget

# Publish to npm (one-time login: npm login)
npm publish --access public

# For updates, increment version first:
# npm version patch  # 1.0.0 -> 1.0.1
# npm version minor  # 1.0.0 -> 1.1.0
# npm version major  # 1.0.0 -> 2.0.0

๐Ÿ› Troubleshooting

Widget shows old user's data after login

  • Cause: Browser cache not cleared
  • Solution: Widget now clears storage on ngOnInit() automatically
  • Manual fix: Clear browser cache (Ctrl+Shift+Delete โ†’ All time)

Widget not loading

  • Check: appId and orgId are correct
  • Check: JWT token is valid (not null/undefined)
  • Check: Network connectivity to Zoho services

Token refresh causes logout

  • Cause: Should not happen - widget detects same user
  • Debug: Check console for user identity extraction logs
  • Verify: JWT payload has oid, sub, or email claim

๐Ÿ”— Resources

๐Ÿ“„ License

MIT