feat: leer comprobantes via OCR externo + Gemini solo-texto
Antes, si Gemini Vision fallaba (cuota/API), el 100% de los comprobantes del chat web quedaban sin poder leerse. Ahora el job intenta primero un servicio OCR externo configurable (imagen -> texto) y le pasa el texto a Gemini para que solo lo estructure en JSON, más barato y sin la cuota de visión. Si el OCR no está habilitado o falla, cae al método anterior (Gemini leyendo la imagen directamente) sin romper nada. Agrega configuración en el panel (URL/token/habilitado + probar conexión) y la spec del servicio OCR a desplegar en docs/ocr-service-spec.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
7f4053ea62
commit
7afd22d581
@@ -18,6 +18,7 @@ class ShowConfiguracionChat extends Component
|
||||
public string $webhookResult = '';
|
||||
public string $whisperResult = '';
|
||||
public string $geminiResult = '';
|
||||
public string $ocrResult = '';
|
||||
|
||||
// ── Gemini IA ─────────────────────────────────────────────
|
||||
public string $gemini_api_key = '';
|
||||
@@ -35,6 +36,11 @@ class ShowConfiguracionChat extends Component
|
||||
public string $whisper_token = '';
|
||||
public string $whisper_habilitado = '0';
|
||||
|
||||
// ── OCR de comprobantes (previo a Gemini) ──────────────────
|
||||
public string $ocr_url = '';
|
||||
public string $ocr_token = '';
|
||||
public string $ocr_habilitado = '0';
|
||||
|
||||
// ── Bre-B ─────────────────────────────────────────────────
|
||||
public string $recarga_banco_nombre = '';
|
||||
public string $recarga_banco_llave = '';
|
||||
@@ -47,6 +53,7 @@ class ShowConfiguracionChat extends Component
|
||||
'gemini_api_key', 'gemini_model', 'gemini_habilitado', 'gemini_prompt_extra',
|
||||
'validacion_foto_habilitada', 'validacion_accion_auto', 'validacion_monto_tolerancia',
|
||||
'whisper_url', 'whisper_token', 'whisper_habilitado',
|
||||
'ocr_url', 'ocr_token', 'ocr_habilitado',
|
||||
'recarga_banco_nombre', 'recarga_banco_llave', 'recarga_banco_titular',
|
||||
];
|
||||
|
||||
@@ -79,6 +86,7 @@ class ShowConfiguracionChat extends Component
|
||||
'gemini_api_key', 'gemini_model', 'gemini_habilitado', 'gemini_prompt_extra',
|
||||
'validacion_foto_habilitada', 'validacion_accion_auto', 'validacion_monto_tolerancia',
|
||||
'whisper_url', 'whisper_token', 'whisper_habilitado',
|
||||
'ocr_url', 'ocr_token', 'ocr_habilitado',
|
||||
'recarga_banco_nombre', 'recarga_banco_llave', 'recarga_banco_titular',
|
||||
];
|
||||
|
||||
@@ -172,6 +180,42 @@ class ShowConfiguracionChat extends Component
|
||||
}
|
||||
}
|
||||
|
||||
public function probarOcr(): void
|
||||
{
|
||||
$url = rtrim(trim($this->ocr_url ?: ChatConfig::get('ocr_url')), '/');
|
||||
$token = trim($this->ocr_token ?: ChatConfig::get('ocr_token'));
|
||||
|
||||
if (! $url) {
|
||||
$this->ocrResult = '⚠️ La URL del servicio OCR está vacía.';
|
||||
return;
|
||||
}
|
||||
|
||||
// 1x1 png transparente, solo para verificar que el servicio responde.
|
||||
$pixel = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=');
|
||||
|
||||
try {
|
||||
$inicio = microtime(true);
|
||||
$response = Http::withToken($token)
|
||||
->timeout(15)
|
||||
->post("{$url}/extract", [
|
||||
'image_base64' => base64_encode($pixel),
|
||||
'mime_type' => 'image/png',
|
||||
]);
|
||||
|
||||
$ms = (int) ((microtime(true) - $inicio) * 1000);
|
||||
|
||||
if ($response->successful()) {
|
||||
$this->ocrResult = "✅ Servicio OCR responde OK ({$ms}ms). " .
|
||||
"Respuesta: " . substr($response->body(), 0, 200);
|
||||
} else {
|
||||
$this->ocrResult = "❌ El servicio respondió con error " . $response->status() . ": " .
|
||||
substr($response->body(), 0, 200);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$this->ocrResult = '❌ No se pudo conectar con el servicio OCR: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function registrarWebhook(): void
|
||||
{
|
||||
$token = trim($this->telegram_token);
|
||||
|
||||
Reference in New Issue
Block a user