jarvis-assist/docs/superpowers/specs/2026-09-13-email-integratio...

4.6 KiB

JARVIS E-Mail-Integration (Phase 4f) - Design

Datum: 2026-09-13 Status: Approved, bereit fuer Implementierungsplan

Kontext

Naechste Integration nach Wetter (n8n-Cache) und Kalender (direktes CalDAV Tool-Use): Zugriff auf das Postfach kontakt@mbo-tech-it.de. JARVIS soll E-Mails lesen/zusammenfassen koennen (Chat, live) und - nach Bestaetigung - E-Mails versenden koennen, plus ein Dashboard-Widget fuer neu eingegangene Mails (n8n-Cache, wie beim Wetter).

Zugangsdaten verifiziert (13.09.2026):

  • IMAP: mx2f35.netcup.net:143, STARTTLS, User kontakt@mbo-tech-it.de (Login + INBOX-Zugriff erfolgreich getestet, 14 vorhandene Nachrichten)
  • SMTP: mx2f35.netcup.net:465, implizites SSL/TLS, gleiche Zugangsdaten (Login erfolgreich getestet, kein Test-Versand)
  • Passwort ist woertlich E%21gq10i (kein URL-encodetes ! - beide Interpretationen getestet, nur die woertliche Variante funktioniert)

Sicherheit: Versand nur nach Bestaetigung

kontakt@mbo-tech-it.de ist die offizielle Firmenadresse. Nach aussen versendete E-Mails sind schwerer zu widerrufen als ein interner Kalendereintrag. Deshalb - analog zum Kalender-Loeschen -: der System-Prompt weist Claude an, vor jedem send_email-Aufruf Empfaenger/Betreff/Text im Chat zur Bestaetigung vorzulegen und das Tool erst nach Zustimmung aufzurufen.

Architektur: zwei Wege, wie beim Kalender/Wetter kombiniert

Chat (live, wie beim Kalender): Zwei neue Claude-Tools in run_chat_completion:

  • list_recent_emails(limit) - liest live per IMAP (imaplib, Python- Standardbibliothek, keine neue Abhaengigkeit) die letzten N Nachrichten aus INBOX (nur Header: From/Subject/Date, BODY.PEEK[...] damit der ungelesen-Status nicht veraendert wird), gibt {from, subject, date, unread} pro Mail zurueck. Betreffzeilen werden mit email.header.decode_header dekodiert (RFC 2047, z.B. =?utf-8?B?...?=).
  • send_email(to, subject, body) - versendet per SMTP (smtplib, Standardbibliothek) ueber Port 465 (implizites TLS). Nur nach Chat-Bestaetigung aufzurufen (siehe oben).

Dashboard-Widget (gecacht, wie beim Wetter): Neuer n8n-Workflow mit dem eingebauten Trigger-Node Email Trigger (IMAP) (n8n-nodes-base.emailReadImap, verifiziert vorhanden in dieser n8n-Version), der selbststaendig neue Nachrichten erkennt (kein eigener Schedule-Trigger noetig, das uebernimmt der Node):

  • postProcessAction: "nothing" - markiert Mails NICHT als gelesen, damit das automatische Cachen den tatsaechlichen Lese-Status im Postfach nicht verfaelscht
  • format: "simple" reicht (nur Header/Text, keine Anhaenge noetig)
  • Schreibt pro neuer Mail eine Zeile in eine neue Tabelle email_cache (sender, subject, received_at)

GET /api/v1/emails (geschuetzt wie alle anderen Routen) liest die neuesten Zeilen daraus fuer das Dashboard-Widget "Neue E-Mails".

Datenmodell

CREATE TABLE email_cache (
    id SERIAL PRIMARY KEY,
    sender VARCHAR(255) NOT NULL,
    subject VARCHAR(500) NOT NULL,
    received_at TIMESTAMP NOT NULL,
    cached_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_email_cache_received_at ON email_cache(received_at);

Nur Metadaten (Absender/Betreff/Datum) werden dauerhaft gespeichert - keine E-Mail-Inhalte/Volltexte, um die Menge an gespeicherter Geschaeftskorrespondenz gering zu halten (die Chat-Tools lesen bei Bedarf live, ohne Zwischenspeicherung).

Fehlerbehandlung

  • IMAP/SMTP nicht erreichbar oder Login fehlgeschlagen: Chat-Tools werfen eine Exception mit klarer Meldung, die als tool_result mit is_error: true an Claude zurueckgeht (gleiches Muster wie beim Kalender).
  • GET /api/v1/emails bei leerem Cache: gibt ein leeres Array zurueck (kein 503) - anders als beim Wetter ist "noch keine neue Mail seit Start des Workflows" ein normaler, kein Fehlerzustand.

Testing

  • Backend: Unit-Tests fuer die IMAP-Parsing-Funktion (RFC-2047-Betreffs dekodieren, unread-Flag aus FLAGS-Antwort ableiten) und fuer den SMTP-Sende-Aufruf, jeweils mit gemocktem imaplib/smtplib.
  • Manueller End-to-End-Test nach Deployment: Chat nach "was ist neu im Postfach?" fragen (echte IMAP-Daten), eine Test-Mail an die eigene Adresse per Chat versenden lassen (inkl. Bestaetigungs-Dialog), n8n- Workflow aktivieren und pruefen, dass die Test-Mail in email_cache auftaucht, Dashboard-Widget ansehen.

Out of Scope (bewusst nicht Teil dieser Phase)

  • Anhaenge (weder lesen noch versenden).
  • Antworten/Weiterleiten als eigene Aktion (nur neues send_email).
  • Loeschen/Verschieben von E-Mails.
  • Mehrere Postfaecher/Ordner (nur INBOX von kontakt@mbo-tech-it.de).