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 <noreply@anthropic.com>
This commit is contained in:
240
README.md
240
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": "<abc123@smtp-relay.sendinblue.com>",
|
||||||
|
"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 |
|
||||||
|
|---------|-----------------|
|
||||||
|
| `<img src="https://...">` | Blockiert, "Bilder anzeigen" nötig |
|
||||||
|
| `<img src="cid:homeicon">` | 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
|
||||||
|
<img src="cid:homeicon" width="40" height="40" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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: '<h1>HTML-Inhalt</h1>',
|
||||||
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user