Add Whisper voice transcription to Telegram bot

- handleVoice() downloads Telegram audio and transcribes via Whisper API
- transcribeAudio() calls Whisper with Basic Auth, handles json response
- TelegramWebhookController now routes message.voice and message.audio
- Whisper URL, token and toggle configurable from admin config panel
- Transcribed text echoed back to user then processed as normal text intent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro
2026-07-14 19:00:57 +00:00
co-authored by Claude Sonnet 4.6
parent ad9d1761d2
commit f39f3d4045
4 changed files with 111 additions and 0 deletions
+65
View File
@@ -196,6 +196,71 @@ class TelegramBotService
}
}
public function handleVoice(string $chatId, string $fileId, string $nombre = ''): void
{
$state = $this->getState($chatId);
$this->convId = $state['conv_id'] ?? null;
if (ChatConfig::get('whisper_habilitado', '0') !== '1') {
$this->send($chatId, "🎤 Recibí tu audio, pero la transcripción de voz no está habilitada. Por favor escribe tu mensaje.");
return;
}
$this->send($chatId, "🎤 Transcribiendo tu audio...");
try {
$audioData = $this->downloadTelegramFile($fileId);
if (! $audioData) {
$this->send($chatId, "No pude descargar el audio. Intenta de nuevo o escribe tu mensaje.");
return;
}
$texto = $this->transcribeAudio($audioData['content']);
if (! $texto) {
$this->send($chatId, "No pude entender el audio. Intenta de nuevo o escribe tu mensaje.");
return;
}
// Confirmar lo que se escuchó y procesar como texto normal
$this->send($chatId, "🎙️ Escuché: _\"{$texto}\"_");
$this->handleText($chatId, $texto, $nombre);
} catch (\Throwable $e) {
Log::warning('[TelegramBot] handleVoice error: ' . $e->getMessage());
$this->send($chatId, "Error procesando el audio. Escribe tu mensaje.");
}
}
private function transcribeAudio(string $audioContent): ?string
{
$whisperUrl = ChatConfig::get('whisper_url');
$whisperToken = ChatConfig::get('whisper_token');
if (! $whisperUrl) {
return null;
}
try {
$response = Http::timeout(30)
->withBasicAuth('whisper', $whisperToken)
->attach('audio_file', $audioContent, 'audio.ogg')
->post($whisperUrl, ['response_format' => 'json']);
if (! $response->successful()) {
Log::warning('[TelegramBot] Whisper error: ' . $response->body());
return null;
}
// Whisper devuelve {"text": "..."} o {"transcription": "..."}
$json = $response->json();
return trim($json['text'] ?? $json['transcription'] ?? '');
} catch (\Throwable $e) {
Log::warning('[TelegramBot] Whisper exception: ' . $e->getMessage());
return null;
}
}
// ─── Auth flow ────────────────────────────────────────────
private function askEmail(string $chatId): void