@snf/access-qa-bot
v3.1.1
Published
ACCESS-specific wrapper around @snf/qa-bot-core
Readme
ACCESS Q&A Bot
A React wrapper around @snf/qa-bot-core that adds ACCESS-specific functionality. This package serves two purposes:
- Production use: The official Q&A bot for ACCESS websites
- Reference implementation: An example of how to build organization-specific wrappers around qa-bot-core
Installation
npm install @snf/access-qa-botFeatures
- 🤖 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="[email protected]"
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 |
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/[email protected]/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 |
CDN Usage
unpkg (npm-based)
<script src="https://unpkg.com/@snf/[email protected]/dist/access-qa-bot.standalone.js"></script>jsdelivr (GitHub-based)
<script src="https://cdn.jsdelivr.net/gh/necyberteam/[email protected]/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-chatbotifyWhat qa-bot-core Provides
- Chat UI (floating/embedded modes)
- Q&A flow with feedback
- Login state management
- Theming and branding props
customFlowprop 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_hereDevelopment
# 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-checkBuild 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:
enabled→isLoggedIn(breaking change) - Flows: Same user-facing flows, cleaner implementation
License
MIT
