Files
fn_registry/python/functions/infra/imap_move_message.md
T
egutierrez 763e06c127 feat(browser): auto-commit con 178 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-20 18:22:23 +02:00

4.8 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
imap_move_message function py infra 1.0.0 impure def imap_move_message(conn, uid: int, dest_mailbox: str) -> dict Mueve un mensaje IMAP (por UID) del mailbox seleccionado a dest_mailbox sobre una conexion imaplib.IMAP4_SSL ya autenticada. Intenta primero conn.uid('MOVE', str(uid), dest_mailbox) (RFC 6851, atomico, soportado por Gmail) detectando la capability en conn.capabilities; si el servidor NO anuncia MOVE o el comando falla, usa el fallback clasico equivalente: UID COPY a dest + UID STORE +FLAGS (\Deleted) en origen + EXPUNGE. Devuelve el camino usado en method ('move' o 'copy_delete'). Opera siempre por UID (estable dentro del mailbox), nunca por numero de secuencia. No abre la conexion ni resuelve credenciales: el caller pasa conn ya conectado, autenticado y con conn.select() del mailbox origen hecho. Nunca lanza: devuelve {status:'ok', uid, dest, method} o {status:'error', error}. En Gmail los nombres de carpeta llevan el prefijo '[Gmail]/' y mover a '[Gmail]/Trash' = papelera. Parte del grupo email/imap. Solo stdlib (imaplib).
email
imap
mail
move
mailbox
infra
false error_py_core
imaplib
name desc
conn objeto imaplib.IMAP4_SSL (o IMAP4) YA conectado, autenticado y con el mailbox ORIGEN seleccionado (conn.select('INBOX')). Normalmente lo produce imap_connect. La funcion no lo abre ni lo cierra. Lee conn.capabilities para decidir MOVE vs fallback.
name desc
uid UID del mensaje en el mailbox origen. Operacion siempre por UID (estable mientras no cambie la UIDVALIDITY), nunca por numero de secuencia.
name desc
dest_mailbox nombre del mailbox destino. En Gmail lleva el prefijo '[Gmail]/' (ej. '[Gmail]/Trash' = papelera, '[Gmail]/Spam'); una carpeta de usuario es solo su nombre. El destino debe existir en el servidor.
dict. En exito: {status:'ok', uid:int, dest:str, method:'move'|'copy_delete'} donde method indica si se uso UID MOVE atomico o el fallback COPY+STORE \Deleted+EXPUNGE. En error (sin lanzar): {status:'error', error:str}, p.ej. si COPY o STORE devuelven un typ distinto de OK. false
python/functions/infra/imap_move_message.py

Ejemplo

import sys
sys.path.insert(0, "python/functions")
from infra.imap_connect import imap_connect
from infra.imap_move_message import imap_move_message

# conn ya conectado, autenticado y con INBOX seleccionado (lo produce imap_connect).
conn = imap_connect(...)["conn"]  # firma exacta la define imap_connect

# Mover el mensaje UID 12345 a la papelera de Gmail (nota el prefijo [Gmail]/).
print(imap_move_message(conn, 12345, "[Gmail]/Trash"))
# {'status': 'ok', 'uid': 12345, 'dest': '[Gmail]/Trash', 'method': 'move'}

# En un servidor sin MOVE el resultado seria identico salvo method:
# {'status': 'ok', 'uid': 12345, 'dest': 'Archive', 'method': 'copy_delete'}

Cuando usarla

Cuando quieres reubicar un mensaje entre carpetas sin descargarlo ni reenviarlo: archivar, clasificar en una etiqueta/carpeta, o enviarlo a la papelera. Es la via correcta para "borrar de verdad" en Gmail (mover a [Gmail]/Trash), donde marcar \\Deleted solo quita la etiqueta de la carpeta actual. La funcion abstrae la diferencia entre servidores con y sin soporte MOVE, asi que el caller no necesita saber si el backend implementa RFC 6851. Compone tras imap_search/imap_fetch_message.

Gotchas

  • Impura: cambia estado en el servidor de forma persistente y puede borrar el mensaje del origen (en el fallback, tras EXPUNGE).
  • Gmail \Deleted vs Trash: en Gmail, marcar \\Deleted NO borra el mensaje, solo le quita la etiqueta de la carpeta actual. Para borrar de verdad hay que mover a [Gmail]/Trash. Por eso esta funcion es la herramienta de borrado real en Gmail (con dest_mailbox="[Gmail]/Trash").
  • Prefijo [Gmail]/: las carpetas del sistema de Gmail llevan el prefijo [Gmail]/ ([Gmail]/Trash, [Gmail]/Spam, [Gmail]/Drafts, [Gmail]/Sent Mail, [Gmail]/All Mail). Las carpetas/etiquetas de usuario van por su nombre directo.
  • MOVE vs COPY+EXPUNGE: MOVE (RFC 6851) es atomico; el fallback COPY+STORE \Deleted+EXPUNGE no lo es — si falla entre pasos, el mensaje puede quedar duplicado (en origen y destino) o marcado \Deleted sin expurgar. El EXPUNGE del fallback materializa los borrados pendientes del mailbox origen completo.
  • UID estable, no secuencia: se usa siempre conn.uid(...). El UID es estable dentro del mailbox mientras no cambie la UIDVALIDITY; el numero de secuencia se desplaza al borrar mensajes y por eso nunca se usa.
  • Nunca lanza: cualquier fallo (destino inexistente, conexion caida, respuesta no-OK) vuelve como {status:'error', error:str}.