Answer the question
In order to leave comments, you need to log in
How to use notifier?
Hey! I'm confused with the development of notifications on the site. I found a ready-made symfony / notifier component in the symphony. It is necessary to send messages through different channels, while subscribers themselves choose which channels to send messages to them, i.e. subscription information is stored in a database. At the moment, we need notifications by channels: service, email, sms. The service is essentially a table in the database, to be displayed in the list on the service, for example, like Yandex has a notification block or similar systems.
I implemented a system of subscriptions to different channels: service, mail, sms. She works and everything is fine with her. Users subscribe to the created notification types. But now we need to connect everything somehow with this component using Event Dispatcher and Messanger from Symfony.
1. As I understand it, I have to publish an event through the EventDispathcher, for example, "user registered". This is a domain event that is published through an aggregate.
// Событие
class UserRegistered extends Event
{
public const NAME = 'user.registered';
protected $user;
public function __construct(User $user)
{
$this-> user = $user;
}
public function getUser()
{
return $this->user;
}
}
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
$user = new User();
$event = new UserRegistered($user);
/ Публикация
$dispatcher->dispatch($event, UserRegistered::NAME);
class NotificationSubscriber implements EventSubscriberInterface
{
private $twig;
private $bus;
public function __construct(Environment $twig, MessageBusInterface $bus)
{
$this->twig = $twig;
$this->bus = $bus;
}
public static function getSubscribedEvents()
{
return [
UserRegistered::NAME => 'onNotification',
];
}
public function onNotification(UserRegistered $event)
{
$notification = new NotificationMessage(
UserRegistered::NAME,
sprintf('Пользователь %s зарегистрирован', $event->getUser()->getName()),
$this->twig->render('notification/user-created.twig')//Шаблон User Created
);
$this->bus->dispatch($notification);
}
}
class NotificationMessage
{
private $content;
private $type;
private $subject;
public function __construct(string $type, $subject, string $content)
{
$this->type = $type;
$this->content = $content;
$this->subject = $subject;
}
public function getType(): string
{
return $this->type;
}
public function getSubject(): string
{
return $this->subject;
}
public function getContent(): string
{
return $this->content;
}
}
use App\Model\Notification\Entity\Subscriber\SubscriberRepository;
use App\Model\Notification\Entity\Subscriber\Subscriber;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\NotifierInterface;
use Symfony\Component\Notifier\Recipient\Recipient;
use Twig\Environment;
class NotificationHandler implements MessageHandlerInterface
{
private $subscribers;
private $notifier;
private $texter;
public function __construct(SubscriberRepository $subscribers, NotifierInterface $notifier, TexterInterface $texter)
{
$this->subscribers = $subscribers;
$this->notifier = $notifier;
$this->texter = $texter;
}
public function __invoke(NotificationMessage $message)
{
/** @var Subscriber[] $subscribers */
$subscribers = $this->subscribers->getAllActiveForType($message->getType());
foreach ($subscribers as $subscriber) {
foreach ($subscriber->getChannels() as $channel) {
if ($channel->isForChannel('email')) {
$notification = (new Notification($message->getSubject()))
->content('You got a new invoice for 15 EUR.');
// The receiver of the Notification
$recipient = new Recipient(
$subscriber->getEmail(),
$subscriber->getPhone()
);
// Send the notification to the recipient
$this->notifier->send($notification, $recipient);
}
if ($channel->isForChannel('sms')) {
$sms = new SmsMessage(
$subscriber->getPhone(),
$message->getContent()
);
$this->texter->send($sms);
}
if ($channel->isForChannel('service')) {
$service = new ServiceMessage(
$recipient,
$message->getSubject(),
$message->getContent()
);
$this->servicer->send($service);
}
}
}
}
}
Answer the question
In order to leave comments, you need to log in
Flow
1.1. Create a listener/subscriber, catch the event itself (symphonic or custom)
1.2. In the event handler, create a message with notification data (if you need to save data for other processing, then write it to the entity, and duplicate it in the message), throw the message into the bus
2. Create a message handler
3. Set up asynchronous processing of these messages in the messenger configs
Documentation there is a very similar example - creating-a-message-handler
Messenger
has a separate configuration for retry.
I didn’t make exactly the same system, I had notifications on a different framework, and in the course on symfonycasts about Messenger there were many examples on setting up this case) I think it’s worth clarifying with the customer / manager the exact flow of all these times of resending, data storage, confirmation of a successful submission, because some may be critical and some may be secondary.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question