und SMS mit einem Interface
In den meisten Anwendungen gibt es drei, vier verschiedene Bibliotheken für Benachrichtigungen: eine für E-Mails, eine für Slack, eine für SMS, eine für Push-Notifications. Symfony Notifier vereint alle Kanäle hinter einem einzigen Interface und einer einzigen Dispatch-Methode — mit konfigurierbarem Routing, kanalspezifischen Nachrichten und der Möglichkeit, eigene Bridges für interne Systeme zu schreiben.
Inhaltsverzeichnis
- 1. Warum Symfony Notifier statt einzelner Bibliotheken?
- 2. Architektur: Channels, Chatter, Texter und Browser
- 3. Installation und erste Notification versenden
- 4. Slack-Nachrichten mit Block-Kit und Attachments
- 5. Microsoft Teams: Adaptive Cards versenden
- 6. SMS mit Twilio, Vonage und anderen Bridges
- 7. Routing: welcher Kanal für welche Notification?
- 8. Eigene Notifier-Bridge für interne Systeme schreiben
- 9. Notifier-Channels im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum Symfony Notifier statt einzelner Bibliotheken?
Symfony Notifier löst ein Organisations- und Wartbarkeitsproblem: Jede Benachrichtigungsintegration, die separat implementiert wird, bringt eigene Konfiguration, eigene Fehlerbehandlung und eigene Abstraktion mit. Das bedeutet vier verschiedene API-Clients, vier verschiedene Konfigurationsblöcke und vier verschiedene Teststrategien für Slack, Teams, SMS und E-Mail. Mit Symfony Notifier gibt es einen einzigen NotifierInterface, der eine Notification entgegennimmt und sie — basierend auf der Konfiguration — an einen oder mehrere Kanäle weiterleitet. Das vereinheitlicht nicht nur den Code, sondern auch das Testen und das Monitoring.
Der zweite Vorteil ist das deklarative Routing. Statt im Code zu entscheiden, ob eine Nachricht an Slack oder Teams geht, definiert man in der Konfiguration: "Kritische Fehler gehen an den Chat-Kanal, SMS-Kanal und E-Mail-Kanal gleichzeitig. Marketing-Events gehen nur an Slack." Die Notification-Klasse trägt die Dringlichkeit, das Routing bestimmt die Kanäle. Das ermöglicht es, Routing-Entscheidungen zu ändern, ohne Code anzufassen. Symfony Notifier unterstützt über 80 offizielle Bridges für externe Dienste — von Twilio und Vonage für SMS bis zu PagerDuty und OpsGenie für Incident-Management.
2. Architektur: Channels, Chatter, Texter und Browser
Die Symfony Notifier-Architektur ist in Channels aufgeteilt, die jeweils bestimmte Kommunikationsarten kapseln. Der Chat-Channel verwaltet Messaging-Dienste wie Slack, Microsoft Teams, Telegram und Discord — alles, was eine asynchrone Team-Kommunikationsplattform ist. Der SMS-Channel verwaltet Textnachrichten über Telekommunikationsanbieter wie Twilio, Vonage und Sinch. Der Email-Channel integriert Symfony Mailer — eine Notification, die den Email-Channel nutzt, wird als E-Mail über den konfigurierten Mailer-Transport gesendet. Der Browser-Channel erzeugt Flash-Messages in der Symfony-Session für sofortige Benutzer-Feedback im Browser.
Die Klassen ChatterInterface und TexterInterface sind spezialisierte Versionen für Chat und SMS, wenn man direkt einen spezifischen Transport ansprechen will. Der NotifierInterface ist das übergeordnete Interface, das alle Channels koordiniert: Es empfängt eine Notification, prüft deren Wichtigkeitsstufe (Urgency), und routet sie an alle relevanten Channels. Dieses Routing geschieht entweder automatisch basierend auf Konfiguration oder explizit durch das Setzen des Empfängers (Recipient) in der Notification. Ein Recipient hat eine E-Mail-Adresse und optional eine Telefonnummer — Symfony Notifier nutzt diese, um zu entscheiden, welche Channels sinnvoll sind.
<?php
declare(strict_types=1);
namespace App\Notification;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\Recipient;
// Basic notification — subject, content, importance level, channels
final class OrderFailedNotification extends Notification
{
public function __construct(
private readonly int $orderId,
private readonly string $errorMessage,
) {
parent::__construct(
subject: sprintf('Order #%d processing failed', $this->orderId),
);
}
/**
* Define urgency and channels — channels filter which transports handle this notification.
*/
public function getChannels(Recipient $recipient): array
{
// URGENT: send via chat (Slack), SMS and email simultaneously
if ($this->getImportance() === Notification::IMPORTANCE_URGENT) {
return ['chat/slack', 'sms', 'email'];
}
// HIGH: chat and email only
return ['chat/slack', 'email'];
}
/**
* Build the Slack message — channel-specific content via ChatNotificationInterface.
*/
public function asChatMessage(
\Symfony\Component\Notifier\Recipient\RecipientInterface $recipient,
string $transport = null,
): ?\Symfony\Component\Notifier\Message\ChatMessage {
if ($transport !== 'slack') {
return null; // Let the parent class handle other chat transports
}
$message = new \Symfony\Component\Notifier\Message\ChatMessage(
subject: $this->getSubject(),
);
// Attach Slack-specific Block Kit options
$message->options(
(new \Symfony\Component\Notifier\Bridge\Slack\SlackOptions())
->iconEmoji('warning')
->block((new \Symfony\Component\Notifier\Bridge\Slack\Block\SlackSectionBlock())
->text(sprintf("*Order #%d failed*\n%s", $this->orderId, $this->errorMessage))
)
);
return $message;
}
}
3. Installation und erste Notification versenden
Die Installation von Symfony Notifier erfolgt modular: Das Basis-Paket symfony/notifier enthält das Interface und den Core. Für jeden Kanal installiert man das entsprechende Bridge-Paket — symfony/slack-notifier für Slack, symfony/microsoft-teams-notifier für Teams, symfony/twilio-notifier für SMS via Twilio. Symfony Flex installiert nicht nur das Paket, sondern legt auch die entsprechende Konfiguration in config/packages/notifier.yaml an und fügt die DSN-Umgebungsvariablen als Kommentar in .env ein.
Eine Notification zu versenden ist in Symfony Notifier eine Frage von drei Zeilen: Notification erstellen, Recipient mit E-Mail und Telefonnummer erstellen, NotifierInterface::send() aufrufen. Der Notifier prüft die konfigurierten Channels, bestimmt anhand der Recipient-Daten und der Notification-Kanäle, wohin die Nachricht geht, und delegiert an die entsprechenden Transports. Das Versenden ist standardmäßig synchron — für asynchrones Versenden über Symfony Messenger konfiguriert man den messenger-Transport in der Notifier-Konfiguration, und die Notifications werden automatisch in eine Queue gestellt.
4. Slack-Nachrichten mit Block-Kit und Attachments
Slack-Nachrichten in Symfony Notifier können über den SlackOptions-Block-Builder mit dem vollen Slack Block Kit formatiert werden. Das Block Kit erlaubt strukturierte Nachrichten mit Abschnitten, Buttons, Dropdown-Menüs, Bildern und Trennlinien — weit über einfachen Text hinaus. Eine Deployment-Benachrichtigung kann einen Header mit dem Deploy-Status, einen Abschnitt mit Branches und Commit-Hash, ein Kontext-Block mit Zeitstempel und Deployer und einen Action-Block mit "Rollback"-Button enthalten. All das wird über den PHP-Builder API von SlackOptions aufgebaut, ohne JSON manuell zu schreiben.
Für Incident-Management-Szenarien ist die Kombination von Symfony Notifier mit Slack besonders wertvoll: Ein kritischer Fehler in der Anwendung dispatcht eine Symfony Messenger-Message, die asynchron verarbeitet wird und über den Slack-Kanal eine formatierte Alerting-Nachricht sendet. Der Alert enthält den Fehlerkontext, den Stack-Trace-Link und einen Button, der das Ticket im Issue-Tracker direkt öffnet. Diese Automatisierung ersetzt manuelle Slack-Nachrichten beim On-Call-Dienst und verkürzt die Zeit von Fehler zu erster Reaktion erheblich. Symfony Notifier macht das möglich, ohne einen separaten Alerting-Dienst zu betreiben.
<?php
declare(strict_types=1);
namespace App\Notification;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackActionsBlock;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackContextBlock;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackDividerBlock;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackHeaderBlock;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackSectionBlock;
use Symfony\Component\Notifier\Bridge\Slack\SlackOptions;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
/**
* Sends a richly formatted Slack deployment notification with Block Kit.
*/
final class DeploymentSlackNotification extends \Symfony\Component\Notifier\Notification\Notification
{
public function __construct(
private readonly string $environment,
private readonly string $version,
private readonly string $deployer,
private readonly bool $success,
) {
parent::__construct(subject: sprintf('Deployment %s: %s v%s', $success ? 'successful' : 'FAILED', $environment, $version));
}
/**
* Build a rich Slack Block Kit message for the deployment notification.
*/
public function asChatMessage(RecipientInterface $recipient, string $transport = null): ?ChatMessage
{
$statusEmoji = $this->success ? ':white_check_mark:' : ':rotating_light:';
$statusText = $this->success ? 'Deployment successful' : 'Deployment FAILED';
$options = (new SlackOptions())
->iconEmoji($this->success ? 'rocket' : 'fire')
->block(new SlackHeaderBlock(sprintf('%s %s', $statusEmoji, $statusText)))
->block(
(new SlackSectionBlock())
->field('*Environment*', $this->environment)
->field('*Version*', $this->version)
)
->block(new SlackDividerBlock())
->block(
(new SlackContextBlock())
->add(sprintf('Deployed by *%s* at %s', $this->deployer, (new \DateTimeImmutable())->format('H:i d.m.Y')))
);
// Add action button only for failed deployments
if (!$this->success) {
$options->block(
(new SlackActionsBlock())
->button('Open Runbook', 'https://wiki.example.com/runbook/deploy-failure', 'danger')
);
}
$message = new ChatMessage(subject: $this->getSubject());
$message->options($options);
return $message;
}
}
5. Microsoft Teams: Adaptive Cards versenden
Microsoft Teams-Benachrichtigungen über Symfony Notifier verwenden Adaptive Cards — das offizielle JSON-Format für interaktive Teams-Nachrichten. Der MicrosoftTeamsOptions-Builder erlaubt es, Adaptive Cards deklarativ in PHP aufzubauen: Texte, Tabellen, Fakten-Listen und Action-Buttons werden als PHP-Objekte zusammengesetzt und von der Bridge automatisch in das korrekte Adaptive-Card-JSON-Format konvertiert. Teams-Benachrichtigungen über Incoming Webhooks sind für einfache Szenarien ausreichend — für komplexere Interaktionen mit Bot-Framework und persönlichen Nachrichten an einzelne Benutzer braucht man die Microsoft Graph API, die nicht über den Standard-Notifier abgedeckt wird.
Ein typischer Anwendungsfall für Teams-Benachrichtigungen in Unternehmensumgebungen ist das Monitoring von Geschäftsprozessen: Eine Bestellung über einem bestimmten Warenkorbwert, eine neue Enterprise-Registrierung oder ein abgeschlossenes kritisches Support-Ticket lösen eine Teams-Benachrichtigung an den zuständigen Account-Manager aus. Symfony Notifier routet diese Notifications basierend auf Urgency und Recipient automatisch in den konfigurierten Teams-Kanal. Im Vergleich zu Slack ist Teams vor allem in Microsoft-orientierten Unternehmen die präferierte Plattform — und mit der Teams-Bridge von Symfony Notifier ist der Wechsel von Slack zu Teams oder das parallele Betreiben beider Plattformen eine Konfigurationsänderung ohne Code-Anpassung.
6. SMS mit Twilio, Vonage und anderen Bridges
SMS-Benachrichtigungen in Symfony Notifier gehen über den SMS-Channel und nutzen Bridge-Pakete für externe Telekommunikationsanbieter. Twilio ist der am häufigsten eingesetzte Anbieter und bietet mit dem TwilioTransport zuverlässige Zustellung weltweit. Vonage (früher Nexmo) ist eine Alternative mit starker Präsenz in Europa. Amazon SNS, Sinch, MessageBird und Infobip sind weitere verfügbare Bridges. Die Konfiguration aller SMS-Bridges läuft über eine DSN-Umgebungsvariable: TWILIO_DSN=twilio://SID:TOKEN@default?from=+4912345678. Das Wechseln des SMS-Anbieters ist damit eine Konfigurationsänderung in einer Zeile.
Eine häufige Frage bei Symfony Notifier und SMS ist die Behandlung von Zustellungsberichten. Twilio und Vonage erlauben die Konfiguration von Webhook-Callbacks, wenn eine SMS zugestellt wurde oder fehlgeschlagen ist. Symfony Notifier selbst verwaltet keine Zustellungsberichte — diese kommen als eingehende Webhooks an und werden von Symfony-Controllern verarbeitet, die den Zustellungsstatus in der Anwendungsdatenbank aktualisieren. Das Notifier-Package kümmert sich um das Senden, die Verarbeitung der Callbacks ist anwendungsspezifische Logik. Bei kritischen SMS-Benachrichtigungen — Zwei-Faktor-Authentifizierung, Sicherheitsalarme — empfiehlt sich der symfony/messenger-Transport für asynchrones Versenden mit automatischem Retry bei Fehlern.
7. Routing: welcher Kanal für welche Notification?
Das Routing in Symfony Notifier bestimmt, welche Notification über welche Channels versendet wird. Es gibt zwei Routing-Ebenen: Die erste ist die Konfiguration in notifier.yaml, die Importance-Levels auf Channels mappt. Notifications mit IMPORTANCE_URGENT gehen an Chat und SMS, Notifications mit IMPORTANCE_LOW nur an E-Mail. Die zweite Ebene ist die getChannels()-Methode in der Notification-Klasse, die für jede Notification spezifisch festlegen kann, welche Channels genutzt werden — unabhängig von der globalen Konfiguration.
Für produktive Setups empfiehlt sich eine klare Kanal-Hierarchie: Monitoring-Alerts und kritische Fehler gehen an Slack oder Teams (schnelle Sichtbarkeit), direkte Nutzermitteilungen gehen als SMS (sofortige Aufmerksamkeit), Zusammenfassungen und Reports gehen als E-Mail (persistenter Nachweis). Symfony Notifier unterstützt das parallele Versenden an mehrere Kanäle in einer einzigen Dispatch-Operation — die Notification wird an alle konfigurierten Kanäle gleichzeitig gesendet, nicht sequenziell. Beim asynchronen Versenden über Symfony Messenger wird jeder Kanal als separate Message in die Queue gestellt, was bei Fehlern einzelne Kanäle separat wiederholen lässt.
# config/packages/notifier.yaml
# Symfony Notifier: channel routing and transport configuration
framework:
notifier:
# Chat transports — Slack and Teams with Incoming Webhook URLs
chatter_transports:
slack: '%env(SLACK_DSN)%' # slack://xoxb-TOKEN@default?channel=alerts
teams: '%env(TEAMS_DSN)%' # microsoftteams://default/WEBHOOK_URL
# SMS transports — Twilio as primary, Vonage as fallback
texter_transports:
twilio: '%env(TWILIO_DSN)%' # twilio://SID:TOKEN@default?from=+49...
vonage: '%env(VONAGE_DSN)%' # vonage://KEY:SECRET@default?from=Mironsoft
# Email channel uses Symfony Mailer — no separate DSN needed
# Browser channel adds Flash messages to the session
# Global routing by urgency level
channel_policy:
urgent: ['chat/slack', 'sms/twilio', 'email']
high: ['chat/slack', 'email']
medium: ['email']
low: ['email']
# Use Symfony Messenger for async sending — prevents slow HTTP calls in requests
# messenger_bus: messenger.default_bus
8. Eigene Notifier-Bridge für interne Systeme schreiben
Wenn das interne Monitoring-System, das Issue-Tracking-Tool oder ein Self-hosted Chat-Server keine offizielle Symfony Notifier-Bridge haben, schreibt man eine eigene. Eine Notifier-Bridge besteht aus drei Klassen: dem Transport, der die HTTP-Anfrage an den externen Dienst sendet, dem TransportFactory, der aus dem DSN-String das Transport-Objekt erzeugt, und optional einem Options-Objekt für kanalspezifische Nachrichtenformate. Der Transport implementiert TransportInterface mit einer send()-Methode und einem supports()-Prädikat, das bestimmt, für welche Message-Typen der Transport zuständig ist.
Das DSN-Pattern ist bei eigenen Bridges dasselbe wie bei offiziellen: eigenes-system://TOKEN@host/channel. Der TransportFactory parst diesen String und erzeugt das Transport-Objekt mit den extrahierten Credentials. Die Bridge-Klasse registriert sich über eine Tagged-Service-Konfiguration im DI-Container als bekannter Transport. Nach der Registrierung funktioniert die eigene Bridge identisch wie eine offizielle: Sie erscheint in der notifier.yaml-Konfiguration, wird über den NotifierInterface angesteuert und unterstützt Retry bei Fehlern über den Messenger-Transport. Eigene Bridges zu schreiben ist eine hervorragende Möglichkeit, interne Werkzeuge in das Symfony Notifier-Ökosystem zu integrieren, ohne auf offizielle Unterstützung zu warten.
9. Notifier-Channels im Vergleich
Jeder Symfony Notifier-Channel hat seine eigene Stärke — die Wahl des richtigen Kanals für den richtigen Anwendungsfall ist entscheidend für die Akzeptanz und Wirksamkeit von Benachrichtigungen.
| Channel | Stärken | Einschränkungen | Typischer Einsatz |
|---|---|---|---|
| Chat (Slack/Teams) | Sofortige Sichtbarkeit, Rich-Text, Buttons | Nur Team-intern sichtbar | Monitoring-Alerts, Deployments |
| SMS | Höchste Öffnungsrate, kein Internet nötig | Kosten pro Nachricht, kein HTML | 2FA, kritische Alerts, On-Call |
| HTML, Anhänge, persistenter Nachweis | Niedrige Öffnungsrate, langsamer | Berichte, Bestätigungen, Rechnungen | |
| Browser (Flash) | Sofort für aktuellen User sichtbar | Nur für Session-Benutzer | Formular-Feedback, Statusmeldungen |
| Push (Firebase) | Auch bei geschlossener App zugestellt | Opt-in, plattformabhängig | Mobile Apps, Service-Updates |
In der Praxis ist die Kombination aus Chat und E-Mail für die meisten Backend-Anwendungen ausreichend: Chat für sofortige Team-Sichtbarkeit bei Fehlern und Deployments, E-Mail für Nutzer-Benachrichtigungen und persistente Protokolle. SMS lohnt sich bei sicherheitskritischen Szenarien (2FA, Sicherheitswarnungen) oder On-Call-Situationen, in denen Chat-Benachrichtigungen übersehen werden könnten. Symfony Notifier macht es trivial, alle drei Kanäle parallel zu nutzen, ohne separaten Code für jeden.
Mironsoft
Symfony Notifier, Alerting-Systeme und Multi-Channel-Benachrichtigungen
Benachrichtigungssystem mit Symfony Notifier aufbauen?
Wir implementieren Multi-Channel-Benachrichtigungssysteme mit Symfony Notifier — von Slack- und Teams-Integration über SMS-Versand bis zu eigenen Bridges für interne Systeme.
Channel-Integration
Slack Block-Kit, Teams Adaptive Cards, SMS-Bridges und E-Mail-Templates für strukturierte Benachrichtigungen
Eigene Bridges
Custom Notifier-Bridges für interne Monitoring-Systeme, Issue-Tracker und Self-hosted Chat-Plattformen
Async-Versand
Symfony Messenger Integration für asynchronen Versand mit Retry-Logik und Failure-Queue
10. Zusammenfassung
Symfony Notifier vereint alle Benachrichtigungskanäle hinter einem einzigen NotifierInterface und eliminiert damit die Notwendigkeit, für jeden Kanal eine separate Integration zu pflegen. Slack Block-Kit, Microsoft Teams Adaptive Cards, SMS über Twilio oder Vonage und Browser Flash-Messages laufen über denselben Dispatch-Mechanismus. Das konfigurative Routing nach Urgency-Level bestimmt, welche Kanäle für welche Notification aktiv sind — ohne Code-Änderungen, wenn sich Routing-Entscheidungen ändern. Eigene Bridges erweitern das System für interne Werkzeuge und Self-hosted Dienste.
Der größte Vorteil von Symfony Notifier liegt in der Testbarkeit: Mit dem Test-Transport werden Notifications nicht wirklich versendet, sondern in einem Array gesammelt. Integrationstests prüfen, ob die richtigen Messages an die richtigen Channels gehen — ohne Slack-Webhooks, Twilio-Account oder echte E-Mail-Zustellung. Die Kombination mit Symfony Messenger für asynchrones Versenden macht Symfony Notifier produktionstauglich: Benachrichtigungen verlangsamen keine HTTP-Requests und werden bei Fehlern automatisch wiederholt.
Symfony Notifier — Das Wichtigste auf einen Blick
Ein Interface, alle Kanäle
NotifierInterface::send() routet Notifications an Chat, SMS, Email und Browser — basierend auf Urgency-Level und Notification::getChannels().
Kanalspezifische Nachrichten
asChatMessage(), asSmsMessage() und asEmailMessage() in der Notification-Klasse liefern kanalspezifische Formate — Block Kit für Slack, Adaptive Cards für Teams.
80+ Bridges
Twilio, Vonage, Slack, Teams, Telegram, PagerDuty, Firebase — oder eigene Bridge für interne Systeme schreiben. Wechsel ist eine Konfigurationszeile.
Async mit Messenger
messenger_bus in notifier.yaml — Notifications landen in der Queue, HTTP-Response bleibt schnell, Retry bei Fehlern automatisch.