Build your first voice AI application with the Outspeed React SDK
useConversation
import React, { useState } from "react"; import { type SessionConfig } from "@outspeed/client"; import { useConversation } from "@outspeed/react"; const getEphemeralKeyFromServer = async (config: SessionConfig) => { const tokenResponse = await fetch("/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(config), }); const data = await tokenResponse.json(); if (!tokenResponse.ok) { throw new Error("Failed to get ephemeral key"); } return data.client_secret.value; }; const sessionConfig: SessionConfig = { model: "outspeed-v1", instructions: "You are a helpful but witty assistant named Alfred.", voice: "david", // see the voices page for all available voices turn_detection: { type: "semantic_vad", }, first_message: "Hello, how can I assist you with Outspeed today?", }; export default function VoiceChat() { const [sessionCreated, setSessionCreated] = useState(false); const [isConnecting, setIsConnecting] = useState(false); const conversation = useConversation({ sessionConfig: sessionConfig, }); const startSession = async () => { try { setIsConnecting(true); const ephemeralKey = await getEphemeralKeyFromServer(sessionConfig); await conversation.startSession(ephemeralKey); // Listen for session creation event conversation.on("session.created", (event) => { console.log("Session created:", event); setSessionCreated(true); setIsConnecting(false); }); } catch (error) { console.error("Error starting session:", error); setIsConnecting(false); } }; const endSession = async () => { try { await conversation.endSession(); setSessionCreated(false); } catch (error) { console.error("Error ending session:", error); } }; if (isConnecting) { return ( <div className="voice-chat"> <h2>Connecting...</h2> <p>Please wait while we establish the connection.</p> </div> ); } if (sessionCreated) { return ( <div className="voice-chat"> <h2>ποΈ Voice Chat Active</h2> <p>You can now speak with the AI assistant!</p> <button onClick={endSession} className="end-button"> End Session </button> </div> ); } return ( <div className="voice-chat"> <h2>Voice AI Assistant</h2> <p>Click the button below to start a voice conversation.</p> <button onClick={startSession} className="start-button"> Start Voice Chat </button> </div> ); }
// Listen for speech detection conversation.on("input_audio_buffer.speech_started", () => { console.log("User started speaking"); }); conversation.on("input_audio_buffer.speech_stopped", () => { console.log("User stopped speaking"); }); // Listen for AI responses conversation.on("response.text.delta", (event) => { console.log("AI response text:", event.delta); }); conversation.on("response.audio_transcript.delta", (event) => { console.log("AI speech transcript:", event.delta); });
const sendTextMessage = () => { conversation.sendText("Tell me about the weather today"); }; return ( <div> {/* ... other components */} <button onClick={sendTextMessage}>Send Text Message</button> </div> );
micMuted
const [isMicMuted, setIsMicMuted] = useState(false); const conversation = useConversation({ micMuted: isMicMuted, }); const toggleMute = () => { setIsMicMuted(!isMicMuted); }; return ( <div> {/* ... other components */} <button onClick={toggleMute}>{isMicMuted ? "π Unmute" : "π€ Mute"}</button> </div> );
volume
const [volume, setVolume] = useState(0.8); const conversation = useConversation({ volume: volume, }); return ( <div> {/* ... other components */} <label> Volume: {Math.round(volume * 100)}% <input type="range" min="0" max="1" step="0.1" value={volume} onChange={(e) => setVolume(parseFloat(e.target.value))} /> </label> </div> );
const [error, setError] = useState<string | null>(null); const conversation = useConversation({ sessionConfig: sessionConfig, onError: (err) => { console.error("Conversation error:", err); setError(err.message); }, }); // Display error to user if (error) { return ( <div className="error-state"> <h2>β Error</h2> <p>{error}</p> <button onClick={() => setError(null)}>Try Again</button> </div> ); }
Was this page helpful?