Vite (JavaScript)

Dowiedz się, jak stworzyć aplikację webową umożliwiającą rozmowy głosowe z agentami AI ElevenLabs

Ten poradnik pokaże ci, jak stworzyć klienta webowego, który może komunikować się z agentem ElevenLabs. Dowiesz się, jak wdrożyć rozmowy głosowe w czasie rzeczywistym, aby użytkownicy mogli rozmawiać z agentem AI, który słucha, rozumie i naturalnie odpowiada za pomocą syntezy głosu.

Chcesz tworzyć w React/Next.js? Zobacz nasz poradnik do Next.js

Czego potrzebujesz

  1. Agenta ElevenLabs utworzonego zgodnie z tym poradnikiem
  2. npm zainstalowanego lokalnie
  3. Podstawowej znajomości JavaScript

Konfiguracja projektu

1

Utwórz katalog projektu

Otwórz terminal i utwórz nowy katalog dla projektu:

mkdir elevenlabs-conversational-ai
cd elevenlabs-conversational-ai
2

Zainicjuj npm i zainstaluj zależności

Zainicjuj nowy projekt npm i zainstaluj wymagane pakiety:

npm init -y
npm install vite @elevenlabs/client
3

Skonfiguruj podstawową strukturę projektu

Dodaj to do pliku package.json:

package.json
{
"scripts": {
...
"dev:frontend": "vite"
}
}

Utwórz taką strukturę plików:

elevenlabs-conversational-ai/
├── index.html
├── script.js
├── package-lock.json
├── package.json
└── node_modules

Wdrażanie interfejsu czatu głosowego

1

Utwórz interfejs HTML

W pliku index.html utwórz prosty interfejs użytkownika:

index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ElevenLabs Agents</title>
</head>
<body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
<h1>ElevenLabs Agents</h1>
<div style="margin-bottom: 20px;">
<button id="startButton" style="padding: 10px 20px; margin: 5px;">Start Conversation</button>
<button id="stopButton" style="padding: 10px 20px; margin: 5px;" disabled>Stop Conversation</button>
</div>
<div style="font-size: 18px;">
<p>Status: <span id="connectionStatus">Disconnected</span></p>
<p>Agent is <span id="agentStatus">listening</span></p>
</div>
<script type="module" src="../images/script.js"></script>
</body>
</html>
2

Wdróż logikę rozmowy

W pliku script.js zaimplementuj funkcjonalność:

script.js
import { Conversation } from '@elevenlabs/client';
const startButton = document.getElementById('startButton');
const stopButton = document.getElementById('stopButton');
const connectionStatus = document.getElementById('connectionStatus');
const agentStatus = document.getElementById('agentStatus');
let conversation;
async function startConversation() {
try {
// Request microphone permission
await navigator.mediaDevices.getUserMedia({ audio: true });
// Start the conversation
conversation = await Conversation.startSession({
agentId: 'YOUR_AGENT_ID', // Replace with your agent ID
onConnect: () => {
connectionStatus.textContent = 'Connected';
startButton.disabled = true;
stopButton.disabled = false;
},
onDisconnect: () => {
connectionStatus.textContent = 'Disconnected';
startButton.disabled = false;
stopButton.disabled = true;
},
onError: (error) => {
console.error('Error:', error);
},
onModeChange: (mode) => {
agentStatus.textContent = mode.mode === 'speaking' ? 'speaking' : 'listening';
},
});
} catch (error) {
console.error('Failed to start conversation:', error);
}
}
async function stopConversation() {
if (conversation) {
await conversation.endSession();
conversation = null;
}
}
startButton.addEventListener('click', startConversation);
stopButton.addEventListener('click', stopConversation);
3

Uruchom serwer frontendu

npm run dev:frontend
Pamiętaj, aby zastąpić 'YOUR_AGENT_ID' rzeczywistym identyfikatorem agenta z ElevenLabs.

Ten krok uwierzytelniania jest wymagany tylko dla prywatnych agentów. Jeśli używasz publicznego agenta, możesz pominąć tę sekcję i użyć bezpośrednio agentId w wywołaniu startSession.

1

Utwórz zmienne środowiskowe

Utwórz plik .env w katalogu głównym projektu:

.env
ELEVENLABS_API_KEY=your-api-key-here
AGENT_ID=your-agent-id-here

Dodaj .env do pliku .gitignore, aby przypadkowo nie zatwierdzić poufnych danych logowania.

2

Skonfiguruj backend

  1. Zainstaluj dodatkowe zależności:
npm install express cors dotenv
  1. Utwórz nowy folder o nazwie backend:
elevenlabs-conversational-ai/
├── backend
...
3

Utwórz serwer

backend/server.js
require("dotenv").config();
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.use(express.json());
const PORT = process.env.PORT || 3001;
app.get("/api/get-signed-url", async (req, res) => {
try {
const response = await fetch(
`https://api.elevenlabs.io/v1/convai/conversation/get-signed-url?agent_id=${process.env.AGENT_ID}`,
{
headers: {
"xi-api-key": process.env.ELEVENLABS_API_KEY,
},
}
);
if (!response.ok) {
throw new Error("Failed to get signed URL");
}
const data = await response.json();
res.json({ signedUrl: data.signed_url });
} catch (error) {
console.error("Error:", error);
res.status(500).json({ error: "Failed to generate signed URL" });
}
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
4

Zaktualizuj kod klienta

Zmień plik script.js, aby pobierać i używać podpisanego URL-a:

script.js
// ... existing imports and variables ...
async function getSignedUrl() {
const response = await fetch('http://localhost:3001/api/get-signed-url');
if (!response.ok) {
throw new Error(`Failed to get signed url: ${response.statusText}`);
}
const { signedUrl } = await response.json();
return signedUrl;
}
async function startConversation() {
try {
await navigator.mediaDevices.getUserMedia({ audio: true });
const signedUrl = await getSignedUrl();
conversation = await Conversation.startSession({
signedUrl,
// agentId has been removed...
onConnect: () => {
connectionStatus.textContent = 'Connected';
startButton.disabled = true;
stopButton.disabled = false;
},
onDisconnect: () => {
connectionStatus.textContent = 'Disconnected';
startButton.disabled = false;
stopButton.disabled = true;
},
onError: (error) => {
console.error('Error:', error);
},
onModeChange: (mode) => {
agentStatus.textContent = mode.mode === 'speaking' ? 'speaking' : 'listening';
},
});
} catch (error) {
console.error('Failed to start conversation:', error);
}
}
// ... rest of the code ...

Podpisane URL-e wygasają po krótkim czasie. Rozmowy rozpoczęte przed wygaśnięciem będą jednak kontynuowane bez przerwy. W środowisku produkcyjnym wdroż odpowiednią obsługę błędów i logikę odświeżania URL-i, by rozpoczynać nowe rozmowy.

5

Zaktualizuj package.json

package.json
{
"scripts": {
...
"dev:backend": "node backend/server.js",
"dev": "npm run dev:frontend & npm run dev:backend"
}
}
6

Uruchom aplikację

Uruchom aplikację poleceniem:

npm run dev

Kolejne kroki

Masz już podstawową implementację, więc możesz:

  1. Dodać wizualne informacje o aktywności głosowej
  2. Wdrożyć obsługę błędów i mechanizm ponawiania prób
  3. Dodać widok historii czatu
  4. Dostosować UI do swojej marki

Więcej zaawansowanych funkcji i opcji dostosowania znajdziesz w pakiecie @elevenlabs/client.