Bu şekilde dosyaları paylaşayım gençler bu şekilde çözüldü sanırım başkasının ihtiyacı olabilir belki ilerde.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use GuzzleHttp\Client;
class TestController extends Controller
{
public function elevenlabsChatReal()
{
return view('elevenlabs-chat-real');
}
public function getSignedUrl()
{
$apiKey = Config::get('services.elevenlabs.api_key');
$agentId = Config::get('services.elevenlabs.agent_id');
$baseUrl = rtrim(Config::get('services.elevenlabs.base_url', 'https://api.elevenlabs.io/v1'), '/');
try {
$client = new Client([
'base_uri' => $baseUrl . '/',
'timeout' => 30,
'http_errors' => false,
]);
$response = $client->get("convai/conversation/get-signed-url", [
'headers' => [
'xi-api-key' => $apiKey,
'Accept' => 'application/json',
],
'query' => [
'agent_id' => $agentId,
],
]);
$status = $response->getStatusCode();
$body = (string) $response->getBody();
$json = json_decode($body, true);
if ($status >= 200 && $status < 300 && isset($json['signed_url'])) {
return response()->json([
'ok' => true,
'signed_url' => $json['signed_url'],
]);
}
return response()->json([
'ok' => false,
'error' => 'Signed URL alınamadı: ' . $status,
'raw' => $body,
], 502);
} catch (\Throwable $e) {
Log::error('ElevenLabs signed URL error', ['message' => $e->getMessage()]);
return response()->json([
'ok' => false,
'error' => 'Signed URL isteği başarısız: ' . $e->getMessage(),
], 500);
}
}
}
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ElevenLabs Gerçek Chat Mode</title>
<style>
body {
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
background: #0b1220;
color: #e5e7eb;
margin: 0;
padding: 20px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.chat-container {
max-width: 800px;
margin: 0 auto;
flex: 1;
display: flex;
flex-direction: column;
background: #111827;
border: 1px solid #1f2937;
border-radius: 12px;
overflow: hidden;
}
.chat-header {
padding: 16px 20px;
background: #1f2937;
border-bottom: 1px solid #374151;
}
.chat-messages {
flex: 1;
padding: 20px;
overflow-y: auto;
min-height: 400px;
max-height: 500px;
}
.message {
margin-bottom: 16px;
padding: 12px 16px;
border-radius: 8px;
max-width: 80%;
}
.message.user {
background: #2563eb;
color: white;
margin-left: auto;
text-align: right;
}
.message.agent {
background: #374151;
color: #e5e7eb;
}
.message.system {
background: #1f2937;
color: #9ca3af;
font-style: italic;
text-align: center;
max-width: 100%;
}
.chat-input {
padding: 16px 20px;
background: #1f2937;
border-top: 1px solid #374151;
display: flex;
gap: 8px;
}
.chat-input input {
flex: 1;
background: #0b1220;
color: #e5e7eb;
border: 1px solid #374151;
border-radius: 8px;
padding: 12px 16px;
outline: none;
}
.chat-input input:focus {
border-color: #2563eb;
}
.chat-input button {
background: #2563eb;
color: white;
border: none;
border-radius: 8px;
padding: 12px 20px;
cursor: pointer;
font-weight: 500;
}
.chat-input button:hover {
background: #1d4ed8;
}
.chat-input button:disabled {
background: #374151;
cursor: not-allowed;
}
.status {
padding: 8px 12px;
margin: 8px 0;
border-radius: 4px;
font-size: 14px;
}
.status.connected {
background: #065f46;
color: #10b981;
}
.status.disconnected {
background: #7f1d1d;
color: #ef4444;
}
.status.connecting {
background: #92400e;
color: #f59e0b;
}
.controls {
display: flex;
gap: 8px;
margin-top: 8px;
}
.controls button {
background: #374151;
color: #e5e7eb;
border: none;
border-radius: 6px;
padding: 8px 12px;
cursor: pointer;
font-size: 12px;
}
.controls button:hover {
background: #4b5563;
}
.controls button.active {
background: #059669;
}
</style>
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<h2>ElevenLabs Gerçek Chat Mode</h2>
<div id="status" class="status disconnected">Hazırlanıyor...</div>
<div class="controls">
<button id="connectBtn">Bağlan</button>
<button id="disconnectBtn" disabled>Bağlantıyı Kes</button>
<button id="textOnlyBtn">Metin Modu</button>
</div>
</div>
<div class="chat-messages" id="messages">
<div class="message system">ElevenLabs gerçek WebSocket chat mode'u. Önce "Bağlan" butonuna basın.</div>
</div>
<div class="chat-input">
<input type="text" id="messageInput" placeholder="Mesajınızı yazın..." disabled>
<button id="sendButton" disabled>Gönder</button>
</div>
</div>
<script src="/elevenlabs-client-umd.js"></script>
<script>
const { Conversation } = window.client;
class ElevenLabsRealChat {
constructor() {
this.conversation = null;
this.isConnected = false;
this.isTextOnly = true; // Default to text-only mode
this.messageInput = document.getElementById('messageInput');
this.sendButton = document.getElementById('sendButton');
this.messagesContainer = document.getElementById('messages');
this.statusElement = document.getElementById('status');
this.connectBtn = document.getElementById('connectBtn');
this.disconnectBtn = document.getElementById('disconnectBtn');
this.textOnlyBtn = document.getElementById('textOnlyBtn');
this.init();
}
init() {
this.messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
this.sendMessage();
}
});
this.sendButton.addEventListener('click', () => this.sendMessage());
this.connectBtn.addEventListener('click', () => this.connect());
this.disconnectBtn.addEventListener('click', () => this.disconnect());
this.textOnlyBtn.addEventListener('click', () => this.toggleTextOnly());
this.updateTextOnlyButton();
this.updateStatus('disconnected', 'Bağlantı bekleniyor');
}
toggleTextOnly() {
this.isTextOnly = !this.isTextOnly;
this.updateTextOnlyButton();
if (this.isConnected) {
this.addMessage('system', `${this.isTextOnly ? 'Metin' : 'Ses'} moduna geçildi. Yeniden bağlanın.`);
this.disconnect();
}
}
updateTextOnlyButton() {
this.textOnlyBtn.textContent = this.isTextOnly ? 'Metin Modu ✓' : 'Ses Modu';
this.textOnlyBtn.classList.toggle('active', this.isTextOnly);
}
async connect() {
this.updateStatus('connecting', 'Bağlanıyor...');
this.connectBtn.disabled = true;
try {
const response = await fetch('{{ route('elevenlabs.signed-url') }}');
const data = await response.json();
if (!data.ok) {
throw new Error(data.error || 'Signed URL alınamadı');
}
const signedUrl = data.signed_url;
this.conversation = await Conversation.startSession({
signedUrl,
connectionType: 'websocket',
textOnly: this.isTextOnly,
overrides: {
conversation: {
textOnly: this.isTextOnly,
},
},
onConnect: () => {
this.isConnected = true;
this.updateStatus('connected', 'Bağlandı');
this.messageInput.disabled = false;
this.sendButton.disabled = false;
this.disconnectBtn.disabled = false;
this.addMessage('system', ` ile ${this.isTextOnly ? 'metin' : 'ses'} modunda konuşabilirsiniz!`);
},
onDisconnect: () => {
this.handleDisconnect();
},
onMessage: (message) => {
console.log('Message received:', message);
if (message.source === 'ai') {
this.addMessage('agent', message.message || 'Agent yanıtı');
} else if (message.source === 'user') {
if (!this.isTextOnly) {
this.addMessage('user', message.message || 'Kullanıcı konuştu');
}
}
if (message.type === 'agent_response') {
this.addMessage('agent', message.text || message.agent_response || 'Agent yanıtı');
} else if (message.type === 'user_transcript') {
if (!this.isTextOnly) {
this.addMessage('user', message.text || message.user_transcript || 'Kullanıcı konuştu');
}
}
},
onError: (error) => {
console.error('Conversation error:', error);
this.addMessage('system', `Hata: ${error.message || error}`);
},
onStatusChange: (status) => {
console.log('Status changed:', status);
},
onModeChange: (mode) => {
console.log('Mode changed:', mode);
},
});
} catch (error) {
console.error('Connection error:', error);
this.addMessage('system', `Bağlantı hatası: ${error.message}`);
this.handleDisconnect();
}
}
async disconnect() {
if (this.conversation) {
try {
await this.conversation.endSession();
} catch (error) {
console.error('Disconnect error:', error);
}
}
this.handleDisconnect();
}
handleDisconnect() {
this.isConnected = false;
this.conversation = null;
this.updateStatus('disconnected', 'Bağlantı kesildi');
this.messageInput.disabled = true;
this.sendButton.disabled = true;
this.connectBtn.disabled = false;
this.disconnectBtn.disabled = true;
this.addMessage('system', 'Bağlantı sonlandırıldı.');
}
updateStatus(type, message) {
this.statusElement.className = `status ${type}`;
this.statusElement.textContent = message;
}
addMessage(type, content) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${type}`;
messageDiv.textContent = content;
this.messagesContainer.appendChild(messageDiv);
this.messagesContainer.scrollTop = this.messagesContainer.scrollHeight;
}
sendMessage() {
const message = this.messageInput.value.trim();
if (!message || !this.isConnected || !this.conversation) return;
this.addMessage('user', message);
this.messageInput.value = '';
try {
this.conversation.sendUserMessage(message);
} catch (error) {
console.error('Send message error:', error);
this.addMessage('system', `Mesaj gönderme hatası: ${error.message}`);
}
}
}
document.addEventListener('DOMContentLoaded', () => {
new ElevenLabsRealChat();
});
</script>
</body>
</html>
eventlab-client
https://codefile.io/f/ks7qCOmIKt
eventlab-client-umd.js
https://codefile.io/f/Q3tapx85Qz
Görünüm:
https://prnt.sc/Kv5CEfCTC0yp