Overview



The (JS API) Pypestream SDK enables you to embed conversational AI chat interfaces into your web applications. It supports both inline embedding and popup window modes, with extensive customization options and event handling capabilities.

Installation

Include the Pypestream SDK script in your HTML:

<script src="https://your-pypestream-domain/config.js"></script>

Getting Started

Basic Usage

// Configure and boot the chat
Pypestream.config({
  APP_ID: 'your-app-id',
  debugMode: false,
  displayMode: 'window'
});

Pypestream.boot();

Inline Mode

const targetElement = document.getElementById('chat-container');

Pypestream.config({
  APP_ID: 'your-app-id',
  displayMode: 'inline'
});

Pypestream.boot({}, targetElement);

API Reference

Configuration

Pypestream.config(config)

Configures the Pypestream instance before initialization. Can be called before boot().

Parameters:

ParameterTypeRequiredDescription
configObjectYesConfiguration object

Configuration Object Properties:

PropertyTypeDefaultDescription
APP_IDString-Required. Your Pypestream application ID
debugModeBooleanfalseEnable debug logging in console
displayModeString'window'Display mode: 'window' or 'inline'
APIModeBooleantrueEnable API mode
withInlineAppLoaderBooleantrueShow loading animation in inline mode
initialMessagesObject-Configure initial welcome messages
initialMessages.welcomeMessageString''Custom welcome message text
initialMessages.showNextThinkingBubbleBooleantrueShow thinking bubble animation
showSurveyForWindowModeBoolean-Enable survey in window mode after chat ends

Example:

Pypestream.config({
  APP_ID: 'your-app-id-here',
  debugMode: true,
  displayMode: 'inline',
  withInlineAppLoader: true,
  initialMessages: {
    welcomeMessage: 'Hello! How can I help you today?',
    showNextThinkingBubble: true
  }
});

Initialization

Pypestream.boot(config, targetElement)

Initializes and starts the chat interface. Must be called before any other methods (except config()).

Parameters:

ParameterTypeRequiredDescription
configObjectYesConfiguration object (same as config() method)
targetElementHTMLElementNoTarget DOM element for inline mode

Behavior:

  • If targetElement is provided, automatically switches to 'inline' display mode
  • If targetElement is omitted, uses 'window' display mode
  • Can be called multiple times - subsequent calls will show the chat if hidden
  • Automatically calls config() internally with provided configuration

Example - Window Mode:

Pypestream.boot({
  APP_ID: 'your-app-id'
});

Example - Inline Mode:

const container = document.getElementById('chat-container');

Pypestream.boot({
  APP_ID: 'your-app-id'
}, container);

Notes:

  • Window mode requires a user interaction (button click) to open the popup due to browser restrictions
  • Returns immediately if already booted; shows chat if currently hidden

Display Control

Pypestream.show()

Shows the chat interface in inline mode.

Behavior:

  • Only works in 'inline' display mode
  • Displays previously hidden chat interface
  • Triggers onShow event handlers
  • Shows inline app loader if enabled

Example:

Pypestream.show();

Warnings:

  • Must call boot() before show()
  • Does not work in 'window' display mode

Pypestream.hide()

Hides the chat interface in inline mode.

Behavior:

  • Only works in 'inline' display mode
  • Hides the chat interface without destroying it
  • Triggers onHide event handlers
  • Hides inline app loader if enabled

Example:

Pypestream.hide();

Warnings:

  • Must call boot() before hide()
  • Does not work in 'window' display mode

Pypestream.toggle()

Toggles the chat interface visibility in inline mode.

Behavior:

  • Only works in 'inline' display mode
  • Shows chat if currently hidden
  • Hides chat if currently showing
  • Triggers corresponding onShow or onHide event handlers

Example:

// Attach to a button
document.getElementById('toggle-chat').addEventListener('click', () => {
  Pypestream.toggle();
});

Warnings:

  • Must call boot() before toggle()
  • Does not work in 'window' display mode

Pypestream.isVisible()

Returns the current visibility state of the chat interface.

Returns:

TypeDescription
Booleantrue if chat is visible, false otherwise

Example:

if (Pypestream.isVisible()) {
  console.log('Chat is currently visible');
} else {
  console.log('Chat is currently hidden');
}

Lifecycle Management

Pypestream.shutdown()

Completely shuts down and removes the chat interface.

Behavior:

  • Closes the chat interface
  • Removes iframe and container elements from DOM
  • Clears all body scroll locks
  • Closes LaunchDarkly client connection
  • Resets boot state
  • Preserves state during user redirects
  • Clears visibility state from localStorage

Example:

Pypestream.shutdown();

Notes:

  • After shutdown, you can call boot() again to reinitialize
  • Does not remove the chat immediately if user is being redirected
  • Window mode: closes the popup window
  • Inline mode: removes wrapper element after brief delay

Warnings:

  • Must call boot() before shutdown()

Pypestream.restartChat()

Restarts the current chat session without shutting down the interface.

Behavior:

  • Clears current conversation
  • Starts a new chat session
  • Maintains the same configuration
  • Keeps the interface visible
  • Triggers onChatRestart event handlers

Example:

// Restart chat on button click
document.getElementById('restart-btn').addEventListener('click', () => {
  Pypestream.restartChat();
});

Warnings:

  • Must call boot() before restartChat()

Configuration Updates

Pypestream.updatePypestreamConfig(pypestreamConfig)

Updates the Pypestream configuration dynamically after initialization.

Parameters:

ParameterTypeRequiredDescription
pypestreamConfigObjectYesNew configuration object to merge

Behavior:

  • Updates configuration without restarting the chat
  • Merges new config with existing configuration
  • Sends update message to iframe
  • Must be called after app iframe is fully mounted

Example:

Pypestream.updatePypestreamConfig({
  debugMode: true,
  initialMessages: {
    welcomeMessage: 'Updated welcome message!'
  }
});

Warnings:

  • Must wait for boot() to complete and iframe to mount
  • Warning displayed if called before iframe is mounted

Event Handlers

Event handlers allow you to respond to various chat lifecycle events.

Pypestream.onShow(handler)

Registers a callback for when the chat interface is shown.

Parameters:

ParameterTypeRequiredDescription
handlerFunctionYesCallback function to execute

Example:

Pypestream.onShow(() => {
  console.log('Chat interface shown');
  // Track analytics event
  analytics.track('Chat Opened');
});

Pypestream.onHide(handler)

Registers a callback for when the chat interface is hidden.

Parameters:

ParameterTypeRequiredDescription
handlerFunctionYesCallback function to execute

Example:

Pypestream.onHide(() => {
  console.log('Chat interface hidden');
  // Track analytics event
  analytics.track('Chat Closed');
});

Pypestream.onChatEnd(handler)

Registers a callback for when a chat session ends.

Parameters:

ParameterTypeRequiredDescription
handlerFunctionYesCallback function to execute

Example:

Pypestream.onChatEnd(() => {
  console.log('Chat session ended');
  // Show feedback form
  showFeedbackForm();
});

Pypestream.onChatRestart(handler)

Registers a callback for when a chat session is restarted.

Parameters:

ParameterTypeRequiredDescription
handlerFunctionYesCallback function to execute

Example:

Pypestream.onChatRestart(() => {
  console.log('Chat session restarted');
  // Reset custom state
  resetChatAnalytics();
});

Pypestream.onSetupComplete(handler)

Registers a callback for when initial setup completes.

Parameters:

ParameterTypeRequiredDescription
handlerFunctionYesCallback function to execute

Example:

Pypestream.onSetupComplete(() => {
  console.log('Pypestream setup complete');
  // Initialize integrations
  initializeChatIntegrations();
});

Notes:

  • Called after iframe loads and initial configuration is complete
  • Custom event queue is processed after this event

Pypestream.onFirstMessage(handler)

Registers a callback for when the first message is received.

Parameters:

ParameterTypeRequiredDescription
handlerFunctionYesCallback function to execute

Example:

Pypestream.onFirstMessage(() => {
  console.log('First message received');
  // Track time to first message
  const loadTime = performance.now();
  analytics.track('First Message Time', { loadTime });
});

Pypestream.onMount(handler)

Registers a callback for when the app iframe is mounted in the DOM.

Parameters:

ParameterTypeRequiredDescription
handlerFunctionYesCallback function to execute

Example:

Pypestream.onMount(() => {
  console.log('Pypestream iframe mounted');
  // Perform post-mount operations
  customizeUIElements();
});

Custom Events

Pypestream.registerForEvents(eventHandles, eventTarget, eventBuffer)

Registers custom event listeners for advanced integration scenarios.

Parameters:

ParameterTypeRequiredDescription
eventHandlesArray/ObjectYesEvent handlers configuration
eventTargetStringYesTarget identifier for events
eventBufferBooleanNoWhether to buffer events

Behavior:

  • Enables listening to custom events from the chat interface
  • Events are queued if setup is not complete
  • Automatically sends queued events after setup completes

Example:

Pypestream.registerForEvents(
  {
    'CUSTOM_EVENT': (data) => {
      console.log('Custom event received:', data);
    }
  },
  'myEventTarget',
  true
);

Notes:

  • Events are buffered in queue until iframe setup completes
  • All queued events are sent after onSetupComplete fires

Display Modes

Window Mode

Opens the chat in a separate popup window.

Features:

  • Opens in new browser window
  • Customizable dimensions (default: 400x600px)
  • Automatically focuses on boot if already open
  • Handles window close events
  • Optional survey display after chat ends

Configuration:

Pypestream.config({
  APP_ID: 'your-app-id',
  displayMode: 'window',
  showSurveyForWindowMode: true // Optional: show survey after close
});

// Must be triggered by user action
document.getElementById('open-chat').addEventListener('click', () => {
  Pypestream.boot();
});

Window Properties:

  • Width: 400px
  • Height: 600px
  • No scrollbars, menubar, toolbar, or status bar
  • Responsive meta viewport tag included

Browser Restrictions:

  • Must be triggered by user interaction (click, keyboard event)
  • Cannot be called on page load due to popup blockers
  • Warning displayed if popup is blocked

Inline Mode

Embeds the chat directly into your webpage.

Features:

  • Embedded in specified container element
  • Responsive sizing based on configuration
  • Optional loading animation
  • Body scroll lock on mobile devices when active
  • Seamless integration with page content

Configuration:

const container = document.getElementById('chat-container');

Pypestream.config({
  APP_ID: 'your-app-id',
  displayMode: 'inline',
  withInlineAppLoader: true
});

Pypestream.boot({}, container);

Container Styling:

The SDK automatically styles the container with:

  • Fixed positioning (if not specified)
  • Responsive width and height
  • Maximum dimensions to prevent overflow
  • Custom CSS can be injected via configuration

Methods Available in Inline Mode:

  • show() - Display the chat
  • hide() - Hide the chat
  • toggle() - Toggle visibility
  • isVisible() - Check current state

Advanced Features

Accessibility

The SDK includes comprehensive accessibility features:

ARIA Live Regions:

  • Polite announcements for non-urgent updates
  • Assertive announcements for critical messages
  • Automatic DOM cleanup after announcements

Screen Reader Support:

  • Proper ARIA labels and roles
  • Semantic HTML structure
  • Keyboard navigation support

Focus Management:

  • Automatic focus on show/boot
  • Focus trapping in modal contexts
  • Restore focus on hide

Mobile Support

Features:

  • Responsive viewport configuration
  • Touch-friendly interface
  • Body scroll lock when chat is active
  • Special handling for mobile browser tabs
  • Page lifecycle event handling

Mobile-Specific Behavior:

// Body scroll is automatically locked when chat shows on mobile
// Using body-scroll-lock library

Performance Optimization

Lazy Loading:

  • Optional inline app loader for perceived performance
  • Iframe loads asynchronously
  • Debounced resize listeners

Resource Management:

  • Automatic cleanup on shutdown
  • Memory leak prevention
  • Efficient event listener management

Performance Metrics:

The SDK tracks timing for:

  • Total setup time
  • First message time
  • App mount time
  • Iframe load time

Access via browser console when debugMode: true.


Error Handling

Console Warnings

The SDK provides clear warnings for common issues:

// Missing configuration
Pypestream Warning: You must call Pypestream.boot() before 'show'.

// Popup blocked
Pypestream Warning: You cannot open a browser window on page load. 
It must be tied to a user event.

// Invalid display mode operation
Pypestream Warning: Cannot show chat in display mode 'window'.

Debug Mode

Enable detailed logging:

Pypestream.config({
  debugMode: true
});

// Console output:
// PSDEBUG: Pypestream.show()
// PSDEBUG: Iframe loaded

Security

Content Security

  • DOMPurify sanitization for all dynamic content
  • XSS protection on ARIA live announcements
  • Secure iframe sandbox attributes

Iframe Sandbox Permissions:

sandbox="allow-same-origin allow-scripts allow-forms allow-modals 
         allow-popups allow-popups-to-escape-sandbox allow-presentation 
         allow-top-navigation allow-top-navigation-by-user-activation 
         allow-downloads"

Permissions

The iframe requests these browser permissions:

  • Geolocation
  • Camera
  • Microphone
  • Payment API

Browser Compatibility

Supported Browsers

  • Chrome (latest 2 versions)
  • Firefox (latest 2 versions)
  • Safari (latest 2 versions)
  • Edge (latest 2 versions)

Required Features

  • ES6+ JavaScript support
  • PostMessage API
  • LocalStorage
  • SessionStorage
  • Iframe support

Code Examples

Complete Integration Example

<!DOCTYPE html>
<html>
<head>
  <title>Pypestream Integration</title>
</head>
<body>
  <div id="chat-container"></div>
  
  <button id="open-chat">Open Chat</button>
  <button id="close-chat">Close Chat</button>
  
  <script src="https://your-domain/pypestream-config.js"></script>
  <script>
    // Configure Pypestream
    Pypestream.config({
      APP_ID: 'your-app-id-here',
      debugMode: true,
      displayMode: 'inline',
      withInlineAppLoader: true,
      initialMessages: {
        welcomeMessage: 'Welcome! How can we help?',
        showNextThinkingBubble: true
      }
    });
    
    // Set up event handlers
    Pypestream.onSetupComplete(() => {
      console.log('Setup complete!');
    });
    
    Pypestream.onShow(() => {
      console.log('Chat opened');
      document.getElementById('open-chat').disabled = true;
      document.getElementById('close-chat').disabled = false;
    });
    
    Pypestream.onHide(() => {
      console.log('Chat closed');
      document.getElementById('open-chat').disabled = false;
      document.getElementById('close-chat').disabled = true;
    });
    
    Pypestream.onChatEnd(() => {
      console.log('Chat session ended');
      // Show feedback survey
    });
    
    // Initialize
    const container = document.getElementById('chat-container');
    Pypestream.boot({}, container);
    
    // Button handlers
    document.getElementById('open-chat').addEventListener('click', () => {
      Pypestream.show();
    });
    
    document.getElementById('close-chat').addEventListener('click', () => {
      Pypestream.hide();
    });
  </script>
</body>
</html>

React Integration

import { useEffect, useRef } from 'react';

function ChatWidget() {
  const containerRef = useRef(null);
  const [isVisible, setIsVisible] = useState(false);
  
  useEffect(() => {
    // Configure Pypestream
    window.Pypestream.config({
      APP_ID: 'your-app-id',
      displayMode: 'inline',
      debugMode: process.env.NODE_ENV === 'development'
    });
    
    // Set up event handlers
    window.Pypestream.onShow(() => setIsVisible(true));
    window.Pypestream.onHide(() => setIsVisible(false));
    
    // Boot Pypestream
    if (containerRef.current) {
      window.Pypestream.boot({}, containerRef.current);
    }
    
    // Cleanup
    return () => {
      window.Pypestream.shutdown();
    };
  }, []);
  
  return (
    <div>
      <div ref={containerRef} id="chat-container" />
      <button onClick={() => window.Pypestream.toggle()}>
        {isVisible ? 'Hide Chat' : 'Show Chat'}
      </button>
    </div>
  );
}

Analytics Integration

// Track chat interactions with your analytics platform
Pypestream.config({
  APP_ID: 'your-app-id'
});

Pypestream.onSetupComplete(() => {
  analytics.track('Chat Initialized');
});

Pypestream.onShow(() => {
  analytics.track('Chat Opened', {
    timestamp: new Date().toISOString()
  });
});

Pypestream.onHide(() => {
  analytics.track('Chat Closed', {
    timestamp: new Date().toISOString()
  });
});

Pypestream.onFirstMessage(() => {
  analytics.track('First Message Received', {
    loadTime: performance.now()
  });
});

Pypestream.onChatEnd(() => {
  analytics.track('Chat Session Ended', {
    duration: sessionDuration
  });
});

Pypestream.boot();

Troubleshooting

Common Issues

Popup Blocked in Window Mode

Problem: Window mode popup is blocked by browser.

Solution:

// Must be triggered by user interaction
document.getElementById('chat-button').addEventListener('click', () => {
  Pypestream.boot({
    APP_ID: 'your-app-id',
    displayMode: 'window'
  });
});

Chat Not Showing

Problem: Chat interface doesn't appear after calling show().

Solutions:

  1. Ensure boot() was called first
  2. Verify display mode is set to 'inline'
  3. Check browser console for warnings
  4. Verify container element exists in DOM
// Correct order
Pypestream.boot({}, targetElement);
// Wait for setup
Pypestream.onSetupComplete(() => {
  Pypestream.show();
});

Configuration Not Applied

Problem: Configuration changes not taking effect.

Solution:

Call config() before boot():

// Correct order
Pypestream.config({ APP_ID: 'your-app-id' });
Pypestream.boot();

Multiple Handler Calls

Problem: Event handlers fire multiple times.

Explanation: Event handlers are additive. Each call to onShow(), onHide(), etc. adds a new handler.

Solution:

// Only call handler registration once
Pypestream.onShow(() => {
  console.log('Chat shown');
});

// Don't call again unless you want multiple handlers

Best Practices

Initialization

  1. Configure before boot:
Pypestream.config({ APP_ID: 'your-app-id' });
Pypestream.boot();
  1. Use setup complete handler for initialization logic:
Pypestream.onSetupComplete(() => {
  // Initialize integrations here
  initializeAnalytics();
});
  1. Handle cleanup properly:
window.addEventListener('beforeunload', () => {
  Pypestream.shutdown();
});

Performance

  1. Enable app loader in inline mode:
Pypestream.config({
  withInlineAppLoader: true
});
  1. Use debounced event handlers:
const debouncedHandler = debounce(() => {
  // Handler logic
}, 300);

Pypestream.onShow(debouncedHandler);

User Experience

  1. Provide visual feedback:
Pypestream.onShow(() => {
  button.textContent = 'Close Chat';
});

Pypestream.onHide(() => {
  button.textContent = 'Open Chat';
});
  1. Handle errors gracefully:
try {
  Pypestream.boot();
} catch (error) {
  console.error('Failed to initialize chat:', error);
  // Show fallback contact method
}

Security

  1. Validate user input before passing to config:
const sanitizedConfig = {
  APP_ID: validateAppId(userInput.appId),
  debugMode: Boolean(userInput.debug)
};

Pypestream.config(sanitizedConfig);
  1. Use HTTPS in production:
// Ensure SDK is loaded via HTTPS
<script src="https://secure-domain/config.js"></script>

Migration Guide

From v2.0 to v3.0

If you're upgrading from a previous version, note these changes:

Changed APIs:

  • updatePypestreamConfig() now requires iframe to be mounted
  • Event handlers are now additive (multiple calls add handlers)

New Features:

  • onMount() handler
  • onFirstMessage() handler
  • onSetupComplete() handler
  • Inline app loader support
  • LaunchDarkly feature flag integration

Removed Features:

  • Legacy browser support (IE11)

Support

Resources

Feature Flags

The SDK uses LaunchDarkly for feature flag management. Flags are automatically configured based on your APP_ID.


Changelog

Version 3.0.0

  • Added onMount(), onFirstMessage(), and onSetupComplete() event handlers
  • Improved inline mode with app loader
  • Enhanced mobile support with body scroll lock
  • Added performance timing metrics
  • LaunchDarkly integration
  • Improved accessibility with ARIA live regions
  • Better error handling and warnings

License

Copyright © Pypestream. All rights reserved.