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>
60 lines
1.6 KiB
PHP
60 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\ChatConfig;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class OcrExtractionService
|
|
{
|
|
private string $url;
|
|
private string $token;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->url = rtrim(ChatConfig::get('ocr_url', ''), '/');
|
|
$this->token = ChatConfig::get('ocr_token', '');
|
|
}
|
|
|
|
public function habilitado(): bool
|
|
{
|
|
return ChatConfig::get('ocr_habilitado', '0') === '1' && $this->url !== '';
|
|
}
|
|
|
|
/** Envia la imagen al servicio OCR externo y devuelve el texto crudo, o null si falla. */
|
|
public function extraerTexto(string $base64, string $mimeType): ?string
|
|
{
|
|
if (! $this->url) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
$response = Http::withToken($this->token)
|
|
->timeout(20)
|
|
->post("{$this->url}/extract", [
|
|
'image_base64' => $base64,
|
|
'mime_type' => $mimeType,
|
|
]);
|
|
|
|
if (! $response->successful()) {
|
|
Log::warning('[OCR] HTTP ' . $response->status() . ': ' . substr($response->body(), 0, 300));
|
|
return null;
|
|
}
|
|
|
|
$data = $response->json();
|
|
|
|
if (! ($data['success'] ?? false) || empty($data['text'])) {
|
|
Log::warning('[OCR] respuesta sin texto util: ' . substr($response->body(), 0, 300));
|
|
return null;
|
|
}
|
|
|
|
return $data['text'];
|
|
|
|
} catch (\Throwable $e) {
|
|
Log::warning('[OCR] excepcion: ' . $e->getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
}
|