Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • SensioLabs Professional services to help you with Symfony
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. Documentation
  3. Creating and Sending Notifications
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • Installation
  • Channels: Chatters, Texters, Email and Browser
    • SMS Channel
    • Chat Channel
    • Email Channel
    • Configure to use Failover or Round-Robin Transports
  • Creating & Sending Notifications
    • Configuring Channel Policies
  • Customize Notifications
    • Customize Notification Messages
  • Disabling Delivery
  • Learn more

Creating and Sending Notifications

Edit this page

Warning: You are browsing the documentation for Symfony 5.1, which is no longer maintained.

Read the updated version of this page for Symfony 6.3 (the current stable version).

Creating and Sending Notifications

5.0

The Notifier component was introduced in Symfony 5.0 as an experimental feature.

Installation

Current web applications use many different channels to send messages to the users (e.g. SMS, Slack messages, emails, push notifications, etc.). The Notifier component in Symfony is an abstraction on top of all these channels. It provides a dynamic way to manage how the messages are sent. Get the Notifier installed using:

1
$ composer require symfony/notifier

Channels: Chatters, Texters, Email and Browser

The notifier component can send notifications to different channels. Each channel can integrate with different providers (e.g. Slack or Twilio SMS) by using transports.

The notifier component supports the following channels:

  • SMS channel sends notifications to phones via SMS messages;
  • Chat channel sends notifications to chat services like Slack and Telegram;
  • Email channel integrates the Symfony Mailer;
  • Browser channel uses flash messages.

Tip

Use secrets to securily store your API's tokens.

SMS Channel

The SMS channel uses Texter classes to send SMS messages to mobile phones. This feature requires subscribing to a third-party service that sends SMS messages. Symfony provides integration with a couple popular SMS services:

Service Package DSN
FreeMobile symfony/free-mobile-notifier freemobile://LOGIN:PASSWORD@default?phone=PHONE
Nexmo symfony/nexmo-notifier nexmo://KEY:SECRET@default?from=FROM
OvhCloud symfony/ovh-cloud-notifier ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME
Sinch symfony/sinch-notifier sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM
Twilio symfony/twilio-notifier twilio://SID:TOKEN@default?from=FROM

5.1

The OvhCloud, Sinch and FreeMobile integrations were introduced in Symfony 5.1.

To enable a texter, add the correct DSN in your .env file and configure the texter_transports:

1
2
# .env
TWILIO_DSN=twilio://SID:TOKEN@default?from=FROM
1
2
3
4
5
# config/packages/notifier.yaml
framework:
    notifier:
        texter_transports:
            twilio: '%env(TWILIO_DSN)%'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- config/packages/notifier.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        https://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <framework:notifier>
            <framework:texter-transport name="twilio">
                %env(TWILIO_DSN)%
            </framework:texter-transport>
        </framework:notifier>
    </framework:config>
</container>
1
2
3
4
5
6
7
8
# config/packages/notifier.php
$container->loadFromExtension('framework', [
    'notifier' => [
        'texter_transports' => [
            'twilio' => '%env(TWILIO_DSN)%',
        ],
    ],
]);

Chat Channel

The chat channel is used to send chat messages to users by using Chatter classes. Symfony provides integration with these chat services:

Service Package DSN
Firebase symfony/firebase-notifier firebase://USERNAME:PASSWORD@default
Mattermost symfony/mattermost-notifier mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL
RocketChat symfony/rocket-chat-notifier rocketchat://TOKEN@ENDPOINT?channel=CHANNEL
Slack symfony/slack-notifier slack://default/ID
Telegram symfony/telegram-notifier telegram://TOKEN@default?channel=CHAT_ID

5.1

The Firebase, Mattermost and RocketChat integrations were introduced in Symfony 5.1. The Slack DSN changed in Symfony 5.1 to use Slack Incoming Webhooks instead of legacy tokens.

Chatters are configured using the chatter_transports setting:

1
2
3
4
# .env
SLACK_DSN=slack://default/ID
# If your slack webhook looks like "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" then use:
SLACK_DSN=slack://default/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
# config/packages/notifier.yaml
framework:
    notifier:
        chatter_transports:
            slack: '%env(SLACK_DSN)%'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- config/packages/notifier.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        https://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <framework:notifier>
            <framework:chatter-transport name="slack">
                %env(SLACK_DSN)%
            </framework:chatter-transport>
        </framework:notifier>
    </framework:config>
</container>
1
2
3
4
5
6
7
8
# config/packages/notifier.php
$container->loadFromExtension('framework', [
    'notifier' => [
        'chatter_transports' => [
            'slack' => '%env(SLACK_DSN)%',
        ],
    ],
]);

Email Channel

The email channel uses the Symfony Mailer to send notifications using the special NotificationEmail. It is required to install the Twig bridge along with the Inky and CSS Inliner Twig extensions:

1
$ composer require symfony/twig-pack twig/cssinliner-extra twig/inky-extra

After this, configure the mailer. You can also set the default "from" email address that should be used to send the notification emails:

1
2
3
4
5
6
# config/packages/mailer.yaml
framework:
    mailer:
        dsn: '%env(MAILER_DSN)%'
        envelope:
            sender: 'notifications@example.com'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- config/packages/mailer.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        https://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <framework:mailer
            dsn="%env(MAILER_DSN)%"
        >
            <framework:envelope
                sender="notifications@example.com"
            />
        </framework:mailer>
    </framework:config>
</container>
1
2
3
4
5
6
7
8
9
# config/packages/mailer.php
$container->loadFromExtension('framework', [
    'mailer' => [
        'dsn' => '%env(MAILER_DSN)%',
        'envelope' => [
            'sender' => 'notifications@example.com',
        ],
    ],
]);

Configure to use Failover or Round-Robin Transports

Besides configuring one or more separate transports, you can also use the special || and && characters to implement a failover or round-robin transport:

1
2
3
4
5
6
7
8
9
10
# config/packages/notifier.yaml
framework:
    notifier:
        chatter_transports:
            # Send notifications to Slack and use Telegram if
            # Slack errored
            main: '%env(SLACK_DSN)% || %env(TELEGRAM_DSN)%'

            # Send notifications to the next scheduled transport calculated by round robin
            roundrobin: '%env(SLACK_DSN)% && %env(TELEGRAM_DSN)%'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- config/packages/notifier.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        https://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <framework:notifier>
            <!-- Send notifications to Slack and use Telegram if
                 Slack errored -->
            <framework:chatter-transport name="slack">
                %env(SLACK_DSN)% || %env(TELEGRAM_DSN)%
            </framework:chatter-transport>

            <!-- Send notifications to the next scheduled transport
                 calculated by round robin -->
            <framework:chatter-transport name="slack"><![CDATA[
                %env(SLACK_DSN)% && %env(TELEGRAM_DSN)%
            ]]></framework:chatter-transport>
        </framework:notifier>
    </framework:config>
</container>
1
2
3
4
5
6
7
8
9
10
11
12
13
# config/packages/notifier.php
$container->loadFromExtension('framework', [
    'notifier' => [
        'chatter_transports' => [
            // Send notifications to Slack and use Telegram if
            // Slack errored
            'main' => '%env(SLACK_DSN)% || %env(TELEGRAM_DSN)%',

            // Send notifications to the next scheduled transport calculated by round robin
            'roundrobin' => '%env(SLACK_DSN)% && %env(TELEGRAM_DSN)%',
        ],
    ],
]);

Creating & Sending Notifications

To send a notification, autowire the NotifierInterface (service ID notifier). This class has a send() method that allows you to send a Notification to a Recipient:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// src/Controller/InvoiceController.php
namespace App\Controller;

use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\NotifierInterface;
use Symfony\Component\Notifier\Recipient\AdminRecipient;

class InvoiceController extends AbstractController
{
    /**
     * @Route("/invoice/create")
     */
    public function create(NotifierInterface $notifier)
    {
        // ...

        // Create a Notification that has to be sent
        // using the "email" channel
        $notification = (new Notification('New Invoice', ['email']))
            ->content('You got a new invoice for 15 EUR.');

        // The receiver of the Notification
        $recipient = new AdminRecipient(
            $user->getEmail(),
            $user->getPhonenumber()
        );

        // Send the notification to the recipient
        $notifier->send($notification, $recipient);

        // ...
    }
}

The Notification is created by using two arguments: the subject and channels. The channels specify which channel (or transport) should be used to send the notification. For instance, ['email', 'sms'] will send both an email and sms notification to the user. It is required to specify the transport when using chatters (e.g. ['email', 'chat/telegram']).

The default notification also has a content() and emoji() method to set the notification content and icon.

Symfony provides three types of recipients:

NoRecipient
This is the default and is useful when there is no need to have information about the receiver. For example, the browser channel uses the current requests's session flashbag;
Recipient
This contains only the email address of the user and can be used for messages on the email and browser channel;
AdminRecipient
This can contain both email address and phonenumber of the user. This recipient can be used for all channels (depending on whether they are actually set).

Configuring Channel Policies

Instead of specifying the target channels on creation, Symfony also allows you to use notification importance levels. Update the configuration to specify what channels should be used for specific levels (using channel_policy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config/packages/notifier.yaml
framework:
    notifier:
        # ...
        channel_policy:
            # Use SMS, Slack and email for urgent notifications
            urgent: ['sms', 'chat/slack', 'email']

            # Use Slack for highly important notifications
            high: ['chat/slack']

            # Use browser for medium and low notifications
            medium: ['browser']
            low: ['browser']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!-- config/packages/notifier.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        https://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <framework:notifier>
            <!-- ... -->

            <framework:channel-policy>
                <!-- Use SMS, Slack and Email for urgent notifications -->
                <framework:urgent>sms</framework:urgent>
                <framework:urgent>chat/slack</framework:urgent>
                <framework:urgent>email</framework:urgent>

                <!-- Use Slack for highly important notifications -->
                <framework:high>chat/slack</framework:high>

                <!-- Use browser for medium and low notifications -->
                <framework:medium>browser</framework:medium>
                <framework:low>browser</framework:low>
            </framework:channel-policy>
        </framework:notifier>
    </framework:config>
</container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# config/packages/notifier.php
$container->loadFromExtension('framework', [
    'notifier' => [
        // ...
        'channel_policy' => [
            // Use SMS, Slack and email for urgent notifications
            'urgent' => ['sms', 'chat/slack', 'email'],

            // Use Slack for highly important notifications
            'high' => ['chat/slack'],

            // Use browser for medium and low notifications
            'medium' => ['browser'],
            'low' => ['browser'],
        ],
    ],
]);

Now, whenever the notification's importance is set to "high", it will be sent using the Slack transport:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ...
class InvoiceController extends AbstractController
{
    /**
     * @Route("/invoice/create")
     */
    public function invoice(NotifierInterface $notifier)
    {
        // ...

        $notification = (new Notification('New Invoice'))
            ->content('You got a new invoice for 15 EUR.')
            ->importance(Notification::IMPORTANCE_HIGH);

        $notifier->send($notification, new Recipient('wouter@example.com'));

        // ...
    }
}

Customize Notifications

You can extend the Notification or Recipient base classes to customize their behavior. For instance, you can overwrite the getChannels() method to only return sms if the invoice price is very high and the recipient has a phone number:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace App\Notifier;

use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\Recipient;

class InvoiceNotification extends Notification
{
    private $price;

    public function __construct(int $price)
    {
        $this->price = $price;
    }

    public function getChannels(Recipient $recipient)
    {
        if (
            $this->price > 10000
            && $recipient instanceof AdminRecipient
            && null !== $recipient->getPhone()
        ) {
            return ['sms'];
        }

        return ['email'];
    }
}

Customize Notification Messages

Each channel has its own notification interface that you can implement to customize the notification message. For instance, if you want to modify the message based on the chat service, implement ChatNotificationInterface and its asChatMessage() method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// src/Notifier/InvoiceNotification.php
namespace App\Notifier;

use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\Recipient;

class InvoiceNotification extends Notification implements ChatNotificationInterface
{
    private $price;

    public function __construct(int $price)
    {
        $this->price = $price;
    }

    public function asChatMessage(Recipient $recipient, string $transport = null): ?ChatMessage
    {
        // Add a custom emoji if the message is sent to Slack
        if ('slack' === $transport) {
            return (new ChatMessage('You\'re invoiced '.$this->price.' EUR.'))
                ->emoji('money');
        }

        // If you return null, the Notifier will create the ChatMessage
        // based on this notification as it would without this method.
        return null;
    }
}

The SmsNotificationInterface and EmailNotificationInterface also exists to modify messages send to those channels.

Disabling Delivery

While developing (or testing), you may want to disable delivery of notifications entirely. You can do this by forcing Notifier to use the NullTransport for all configured texter and chatter transports only in the dev (and/or test) environment:

1
2
3
4
5
6
7
# config/packages/dev/notifier.yaml
framework:
    notifier:
        texter_transports:
            twilio: 'null://null'
        chatter_transports:
            slack: 'null://null'

Learn more

  • How to send Chat Messages
  • How to send SMS Messages
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:
    Online Symfony certification, take it now!

    Online Symfony certification, take it now!

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of Jesper Noordsij, a Symfony contributor

    Thanks Jesper Noordsij for being a Symfony contributor

    1 commit • 10 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony

    Search by Meilisearch