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