8c2f4b5f922bd04660775abc5c10171b4146903f
- 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>
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
# 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)
# 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
- Bei Brevo einloggen
- Gehe zu: Einstellungen → SMTP & API → SMTP
- "SMTP-Schlüssel generieren" klicken
- Schlüssel in
.envalsSMTP_PASSWORDeintragen
Starten
# 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:
{
"to": "empfaenger@example.com",
"cc": "optional@example.com",
"subject": "Betreff",
"body": "Nachrichteninhalt",
"isHtml": false
}
Response (Erfolg):
{
"success": true,
"message": "E-Mail erfolgreich gesendet",
"messageId": "<abc123@smtp-relay.sendinblue.com>",
"id": 1
}
Response (Fehler):
{
"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)
// 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
- Bild ändern:
assets/homeicon.pngersetzen (empfohlen: 40x40 PNG) - Name ändern: In
.envsetzen:MAIL_FOOTER_NAME=Neuer Name - Layout ändern: In
src/mailer.jsdie FunktiongetHtmlFooter()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
// 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:
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
V 1.1.0
Latest
Languages
JavaScript
66.5%
CSS
22.5%
HTML
11%