From 8c2f4b5f922bd04660775abc5c10171b4146903f Mon Sep 17 00:00:00 2001 From: Joachim Hummel Date: Fri, 16 Jan 2026 21:31:22 +0000 Subject: [PATCH] Add comprehensive README documentation - Installation and configuration guide - API documentation with examples - CID-embedding explanation for image footer - Integration examples for other projects - Database schema and error handling reference Co-Authored-By: Claude Opus 4.5 --- README.md | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 239 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bc0162..25aa5bb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,240 @@ -# mail-service-embedded +# Mail-Service mit Brevo SMTP +Ein Node.js-basierter Mail-Service mit Weboberfläche zum Versenden von E-Mails über Brevo (ehemals Sendinblue) SMTP. Inklusive persistenter Versand-Historie und eingebettetem Bild-Footer. + +## Features + +- **Weboberfläche** zum Versenden von E-Mails (Empfänger, CC, Betreff, Text/HTML) +- **Persistente Historie** in SQLite-Datenbank +- **Eingebetteter Bild-Footer** via CID-Attachment (wird ohne "Bilder anzeigen" dargestellt) +- **REST-API** für programmatischen Zugriff +- **Brevo SMTP** mit DKIM/SPF/DMARC-Unterstützung + +## Projektstruktur + +``` +mail-service/ +├── .env # Konfiguration (nicht im Git) +├── .env.example # Vorlage +├── package.json +├── src/ +│ ├── server.js # Express-Server, API-Routen +│ ├── mailer.js # Nodemailer mit CID-Footer +│ └── database.js # SQLite-Setup und Queries +├── public/ +│ ├── index.html # Weboberfläche +│ ├── style.css # Styling +│ └── script.js # Frontend-Logik +├── assets/ +│ └── homeicon.png # Footer-Bild (40x40 PNG) +└── data/ + └── emails.db # SQLite-Datenbank (automatisch erstellt) +``` + +## Installation + +```bash +# Repository klonen +git clone https://git.unixweb.net/joachim/mail-service-embedded.git +cd mail-service-embedded + +# Dependencies installieren +npm install + +# Konfiguration erstellen +cp .env.example .env +# .env bearbeiten und SMTP-Credentials eintragen +``` + +## Konfiguration (.env) + +```env +# Server +PORT=3000 + +# Email Configuration +MAIL_PROVIDER=smtp +MAIL_FROM_EMAIL=noreply@example.com +MAIL_FROM_NAME=Secure Portal +MAIL_FOOTER_NAME=Dein Name + +# SMTP (Brevo) +SMTP_HOST=smtp-relay.brevo.com +SMTP_PORT=587 +SMTP_USER=deine-email@example.com +SMTP_PASSWORD=dein-brevo-smtp-key +SMTP_SECURE=false +``` + +### Brevo SMTP-Key erstellen + +1. Bei [Brevo](https://www.brevo.com) einloggen +2. Gehe zu: Einstellungen → SMTP & API → SMTP +3. "SMTP-Schlüssel generieren" klicken +4. Schlüssel in `.env` als `SMTP_PASSWORD` eintragen + +## Starten + +```bash +# Produktion +npm start + +# Entwicklung (mit Auto-Reload) +npm run dev +``` + +Server läuft auf: http://localhost:3000 + +## API-Endpunkte + +| Methode | Route | Beschreibung | +|---------|-------|--------------| +| GET | `/` | Weboberfläche | +| POST | `/api/send` | E-Mail versenden | +| GET | `/api/history` | Historie abrufen (letzte 50) | +| DELETE | `/api/history/:id` | Einzelnen Eintrag löschen | +| DELETE | `/api/history` | Gesamte Historie löschen | + +### POST /api/send + +**Request Body:** +```json +{ + "to": "empfaenger@example.com", + "cc": "optional@example.com", + "subject": "Betreff", + "body": "Nachrichteninhalt", + "isHtml": false +} +``` + +**Response (Erfolg):** +```json +{ + "success": true, + "message": "E-Mail erfolgreich gesendet", + "messageId": "", + "id": 1 +} +``` + +**Response (Fehler):** +```json +{ + "success": false, + "error": "Versand fehlgeschlagen: Connection refused", + "id": 2 +} +``` + +## Datenbank-Schema + +**Tabelle `emails`:** + +| Spalte | Typ | Beschreibung | +|--------|-----|--------------| +| id | INTEGER | Primary Key, Auto-Increment | +| to_email | TEXT | Empfänger-Adresse | +| cc_email | TEXT | CC-Adresse (optional) | +| subject | TEXT | Betreff | +| body | TEXT | Nachrichteninhalt | +| is_html | INTEGER | 0 = Text, 1 = HTML | +| status | TEXT | "success" oder "failed" | +| error_message | TEXT | Fehlermeldung (bei Fehler) | +| created_at | TEXT | ISO-Timestamp | + +## Bild-Footer mit CID-Embedding + +Der Footer mit eingebettetem Bild wird automatisch an jede E-Mail angehängt. + +### Warum CID statt externe URL? + +| Methode | Gmail-Verhalten | +|---------|-----------------| +| `` | Blockiert, "Bilder anzeigen" nötig | +| `` | Sofort sichtbar | + +### Implementierung (mailer.js) + +```javascript +// 1. Bild als Anhang mit Content-ID +attachments: [ + { + filename: 'homeicon.png', + path: '/pfad/zu/assets/homeicon.png', + cid: 'homeicon' // Referenz-ID + } +] + +// 2. Im HTML referenzieren + +``` + +### Footer anpassen + +1. **Bild ändern:** `assets/homeicon.png` ersetzen (empfohlen: 40x40 PNG) +2. **Name ändern:** In `.env` setzen: `MAIL_FOOTER_NAME=Neuer Name` +3. **Layout ändern:** In `src/mailer.js` die Funktion `getHtmlFooter()` bearbeiten + +## Dependencies + +| Paket | Version | Beschreibung | +|-------|---------|--------------| +| express | ^4.18.0 | Webserver | +| nodemailer | ^6.9.0 | E-Mail-Versand | +| better-sqlite3 | ^11.0.0 | SQLite-Datenbank | +| dotenv | ^16.4.0 | Umgebungsvariablen | + +## Integration in andere Projekte + +### Als Standalone-Service + +```javascript +// Externer Aufruf der API +const response = await fetch('http://localhost:3000/api/send', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + to: 'empfaenger@example.com', + subject: 'Test', + body: 'Hallo Welt', + isHtml: false + }) +}); +const result = await response.json(); +``` + +### Mailer-Modul extrahieren + +Die Datei `src/mailer.js` kann direkt in andere Node.js-Projekte kopiert werden: + +```javascript +require('dotenv').config(); +const mailer = require('./mailer'); + +// E-Mail senden +await mailer.sendMail({ + to: 'empfaenger@example.com', + cc: null, + subject: 'Betreff', + body: '

HTML-Inhalt

', + isHtml: true +}); + +// SMTP-Verbindung prüfen +const status = await mailer.verifyConnection(); +console.log(status.success ? 'OK' : status.error); +``` + +## Fehlerbehandlung + +| Fehler | Ursache | Lösung | +|--------|---------|--------| +| `ECONNREFUSED` | SMTP-Server nicht erreichbar | Host/Port in .env prüfen | +| `Invalid login` | Falsche Credentials | SMTP_USER/PASSWORD prüfen | +| `EADDRINUSE` | Port bereits belegt | Anderen PORT in .env setzen | +| `Ungültige E-Mail` | Validierung fehlgeschlagen | E-Mail-Format prüfen | + +## Lizenz + +ISC