Skip to content

necyberteam/access-qa-bot

Repository files navigation

ACCESS Q&A Bot

A React wrapper around @snf/qa-bot-core that adds ACCESS-specific functionality. This package serves two purposes:

  1. Production use: The official Q&A bot for ACCESS websites
  2. Reference implementation: An example of how to build organization-specific wrappers around qa-bot-core

Installation

npm install @snf/access-qa-bot

Features

  • 🤖 Intelligent Q&A: AI-powered responses about ACCESS resources and services
  • 🎫 Support Tickets: Create help tickets for general support, ACCESS login issues, and resource provider login problems
  • 🔒 Security Reporting: Report security incidents with priority levels and file attachments
  • 📊 Metrics/XDMoD: Query usage and performance data for ACCESS resources
  • 📎 File Attachments: Upload screenshots, logs, and documents with tickets
  • 👤 User Pre-population: Auto-fill forms with user info when logged in
  • 🎨 Theming: Customizable colors and branding via qa-bot-core
  • ♿ Accessibility: Full screen reader support and keyboard navigation
  • 📱 Responsive: Works on desktop and mobile devices

Display Modes

  • Floating Mode (default): Chat button that opens/closes a floating window
  • Embedded Mode: Always visible, embedded in page content

Available Flows

🤖 Q&A Flow

  • Ask questions about ACCESS resources, services, and documentation
  • AI-powered responses with HTML and Markdown formatting
  • Thumbs up/down feedback after each response
  • Requires login (gated by default)

🎫 Support Ticket Flows

  • General Help: Any ACCESS-related issues
  • ACCESS Login: Problems logging into access-ci.org
  • Resource Login: Problems logging into resource providers (Anvil, Expanse, etc.)
  • All flows support file attachments and integrate with JSM ProForma

🔒 Security Incident Flow

  • Report security issues, vulnerabilities, and incidents
  • Priority levels: Critical, High, Medium, Low
  • Direct routing to ACCESS cybersecurity team
  • File attachments for evidence

📊 Metrics/XDMoD Flow

  • Query usage and performance data
  • Interactive Q&A loop with feedback buttons

Integration Methods

React Component

For React applications, import and use the component directly:

import React, { useRef, useState } from 'react';
import { AccessQABot } from '@snf/access-qa-bot';

function MyApp() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [chatOpen, setChatOpen] = useState(false);
  const botRef = useRef();

  return (
    <div className="app">
      <h1>My Application</h1>

      <button onClick={() => botRef.current?.addMessage("Hello!")}>
        Send Message
      </button>

      <button onClick={() => setChatOpen(true)}>
        Open Chat
      </button>

      <AccessQABot
        ref={botRef}
        isLoggedIn={isLoggedIn}
        open={chatOpen}
        onOpenChange={setChatOpen}
        userEmail="user@example.com"
        userName="Jane Doe"
        accessId="jdoe"
        apiKey={process.env.VITE_API_KEY}
      />
    </div>
  );
}

React Props

Property Type Default Description
isLoggedIn boolean false User login state (gates Q&A, shows login/user icon)
apiKey string "demo-key" API key for authentication
embedded boolean false Embedded or floating mode
loginUrl string "/login" Login redirect URL
open boolean - Control chat window (floating mode)
onOpenChange function - Chat window state callback
onAnalyticsEvent function - Analytics event callback (receives core + wrapper events)
welcome string - Custom welcome message
userEmail string - Pre-populate email in forms
userName string - Pre-populate name in forms
accessId string - Pre-populate ACCESS ID in forms
actingUser string - Acting user identifier forwarded to backend as X-Acting-User header

Ref Methods

const botRef = useRef<AccessQABotRef>(null);

// Add a message programmatically
botRef.current?.addMessage("Hello from code!");

Standalone JavaScript

For plain HTML/JS, use the self-contained standalone bundle:

<script src="https://unpkg.com/@snf/access-qa-bot@3.0.0/dist/access-qa-bot.standalone.js"></script>

<div id="qa-bot"></div>

<script>
const bot = qaBot({
  target: document.getElementById('qa-bot'),
  isLoggedIn: false,
  embedded: false,
  welcome: "Welcome! How can I help you today?",
  defaultOpen: false,
});
</script>

Programmatic Control

The qaBot() function returns a controller object:

const bot = qaBot({
  target: document.getElementById('qa-bot'),
  isLoggedIn: false,
});

// Add messages
bot.addMessage("Hello World!");

// Update login state
bot.setBotIsLoggedIn(true);

// Control chat window (floating mode only)
bot.openChat();
bot.closeChat();
bot.toggleChat();

// Cleanup
bot.destroy();

Standalone Config

Property Type Default Description
target HTMLElement required DOM element to render into
apiKey string "demo-key" API key for authentication
defaultOpen boolean false Initial chat window state
embedded boolean false Embedded or floating mode
isLoggedIn boolean false User login state
loginUrl string "/login" Login redirect URL
onAnalyticsEvent function - Analytics event callback
welcome string - Welcome message
userEmail string - Pre-populate email
userName string - Pre-populate name
accessId string - Pre-populate ACCESS ID
actingUser string - Acting user identifier forwarded to backend as X-Acting-User header

CDN Usage

unpkg (npm-based)

<script src="https://unpkg.com/@snf/access-qa-bot@3.0.0/dist/access-qa-bot.standalone.js"></script>

jsdelivr (GitHub-based)

<script src="https://cdn.jsdelivr.net/gh/necyberteam/access-qa-bot@v3.0.0/dist/access-qa-bot.standalone.js"></script>

Building Your Own Wrapper

This repository demonstrates the wrapper pattern for extending qa-bot-core with organization-specific functionality. Use this as a reference for building your own wrapper.

Architecture

YourWrapper (this pattern)
  └── QABot (from @snf/qa-bot-core)
      └── react-chatbotify

What qa-bot-core Provides

  • Chat UI (floating/embedded modes)
  • Q&A flow with feedback
  • Login state management
  • Theming and branding props
  • customFlow prop for extending functionality

What Your Wrapper Adds

  • Organization-specific flows (tickets, security, etc.)
  • Integration with your backend services (JIRA, APIs)
  • Custom form validation and state management
  • Environment-specific configuration

Key Files to Study

File Purpose
src/components/AccessQABot.tsx Main wrapper component - combines flows, passes props to core
src/flows/*.ts Custom conversation flows using react-chatbotify format
src/utils/flow-context.ts Form state management across flow steps
src/utils/ticket-api.ts Backend integration (JIRA ticket submission)
src/standalone.tsx Standalone JS API wrapper
src/config/constants.ts Environment config and defaults

Creating Custom Flows

Flows use the react-chatbotify format:

import { Flow } from 'react-chatbotify';

export function createMyFlow(): Flow {
  return {
    my_start: {
      message: "Hello! What would you like to do?",
      options: ["Option A", "Option B"],
      path: (params) => {
        if (params.userInput === "Option A") return "option_a_step";
        return "option_b_step";
      },
    },
    option_a_step: {
      message: "You chose A!",
      path: "end",
    },
    // ... more steps
  };
}

Combining Flows

In your wrapper component:

import { QABot, applyFlowSettings } from '@snf/qa-bot-core';

const customFlow = useMemo(() => {
  const flow1 = createMenuFlow();
  const flow2 = createTicketFlow();
  const flow3 = createMyCustomFlow();

  const combined = { ...flow1, ...flow2, ...flow3 };

  // Auto-set chatDisabled based on options/checkboxes
  return applyFlowSettings(combined, { disableOnOptions: true });
}, [dependencies]);

return (
  <QABot
    isLoggedIn={isLoggedIn}
    customFlow={customFlow}
    // ... other props
  />
);

Analytics Integration

qa-bot-core fires analytics events for core functionality (Q&A, ratings, open/close). Your wrapper can add its own events and forward everything to consumers.

1. Define a tracking function type:

// src/utils/analytics.ts
export interface TrackEventInput {
  type: string;
  sessionId?: string;
  timestamp?: number;
  [key: string]: unknown;
}

export type TrackEventFn = (event: TrackEventInput) => void;

2. Accept onAnalyticsEvent prop and create trackers:

// In your wrapper component
const trackEvent: TrackEventFn = useCallback((event) => {
  if (onAnalyticsEvent) {
    onAnalyticsEvent({
      ...event,
      timestamp: event.timestamp ?? Date.now(),
      sessionId: event.sessionId ?? sessionId,
    });
  }
}, [onAnalyticsEvent, sessionId]);

// Handler for core events from qa-bot-core
const handleCoreAnalyticsEvent = useCallback((event) => {
  if (onAnalyticsEvent) {
    onAnalyticsEvent({
      ...event,
      timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),
      sessionId: typeof event.sessionId === 'string' ? event.sessionId : sessionId,
    });
  }
}, [onAnalyticsEvent, sessionId]);

3. Pass trackEvent to your flow creators:

const customFlow = useMemo(() => {
  const menuFlow = createMenuFlow({ trackEvent });
  const ticketFlow = createTicketFlow({ trackEvent });
  // ...
}, [trackEvent]);

4. Wire up core analytics:

<QABot
  onAnalyticsEvent={handleCoreAnalyticsEvent}
  customFlow={customFlow}
  // ...
/>

5. Fire events in your flows:

export function createTicketFlow({ trackEvent }: FlowParams) {
  return {
    ticket_submit: {
      function: async (chatState) => {
        const result = await submitTicket(data);
        trackEvent({
          type: 'ticket_submitted',
          ticketType: 'general',
          success: result.success,
        });
      },
      // ...
    },
  };
}

Consumers can then wire events to their analytics platform:

<YourWrapper
  onAnalyticsEvent={(event) => {
    window.dataLayer?.push({ event: event.type, ...event });
  }}
/>

Environment Variables

Create .env.local from .env.example:

VITE_API_ENDPOINT=https://your-qa-api.com/api/
VITE_RATING_ENDPOINT=https://your-qa-api.com/rating/
VITE_NETLIFY_BASE_URL=https://your-ticket-api.netlify.app
VITE_METRICS_API_ENDPOINT=https://your-metrics-api.com/
VITE_API_KEY=your_api_key_here

Development

# Install dependencies
npm install

# Start dev server
npm run dev

# Build all outputs (ESM, UMD, standalone)
npm run build

# Build library only (ESM, UMD)
npm run build:lib

# Type check
npm run type-check

Build Outputs

File Format Use Case
dist/access-qa-bot.js ESM npm import (React apps)
dist/access-qa-bot.umd.cjs UMD CommonJS require
dist/access-qa-bot.standalone.js IIFE CDN/script tag (bundles Preact)
dist/style.css CSS Styles (auto-imported by standalone)

Version History

This package continues the @snf/access-qa-bot npm package:

Version Repository Notes
v0.x - v2.x qa-bot (deprecated) Original implementation
v3.0.0+ access-qa-bot (this repo) Rewrite using qa-bot-core

What's New in v3.0.0

  • Architecture: Now wraps @snf/qa-bot-core instead of embedding all logic
  • TypeScript: Full TypeScript rewrite with type definitions
  • Build: Vite-based build system (was Rollup + CRA)
  • Props: enabledisLoggedIn (breaking change)
  • Flows: Same user-facing flows, cleaner implementation

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •