
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@buzztrail-ai/presentation
Advanced tools
AI-powered slide presentations with voice interaction for any website platform.
AI-powered slide presentations with voice interaction for any website platform.
@buzztrail-ai/presentation enables AI-powered slide presentations with voice interaction on any website platform. Add an interactive AI-guided slide deck to your site in minutes - no complex setup required.
⚠️ Account Required: You need an active BuzzTrail account to use this package. Sign up at buzztrail.ai to get your customer ID and configure your presentations.
createPresentation()npm install @buzztrail-ai/presentation
yarn add @buzztrail-ai/presentation
pnpm add @buzztrail-ai/presentation
<script src="https://cdn.jsdelivr.net/npm/@buzztrail-ai/presentation@1/buzztrail-presentation.min.js"></script>
Fallback CDN (unpkg):
<script src="https://unpkg.com/@buzztrail-ai/presentation@1/buzztrail-presentation.min.js"></script>
<!-- 1. Add a container element to your page -->
<div id="presentation-container"></div>
<!-- 2. Add the BuzzTrail Presentation script -->
<script src="https://cdn.jsdelivr.net/npm/@buzztrail-ai/presentation@1/buzztrail-presentation.min.js"></script>
<!-- 3. Initialize the presentation -->
<script>
const presentation = createPresentation('presentation-container', {
customerId: 'your-customer-id',
deckId: 'your-deck-id',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key'
});
// Start the presentation
presentation.start();
</script>
That's it! The interactive presentation will appear in your container.
For more control, add callback functions:
<div id="my-presentation"></div>
<script src="https://cdn.jsdelivr.net/npm/@buzztrail-ai/presentation@1/buzztrail-presentation.min.js"></script>
<script>
const presentation = createPresentation('my-presentation', {
customerId: 'your-customer-id',
deckId: 'your-deck-id',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
onStart: () => console.log('Presentation started'),
onEnd: () => console.log('Presentation ended'),
onError: (error) => console.error('Error:', error),
onStateChange: (state) => console.log('State:', state)
});
presentation.start();
</script>
import { createPresentation } from '@buzztrail-ai/presentation';
import type { PresentationConfig } from '@buzztrail-ai/presentation';
const config: PresentationConfig = {
customerId: 'acme-corp',
deckId: 'product-demo-2024',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
// Optional: Viewer configuration
viewer: {
position: 'center',
showControls: true,
controlsPosition: 'bottom',
aspectRatio: '16:9',
showLoading: true,
loadingMessage: 'Loading presentation...'
},
// Optional: Theme
theme: 'auto', // 'light', 'dark', or 'auto'
// Optional: Lead capture
gating: {
enabled: true,
fields: ['email', 'name']
},
// Lifecycle callbacks
onStart: () => {
console.log('Presentation started');
},
onEnd: () => {
console.log('Presentation ended');
},
onError: (error) => {
console.error('Error:', error);
},
onStateChange: (state) => {
console.log('State changed:', state);
}
};
const presentation = createPresentation('my-container', config);
// Start the presentation
await presentation.start();
// Later: End the presentation
await presentation.end();
// Get current state
const state = presentation.getState(); // 'idle' | 'connecting' | 'connected' | 'disconnected'
// Cleanup
presentation.destroy();
The createDemoExperience() function provides an automated investor demo experience with greeter agent warmup and seamless handoff to presentation.
Features:
Basic Usage:
import { createDemoExperience } from '@buzztrail-ai/presentation';
const demo = createDemoExperience('container', {
// Required
customerName: 'Jane Investor',
customerEmail: 'jane@acme.com',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
});
await demo.start();
With Custom Options:
const demo = createDemoExperience('container', {
// Required
customerName: 'Jane Investor',
customerEmail: 'jane@acme.com',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
// Optional
customerCompany: 'Acme Corp',
deckUrl: 'https://example.com/custom-deck',
timelineConfig: 'investor_demo_quick', // 20s handoff for testing
// Callbacks
onHandoff: () => console.log('Transitioning to presentation!'),
onStart: () => console.log('Demo started'),
onEnd: () => console.log('Demo ended'),
});
await demo.start();
Timeline Configurations:
investor_demo (default): 50-second greeter warmupinvestor_demo_quick: 20-second warmup for testingSystem Defaults:
deckUrl providedinvestor_demo (50s)CDN Usage:
<script src="https://cdn.jsdelivr.net/npm/@buzztrail-ai/presentation@1.1/index.umd.js"></script>
<script>
const demo = BuzztrailPresentation.createDemoExperience('container', {
customerName: 'Jane Investor',
customerEmail: 'jane@acme.com',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
});
demo.start();
</script>
Wix requires special handling due to iframe permission restrictions. Follow these steps:
comp-mfy88b7h)<script src="https://cdn.jsdelivr.net/npm/@buzztrail-ai/presentation@1/buzztrail-presentation.min.js"></script>
<script>
const presentation = createPresentation('comp-mfy88b7h', {
customerId: 'your-customer-id',
deckId: 'your-deck-id',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key'
});
presentation.start();
</script>
Each Wix page element has a unique ID. To find the correct container ID for your page:
document.querySelectorAll('[id^="comp-"]').forEach(el => {
console.log(`ID: ${el.id}, Size: ${el.offsetWidth}x${el.offsetHeight}px`);
});
comp-abc123xyz) and use it in createPresentation()This package includes full TypeScript type definitions. No need to install @types packages.
import type {
// Main API
Presentation,
PresentationConfig,
PresentationState,
// Configuration types
ViewerConfig,
GatingConfig,
ThemeMode,
PresentationThemeConfig,
// Session types
Session,
SessionState,
// Error types
PresentationError,
SessionError,
NetworkError,
BotError,
ConfigError,
ErrorSeverity,
ErrorCategory,
RecoveryStrategy,
} from '@buzztrail-ai/presentation';
import { createPresentation } from '@buzztrail-ai/presentation';
import type { PresentationConfig, PresentationState } from '@buzztrail-ai/presentation';
const config: PresentationConfig = {
customerId: 'acme-corp',
deckId: 'product-demo',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
// TypeScript will autocomplete and validate these properties
viewer: {
position: 'center', // Type-checked: 'left' | 'center' | 'right'
showControls: true,
aspectRatio: '16:9' // Type-checked: '16:9' | '4:3' | '21:9'
},
theme: 'auto', // Type-checked: 'light' | 'dark' | 'auto'
// TypeScript will autocomplete and validate callbacks
onStateChange: (state: PresentationState) => {
console.log('State:', state); // Type: 'idle' | 'connecting' | 'connected' | 'disconnected'
}
};
const presentation = createPresentation('my-container', config);
interface PresentationConfig {
// Required: Your BuzzTrail customer ID
customerId: string;
// Required: Deck ID to present
deckId: string;
// Required: Supabase project URL
supabaseUrl: string;
// Required: Supabase anonymous key
supabaseKey: string;
// Optional: Backend API base URL (defaults to production)
apiUrl?: string;
// Optional: Viewer configuration
viewer?: ViewerConfig;
// Optional: Theme mode
theme?: ThemeMode; // 'light' | 'dark' | 'auto'
// Optional: Custom theme configuration
themeConfig?: PresentationThemeConfig;
// Optional: Lead capture configuration
gating?: GatingConfig;
// Optional: Customer metadata for session tracking
customerInfo?: {
name?: string;
email?: string;
[key: string]: unknown;
};
// Optional: Enable debug logging
debug?: boolean;
// Optional: Lifecycle callbacks
onStart?: () => void;
onEnd?: () => void;
onError?: (error: Error) => void;
onStateChange?: (state: PresentationState) => void;
}
interface ViewerConfig {
// Viewer position in container
position?: 'left' | 'center' | 'right'; // default: 'center'
// Show manual slide controls
showControls?: boolean; // default: false
// Controls position
controlsPosition?: 'top' | 'bottom'; // default: 'bottom'
// Video aspect ratio
aspectRatio?: '16:9' | '4:3' | '21:9'; // default: '16:9'
// Show loading state
showLoading?: boolean; // default: true
// Custom loading message
loadingMessage?: string; // default: 'Loading presentation...'
}
interface GatingConfig {
// Enable lead capture form
enabled: boolean;
// Fields to collect
fields: Array<'name' | 'email' | 'phone' | 'company'>;
// Form title (optional)
title?: string;
// Form description (optional)
description?: string;
}
interface PresentationThemeConfig {
// Theme mode
mode: 'light' | 'dark' | 'auto';
// Custom colors (optional)
colors?: {
background?: string;
text?: string;
accent?: string;
border?: string;
};
}
createPresentation(containerOrId, config)Create a presentation instance in the specified container.
Parameters:
containerOrId (string | HTMLElement): DOM element or element ID to inject the presentation intoconfig (PresentationConfig): Configuration optionsReturns: Presentation instance
const presentation = createPresentation('my-container', {
customerId: 'acme-corp',
deckId: 'product-demo',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key'
});
endPresentation(sessionId)End a presentation by session ID.
Parameters:
sessionId (string): The session ID to endReturns: Promise<void>
await endPresentation('session-abc123');
The object returned by createPresentation() has the following methods:
presentation.start()Start the presentation session. Connects to LiveKit room, spawns bots, and begins the interactive presentation.
Returns: Promise<void>
await presentation.start();
presentation.end()End the presentation session. Disconnects from room, cleans up resources.
Returns: Promise<void>
await presentation.end();
presentation.getState()Get the current presentation state.
Returns: PresentationState - 'idle' | 'connecting' | 'connected' | 'disconnected'
const state = presentation.getState();
console.log(state); // 'connected'
presentation.destroy()Destroy the presentation instance and clean up all resources. Call this when removing the presentation from the page.
Returns: void
presentation.destroy();
presentation.sessionIdRead-only property containing the unique session ID.
console.log(presentation.sessionId); // 'session-abc123'
const presentation = createPresentation('container', {
customerId: 'acme-corp',
deckId: 'product-demo',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key'
});
await presentation.start();
const presentation = createPresentation('container', {
customerId: 'acme-corp',
deckId: 'product-demo',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
viewer: {
showControls: true,
controlsPosition: 'bottom'
}
});
await presentation.start();
const presentation = createPresentation('container', {
customerId: 'acme-corp',
deckId: 'product-demo',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
gating: {
enabled: true,
fields: ['name', 'email', 'company'],
title: 'Get Access to Our Product Demo',
description: 'Please provide your information to continue'
}
});
await presentation.start();
const presentation = createPresentation('container', {
customerId: 'acme-corp',
deckId: 'product-demo',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
apiUrl: 'https://api.buzztrail.ai',
viewer: {
position: 'center',
showControls: true,
controlsPosition: 'bottom',
aspectRatio: '16:9',
showLoading: true,
loadingMessage: 'Preparing your personalized demo...'
},
theme: 'auto',
gating: {
enabled: true,
fields: ['name', 'email']
},
customerInfo: {
name: 'Jane Smith',
email: 'jane@example.com',
company: 'Acme Inc'
},
debug: true,
onStart: () => {
console.log('Presentation started');
// Track analytics, show UI elements, etc.
},
onEnd: () => {
console.log('Presentation ended');
// Hide UI elements, show follow-up actions, etc.
},
onError: (error) => {
console.error('Presentation error:', error);
// Show user-friendly error message
},
onStateChange: (state) => {
console.log('State changed to:', state);
// Update UI based on state
if (state === 'connected') {
// Show "presentation is live" indicator
}
}
});
await presentation.start();
Note: Voice interaction requires browser support for WebRTC and getUserMedia API.
Solution: Contact BuzzTrail support to authorize your domain. Domain authorization is managed by BuzzTrail admins for security purposes.
createPresentation()viewer.showControls: true if you want user controlIf you see "Bot spawn failed" errors:
apiUrl is correct (or omit to use default)debug: true to see detailed bot spawn logsEnable debug mode to see detailed logs:
const presentation = createPresentation('container', {
customerId: 'acme-corp',
deckId: 'product-demo',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
debug: true // Enable debug logging
});
Debug logs will show:
<!-- Add via Wix Settings → Advanced → Custom Code → Body - end -->
<script src="https://cdn.jsdelivr.net/npm/@buzztrail-ai/presentation@1/buzztrail-presentation.min.js"></script>
<script>
// Replace these values with your credentials
const CUSTOMER_ID = 'your-customer-id';
const DECK_ID = 'your-deck-id';
const SUPABASE_URL = 'https://your-project.supabase.co';
const SUPABASE_KEY = 'your-anon-key';
const CONTAINER_ID = 'comp-mfy88b7h'; // Your Wix element ID
const presentation = createPresentation(CONTAINER_ID, {
customerId: CUSTOMER_ID,
deckId: DECK_ID,
supabaseUrl: SUPABASE_URL,
supabaseKey: SUPABASE_KEY,
viewer: {
showControls: true,
aspectRatio: '16:9'
},
onStart: () => console.log('Presentation started!'),
onEnd: () => console.log('Presentation ended!'),
onError: (error) => console.error('Error:', error.message)
});
presentation.start().catch(error => {
console.error('Failed to start presentation:', error);
});
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BuzzTrail Presentation Demo</title>
<style>
body {
margin: 0;
padding: 20px;
font-family: Arial, sans-serif;
background: #f5f5f5;
}
h1 {
text-align: center;
color: #333;
}
#presentation-container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
min-height: 600px;
padding: 20px;
}
.status {
text-align: center;
padding: 10px;
margin: 20px auto;
max-width: 400px;
border-radius: 4px;
background: #e3f2fd;
color: #1976d2;
}
</style>
</head>
<body>
<h1>Product Demo Presentation</h1>
<div id="status" class="status">
Initializing presentation...
</div>
<div id="presentation-container"></div>
<!-- Load BuzzTrail Presentation SDK -->
<script src="https://cdn.jsdelivr.net/npm/@buzztrail-ai/presentation@1/buzztrail-presentation.min.js"></script>
<script>
// Configuration
const config = {
customerId: 'your-customer-id',
deckId: 'your-deck-id',
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key',
viewer: {
position: 'center',
showControls: true,
controlsPosition: 'bottom',
aspectRatio: '16:9'
},
theme: 'auto',
debug: true,
onStart: () => {
updateStatus('Presentation is live!', 'success');
},
onEnd: () => {
updateStatus('Presentation ended. Thank you!', 'info');
},
onError: (error) => {
updateStatus('Error: ' + error.message, 'error');
console.error('Presentation error:', error);
},
onStateChange: (state) => {
console.log('State:', state);
if (state === 'connecting') {
updateStatus('Connecting...', 'info');
} else if (state === 'connected') {
updateStatus('Connected!', 'success');
} else if (state === 'disconnected') {
updateStatus('Disconnected', 'info');
}
}
};
// Helper function to update status
function updateStatus(message, type = 'info') {
const statusEl = document.getElementById('status');
statusEl.textContent = message;
statusEl.style.background = {
success: '#e8f5e9',
error: '#ffebee',
info: '#e3f2fd'
}[type];
statusEl.style.color = {
success: '#2e7d32',
error: '#c62828',
info: '#1976d2'
}[type];
}
// Create and start presentation
const presentation = createPresentation('presentation-container', config);
presentation.start()
.then(() => {
console.log('Presentation started successfully');
})
.catch(error => {
updateStatus('Failed to start: ' + error.message, 'error');
console.error('Failed to start presentation:', error);
});
// Cleanup on page unload
window.addEventListener('beforeunload', () => {
presentation.destroy();
});
</script>
</body>
</html>
See CHANGELOG.md for version history.
Proprietary - BuzzTrail AI
Built with TypeScript • AI-Powered Presentations • Made for modern web platforms
FAQs
AI-powered slide presentations with voice interaction for any website platform.
We found that @buzztrail-ai/presentation demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.