Commit Graph
6 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Opus 5 1b599606f7 feat(soporte): botón de borrador que redacta con la base de conocimiento
En cada ticket, " Borrador" propone una respuesta usando los fragmentos más
parecidos de la base de conocimiento del agente de uMind que se elija en la
configuración de soporte, más el hilo de la conversación.

El borrador cae en el cuadro de respuesta y no se manda: lo revisa una persona
y aprieta enviar. Contestarle a un cliente con lo que dijo un modelo, sin que
nadie lo lea, es la forma más rápida de perderlo.

Sin agente configurado el borrador se arma igual, solo con la conversación —
peor, pero mejor que un error. El prompt le prohíbe inventar precios, plazos o
pasos que no estén en la documentación, y le pide decir qué falta preguntar
cuando no alcanza para resolver.

El cuadro de respuesta pasa a textarea: un borrador de varios renglones no
entraba en un input de una línea.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 19:45:38 -05:00
Lizandro GuarnizoandClaude Opus 5 6afad025c2 feat(soporte): leer solo los correos recientes, no todo el buzón
Sin ventana, la primera corrida convierte en tickets todo lo que haya sin leer,
que en una casilla de años es una avalancha. Ahora hay un desplegable de
antigüedad máxima —6h, 12h, 24h, 3 días o todo— y por defecto 12 horas.

El corte se hace en dos pasos porque IMAP no da para más: al servidor se le
pide SINCE con un día de margen (SINCE compara solo la fecha, no la hora) y el
corte fino por hora se aplica contra la fecha real de cada mensaje. Afinar el
SINCE sería perder los correos del borde.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 19:39:00 -05:00
Lizandro GuarnizoandClaude Opus 5 d7c266f111 feat(soporte): filtro con IA para los correos entrantes, y que un correo no pueda abrir dos tickets
Filtro (opcional, apagado por defecto): antes de abrir ticket, la IA lee el
correo y decide si es soporte o ruido —newsletters, notificaciones de
plataformas, facturas de proveedores, spam—. Falla abierto: si la IA no está
configurada o se cae, el ticket se abre igual. Ignorar a un cliente es peor que
tener un ticket de más. Hay un campo de contexto del negocio para los casos
raros de cada uno.

Los correos masivos se descartan por sus propios encabezados (List-Unsubscribe,
Precedence, Auto-Submitted) sin gastar una llamada de IA.

Y el motivo por el que el mismo correo se leía y se contestaba de nuevo: la
deduplicación era solo un SELECT previo, que no sirve si el flag de leído no
llegó a guardarse o si dos instancias leen el buzón a la vez. Ahora hay un
índice único parcial sobre message_id: la base rechaza el segundo, y ese rechazo
se trata como "ya estaba", no como error — sin ticket repetido y sin segunda
auto-respuesta.

Si algún correo no se pudo marcar como leído, "Revisar buzón ahora" lo dice en
vez de dejarlo solo en el log: es la señal de que van a volver a leerse.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 19:36:01 -05:00
Lizandro GuarnizoandClaude Opus 5 8c3ab79e88 feat(soporte): leer el buzón por IMAP, no solo esperar el webhook
Los clientes escriben a soporte@ desde su correo de siempre. Hasta ahora eso
solo llegaba si un proveedor (SendGrid/Mailgun) nos hacía POST; si nadie lo
configuraba, los correos quedaban sin leer en el buzón.

Ahora el cron entra al buzón cada 2 minutos, baja los no leídos, abre ticket
(o los engancha al hilo si son respuesta) y los marca como leídos. La lógica
de ingesta se movió a services para que webhook e IMAP se comporten igual.

La contraseña del buzón se guarda cifrada (AES-GCM con APP_KEY) y no vuelve
al navegador.

De paso, dos bugs que impedían guardar la configuración: el formulario mandaba
id=0 (gorm.Model serializa "ID"), así que cada guardado creaba una fila nueva
en vez de editar la que se usa; y Updates con struct ignoraba los booleanos en
false, así que desactivar algo no tenía efecto.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:36:08 -05:00
Lizandro Guarnizo 03b18418eb feat: SMTP salida propio en webhook de soporte 2026-07-30 12:19:56 -05:00
Lizandro Guarnizo 28affb5a55 feat: área de soporte con webhook de correo y asignación de tickets 2026-07-28 23:39:03 -05:00