Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symfony Notifier Component

Symfony Notifier Component

Jan Schädlich

February 04, 2020
Tweet

More Decks by Jan Schädlich

Other Decks in Programming

Transcript

  1. Symfony Notifier Sending messages via a unified API Jan Schädlich

    @jschaedl SensioLabs 2020-02-04 | Symfony User Group Hamburg
  2. “… a notification system is a … software … that

    provides a means of delivering a message to a set of recipients … “ https://en.wikipedia.org/wiki/Notification_system What is a Notification System?
  3. ChannelPolicy ChatChannel SmsChannel EmailChannel Notifier Notification ChatMessage SmsMessage EmailMessage Texter

    Transport SmsMessage Transport ChatMessage Chatter Transports Transports Transports
  4. Transport Install with Slack composer require symfony/slack-notifier Telegram composer require

    symfony/telegram-notifier Twilio composer require symfony/twilio-notifier Nexmo composer require symfony/nexmo-notifier * Using Mailer Transports is also possible.
  5. use Symfony\Component\Notifier\Notification\Notification; $notification = (new Notification()) ->subject('A nice subject') ->content(‘An

    even nicer content.') ->importance(Notification::IMPORTANCE_URGENT) ->emoji('!') # email, chat, sms # chat/slack, chat/telegram, sms/twilio, sms/nexmo # {channel}/{transport} ->channels([‘chat/slack', 'email']) ; 1 2 3 4 5 6 7 8 9 10 11 12
  6. use Symfony\Component\Notifier\Notification\Notification; $errorNotification = Notification::fromThrowable( new \Exception(‘Oops!'), # email, chat,

    sms # chat/slack, chat/telegram, sms/twilio, sms/nexmo ['chat/slack', 'email'] ); 1 2 3 4 5 6 7 8
  7. use Symfony\Component\Notifier\Notifier; use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory; use Symfony\Component\Notifier\Channel\ChatChannel; use Symfony\Component\Notifier\Channel\ChannelPolicy; $transport =

    (new SlackTransportFactory())->create(‘slack://...’); $channels = ['chat' => new ChatChannel($transport)]; $channelPolicy = new ChannelPolicy([ 'urgent' => [‘chat‘], 'high' => ['chat'], 'medium' => [‘chat/slack‘], 'low' => [‘chat/slack'], ]); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  8. use Symfony\Component\Notifier\Notifier; use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory; use Symfony\Component\Notifier\Channel\ChatChannel; use Symfony\Component\Notifier\Channel\ChannelPolicy; $transport =

    (new SlackTransportFactory())->create(‘slack://...’); $channels = ['chat' => new ChatChannel($transport)]; $channelPolicy = new ChannelPolicy([/* ... */]); $notifier = new Notifier($channels, $channelPolicy); $notifier->send(new Notification(…), new Recipient(…)); 1 2 3 4 5 6 7 8 9 10 … 16 17 18 19 20
  9. $channelPolicy = new ChannelPolicy([ 'urgent' => ['email', 'chat/slack', 'sms'], 'high'

    => ['email', ‘chat/slack'], 'medium' => ['email'], 'low' => ['pidgeon'], ]); • Routing Notifications by importance to channels and transports • Define your own importance
  10. $channels = [ 'email' => new EmailChannel($emailTransports), 'chat' => new

    ChatChannel($chatTransports), 'sms' => new SmsChannel($smsTransports), // ... ]; • Channels are like categories • Channels can hold several Transports • Channels convert Notifications into Messages - EmailNotificationInterface - ChatNotificationInterface - SmsNotificationInterface
  11. $channels = [ 'email' => new EmailChannel($emailTransports), 'chat' => new

    ChatChannel($chatTransports), 'sms' => new SmsChannel($smsTransports), 'browser' => new BrowserChannel($requestStack), ]; • BrowserChannel holds the RequestStack • BrowserChannel writes Notification as flash messages
  12. framework: notifier: enabled: true chatter_transports: slack: '%env(SLACK_DSN)%' telegram: '%env(TELEGRAM_DSN)%' texter_transports:

    twilio: '%env(TWILIO_DSN)%' nexmo: '%env(NEXMO_DSN)%' channel_policy: # use chat/slack, chat/telegram, sms/twilio, sms/nexmo # or email, chat, sms urgent: ['email', 'chat', 'sms'] high: ['email', 'chat'] medium: ['email'] low: ['email'] admin_recipients: - { email: '[email protected]', phone: '0815 223445' } notification_on_failed_messages: false
  13. # config/packages/prod/monolog.yaml monolog: channels: ['notifier'] handlers: admin_notifications: type: filter handler:

    notifier max_level: info channels: ['notifier'] notifier: type: service id: Symfony\Bridge\Monolog\Handler\NotifierHandler
  14. namespace Symfony\Component\Notifier\Channel; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Notifier\Exception\LogicException; use Symfony\Component\Notifier\Transport\TransportInterface; abstract class

    AbstractChannel implements ChannelInterface { protected $transport; protected $bus; public function __construct( TransportInterface $transport = null, MessageBusInterface $bus = null ) { if (null === $transport && null === $bus) { throw new LogicException(...); } $this->transport = $transport; $this->bus = $bus; } }
  15. namespace Symfony\Component\Notifier\Messenger; use Symfony\Component\Notifier\Message\MessageInterface; use Symfony\Component\Notifier\Transport\TransportInterface; final class MessageHandler {

    private $transport; public function __construct(TransportInterface $transport) { $this->transport = $transport; } public function __invoke(MessageInterface $message) { $this->transport->send($message); } }
  16. # FrameworkBundle/Resources/config/notifier.xml <services> <service id="chatter.messenger.chat_handler" class="Symfony\Component\Notifier\Messenger\MessageHandler"> <argument type="service" id="chatter.transports" />

    <tag name="messenger.message_handler" handles="Symfony\Component\Notifier\Message\ChatMessage" /> </service> <service id="texter.messenger.sms_handler" class="Symfony\Component\Notifier\Messenger\MessageHandler"> <argument type="service" id="texter.transports" /> <tag name="messenger.message_handler" handles="Symfony\Component\Notifier\Message\SmsMessage" /> </service> </services>
  17. Feature Recap • Sending chat, sms, email and browser notifications

    • Built-in providers (Slack, Telegram, Nexmo, Twilio) • Monolog Handler • Async notifications via messenger • NULL transport for dev and test environment
  18. What’s missing? • More built-in providers (Microsofft Teams, Mattermost, etc.)

    • Possibility to define a custom transport • (Disable usage of messenger) • WebProfiler and DebugToolBar integration • WebTestCase notifier assertions