npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@asheshgoplani/chatbot-widget

v1.0.3

Published

Angular chatbot widget for OpenJanela ERP with iframe integration and JWT authentication

Readme

@openjanela/chatbot-widget

Angular chatbot widget with iframe integration and JWT authentication for OpenJanela ERP

npm version License: MIT

A production-ready, plug-and-play Angular component that integrates the OpenJanela AI chatbot into your Angular application with just 3 lines of code.

✨ Features

  • 🚀 Super Easy Integration - Just import, configure, and use
  • 🔐 JWT Authentication - Automatic token generation and authentication
  • 🎨 Fully Styled - Beautiful, draggable, resizable chat window
  • 📱 Responsive - Works perfectly on mobile and desktop
  • 💾 State Persistence - Saves chat state in localStorage
  • 🎯 Context-Aware - Automatically sends page context to chatbot
  • 🔒 Secure - postMessage communication with origin validation
  • 📦 Zero Configuration - Sensible defaults, customize as needed
  • Explicit User Inputs - Pass user data via @Input decorators (NEW!)
  • 🔄 Real-time Updates - Automatic re-authentication on user changes

📦 Installation

npm install @openjanela/chatbot-widget jose

Note: jose is a peer dependency required for JWT token generation.

🚀 Quick Start

Step 1: Import the Module

In your app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { OpenjanelaC hatbotModule } from '@openjanela/chatbot-widget';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    OpenjanelaC hatbotModule.forRoot({
      chatbotUrl: 'https://your-chatbot-url.com',
      jwtSecret: 'your-production-jwt-secret-here-128-characters-long',
      enabled: true
    })
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Step 2: Add the Component

In your app.component.html (or any template):

<router-outlet></router-outlet>

<!-- Chatbot widget - automatically appears when user is logged in -->
<openjanela-chatbot-widget></openjanela-chatbot-widget>

<!-- OR use explicit user inputs (RECOMMENDED) -->
<openjanela-chatbot-widget
  [userId]="currentUser?.userId"
  [username]="currentUser?.userName"
  [userRole]="currentUser?.role">
</openjanela-chatbot-widget>

Step 3: Store User Data

After successful login, store user data in sessionStorage:

// In your authentication service
login(username: string, password: string) {
  return this.http.post('/api/login', { username, password })
    .pipe(
      tap(response => {
        // Store user data for chatbot
        sessionStorage.setItem('userData', JSON.stringify({
          id: response.userId,
          username: response.username,
          role: response.role,
          permissions: response.permissions
        }));
      })
    );
}

That's it! The chatbot will now:

  • ✅ Automatically appear when user is logged in
  • ✅ Generate JWT token from user data
  • ✅ Authenticate with the chatbot backend
  • ✅ Hide when user logs out

🆕 Explicit User Inputs (Recommended Approach)

Instead of relying on sessionStorage, you can now pass user data directly via Angular inputs:

Basic Usage

// app.component.ts
export class AppComponent implements OnInit {
  currentUser: any = null;

  constructor(
    private authService: AuthenticationService,
    private encryptDecryptService: EncryptDecryptService
  ) {}

  ngOnInit() {
    this.authService.authUser.subscribe(encryptedUser => {
      if (encryptedUser) {
        this.currentUser = this.encryptDecryptService.decrypted(encryptedUser);
      } else {
        this.currentUser = null;
      }
    });
  }
}
<!-- app.component.html -->
<openjanela-chatbot-widget
  *ngIf="currentUser"
  [userId]="currentUser?.userId"
  [username]="currentUser?.userName"
  [userRole]="currentUser?.role">
</openjanela-chatbot-widget>

<!-- OR pass complete user object -->
<openjanela-chatbot-widget
  *ngIf="currentUser"
  [user]="currentUser">
</openjanela-chatbot-widget>

Benefits

  • Better Control - Parent component manages user data
  • Type Safety - TypeScript type checking
  • No Storage Dependency - Eliminates race conditions
  • Real-time Updates - User changes propagate immediately
  • Testability - Easier to unit test

Priority System

  1. Explicit Inputs (Highest) - Data passed via @Input
  2. SessionStorage (Fallback) - Legacy support
  3. Guest Mode (Default) - When no user data available

📖 See full documentation →

⚙️ Configuration Options

interface ChatbotConfig {
  /**
   * URL of the chatbot iframe (REQUIRED)
   * @example 'https://your-chatbot-url.com'
   */
  chatbotUrl: string;

  /**
   * JWT secret for token generation (REQUIRED)
   * Must match the chatbot backend secret
   * @example 'your-production-jwt-secret-here-128-characters-long'
   */
  jwtSecret: string;

  /**
   * Enable/disable the chatbot widget
   * @default true
   */
  enabled?: boolean;

  /**
   * Auto-open chatbot on page load
   * @default false
   */
  autoOpen?: boolean;

  /**
   * Position of the chatbot button
   * @default 'bottom-right'
   */
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';

  /**
   * Allowed origins for postMessage communication
   * @default [chatbotUrl origin]
   */
  allowedOrigins?: string[];
}

🎯 Advanced Usage

Using the Chatbot Service

You can interact with the chatbot programmatically using ChatbotService:

import { Component } from '@angular/core';
import { ChatbotService } from '@openjanela/chatbot-widget';

@Component({
  selector: 'app-dashboard',
  template: `
    <button (click)="openChatbot()">Open Chatbot</button>
  `
})
export class DashboardComponent {
  constructor(private chatbotService: ChatbotService) {}

  openChatbot() {
    // Send a context update to the chatbot
    this.chatbotService.sendContextUpdate({
      page: 'dashboard',
      customerId: '12345',
      orderId: '67890'
    });
  }
}

Listening to Chatbot Messages

import { Component, OnInit } from '@angular/core';
import { ChatbotService } from '@openjanela/chatbot-widget';

@Component({
  selector: 'app-home'
})
export class HomeComponent implements OnInit {
  constructor(private chatbotService: ChatbotService) {}

  ngOnInit() {
    // Subscribe to messages from chatbot
    this.chatbotService.getMessages().subscribe(message => {
      if (message?.type === 'NAVIGATE_REQUEST') {
        console.log('Chatbot requested navigation to:', message.payload.path);
      }
    });

    // Subscribe to unread count
    this.chatbotService.getUnreadCount().subscribe(count => {
      console.log('Unread messages:', count);
    });
  }
}

Custom JWT Token Generation

If you need custom JWT token generation logic:

import { Component } from '@angular/core';
import { ChatbotJwtService } from '@openjanela/chatbot-widget';

@Component({
  selector: 'app-custom'
})
export class CustomComponent {
  constructor(private jwtService: ChatbotJwtService) {}

  async generateCustomToken() {
    const user = {
      id: '123',
      username: 'john.doe',
      role: 'admin',
      permissions: ['read', 'write', 'admin']
    };

    const token = await this.jwtService.generateToken(user);
    console.log('Generated token:', token);
  }
}

🎨 Customization

Styling

The chatbot widget uses inline styles by default, but you can override them using CSS:

/* In your global styles.css */
openjanela-chatbot-widget .chatbot-button {
  background: linear-gradient(135deg, #your-color-1, #your-color-2) !important;
}

openjanela-chatbot-widget .chatbot-header {
  background: linear-gradient(135deg, #your-color-1, #your-color-2) !important;
}

Environment-based Configuration

// environment.ts
export const environment = {
  production: false,
  chatbot: {
    url: 'http://localhost:3001',
    jwtSecret: 'dev-secret'
  }
};

// environment.prod.ts
export const environment = {
  production: true,
  chatbot: {
    url: 'https://your-chatbot-url.com',
    jwtSecret: 'your-production-jwt-secret-here-128-characters-long'
  }
};

// app.module.ts
import { environment } from './environments/environment';

OpenjanelaC hatbotModule.forRoot({
  chatbotUrl: environment.chatbot.url,
  jwtSecret: environment.chatbot.jwtSecret
})

🔐 Security Considerations

  1. JWT Secret: Keep your JWT secret secure and never commit it to version control
  2. Origin Validation: The widget validates postMessage origins automatically
  3. User Data: User data is read from sessionStorage/localStorage - ensure it's encrypted if needed
  4. HTTPS: Use HTTPS in production for secure communication

📱 Mobile Support

The chatbot is fully responsive and works on mobile devices. On small screens, it automatically goes fullscreen for better UX.

🐛 Troubleshooting

Chatbot not appearing

Check:

  • User is logged in (sessionStorage.getItem('userData') exists)
  • enabled: true in configuration
  • Console for any error messages

JWT token errors

Check:

  • JWT secret matches between Angular app and chatbot backend
  • User data is correctly stored in sessionStorage
  • jose package is installed

iframe not loading

Check:

  • Chatbot URL is correct and accessible
  • No CORS issues (check browser console)
  • Network connectivity

📝 Example Project Structure

my-angular-app/
├── src/
│   ├── app/
│   │   ├── app.module.ts          # Import OpenjanelaC hatbotModule
│   │   ├── app.component.html     # Add <openjanela-chatbot-widget>
│   │   ├── auth/
│   │   │   └── auth.service.ts    # Store user data on login
│   │   └── features/
│   │       └── dashboard/
│   │           └── dashboard.component.ts  # Use ChatbotService
│   ├── environments/
│   │   ├── environment.ts         # Dev chatbot config
│   │   └── environment.prod.ts    # Prod chatbot config
│   └── styles.css                 # Global chatbot styles (optional)
└── package.json

🤝 Integration with OpenJanela ERP

This widget is designed to work seamlessly with the OpenJanela ERP chatbot backend. The backend:

  • Validates JWT tokens using the same secret
  • Processes natural language queries
  • Returns formatted responses
  • Supports real-time status updates via WebSocket

Production URLs:

  • Frontend (Chatbot UI): https://your-chatbot-url.com
  • Backend API: https://your-chatbot-api.com

📚 API Reference

OpenjanelaC hatbotModule

Main module for the chatbot widget.

static forRoot(config: ChatbotConfig): ModuleWithProviders<OpenjanelaC hatbotModule>

ChatbotService

Service for interacting with the chatbot programmatically.

Methods:

  • initialize(iframe: HTMLIFrameElement): void - Initialize the chatbot
  • sendAuthentication(): Promise<void> - Send JWT authentication
  • sendContextUpdate(context?: any): void - Update page context
  • getMessages(): Observable<ChatbotMessage | null> - Subscribe to messages
  • getUnreadCount(): Observable<number> - Subscribe to unread count
  • getIframeUrl(): string - Get iframe URL
  • isReady(): boolean - Check if initialized
  • isEnabled(): boolean - Check if enabled
  • resetUnreadCount(): void - Reset unread count

ChatbotJwtService

Service for JWT token generation and verification.

Methods:

  • generateToken(user: any): Promise<string> - Generate JWT token
  • verifyToken(token: string): Promise<ChatbotJWTPayload | null> - Verify JWT token

📄 License

MIT © OpenJanela Team

🙋 Support

For issues, questions, or contributions, please visit:

  • GitHub Issues: https://github.com/openjanela/chatbot-widget/issues
  • Documentation: https://github.com/openjanela/chatbot-widget#readme

🔄 Changelog

v1.0.0 (2025-01-09)

  • Initial release
  • JWT authentication
  • Draggable and resizable chat window
  • State persistence
  • Context-aware messaging
  • Mobile responsive design