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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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:

  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="[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-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