Fix: IMAP Sent-Ordner — echten Namen aus LIST-Antwort extrahieren (INBOX.Sent)
This commit is contained in:
parent
31fae63658
commit
4c6dd07c31
1 changed files with 25 additions and 11 deletions
|
|
@ -10,13 +10,16 @@ from email.utils import formataddr
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from auth import require_admin
|
from auth import require_admin
|
||||||
from database import db
|
from database import db
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
_log = logging.getLogger(__name__)
|
||||||
|
|
||||||
_SMTP_HOST = os.getenv("SMTP_HOST", "mail.your-server.de")
|
_SMTP_HOST = os.getenv("SMTP_HOST", "mail.your-server.de")
|
||||||
_SMTP_PORT = int(os.getenv("SMTP_PORT", "587"))
|
_SMTP_PORT = int(os.getenv("SMTP_PORT", "587"))
|
||||||
|
|
@ -45,29 +48,40 @@ _SENT_CANDIDATES = ["Sent", "Sent Messages", "Sent Items", "INBOX.Sent", "Gesend
|
||||||
def _imap_save_sent(msg_bytes: bytes, account: str):
|
def _imap_save_sent(msg_bytes: bytes, account: str):
|
||||||
acc = _ACCOUNTS.get(account) or _ACCOUNTS["partner"]
|
acc = _ACCOUNTS.get(account) or _ACCOUNTS["partner"]
|
||||||
if not acc["user"] or not acc["pass"]:
|
if not acc["user"] or not acc["pass"]:
|
||||||
|
_log.warning("IMAP: Account '%s' nicht konfiguriert, überspringe.", account)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
ctx = ssl.create_default_context()
|
ctx = ssl.create_default_context()
|
||||||
with imaplib.IMAP4_SSL(_IMAP_HOST, _IMAP_PORT, ssl_context=ctx) as imap:
|
with imaplib.IMAP4_SSL(_IMAP_HOST, _IMAP_PORT, ssl_context=ctx) as imap:
|
||||||
imap.login(acc["user"], acc["pass"])
|
imap.login(acc["user"], acc["pass"])
|
||||||
# Sent-Ordner finden
|
_, raw_folders = imap.list()
|
||||||
|
available = [f.decode(errors="replace") for f in (raw_folders or [])]
|
||||||
|
_log.info("IMAP Ordner (%s): %s", account, available)
|
||||||
|
|
||||||
|
# Echten Ordnernamen aus LIST-Antwort extrahieren
|
||||||
|
# Format: '(\Flags) "." INBOX.Sent' → letztes Token
|
||||||
folder = None
|
folder = None
|
||||||
_, folders = imap.list()
|
for line in available:
|
||||||
available = [f.decode() for f in (folders or [])]
|
name = line.rsplit('"." ', 1)[-1].strip().strip('"')
|
||||||
for candidate in _SENT_CANDIDATES:
|
for candidate in _SENT_CANDIDATES:
|
||||||
if any(candidate.lower() in f.lower() for f in available):
|
if candidate.lower() in name.lower():
|
||||||
folder = candidate
|
folder = name
|
||||||
|
break
|
||||||
|
if folder:
|
||||||
break
|
break
|
||||||
if not folder:
|
if not folder:
|
||||||
folder = "Sent" # Fallback: anlegen lassen
|
folder = "INBOX.Sent"
|
||||||
imap.append(
|
_log.info("IMAP: speichere in Ordner '%s' (%s)", folder, account)
|
||||||
|
|
||||||
|
typ, data = imap.append(
|
||||||
folder,
|
folder,
|
||||||
r"\Seen",
|
r"\Seen",
|
||||||
imaplib.Time2Internaldate(datetime.now().timestamp()),
|
imaplib.Time2Internaldate(datetime.now().timestamp()),
|
||||||
msg_bytes,
|
msg_bytes,
|
||||||
)
|
)
|
||||||
except Exception:
|
_log.info("IMAP append: %s %s", typ, data)
|
||||||
pass # Nicht blockieren wenn IMAP fehlschlägt
|
except Exception as e:
|
||||||
|
_log.error("IMAP Sent-Speicherung fehlgeschlagen (%s): %s", account, e)
|
||||||
|
|
||||||
|
|
||||||
def _build_message(to: str, subject: str, body: str, account: str) -> MIMEMultipart:
|
def _build_message(to: str, subject: str, body: str, account: str) -> MIMEMultipart:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue