mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 12:45:42 +02:00
Merge branch 'main' of https://github.com/idrainformatica/PecFlow
This commit is contained in:
+55
-5
@@ -35,6 +35,8 @@ from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.config import get_settings
|
||||
from app.jobs.dispatch_notification import evaluate_and_enqueue_notifications
|
||||
from app.jobs.index_message import index_message
|
||||
from app.models import Attachment, Mailbox, Message
|
||||
from app.parsers.eml_parser import parse_eml
|
||||
from app.parsers.pec_parser import apply_outbound_transition, classify_pec_message
|
||||
@@ -539,11 +541,15 @@ async def _save_message(
|
||||
logger.debug(f"[{mailbox.email_address}] UID {uid} in {imap_folder!r} già in DB, skip")
|
||||
return False
|
||||
|
||||
# ── Parsing completo EML ──────────────────────────────────────────────────
|
||||
parsed = parse_eml(raw_eml)
|
||||
pec_class = classify_pec_message(
|
||||
parsed.raw_message or email.message_from_bytes(raw_eml)
|
||||
)
|
||||
# ── Classificazione PEC da header (veloce, senza body) ───────────────────
|
||||
# La classificazione avviene PRIMA del parsing completo perche' il parser
|
||||
# deve sapere se il messaggio e' una ricevuta per evitare di sovrascrivere
|
||||
# il body_text (testo della ricevuta) con il contenuto di postacert.eml.
|
||||
quick_msg = email.message_from_bytes(raw_eml)
|
||||
pec_class = classify_pec_message(quick_msg)
|
||||
|
||||
# ── Parsing completo EML (con is_receipt per proteggere il body) ──────────
|
||||
parsed = parse_eml(raw_eml, is_receipt=pec_class.is_receipt)
|
||||
received_at = datetime.now(UTC)
|
||||
|
||||
# ── State machine: trova e aggiorna messaggio outbound ────────────────────
|
||||
@@ -635,6 +641,50 @@ async def _save_message(
|
||||
f"direction={direction!r} pec_type={pec_class.pec_type!r} "
|
||||
f"subject={message.subject!r} allegati={len(parsed.attachments)}"
|
||||
)
|
||||
|
||||
# ── Indicizzazione full-text (non bloccante, non interrompe la sync) ─────
|
||||
# Chiamata dopo il flush degli allegati: index_message puo' leggere
|
||||
# sia il messaggio che gli allegati dalla sessione corrente.
|
||||
await index_message(message.id, db)
|
||||
|
||||
# ── Valutazione e accodamento notifiche (non bloccante) ───────────────────
|
||||
# Solo per messaggi inbound: le ricevute PEC e la posta in arrivo
|
||||
# possono triggerare regole di notifica configurate dal tenant.
|
||||
# I messaggi outbound (Sent) non generano notifiche automatiche.
|
||||
if direction == "inbound":
|
||||
await evaluate_and_enqueue_notifications(
|
||||
message=message,
|
||||
mailbox=mailbox,
|
||||
db=db,
|
||||
redis_client=redis_client,
|
||||
)
|
||||
|
||||
# ── Regole di smistamento automatico (Feature 2) ──────────────────────────
|
||||
# Solo per messaggi inbound posta_certificata (non ricevute di sistema).
|
||||
if direction == "inbound" and pec_class.pec_type == "posta_certificata":
|
||||
try:
|
||||
await redis_client.enqueue_job("apply_routing_rules", str(message.id))
|
||||
except Exception as e:
|
||||
logger.warning(f"[{mailbox.email_address}] Impossibile enqueue apply_routing_rules: {e}")
|
||||
|
||||
# ── Auto-save mittente nella rubrica (Feature 6) ──────────────────────────
|
||||
# Per messaggi inbound di tipo posta_certificata, salva automaticamente
|
||||
# il mittente nella rubrica pec_contacts del tenant (upsert idempotente).
|
||||
if direction == "inbound" and pec_class.pec_type == "posta_certificata" and message.from_address:
|
||||
try:
|
||||
from sqlalchemy import text as _text
|
||||
await db.execute(
|
||||
_text("""
|
||||
INSERT INTO pec_contacts (id, tenant_id, email, auto_saved, created_at, updated_at)
|
||||
VALUES (gen_random_uuid(), :tenant_id, :email, true, now(), now())
|
||||
ON CONFLICT (tenant_id, email) DO NOTHING
|
||||
"""),
|
||||
{"tenant_id": str(mailbox.tenant_id), "email": message.from_address.lower().strip()},
|
||||
)
|
||||
await db.flush()
|
||||
except Exception as e:
|
||||
logger.debug(f"[{mailbox.email_address}] Auto-save contatto fallito (non critico): {e}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user