# Modul: Email-System > SMTP-Versand mit Nodemailer (STARTTLS Port 587), Queue-Fallback in Supabase bei Versandfehlern, exponentielles Retry (max 10 Versuche). Unterstützt HTML + Plaintext, HMAC-signierte Action-Buttons in Admin-Mails (7 Tage gültig, One-Time-Use). --- ## Enthaltene Dateien | Ziel im neuen Projekt | Quelle | |---|---| | `lib/mailer.ts` | Haupt-Mailer (Nodemailer + alle Email-Funktionen) | | `lib/email-queue.ts` | Queue-System (Supabase-Fallback + Worker) | | `app/api/admin/email-queue/route.ts` | Admin-API: Queue-Status anzeigen | | `app/api/admin/smtp-test/route.ts` | Admin-API: SMTP-Verbindung testen | **Hinweis:** `[id]`-Ordner in `files/` entsprechen Next.js Dynamic-Route-Ordnern `[id]`. --- ## Voraussetzungen ```bash npm install nodemailer npm install -D @types/nodemailer ``` Benötigt außerdem: - `lib/supabase.ts` (Service Client für Queue-Speicherung) - `lib/admin-auth.ts` (für `createActionToken` in Admin-Mails, optional) --- ## Umgebungsvariablen (`.env.local`) ```env SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=user@example.com SMTP_PASS=password SMTP_FROM=noreply@example.com # Absender SMTP_TO=admin@example.com # Admin-Inbox COMPANY_PHONE=+49123456789 # Wird in Mails angezeigt APP_URL=https://example.com # Basis-URL für Links in Mails NEXTAUTH_SECRET=your-secret # HMAC-Key für Action-Tokens ``` --- ## Datenbank-Migration (Supabase) Tabelle `email_queue` muss in `lib/supabase.ts` als Type definiert und in Supabase existieren: ```sql CREATE TABLE email_queue ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), to_addr text NOT NULL, subject text NOT NULL, html text NOT NULL, text text, attempts int DEFAULT 0, max_attempts int DEFAULT 10, status text DEFAULT 'pending' CHECK (status IN ('pending','sent','failed')), last_error text, next_retry_at timestamptz DEFAULT now(), created_at timestamptz DEFAULT now(), sent_at timestamptz ); CREATE INDEX idx_email_queue_pending ON email_queue(status, next_retry_at) WHERE status = 'pending'; ``` --- ## Einbindung Schritt für Schritt ### 1. Dateien kopieren Alle Dateien aus `files/` in die entsprechenden Pfade des neuen Projekts kopieren. ### 2. Mailer an Projekt anpassen (`lib/mailer.ts`) Die Datei enthält projektspezifische Email-Funktionen (Anfragen, Kunden-Bestätigungen etc.). Folgende Funktionen beibehalten oder anpassen: - `sendeKontaktEmail(data)` → bleibt meist unverändert - Alle anderen Funktionen nach Bedarf umbenennen/entfernen - Firmenname/Branding in HTML-Templates ersetzen (Suche nach `Mietpark Hahn`) ### 3. Queue-Worker starten (`instrumentation.ts`) ```ts // instrumentation.ts (Projekt-Root) import { startEmailQueueWorker } from "@/lib/email-queue"; export async function register() { if (process.env.NEXT_RUNTIME === "nodejs") { startEmailQueueWorker(); } } ``` ### 4. Email-Queue Typ in `lib/supabase.ts` ergänzen Im `Database`-Typ die `email_queue` Tabelle mit den Feldern aus der Migration ergänzen. ### 5. Action-Buttons (optional) Wenn Admin-Mails HMAC-signierte Buttons enthalten sollen (z.B. "Bestätigen / Ablehnen"): - Modul `02-admin-auth` muss eingebunden sein (liefert `createActionToken`) - Buttons verweisen auf `GET /api/admin/anfragen-action?token=...` ### 6. SMTP testen ```bash curl -X POST http://localhost:3000/api/admin/smtp-test \ -H "Content-Type: application/json" \ -d '{"to":"test@example.com"}' ``` --- ## Anpassungspunkte | Was | Wo | |---|---| | HTML-Templates (Firmenname, Farben) | `lib/mailer.ts` – alle `html`-Variablen | | Email-Betreffs | `lib/mailer.ts` – alle `subject`-Zeilen | | Retry-Intervalle | `lib/email-queue.ts` – `calcNextRetry()` | | Max. Versuche | `lib/email-queue.ts` – `maxAttempts: 10` | | Queue-Worker-Intervall | `lib/email-queue.ts` – `setInterval(60_000)` | | SMTP Port (465 statt 587) | `lib/mailer.ts` – `secure: true, port: 465` | --- ## Integrations-Prompt Kopiere diesen Prompt in eine neue KI-Konversation, nachdem du die `files/` in dein Projekt kopiert hast. Ersetze alle `[PLATZHALTER]`. ``` Ich integriere das Email-System-Modul (Nodemailer + Supabase Queue) in mein bestehendes Next.js/Supabase-Projekt. PROJEKT-KONTEXT: - Projektname: [PROJEKTNAME] - Admin-Email (Empfänger): [ADMIN_EMAIL] - SMTP-Absender: [SMTP_FROM_EMAIL] - App-URL (für Links in Mails): [https://beispiel.de] BEREITS KOPIERTE DATEIEN (aus modules/01-email-system/files/): - lib/mailer.ts - lib/email-queue.ts - app/api/admin/email-queue/route.ts - app/api/admin/smtp-test/route.ts AUFGABEN – führe sie der Reihe nach aus: 1. SUPABASE-MIGRATION: Führe folgendes SQL im Supabase SQL-Editor aus: CREATE TABLE email_queue ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), to_addr text NOT NULL, subject text NOT NULL, html text NOT NULL, text text, attempts int DEFAULT 0, max_attempts int DEFAULT 10, status text DEFAULT 'pending' CHECK (status IN ('pending','sent','failed')), last_error text, next_retry_at timestamptz DEFAULT now(), created_at timestamptz DEFAULT now(), sent_at timestamptz ); CREATE INDEX idx_email_queue_pending ON email_queue(status, next_retry_at) WHERE status = 'pending'; 2. SUPABASE-TYPEN: Lies lib/supabase.ts und ergänze in Database.public.Tables: email_queue: { Row: { id: string; to_addr: string; subject: string; html: string; text: string | null; attempts: number; max_attempts: number; status: string; last_error: string | null; next_retry_at: string; created_at: string; sent_at: string | null } } 3. BRANDING: Ersetze in lib/mailer.ts alle Vorkommen von "Mietpark Hahn" durch "[PROJEKTNAME]". Passe außerdem die Farben im HTML-Template an (aktuell #f7d334 für Buttons). 4. QUEUE-WORKER: Lies instrumentation.ts (oder erstelle sie im Projekt-Root falls nicht vorhanden). Ergänze/ersetze den Inhalt um: import { startEmailQueueWorker } from "@/lib/email-queue"; export async function register() { if (process.env.NEXT_RUNTIME === "nodejs") startEmailQueueWorker(); } 5. ENV-VARIABLEN: Ergänze .env.local um: SMTP_HOST=[SMTP_HOST] SMTP_PORT=587 SMTP_USER=[SMTP_USER] SMTP_PASS=[SMTP_PASS] SMTP_FROM=[SMTP_FROM_EMAIL] SMTP_TO=[ADMIN_EMAIL] COMPANY_PHONE=[TELEFON] APP_URL=[https://beispiel.de] NEXTAUTH_SECRET=[MIN_32_ZEICHEN_ZUFAELLIGER_STRING] 6. TEST: Starte den Dev-Server und sende eine Test-Email: curl -X POST http://localhost:3000/api/admin/smtp-test \ -H "Content-Type: application/json" \ -d '{"to":"[ADMIN_EMAIL]"}' Lies jede Datei vor dem Bearbeiten. Melde wenn alle Schritte abgeschlossen sind. ```