Todos los sistemas

galacticBills

Captura y contabilización de facturas para negocios pequeños con un LLM — sin digitación manual.

Rol
Diseño, construcción y operación
Año
2026
Stack
n8nGeminiTelegramGoogle DriveGoogle SheetsAWS EC2Docker
12 Campos extraídos por factura
60s Del envío a la fila archivada
0 Fallos silenciosos tras la auditoría
1 Cliente en producción

El problema

Un negocio pequeño pierde horas cada mes pasando facturas a una hoja de cálculo. Es el tipo de trabajo que nadie quiere y todo el mundo aplaza, así que se acumula hasta que el contador lo pide.

La respuesta obvia es OCR. La real no lo es: una factura no es un formulario. Cada proveedor la maqueta distinto, la mitad llegan fotografiadas en ángulo, y los números que importan — base imponible, porcentaje de IVA, valor del IVA, total — tienen que ser coherentes entre sí o la fila es peor que inútil. Un número equivocado archivado en silencio cuesta más que no tener ningún número.

El sistema

El cliente manda una foto o un PDF a un bot de Telegram, o lo deja en una carpeta compartida de Drive. A partir de ahí funciona solo:

  1. 01

    Ingesta

    Llega una foto o un PDF por el bot de Telegram, o se deja en la carpeta compartida de Drive.

  2. 02

    Recogida

    El archivo queda guardado y el pipeline lo detecta en menos de un minuto.

  3. 03

    Clasificación

    ¿Esto es realmente una factura?

    si no → no lo es — se rechaza aquí, antes de poder contaminar la contabilidad.

  4. 04

    Extracción

    Gemini lee los campos fiscales contra un esquema fijo, a temperatura 0 y con tipo de respuesta JSON estricto.

  5. 05

    Validación

    La base imponible más el IVA tiene que dar el total.

    si no → los números no cuadran — va a una cola de revisión humana por Telegram, nunca a la hoja.

  6. 06

    Archivado

    Se escribe la fila, deduplicada por un hash del propio archivo.

  7. 07

    Confirmación

    El cliente recibe respuesta por el mismo canal que usó.

Dos comprobaciones deciden todo: una antes de que corra el modelo y otra después. Ninguna de las dos existía en la primera versión.

Corre sobre n8n self-hosted — AWS EC2, Docker Compose, nginx — infraestructura que gestiono yo.

Lo que hice mal la primera vez

La primera versión funcionaba, y ese era el problema. Audité mi propio workflow antes de venderlo, y los hallazgos fueron incómodos.

Fallaba en silencio. Sin workflow de error, sin try/catch alrededor de la salida del modelo. Si Gemini devolvía algo que no era JSON válido, o la hoja rechazaba la fila, la factura simplemente desaparecía. El cliente nunca se enteraba. Es el peor modo de fallo posible para una contabilidad — peor que romperse, porque nadie investiga una caída que nunca ocurrió.

La deduplicación era falsa. Cuando una factura no tenía número, el sistema generaba un timestamp como identificador. Sube la misma factura dos veces y obtenías dos filas con timestamps distintos, y la lógica de “cruzar por id” veía dos facturas diferentes. Ahora la clave de deduplicación es un hash del propio archivo.

Nada validaba los números. La salida del modelo iba directa a la hoja. Ahora tiene que sobrevivir primero a una comprobación aritmética, y si no lo hace toma la ruta de revisión.

Aceptaba cualquier cosa. Cualquier archivo que cayera en la carpeta se procesaba como factura, y el modelo inventaba campos para un recibo, un contrato o el gato de alguien.

Ninguna de estas era una funcionalidad. Todas eran la diferencia entre un script que funciona en mi máquina y algo de lo que un negocio puede depender.

La decisión difícil: una instalación, o una por cliente

El problema interesante nunca fue la extracción. Fue cómo servir el mismo producto a varios clientes.

El camino tentador es clonar el workflow por cliente y editar los valores fijos. Funciona para el segundo cliente y se derrumba en el quinto: cada corrección hay que aplicarla a mano, N veces, y las copias se separan hasta que nadie sabe qué versión tiene cada cliente.

La alternativa es una instalación compartida con una capa de configuración — cada cliente es una fila: su NIF, su canal, su carpeta, su plan contable, su moneda. Un workflow, N configuraciones.

El trade-off no es la comodidad del desarrollador. El aislamiento de datos es la línea que no se cruza: las facturas de un negocio jamás pueden aparecer en la contabilidad de otro. Una instalación compartida convierte eso en una propiedad que hay que hacer cumplir activamente. Instalaciones separadas lo hacen cierto por construcción, a cambio de una carga operativa que crece con cada venta.

Dónde está esa línea depende de quiénes sean los clientes, no de qué arquitectura suena mejor. La decisión está documentada y sigue abierta — que es el estado honesto de un producto con un piloto corriendo y un segundo en preparación.

Estado actual

Un cliente en producción, procesando facturas reales. El pipeline está blindado: cada hallazgo de arriba está corregido y verificado de punta a punta.

La capa multi-tenant es la siguiente fase, y deliberadamente todavía no está construida. Construirla antes de saber en qué se diferencia de verdad el segundo cliente del primero es la forma de acabar con opciones de configuración que nadie pidió.