https://github.com/vbrazo/upriser-agents
A standalone JavaScript widget for integrating Upriser ElevenLabs ConvAI into any website.
https://github.com/vbrazo/upriser-agents
Last synced: 5 months ago
JSON representation
A standalone JavaScript widget for integrating Upriser ElevenLabs ConvAI into any website.
- Host: GitHub
- URL: https://github.com/vbrazo/upriser-agents
- Owner: vbrazo
- License: mit
- Created: 2025-09-23T02:47:15.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-09-23T03:16:51.000Z (9 months ago)
- Last Synced: 2025-09-23T04:23:12.378Z (9 months ago)
- Language: JavaScript
- Homepage:
- Size: 7.04 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Upriser Widget
A standalone JavaScript widget for integrating Upriser ConvAI into any website. This package provides both npm module support and raw JavaScript files for maximum flexibility.
## ๐ Table of Contents
- [Installation](#installation)
- [Usage](#usage)
- [NPM Module Usage](#npm-module-usage)
- [Raw JavaScript Usage](#raw-javascript-usage)
- [๐ Modal & Client Tools (NEW!)](#-modal--client-tools-new)
- [๐จ Whitelabel Features](#-whitelabel-features)
- [Configuration Options](#configuration-options)
- [API Methods](#api-methods)
- [React Integration Example](#react-integration-example)
- [๐ฏ Client Tools Use Cases](#-client-tools-use-cases)
- [Vue Integration Example](#vue-integration-example)
- [๐ก Event Handling](#-event-handling)
- [Browser Support](#browser-support)
- [Features](#features)
- [Development](#development)
- [๐ Continuous Integration (CI)](#-continuous-integration-ci)
- [File Structure](#file-structure)
- [License](#license)
- [Support](#support)
## Installation
### Option 1: NPM Package (Recommended for React, Vue, Angular, etc.)
```bash
npm install @upriser.ai/widget
```
### Option 2: CDN / Direct Script Inclusion
```html
```
## Usage
### NPM Module Usage
#### ES Modules (Modern bundlers like Webpack, Vite, etc.)
```javascript
import UpriserWidget from "@upriser.ai/widget/dist/upriser-widget.js";
// Create and initialize the widget
const widget = new UpriserWidget({
agentId: "your-agent-id-here",
fontColor: "#ffffff",
linkColor: "#007bff",
});
// Initialize the widget
widget
.init()
.then(() => {
console.log("Upriser widget initialized successfully!");
})
.catch((error) => {
console.error("Failed to initialize widget:", error);
});
```
#### CommonJS (Node.js style)
```javascript
import UpriserWidget from "@upriser.ai/widget/dist/upriser-widget.js";
const widget = new UpriserWidget({
agentId: "your-agent-id-here",
debug: false,
});
widget.init();
```
#### TypeScript Support
The package includes full TypeScript definitions:
```typescript
import UpriserWidget, { UpriserWidgetConfig } from "@upriser.ai/widget";
const config: UpriserWidgetConfig = {
agentId: "your-agent-id-here",
};
const widget = new UpriserWidget(config);
widget.init();
```
### Raw JavaScript Usage
#### Basic Usage
```html
My Website
// The widget will auto-initialize with default settings
// Or manually initialize:
// Option 1: Use the global instance (auto-created)
if (window.upriserWidget) {
console.log("Widget auto-initialized");
}
// Option 2: Create your own instance
const myWidget = new UpriserWidget({
agentId: "your-custom-agent-id",
fontColor: "#ffffff",
linkColor: "#007bff",
});
myWidget.init();
```
#### Custom Configuration
```html
// Configure before the script loads (for auto-initialization)
window.UPRISER_WIDGET_CONFIG = {
agentId: "your-agent-id-here",
};
// Disable auto-initialization if you want full control
// window.UPRISER_DISABLE_AUTO_INIT = true;
```
#### WordPress Integration
```php
// In your WordPress theme's functions.php
function add_upriser_widget() {
?>
window.UPRISER_WIDGET_CONFIG = {
agentId: '<?php echo get_option('upriser_agent_id', 'agent_8401k5nnvgqpezf9fd17t3tb7t69'); ?>'
};
{
const url = parameters?.url || "https://meetings.hubspot.com/default";
return widget.openModal({
url,
title: "Schedule a Demo",
onClose: () => console.log("Demo modal closed"),
});
},
},
});
```
### Client Tools System
Client tools are JavaScript functions that the AI agent can call to perform specific actions:
```javascript
// Option 1: Global client tools
window.UPRISER_CLIENT_TOOLS = {
show_demo_form: (parameters) => {
const url = parameters?.url || "https://meetings.hubspot.com/default";
// Open your custom modal or use the built-in one
return { success: true, message: "Demo form opened" };
},
show_vehicle_page: (parameters) => {
if (!parameters?.url) {
return { success: false, message: "URL required" };
}
// Open vehicle details modal
return { success: true, message: "Vehicle page opened" };
},
};
// Option 2: Widget configuration
const widget = new UpriserWidget({
agentId: "your-agent-id",
clientTools: {
// Your client tools here
},
});
```
## ๐จ Whitelabel Features
Upriser Widget supports complete whitelabeling with custom branding and colors!
### Custom HTML Element
```html
```
### Custom Element Attributes
| Attribute | Type | Default | Description |
| ------------ | ------ | --------- | -------------------------------------- |
| `agent-id` | string | Required | Upriser agent ID |
| `font-color` | string | `#ffffff` | Color for "Powered by Upriser.ai" text |
| `link-color` | string | `#ffffff` | Color for links to Upriser.ai |
### Dynamic Color Changes
You can change colors dynamically using JavaScript:
```javascript
// Get the widget element
const widget = document.querySelector("upriser-convai");
// Change colors
widget.setAttribute("font-color", "#ff6b6b");
widget.setAttribute("link-color", "#4ecdc4");
```
### JavaScript Class with Colors
Use the UpriserWidget class with custom colors:
```javascript
const widget = new UpriserWidget({
agentId: "agent_8401k5nnvgqpezf9fd17t3tb7t69",
fontColor: "#ffffff",
linkColor: "#007bff",
});
widget.init();
```
### Color Examples
```html
```
### Benefits of Whitelabel Version
- โ
**Custom Colors** - Match your brand colors exactly
- โ
**Dynamic Updates** - Change colors on the fly
- โ
**Better Events** - Enhanced event handling and API
## Configuration Options
| Option | Type | Default | Description |
| ----------------- | ------------------------ | -------------------------------------- | --------------------------------------------------------- |
| `agentId` | string | `'agent_8401k5nnvgqpezf9fd17t3tb7t69'` | Upriser agent ID to use |
| `widgetContainer` | HTMLElement \| null | `null` | Container to append widget to (defaults to document.body) |
| `debug` | boolean | `false` | Enable debug logging |
| `fontColor` | string | `'#ffffff'` | Custom color for "Powered by Upriser.ai" text |
| `linkColor` | string | `'#ffffff'` | Custom color for links to Upriser.ai |
| `clientTools` | Record | `{}` | **NEW!** Custom functions that the AI agent can call |
## API Methods
### `widget.init()`
Initializes the widget. Returns a Promise.
```javascript
await widget.init();
```
### `widget.updateConfig(newConfig)`
Updates the widget configuration.
```javascript
widget.updateConfig({ debug: true, agentId: "new-agent-id" });
```
### `widget.test()`
Tests widget functionality and returns status.
```javascript
const status = widget.test();
console.log("Widget status:", status);
```
### `widget.openModal(options)`
**NEW!** Opens a modal with the specified URL and options.
```javascript
const result = widget.openModal({
url: "https://meetings.hubspot.com/demo",
title: "Schedule a Demo",
onClose: () => console.log("Modal closed"),
});
console.log(result);
// { success: true, message: "Modal opened successfully" }
```
### `widget.setClientTools(clientTools)`
**NEW!** Updates the client tools available to the AI agent.
```javascript
widget.setClientTools({
show_demo_form: (parameters) => {
const url = parameters?.url || "https://meetings.hubspot.com/default";
return widget.openModal({ url, title: "Schedule Demo" });
},
show_vehicle_page: (parameters) => {
if (!parameters?.url) {
return { success: false, message: "URL required" };
}
return widget.openModal({
url: parameters.url,
title: parameters.title || "Vehicle Details",
});
},
});
```
### `widget.getClientTools()`
**NEW!** Returns the current client tools configuration.
```javascript
const tools = widget.getClientTools();
console.log("Available tools:", Object.keys(tools));
```
### `widget.destroy()`
Destroys the widget and cleans up all resources.
```javascript
widget.destroy();
```
## React Integration Example
```jsx
import React, { useEffect, useRef } from "react";
import UpriserWidget from "@upriser.ai/widget/dist/upriser-widget.js";
function ChatWidget({ agentId, debug = false }) {
const widgetRef = useRef(null);
const containerRef = useRef(null);
useEffect(() => {
if (containerRef.current) {
const widget = new UpriserWidget({
agentId,
debug,
widgetContainer: containerRef.current,
});
widget.init().catch(console.error);
widgetRef.current = widget;
return () => {
if (widgetRef.current) {
widgetRef.current.destroy();
}
};
}
}, [agentId, debug]);
return
;
}
export default ChatWidget;
```
## ๐ฏ Client Tools Use Cases
### Demo Scheduling Integration
Perfect for sales teams and lead generation websites:
```javascript
// Setup demo scheduling client tools
window.UPRISER_CLIENT_TOOLS = {
show_demo_form: (parameters) => {
const url = parameters?.url || "https://meetings.hubspot.com/default";
// Use the built-in modal system
if (window.upriserWidgetInstance) {
return window.upriserWidgetInstance.openModal({
url,
title: "Schedule a Demo",
onClose: () => {
console.log("Demo modal closed");
// Track analytics
},
});
}
// Fallback to custom implementation
openCustomDemoModal(url);
return { success: true, message: "Demo form opened" };
},
};
// The AI agent can now call: "Let me show you our demo scheduling form"
// This will trigger the show_demo_form client tool
```
### Vehicle Browsing Integration
Ideal for automotive dealerships:
```javascript
// Setup vehicle browsing client tools
window.UPRISER_CLIENT_TOOLS = {
show_vehicle_page: (parameters) => {
const url = parameters?.url;
const title = parameters?.title || "Vehicle Details";
// Validate required parameters
if (!url || typeof url !== "string") {
console.warn("show_vehicle_page requires a valid URL");
return { success: false, message: "Missing or invalid URL parameter" };
}
// Use the built-in modal system
if (window.upriserWidgetInstance) {
return window.upriserWidgetInstance.openModal({
url,
title,
onClose: () => {
console.log("Vehicle modal closed");
},
});
}
// Fallback to new tab
window.open(url, "_blank", "noopener,noreferrer");
return {
success: true,
message: "Opened vehicle page in new tab (fallback)",
};
},
};
// The AI agent can now call: "Let me show you this vehicle"
// This will trigger the show_vehicle_page client tool with the vehicle URL
```
### Custom Modal Content
You can also create completely custom modals:
```javascript
window.UPRISER_CLIENT_TOOLS = {
show_product_catalog: (parameters) => {
const category = parameters?.category || "all";
const searchTerm = parameters?.search || "";
// Create custom modal content
const modalContent = document.createElement("div");
modalContent.innerHTML = `
Product Catalog
All Categories
Electronics
Clothing
`;
// Use built-in modal with custom content
if (window.upriserWidgetInstance) {
const modal = window.upriserWidgetInstance.createModal({
title: "Product Catalog",
content: modalContent,
className: "product-catalog-modal",
});
if (modal) {
return { success: true, message: "Product catalog opened" };
}
}
return { success: false, message: "Failed to open catalog" };
},
};
```
## Vue Integration Example
```vue
import UpriserWidget from "@upriser.ai/widget/dist/upriser-widget.js";
export default {
name: "UpriserChat",
props: {
agentId: {
type: String,
default: "agent_8401k5nnvgqpezf9fd17t3tb7t69",
},
debug: {
type: Boolean,
default: false,
},
},
data() {
return {
widget: null,
};
},
async mounted() {
this.widget = new UpriserWidget({
agentId: this.agentId,
debug: this.debug,
widgetContainer: this.$refs.chatContainer,
});
try {
await this.widget.init();
} catch (error) {
console.error("Failed to initialize Upriser widget:", error);
}
},
beforeUnmount() {
if (this.widget) {
this.widget.destroy();
}
},
};
```
## ๐ก Event Handling
The widget dispatches custom events that you can listen for:
### Modal Events
```javascript
// Listen for modal opened events
window.addEventListener("upriser:modal-opened", (event) => {
console.log("Modal opened:", event.detail);
// Track analytics based on modal type
if (event.detail.type === "demo") {
// ...
} else if (event.detail.type === "vehicle") {
// ...
}
});
// Listen for modal closed events
window.addEventListener("upriser:modal-closed", (event) => {
console.log("Modal closed:", event.detail);
// you could track analytics here
});
```
### Widget Events
```javascript
// Listen for widget initialization
window.addEventListener("upriser:initialized", (event) => {
console.log("Widget initialized:", event.detail);
// Widget is ready, you can now safely call client tools
const tools = event.detail.element.getClientTools();
console.log("Available client tools:", Object.keys(tools));
});
// Listen for widget errors
window.addEventListener("upriser:error", (event) => {
console.error("Widget error:", event.detail.error);
// Handle errors gracefully
showErrorMessage(
"Chat widget encountered an error. Please refresh the page.",
);
});
```
### Client Tool Response Handling
```javascript
// Example of handling client tool responses
window.UPRISER_CLIENT_TOOLS = {
show_demo_form: (parameters) => {
try {
const url = parameters?.url || "https://meetings.hubspot.com/default";
// Attempt to open modal
if (window.upriserWidgetInstance) {
const result = window.upriserWidgetInstance.openModal({
url,
title: "Schedule a Demo",
});
if (result.success) {
// Dispatch custom success event
window.dispatchEvent(
new CustomEvent("upriser:demo-opened", {
detail: { url, timestamp: Date.now() },
}),
);
}
return result;
}
return { success: false, message: "Widget not available" };
} catch (error) {
console.error("Error in show_demo_form:", error);
// Dispatch error event
window.dispatchEvent(
new CustomEvent("upriser:client-tool-error", {
detail: { tool: "show_demo_form", error: error.message },
}),
);
return { success: false, message: "Failed to open demo form" };
}
},
};
```
## Browser Support
- Modern browsers (Chrome 60+, Firefox 55+, Safari 12+, Edge 79+)
- Supports both ES modules and UMD
- Works with or without build tools
- No external dependencies
## Features
- ๐ **Zero dependencies** - Works standalone
- ๐ฆ **Multiple formats** - UMD, ESM, and raw JavaScript
- ๐ฏ **TypeScript support** - Full type definitions included
- ๐ง **Auto-initialization** - Works out of the box
- ๐จ **Customizable** - Override default agent and styling
- ๐งช **Well tested** - Comprehensive test suite
- ๐ฑ **Responsive** - Works on desktop and mobile
- ๐ช **Built-in modals** - **NEW!** Integrated modal system for seamless user experiences
- ๐ ๏ธ **Client tools** - **NEW!** Custom functions that AI agents can call
- ๐ก **Event system** - **NEW!** Rich event handling for modal and widget interactions
- ๐ฏ **Use case ready** - **NEW!** Pre-built patterns for demos, vehicle browsing, and more
## Development
```bash
# Install dependencies
npm install
# Build all formats
npm run build
# Run tests
npm test
# Watch tests
npm test:watch
```
## ๐ Continuous Integration (CI)
This project uses GitHub Actions for continuous integration to ensure code quality and reliability across multiple Node.js versions.
### CI Pipeline Overview
The CI pipeline runs on every push and pull request to `main`, `master`, and `develop` branches, performing the following checks:
#### Test Job
- **Node.js Matrix Testing**: Tests against Node.js versions 16.x, 18.x, and 20.x
- **Dependency Installation**: Uses `npm ci` for clean, reproducible builds
- **Code Linting**: Runs ESLint to ensure code quality
- **Test Execution**: Runs the complete test suite
- **Build Verification**: Ensures all build formats compile successfully
- **Coverage Reports**: Uploads test coverage to Codecov (Node.js 18.x only)
#### Lint Job
- **Dedicated Linting**: Separate job for thorough ESLint checks
- **Node.js 18.x**: Uses stable Node.js version for consistent linting
### Available Scripts for CI
```bash
# Core CI commands
npm ci # Clean install (used in CI)
npm run lint # Run ESLint
npm run lint:check # Check linting without fixing
npm run lint:fix # Fix linting issues automatically
npm test # Run test suite
npm test:coverage # Run tests with coverage report
npm run build # Build all formats (UMD, ESM, Types, Raw)
# Individual build commands
npm run build:raw # Build raw JavaScript file
npm run build:umd # Build UMD format
npm run build:esm # Build ES module format
npm run build:types # Generate TypeScript definitions
```
### Local Development Workflow
To match the CI environment locally:
```bash
# 1. Clean install dependencies (like CI)
npm ci
# 2. Run linting checks
npm run lint:check
# 3. Run tests with coverage
npm test:coverage
# 4. Verify build works
npm run build
# 5. Fix any linting issues
npm run lint:fix
```
### CI Configuration Details
The CI configuration includes:
- **Automated Testing**: Ensures all tests pass before merging
- **Multi-Node Support**: Validates compatibility across Node.js LTS versions
- **Code Quality**: ESLint enforcement for consistent code style
- **Build Verification**: Confirms all distribution formats build successfully
- **Coverage Tracking**: Monitors test coverage trends via Codecov
- **Fail-Fast**: Stops on first failure to provide quick feedback
### Contributing Guidelines
When contributing to this project:
1. **Write Tests**: All new features must include comprehensive tests [[memory:9100424]]
2. **Follow Linting**: Ensure `npm run lint:check` passes
3. **Test Locally**: Run `npm test` before submitting PRs
4. **Build Verification**: Confirm `npm run build` succeeds
5. **Coverage**: Maintain or improve test coverage
### CI Status
The CI pipeline must pass for all pull requests. Check the GitHub Actions tab for detailed build logs and status updates.
## File Structure
```
@upriser/widget/
โโโ dist/ # Built files for npm
โ โโโ upriser-widget.js # UMD build
โ โโโ upriser-widget.esm.js # ES module build
โ โโโ upriser-widget.d.ts # TypeScript definitions
โโโ upriser-widget.js # Raw JavaScript file (for CDN/direct use)
โโโ src/ # Source files
โโโ package.json
```
## License
MIT
## Support
For support, please visit [https://www.upriser.ai](https://www.upriser.ai) or create an issue in the repository.