fix(soporte): el buzón IMAP nunca se leía — la búsqueda pedía UIDs a una búsqueda por secuencia

Usé c.Search, que devuelve números de secuencia, y después le pedí los UIDs al
resultado. go-imap devuelve nil ahí, así que la lista salía siempre vacía: el
cron conectaba bien, buscaba bien, y se iba sin leer nada ni escribir un solo
error en el log. Va con UIDSearch.

Con eso se arreglan las dos cosas: no leía y no creaba tickets.

Además:
- Fetch con Peek: el correo queda marcado como leído solo si se llegó a
  procesar. Antes, un fallo a mitad de camino lo perdía para siempre.
- "Probar conexión" ahora informa cuántos mensajes hay en la carpeta y cuántos
  sin leer; "Revisar buzón ahora" informa cuántos encontró y cuántos convirtió
  en ticket, y avisa si la lectura está desactivada.
- Un correo sin asunto abre ticket como "(sin asunto)" en vez de descartarse en
  silencio, y los descartes quedan en el log.

Los tres tests nuevos corren contra un servidor IMAP en memoria: bajar los no
leídos, que marcar como leído los saque de la próxima corrida, y que bajarlos
sin procesarlos no los marque. El primero falla si se vuelve a poner Search.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-08-17 19:20:27 -05:00
co-authored by Claude Opus 5
parent d1bbb4a508
commit 5875f9e36b
5 changed files with 247 additions and 38 deletions
+13 -4
View File
@@ -2,6 +2,7 @@ package controllers
import (
"crypto/subtle"
"fmt"
"log"
"regexp"
"strconv"
@@ -305,15 +306,23 @@ func ProbarImapSoporte(c *fiber.Ctx) error {
if err != nil || cfg == nil {
return c.Status(400).JSON(fiber.Map{"error": "Guardá la configuración antes de probar"})
}
if err := services.ProbarConexionImap(cfg); err != nil {
detalle, err := services.ProbarConexionImap(cfg)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"ok": true, "message": "Conexión IMAP correcta"})
return c.JSON(fiber.Map{"ok": true, "message": detalle})
}
// RevisarBuzonAhora dispara una lectura del buzón sin esperar al cron.
// POST /app/api/soporte-webhook/revisar-buzon
func RevisarBuzonAhora(c *fiber.Ctx) error {
services.RevisarBuzonSoporte()
return c.JSON(fiber.Map{"ok": true, "message": "Buzón revisado, mirá la lista de tickets"})
encontrados, procesados, err := services.RevisarBuzonSoporteConDetalle()
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
if encontrados == 0 {
return c.JSON(fiber.Map{"ok": true, "message": "Conectó bien, pero no hay correos sin leer en el buzón"})
}
return c.JSON(fiber.Map{"ok": true, "message": fmt.Sprintf(
"%d correo(s) sin leer, %d convertido(s) en ticket. El resto ya estaba registrado.", encontrados, procesados)})
}