logoRocketFlow

Integration Guide - Session Initialization

Step-by-step guide to integrate session initialization in your application

Integration Guide

This guide walks you through integrating RKT Chat Client session initialization into your application, from basic setup to advanced configurations.

Prerequisites

Before starting, ensure you have:

  • Node.js 16+ installed
  • React 18+ in your project
  • Basic understanding of React hooks
  • Access to your chatbot API endpoint

Installation

Install the Package

npm install @rkt/rkt-chat-client
# or
yarn add @rkt/rkt-chat-client
# or
pnpm add @rkt/rkt-chat-client

Verify Installation

import { useChat } from "@rkt/rkt-chat-client";

// This should work without errors
console.log("RKT Chat Client installed successfully");

Basic Integration

Step 1: Create a Basic Chat Component

Create a new component file ChatComponent.tsx:

import React from 'react';
import { useChat } from '@rkt/rkt-chat-client';

interface ChatComponentProps {
  chatbotId: string;
  apiUrl: string;
}

const ChatComponent: React.FC<ChatComponentProps> = ({ chatbotId, apiUrl }) => {
  const {
    sessionId,
    isSessionReady,
    messages,
    sendMessage,
    isChatLoading,
  } = useChat({
    chatbot: {
      id: chatbotId,
      prompt: "You are a helpful assistant.",
    },
    baseUrl: apiUrl,
  });

  const [inputMessage, setInputMessage] = React.useState('');

  const handleSend = () => {
    if (inputMessage.trim()) {
      sendMessage(inputMessage);
      setInputMessage('');
    }
  };

  if (!isSessionReady) {
    return (
      <div className="flex items-center justify-center p-4">
        <div className="text-center">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-2"></div>
          <p>Initializing session...</p>
          <p className="text-sm text-gray-500">Session ID: {sessionId}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="max-w-2xl mx-auto p-4">
      <div className="mb-4 p-3 bg-gray-100 rounded">
        <p className="text-sm">
          <strong>Session ID:</strong> {sessionId}
        </p>
      </div>
      
      <div className="border rounded-lg p-4 mb-4 h-96 overflow-y-auto">
        {messages.map((message, index) => (
          <div key={index} className={`mb-2 ${message.role === 'user' ? 'text-right' : 'text-left'}`}>
            <div className={`inline-block p-2 rounded ${
              message.role === 'user' 
                ? 'bg-blue-500 text-white' 
                : 'bg-gray-200 text-gray-800'
            }`}>
              {message.content}
            </div>
          </div>
        ))}
        {isChatLoading && (
          <div className="text-center text-gray-500">
            <div className="animate-pulse">AI is typing...</div>
          </div>
        )}
      </div>
      
      <div className="flex gap-2">
        <input
          type="text"
          value={inputMessage}
          onChange={(e) => setInputMessage(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && handleSend()}
          placeholder="Type your message..."
          className="flex-1 p-2 border rounded"
          disabled={isChatLoading}
        />
        <button
          onClick={handleSend}
          disabled={isChatLoading || !inputMessage.trim()}
          className="px-4 py-2 bg-blue-500 text-white rounded disabled:bg-gray-300"
        >
          Send
        </button>
      </div>
    </div>
  );
};

export default ChatComponent;

Step 2: Use the Component

In your main application:

import React from 'react';
import ChatComponent from './ChatComponent';

const App: React.FC = () => {
  return (
    <div className="min-h-screen bg-gray-50">
      <header className="bg-white shadow p-4">
        <h1 className="text-2xl font-bold">My Chat Application</h1>
      </header>
      
      <main className="container mx-auto py-8">
        <ChatComponent 
          chatbotId="your-chatbot-id"
          apiUrl="https://your-api.com/api/chat"
        />
      </main>
    </div>
  );
};

export default App;

Advanced Integration

Step 1: Add Telemetry Integration

Create a telemetry service:

// services/telemetry.ts
interface TelemetryService {
  initializeSession: (data: any) => void;
  trackEvent: (event: string, properties?: any) => void;
  trackError: (error: Error, context?: any) => void;
}

class AnalyticsTelemetry implements TelemetryService {
  private apiKey: string;
  private baseUrl: string;

  constructor(apiKey: string, baseUrl: string) {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
  }

  initializeSession(data: any) {
    // Send to your analytics service
    fetch(`${this.baseUrl}/sessions`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`,
      },
      body: JSON.stringify({
        ...data,
        timestamp: new Date().toISOString(),
      }),
    }).catch(error => {
      console.error('Failed to initialize session:', error);
    });
  }

  trackEvent(event: string, properties?: any) {
    // Track custom events
    fetch(`${this.baseUrl}/events`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`,
      },
      body: JSON.stringify({
        event,
        properties,
        timestamp: new Date().toISOString(),
      }),
    }).catch(error => {
      console.error('Failed to track event:', error);
    });
  }

  trackError(error: Error, context?: any) {
    // Track errors
    fetch(`${this.baseUrl}/errors`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`,
      },
      body: JSON.stringify({
        error: {
          message: error.message,
          stack: error.stack,
        },
        context,
        timestamp: new Date().toISOString(),
      }),
    }).catch(err => {
      console.error('Failed to track error:', err);
    });
  }
}

export const telemetryService = new AnalyticsTelemetry(
  process.env.REACT_APP_ANALYTICS_API_KEY!,
  process.env.REACT_APP_ANALYTICS_BASE_URL!
);

Step 2: Add Error Tracking

Create an error tracking service:

// services/errorTracker.ts
interface ErrorTracker {
  captureException: (error: Error, context?: any) => void;
  captureMessage: (message: string, level?: string, context?: any) => void;
}

class SentryErrorTracker implements ErrorTracker {
  private dsn: string;

  constructor(dsn: string) {
    this.dsn = dsn;
  }

  captureException(error: Error, context?: any) {
    // Send to Sentry or your error tracking service
    console.error('Exception captured:', error, context);
    
    // Example Sentry integration
    // Sentry.captureException(error, { extra: context });
  }

  captureMessage(message: string, level: string = 'info', context?: any) {
    // Send to your logging service
    console.log(`[${level.toUpperCase()}] ${message}`, context);
    
    // Example Sentry integration
    // Sentry.captureMessage(message, level, { extra: context });
  }
}

export const errorTracker = new SentryErrorTracker(
  process.env.REACT_APP_SENTRY_DSN!
);

Step 3: Enhanced Chat Component

Update your chat component with telemetry and error tracking:

import React from 'react';
import { useChat } from '@rkt/rkt-chat-client';
import { telemetryService } from '../services/telemetry';
import { errorTracker } from '../services/errorTracker';

interface EnhancedChatComponentProps {
  chatbotId: string;
  apiUrl: string;
  userId?: string;
}

const EnhancedChatComponent: React.FC<EnhancedChatComponentProps> = ({ 
  chatbotId, 
  apiUrl, 
  userId 
}) => {
  const {
    sessionId,
    isSessionReady,
    telemetryInitialized,
    messages,
    sendMessage,
    isChatLoading,
    isError,
    errorMessage,
  } = useChat({
    chatbot: {
      id: chatbotId,
      prompt: "You are a helpful assistant.",
    },
    baseUrl: apiUrl,
    telemetry: telemetryService,
    errorTracker: errorTracker,
    onReady: (sessionId) => {
      console.log(`Session ready: ${sessionId}`);
      // Track session start
      telemetryService.trackEvent('session_started', {
        sessionId,
        userId,
        chatbotId,
      });
    },
  });

  const [inputMessage, setInputMessage] = React.useState('');

  const handleSend = () => {
    if (inputMessage.trim()) {
      // Track message sent
      telemetryService.trackEvent('message_sent', {
        sessionId,
        messageLength: inputMessage.length,
        messageCount: messages.length + 1,
      });
      
      sendMessage(inputMessage);
      setInputMessage('');
    }
  };

  // Track errors
  React.useEffect(() => {
    if (isError && errorMessage) {
      telemetryService.trackError(new Error(errorMessage), {
        sessionId,
        chatbotId,
        userId,
      });
    }
  }, [isError, errorMessage, sessionId, chatbotId, userId]);

  if (!isSessionReady) {
    return (
      <div className="flex items-center justify-center p-4">
        <div className="text-center">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-2"></div>
          <p>Initializing session...</p>
          <p className="text-sm text-gray-500">Session ID: {sessionId}</p>
          <p className="text-sm text-gray-500">
            Telemetry: {telemetryInitialized ? '' : ''}
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="max-w-2xl mx-auto p-4">
      {/* Session Status */}
      <div className="mb-4 p-3 bg-gray-100 rounded">
        <div className="grid grid-cols-2 gap-2 text-sm">
          <p><strong>Session ID:</strong> {sessionId}</p>
          <p><strong>Telemetry:</strong> {telemetryInitialized ? '✅' : '❌'}</p>
        </div>
      </div>

      {/* Error Display */}
      {isError && (
        <div className="mb-4 p-3 bg-red-100 border border-red-300 rounded text-red-700">
          <strong>Error:</strong> {errorMessage}
        </div>
      )}
      
      {/* Chat Interface */}
      <div className="border rounded-lg p-4 mb-4 h-96 overflow-y-auto">
        {messages.map((message, index) => (
          <div key={index} className={`mb-2 ${message.role === 'user' ? 'text-right' : 'text-left'}`}>
            <div className={`inline-block p-2 rounded ${
              message.role === 'user' 
                ? 'bg-blue-500 text-white' 
                : 'bg-gray-200 text-gray-800'
            }`}>
              {message.content}
            </div>
          </div>
        ))}
        {isChatLoading && (
          <div className="text-center text-gray-500">
            <div className="animate-pulse">AI is typing...</div>
          </div>
        )}
      </div>
      
      <div className="flex gap-2">
        <input
          type="text"
          value={inputMessage}
          onChange={(e) => setInputMessage(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && handleSend()}
          placeholder="Type your message..."
          className="flex-1 p-2 border rounded"
          disabled={isChatLoading}
        />
        <button
          onClick={handleSend}
          disabled={isChatLoading || !inputMessage.trim()}
          className="px-4 py-2 bg-blue-500 text-white rounded disabled:bg-gray-300"
        >
          Send
        </button>
      </div>
    </div>
  );
};

export default EnhancedChatComponent;

Environment Configuration

Step 1: Environment Variables

Create a .env file in your project root:

# Chat Configuration
REACT_APP_CHATBOT_ID=your-chatbot-id
REACT_APP_API_URL=https://your-api.com/api/chat

# Analytics Configuration
REACT_APP_ANALYTICS_API_KEY=your-analytics-api-key
REACT_APP_ANALYTICS_BASE_URL=https://your-analytics.com/api

# Error Tracking Configuration
REACT_APP_SENTRY_DSN=your-sentry-dsn

Step 2: TypeScript Configuration

Add type definitions for environment variables:

// types/env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    REACT_APP_CHATBOT_ID: string;
    REACT_APP_API_URL: string;
    REACT_APP_ANALYTICS_API_KEY: string;
    REACT_APP_ANALYTICS_BASE_URL: string;
    REACT_APP_SENTRY_DSN: string;
  }
}

Testing Integration

Step 1: Create Test Component

// components/ChatTest.tsx
import React from 'react';
import { useChat } from '@rkt/rkt-chat-client';

const ChatTest: React.FC = () => {
  const {
    sessionId,
    isSessionReady,
    telemetryInitialized,
    initializeSession,
  } = useChat({
    chatbot: {
      id: 'test-chatbot',
      prompt: 'You are a test assistant.',
    },
    baseUrl: 'http://localhost:3000/api/chat',
    onReady: (sessionId) => {
      console.log('Test session ready:', sessionId);
    },
  });

  return (
    <div className="p-4 border rounded">
      <h3 className="font-bold mb-2">Session Initialization Test</h3>
      <div className="space-y-2 text-sm">
        <p>Session ID: {sessionId || 'Not generated'}</p>
        <p>Session Ready: {isSessionReady ? '' : ''}</p>
        <p>Telemetry: {telemetryInitialized ? '' : ''}</p>
      </div>
      <button
        onClick={() => initializeSession(sessionId)}
        className="mt-2 px-3 py-1 bg-blue-500 text-white rounded text-sm"
        disabled={!sessionId}
      >
        Reinitialize Session
      </button>
    </div>
  );
};

export default ChatTest;

Step 2: Add to Development Environment

// App.tsx
import React from 'react';
import ChatComponent from './ChatComponent';
import ChatTest from './components/ChatTest';

const App: React.FC = () => {
  const isDevelopment = process.env.NODE_ENV === 'development';

  return (
    <div className="min-h-screen bg-gray-50">
      <header className="bg-white shadow p-4">
        <h1 className="text-2xl font-bold">My Chat Application</h1>
      </header>
      
      <main className="container mx-auto py-8">
        {isDevelopment && (
          <div className="mb-8">
            <ChatTest />
          </div>
        )}
        
        <ChatComponent 
          chatbotId={process.env.REACT_APP_CHATBOT_ID!}
          apiUrl={process.env.REACT_APP_API_URL!}
        />
      </main>
    </div>
  );
};

export default App;

Production Deployment

Step 1: Build Configuration

Ensure your build process includes environment variables:

// package.json
{
  "scripts": {
    "build": "react-scripts build",
    "build:prod": "REACT_APP_NODE_ENV=production react-scripts build"
  }
}

Step 2: Runtime Configuration

For dynamic configuration in production:

// config/runtime.ts
interface RuntimeConfig {
  chatbotId: string;
  apiUrl: string;
  analyticsApiKey?: string;
  analyticsBaseUrl?: string;
  sentryDsn?: string;
}

export const getRuntimeConfig = (): RuntimeConfig => {
  // In production, you might load this from a config endpoint
  if (process.env.NODE_ENV === 'production') {
    return {
      chatbotId: window.APP_CONFIG?.chatbotId || process.env.REACT_APP_CHATBOT_ID!,
      apiUrl: window.APP_CONFIG?.apiUrl || process.env.REACT_APP_API_URL!,
      analyticsApiKey: window.APP_CONFIG?.analyticsApiKey,
      analyticsBaseUrl: window.APP_CONFIG?.analyticsBaseUrl,
      sentryDsn: window.APP_CONFIG?.sentryDsn,
    };
  }

  // Development configuration
  return {
    chatbotId: process.env.REACT_APP_CHATBOT_ID!,
    apiUrl: process.env.REACT_APP_API_URL!,
    analyticsApiKey: process.env.REACT_APP_ANALYTICS_API_KEY,
    analyticsBaseUrl: process.env.REACT_APP_ANALYTICS_BASE_URL,
    sentryDsn: process.env.REACT_APP_SENTRY_DSN,
  };
};

Next Steps

Last updated on