Handle widget events and tool execution
function
onReady: () => {
console.log("Widget ready");
// Enable UI elements, track analytics, etc.
}
function(error)
onError: (error) => {
console.error("Widget error:", error);
// Show user-friendly error message
if (error.message.includes("microphone")) {
showMicrophoneHelp();
}
}
function(summary)
onCallEnded: (summary) => {
console.log("Session ended:", summary);
// Track analytics, show feedback form, etc.
analytics.track("navi_session_ended", {
duration: summary.duration,
messageCount: summary.messages?.length
});
}
function(result)
result.success
- Boolean indicating if initialization was successfulresult.error
- Error message when initialization fails (only when success is false)result.widgetReady
- Boolean indicating if widget is ready for interactiononInitialized: (result) => {
if (result.success) {
console.log("Widget initialized successfully!");
// Enable dependent UI elements
document.getElementById('chat-button').disabled = false;
document.getElementById('voice-button').disabled = false;
// Track successful initialization
analytics.track("navi_widget_initialized", {
widgetReady: result.widgetReady
});
} else {
console.error("Widget initialization failed:", result.error);
// Show error state in UI
showErrorMessage(`Assistant unavailable: ${result.error}`);
// Track initialization failure
analytics.track("navi_widget_init_failed", {
error: result.error
});
}
}
function(toolName, args)
runTool: (toolName, args) => {
switch (toolName) {
case "navigate":
// SPA navigation without page refresh
router.push(args.url);
break;
case "show_info":
// Display information
showModal(args.message);
break;
case "update_cart":
// Update shopping cart
cart.update(args.items);
break;
default:
console.log("Unknown tool:", toolName, args);
}
}
initUnifiedWidget({
agentConfigId: "your-agent-id",
agentKey: "your-agent-key",
onError: (error) => {
// Log for debugging
console.error("Navi error:", error);
// Show user-friendly messages
if (error.message.includes("Permission denied")) {
showNotification("Please allow microphone access to use voice features");
} else if (error.message.includes("Network")) {
showNotification("Connection issue. Please check your internet connection");
} else if (error.message.includes("Usage limit")) {
showNotification("You've reached your usage limit for this month");
} else {
showNotification("Something went wrong. Please try again");
}
}
});
initUnifiedWidget({
agentConfigId: "your-agent-id",
agentKey: "your-agent-key",
onReady: () => {
analytics.track("navi_widget_ready");
},
onCallEnded: (summary) => {
analytics.track("navi_session_ended", {
duration: summary.duration,
messageCount: summary.messages?.length,
endReason: summary.endReason,
userSatisfaction: summary.rating
});
}
});
const runTool = (toolName, args) => {
// Log all tool calls for debugging
console.log(`Tool called: ${toolName}`, args);
switch (toolName) {
case "navigate":
// Validate URL before navigation
if (args.url && args.url.startsWith('/')) {
router.push(args.url);
analytics.track("navi_navigation", { url: args.url });
} else {
console.error("Invalid navigation URL:", args.url);
}
break;
case "show_product":
// Show product with validation
if (args.productId) {
showProduct(args.productId);
analytics.track("navi_product_view", { productId: args.productId });
}
break;
case "add_to_cart":
// Add to cart with error handling
try {
cart.add(args.productId, args.quantity || 1);
showNotification("Added to cart!");
analytics.track("navi_add_to_cart", args);
} catch (error) {
console.error("Failed to add to cart:", error);
showNotification("Failed to add item to cart");
}
break;
default:
console.warn("Unknown tool:", toolName, args);
analytics.track("navi_unknown_tool", { toolName, args });
}
};
initUnifiedWidget({
agentConfigId: "your-agent-id",
agentKey: "your-agent-key",
runTool
});
import { useCallback } from 'react';
import { useRouter } from 'next/router';
function useNaviHandlers() {
const router = useRouter();
const handleReady = useCallback(() => {
console.log("Navi ready");
// Initialize any dependent features
}, []);
const handleError = useCallback((error) => {
console.error("Navi error:", error);
// Show toast notification
}, []);
const handleCallEnded = useCallback((summary) => {
console.log("Call ended:", summary);
// Update UI state
}, []);
const handleInitialized = useCallback((result) => {
if (result.success) {
console.log("Widget ready!");
// Enable UI features
} else {
console.error("Widget failed:", result.error);
// Show error state
}
}, []);
const handleRunTool = useCallback((toolName, args) => {
if (toolName === "navigate") {
router.push(args.url);
}
}, [router]);
return {
onReady: handleReady,
onError: handleError,
onCallEnded: handleCallEnded,
onInitialized: handleInitialized,
runTool: handleRunTool
};
}
// Usage
function App() {
const handlers = useNaviHandlers();
useEffect(() => {
initUnifiedWidget({
agentConfigId: "your-agent-id",
agentKey: "your-agent-key",
...handlers
});
}, [handlers]);
}
import { onMounted } from 'vue';
import { useRouter } from 'vue-router';
export function useNaviHandlers() {
const router = useRouter();
const handleReady = () => {
console.log("Navi ready");
};
const handleError = (error) => {
console.error("Navi error:", error);
};
const handleCallEnded = (summary) => {
console.log("Call ended:", summary);
};
const handleInitialized = (result) => {
if (result.success) {
console.log("Widget ready!");
} else {
console.error("Widget failed:", result.error);
}
};
const handleRunTool = (toolName, args) => {
if (toolName === "navigate") {
router.push(args.url);
}
};
return {
onReady: handleReady,
onError: handleError,
onCallEnded: handleCallEnded,
onInitialized: handleInitialized,
runTool: handleRunTool
};
}