9.3 KiB
Newsletter-Modul Dokumentation
Übersicht
Das Newsletter-Modul ermöglicht die zentrale Verwaltung von Newsletter-Kontakten aus beiden Buchungssystemen (Kulturreisen und Ferienwohnungen). Es synchronisiert automatisch Kundendaten aus Buchungen und bietet Export-Funktionen für Newsletter-Kampagnen.
Features
- ✅ Zentrale Kontaktverwaltung für beide Newsletter-Gruppen
- ✅ Automatische Synchronisation aus Buchungssystemen
- ✅ Duplikat-Erkennung über E-Mail-Adressen
- ✅ Tracking von Buchungsstatistiken
- ✅ Status-Verwaltung (Aktiv, Inaktiv, Abgemeldet, Bounced)
- ✅ Herkunfts-Tracking (Buchung, Newsletter-Anmeldung, etc.)
- ✅ Export-Funktion (CSV)
- ✅ Aktivitäts-Log für jeden Kontakt
- ✅ Filter- und Suchfunktionen
Installation
1. Migrationen ausführen
./vendor/bin/sail artisan migrate
Dies erstellt folgende Tabellen:
newsletter_contacts- Haupt-Kontakte-Tabellenewsletter_logs- Aktivitäts-Log
2. Berechtigung hinzufügen
In der Datenbank muss die Berechtigung cms-newsletter für Benutzer aktiviert werden, die Zugriff auf das Newsletter-Modul haben sollen.
-- Beispiel: Berechtigung für einen User aktivieren
-- Dies muss über das bestehende Berechtigungssystem erfolgen
3. Erste Synchronisation
Nach der Installation sollte eine vollständige Synchronisation durchgeführt werden:
# Alle Buchungen synchronisieren
./vendor/bin/sail artisan newsletter:sync-kulturreisen --force
./vendor/bin/sail artisan newsletter:sync-ferienwohnungen --force
Verwendung
Admin-Panel
Das Newsletter-Modul ist im Admin-Panel unter CMS > Inhalte > Newsletter erreichbar.
Hauptfunktionen:
-
Kontaktliste
- Übersicht aller Newsletter-Kontakte
- Filter nach Gruppe, Status, Herkunft
- Suchfunktion nach E-Mail und Name
- DataTables mit Sortierung und Pagination
-
Kontakt-Detail
- Vollständige Kontaktinformationen
- Buchungsstatistiken
- Aktivitäts-Log
- Verlinkung zu Original-Kundendaten
-
Kontakt bearbeiten
- Manuelles Erstellen von Kontakten
- Bearbeiten von Kontaktdaten
- Status-Änderung
- Gruppen-Zuweisung
-
Synchronisation
- Manuelle Synchronisation über UI
- Incremental Sync (letzte 30 Tage)
- Full Sync (alle Buchungen)
-
Export
- Export nach Gruppe
- Export nach Status
- CSV-Format
- Vorkonfigurierte Export-Optionen
Artisan-Befehle
Synchronisation Kulturreisen
# Incremental Sync (letzte 30 Tage)
./vendor/bin/sail artisan newsletter:sync-kulturreisen
# Full Sync (alle Buchungen)
./vendor/bin/sail artisan newsletter:sync-kulturreisen --force
Dieser Befehl:
- Liest alle Buchungen aus der
bookingTabelle - Verknüpft mit
customerDaten - Erstellt oder aktualisiert Newsletter-Kontakte
- Zählt Buchungen pro Kunde
- Trackt letzte Buchung
Synchronisation Ferienwohnungen
# Incremental Sync (letzte 30 Tage)
./vendor/bin/sail artisan newsletter:sync-ferienwohnungen
# Full Sync (alle Buchungen)
./vendor/bin/sail artisan newsletter:sync-ferienwohnungen --force
Dieser Befehl:
- Liest Buchungen aus
travel_user_booking_fewosmitinvoice_number - Nur Buchungen mit reiner Nummer (keine Storno etc.)
- Verknüpft mit
travel_usersDaten - Erstellt oder aktualisiert Newsletter-Kontakte
- Zählt Buchungen pro Kunde
Automatische Synchronisation
Für regelmäßige Synchronisation empfiehlt sich ein Cron-Job:
# In der crontab
# Täglich um 2 Uhr morgens
0 2 * * * cd /var/www/html && ./vendor/bin/sail artisan newsletter:sync-kulturreisen
0 2 * * * cd /var/www/html && ./vendor/bin/sail artisan newsletter:sync-ferienwohnungen
Oder im Laravel Scheduler (app/Console/Kernel.php):
protected function schedule(Schedule $schedule)
{
// Täglich um 2 Uhr
$schedule->command('newsletter:sync-kulturreisen')->dailyAt('02:00');
$schedule->command('newsletter:sync-ferienwohnungen')->dailyAt('02:15');
}
Datenmodell
Newsletter Contact
| Feld | Typ | Beschreibung |
|---|---|---|
id |
bigint | Primary Key |
email |
string | E-Mail-Adresse (unique) |
firstname |
string | Vorname |
lastname |
string | Nachname |
group_kulturreisen |
boolean | Zugehörigkeit zur Gruppe Kulturreisen |
group_ferienwohnungen |
boolean | Zugehörigkeit zur Gruppe Ferienwohnungen |
source |
enum | Herkunft des Kontakts |
status |
enum | Status (active, inactive, unsubscribed, bounced) |
subscribed_at |
timestamp | Zeitpunkt der Anmeldung |
unsubscribed_at |
timestamp | Zeitpunkt der Abmeldung |
last_booking_at |
timestamp | Zeitpunkt der letzten Buchung |
total_bookings_kulturreisen |
int | Anzahl Buchungen Kulturreisen |
total_bookings_ferienwohnungen |
int | Anzahl Buchungen Ferienwohnungen |
customer_id |
int | Referenz zu customer (Kulturreisen) |
travel_user_id |
int | Referenz zu travel_users (Ferienwohnungen) |
last_synced_at |
timestamp | Letzte Synchronisation |
sync_hash |
string | Hash für Duplikat-Erkennung |
notes |
text | Notizen |
Newsletter Log
| Feld | Typ | Beschreibung |
|---|---|---|
id |
bigint | Primary Key |
newsletter_contact_id |
bigint | Foreign Key zu newsletter_contacts |
action |
enum | Aktion (subscribed, unsubscribed, etc.) |
description |
string | Beschreibung der Aktion |
metadata |
json | Zusätzliche Daten |
user_id |
int | Admin-User der die Aktion ausgeführt hat |
Status-Typen
- active: Aktiver Newsletter-Empfänger
- inactive: Inaktiv (z.B. temporär deaktiviert)
- unsubscribed: Abgemeldet vom Newsletter
- bounced: E-Mail nicht zustellbar (Bounced)
Herkunfts-Typen
- booking_kulturreisen: Aus Kulturreisen-Buchung
- booking_ferienwohnungen: Aus Ferienwohnungs-Buchung
- newsletter_signup: Newsletter-Anmeldung über Formular
- manual: Manuell erstellt
- import: Über Import hinzugefügt
Export-Formate
CSV-Export
Der CSV-Export enthält folgende Spalten:
- ID
- Vorname
- Nachname
- Gruppe Kulturreisen (Ja/Nein)
- Gruppe Ferienwohnungen (Ja/Nein)
- Status
- Herkunft
- Buchungen Kulturreisen
- Buchungen Ferienwohnungen
- Letzte Buchung
- Angemeldet am
- Abgemeldet am
- Erstellt am
Best Practices
Duplikat-Vermeidung
Das System verwendet einen Hash basierend auf E-Mail und Quelle zur Duplikat-Erkennung. Kontakte werden automatisch zusammengeführt, wenn:
- Dieselbe E-Mail-Adresse in beiden Systemen vorkommt
- Der neuere Datensatz wird bevorzugt
- Gruppenzugehörigkeiten werden kombiniert
Datenschutz
- Soft-Delete: Gelöschte Kontakte werden nicht permanent entfernt
- Log-Tracking: Alle Änderungen werden protokolliert
- Abmelde-Funktion: Kontakte können sich jederzeit abmelden
- Export-Kontrolle: Nur autorisierte Benutzer können exportieren
Performance
- Incremental Sync: Standardmäßig werden nur die letzten 30 Tage synchronisiert
- Indexierung: E-Mail, Status und Gruppen sind indexiert
- DataTables: Server-Side Processing für große Datenmengen
- Batch-Processing: Synchronisation verarbeitet Datensätze effizient
Troubleshooting
Problem: Synchronisation schlägt fehl
Lösung:
- Prüfe Datenbankverbindungen (beide Datenbanken müssen erreichbar sein)
- Prüfe Logs:
storage/logs/laravel.log - Führe Sync mit
--forceaus für vollständige Synchronisation
Problem: Duplikate in der Liste
Lösung:
- Prüfe
sync_hashSpalte - Führe manuelle Bereinigung durch
- Kontakte können manuell zusammengeführt werden
Problem: Export enthält keine Daten
Lösung:
- Prüfe Filter-Einstellungen
- Prüfe Status der Kontakte
- Prüfe Berechtigungen
API-Endpunkte
Alle Routen sind unter dem Middleware-Schutz ['admin', '2fa', 'auth.permission:cms-newsletter'].
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /newsletter |
Liste aller Kontakte |
| GET | /newsletter/datatable |
DataTables AJAX |
| GET | /newsletter/{id} |
Detail eines Kontakts |
| GET | /newsletter/{id}/edit |
Bearbeitungsformular |
| POST | /newsletter/{id}/store |
Speichern |
| DELETE | /newsletter/{id} |
Löschen (soft delete) |
| POST | /newsletter/{id}/unsubscribe |
Abmelden |
| POST | /newsletter/{id}/resubscribe |
Wieder aktivieren |
| POST | /newsletter/sync |
Synchronisation starten |
| GET | /newsletter/export |
Export |
Erweiterungen
Integration mit Newsletter-Diensten
Das Modul kann einfach mit externen Newsletter-Diensten (Mailchimp, SendGrid, etc.) integriert werden:
// Beispiel: Export für Mailchimp
$contacts = NewsletterContact::active()->kulturreisen()->get();
foreach ($contacts as $contact) {
// Mailchimp API Call
}
Webhook für Abmeldungen
Eine öffentliche Abmelde-Route kann hinzugefügt werden:
// routes/web.php
Route::get('/newsletter/unsubscribe/{token}', 'NewsletterPublicController@unsubscribe');
Double-Opt-In
Für Newsletter-Anmeldungen kann ein Double-Opt-In Prozess implementiert werden.
Support
Bei Fragen oder Problemen:
- Prüfe diese Dokumentation
- Prüfe Laravel Logs
- Prüfe Artisan Command Output
- Kontaktiere das Entwickler-Team
Changelog
Version 1.0.0 (2025-11-07)
- ✅ Initiales Release
- ✅ Kontaktverwaltung
- ✅ Synchronisation Kulturreisen
- ✅ Synchronisation Ferienwohnungen
- ✅ Export-Funktion
- ✅ Admin-Panel Integration