Create a custom channel into Symfony Notifier

Nicolas Jourdan
3 min readNov 21, 2022

Symfony Notifier is a Symfony component that allows you to manage notifications for your PHP applications. A notification can be sent to different channels: SMS, Chat, Email, Browser and Push. In most cases, all you need are these, and you don’t have to create your own channel, you just have to create a custom transport.

If you need more information on the basics of Notifier, you can refer to the documentation.

By default there are 5 channels in Notifier which are explained in the component documentation:

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.
Push Channel sends notifications to phones and browsers via push notifications.

In this article we will see the creation of a database channel allowing to send notifications on different types of databases (MySQL and PostgreSQL).

1/ Creation of the notification and message classes ✉️

First, we will need to create a receiver, a message and a notification.

1.1/ The recipient 📩

1.2/ The message ✉️

1.3/ The notification 🔔

2/ Creation of the transports

Transports are the classes that allow us to communicate with the different providers (MySQL and PostgreSQL in this case). We have to create our transports and the different factories that will instantiate them.

2.1/ The transports ✈️

These classes must respect the following requirements:

  • Implement Symfony\Component\Notifier\Transport\TransportInterface (extend Symfony\Component\Notifier\Transport\AbsractTransport is enough)
  • Implement the supports() method (in our case, we support messages with mysql or postgresql transports)
  • Implement the toString() method in order to build the DSN
  • Implement the doSend() method which defines the code executed when sending a message

2.2/ The factories 🏭

The factories are used to create the transports from the different DSN.

This classes must respect the following requirements:

  • Implement Symfony\Component\Notifier\Transport\TransportFactoryInterface (extend Symfony\Component\Notifier\Transport\AbsractTransportFactory is enough)
  • Implement the getSupportedSchemes() method in order to define the supported schemes
  • Implement the create() method allowing to create a transport from a DSN

2.3/ The configuration ⚙️

In the above configuration, we tag our factories with database.transport_factory. These will be used by our database.transport_factory service (Symfony\Component\Notifier\Transport) when creating the different DSN from the strings defined by %env(DATABASE_POSTGRESQL)% and %env(DATABASE_MYSQL)%.

The database.transports service contains the different transports we have just defined. These are created thanks to our factories.

We also have to define our constants:

3/ Creation of the Channel 🗣️

Last but not least, the channel! This is the last class we have to create!

3.1/ The Channel class

The channel class must respect the following requirements:

  • Implement Symfony\Component\Notifier\Channel\ChannelInterface (extend Symfony\Component\Notifier\Channel\AbsractChannel is enough)
  • Implement the support() method to define which type of notification/recipient the channel supports
  • Implement the notify() method which contains the logic of what happens when a notification is sent to this channel (we need to call the transport in this method)

3.2/ The configuration

In the above configuration we tag our class so that it is considered as such in Symfony. The value given to channel (database) is the name of the channel. So we will have 6 channels in our application: sms, chat, email, browser, push and database.

4/ Let’s try 🚀

It is the most important moment… Testing! We need the following controller:

In order to see the result, I added a dump() in the doSend() method of each transport. After a small call via postman:

Call to /notify via Postman

Boom! We can see our dump(), that means our channel is fully configured and working!

Thank you for taking the time to read this article, I hope you enjoyed it and learned something! If so, please feel free to put a clap 👏 on it and any feedback is welcome!



Nicolas Jourdan

Symfony 5 Certified Developer 🎓 Lead Developer at Smart Traffik 🚀