Создание и отправка уведомлений

Дата обновления перевода 2024-07-31

Создание и отправка уведомлений

Установка

Современные веб-приложения используют много каналов для отправки сообщений пользователям (такие как SMS, сообщения в Slack, email, push-уведомления и другие). Symfony-компонент Notifier - это абстракция над всеми этими каналами. Он предоставляет динамический способ управления как отправляются сообщения. Установите Notifier с помощью:

1
$ composer require symfony/notifier

Каналы: Chatters, Texters, Email, Browser и Push

Компонент Notifier может отправлять уведомления разными каналами. Каждый канал может с помощью транспортов интегрироваться с разными провайдерами (например, Slack или Twilio SMS).

Комонент Notifier поддерживает такие каналы:

  • SMS-канал отправляет уведомления на телефоны SMS-сообщениями;
  • Чат-канал отправляет уведомления в чат-сервисы как Slack и Telegram;
  • Email-канал интегрируется с Symfony Mailer;
  • Канал браузера использует flash-сообщения .
  • Пуш-канал отправляет уведомления на телефоны и браузеры через пуш-уведомления.

Tip

Используйте секреты для безопасного хранения ваших API-токенов.

SMS-канал

Caution

Если любое из значений DSN содержит любой символ, считающийся специальным в URI (такой как : / ? # [ ] @ ! $ & ' ( ) * + , ; =), вы должны зашифровать его. См. RFC 3986, чтобы увидеть полный список зарезервированных символов, или используйте функцию urlencode, чтобы зашифровать их.

SMS канал использует классы Texter для отправки SMS-сообщений на мобильные телефоны. Эта функция требует подписки на внешние сервисы, которые отправляют SMS-сообщения. Symfony предоставляет интеграцию с несколькими популярными SMS-сервисами:

?????? ????? DSN  
46elks symfony/forty-six-elks-notifier forty-six-elks://API_USERNAME:API_PASSWORD@default?from=FROM  
AllMySms symfony/all-my-sms-notifier allmysms://LOGIN:APIKEY@default?from=FROM  
AmazonSns symfony/amazon-sns-notifier sns://ACCESS_KEY:SECRET_KEY@default?region=REGION  
Bandwidth symfony/bandwidth-notifier bandwidth://USERNAME:PASSWORD@default?from=FROM&account_id=ACCOUNT_ID&application_id=APPLICATION_ID&priority=PRIORITY  
Brevo symfony/brevo-notifier brevo://API_KEY@default?sender=SENDER  
Clickatell symfony/clickatell-notifier clickatell://ACCESS_TOKEN@default?from=FROM  
ContactEveryone symfony/contact-everyone-notifier contact-everyone://TOKEN@default?&diffusionname=DIFFUSION_NAME&category=CATEGORY  
Esendex symfony/esendex-notifier esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROM  
FakeSms symfony/fake-sms-notifier fakesms+email://MAILER_SERVICE_ID?to=TO&from=FROM or fakesms+logger://default  
FreeMobile symfony/free-mobile-notifier freemobile://LOGIN:API_KEY@default?phone=PHONE  
GatewayApi symfony/gateway-api-notifier gatewayapi://TOKEN@default?from=FROM  
GoIP symfony/goip-notifier goip://USERNAME:PASSWORD@HOST:80?sim_slot=SIM_SLOT  
Infobip symfony/infobip-notifier infobip://AUTH_TOKEN@HOST?from=FROM  
Iqsms symfony/iqsms-notifier iqsms://LOGIN:PASSWORD@default?from=FROM  
KazInfoTeh symfony/kaz-info-teh-notifier kaz-info-teh://USERNAME:PASSWORD@default?sender=FROM  
LightSms symfony/light-sms-notifier lightsms://LOGIN:TOKEN@default?from=PHONE  
Mailjet symfony/mailjet-notifier mailjet://TOKEN@default?from=FROM  
MessageBird symfony/message-bird-notifier messagebird://TOKEN@default?from=FROM  
MessageMedia symfony/message-media-notifier messagemedia://API_KEY:API_SECRET@default?from=FROM  
Mobyt symfony/mobyt-notifier mobyt://USER_KEY:ACCESS_TOKEN@default?from=FROM  
Nexmo symfony/nexmo-notifier ??????? ? ?????? Vonage (symfony/vonage-notifier).  
Octopush symfony/octopush-notifier octopush://USERLOGIN:APIKEY@default?from=FROM&type=TYPE  
OrangeSms symfony/orange-sms-notifier orange-sms://CLIENT_ID:CLIENT_SECRET@default?from=FROM&sender_name=SENDER_NAME  
OvhCloud symfony/ovh-cloud-notifier ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME  
Plivo symfony/plivo-notifier plivo://AUTH_ID:AUTH_TOKEN@default?from=FROM  
Redlink symfony/redlink-notifier redlink://API_KEY:APP_KEY@default?from=SENDER_NAME&version=API_VERSION  
RingCentral symfony/ring-central-notifier ringcentral://API_TOKEN@default?from=FROM  
SMSFactor symfony/sms-factor-notifier sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPE  
Sendberry symfony/sendberry-notifier sendberry://USERNAME:PASSWORD@default?auth_key=AUTH_KEY&from=FROM  
Seven.io symfony/sevenio-notifier sevenio://API_KEY@default?from=FROM  
SimpleTextin symfony/simple-textin-notifier simpletextin://API_KEY@default?from=FROM  
Sinch symfony/sinch-notifier sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM  
Sms77 symfony/sms77-notifier sms77://API_KEY@default?from=FROM  
SmsBiuras symfony/sms-biuras-notifier smsbiuras://UID:API_KEY@default?from=FROM&test_mode=0  
SmsSluzba symfony/sms-sluzba-notifier sms-sluzba://USERNAME:PASSWORD@default  
Smsapi symfony/smsapi-notifier smsapi://TOKEN@default?from=FROM  
Smsbox symfony/smsbox-notifier smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDER  
Smsc symfony/smsc-notifier smsc://LOGIN:PASSWORD@default?from=FROM  
SMSense symfony/smsense-notifier smsense://API_TOKEN@default?from=FROM  
SpotHit symfony/spot-hit-notifier spothit://TOKEN@default?from=FROM  
Telnyx symfony/telnyx-notifier telnyx://API_KEY@default?from=FROM&messaging_profile_id=MESSAGING_PROFILE_ID  
TurboSms symfony/turbo-sms-notifier turbosms://AUTH_TOKEN@default?from=FROM  
Twilio symfony/twilio-notifier twilio://SID:TOKEN@default?from=FROM yes
Unifonic symfony/unifonic-notifier unifonic://APP_SID@default?from=FROM  
Vonage symfony/vonage-notifier vonage://KEY:SECRET@default?from=FROM yes
Yunpian symfony/yunpian-notifier yunpian://APIKEY@default  
iSendPro symfony/isendpro-notifier isendpro://ACCOUNT_KEY_ID@default?from=FROM&no_stop=NO_STOP&sandbox=SANDBOX  

Tip

Некоторые сторонние транспорты, использующие API, поддерживают обратные вызовы статуса через веб-хуки. Подробнее см. в документации документации Webhook.

7.1

Интеграции SmsSluzba и SMSense были представлены в Symfony 7.1.

7.1

Интеграция Sms77 устарела, начиная с Symfony 7.1, вместо этого используйте интеграцию Seven.io.

Для включения texter, добавьте корректный DSN в ваш .env файл и настройте 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)%'

Класс TexterInterface позволяет вам отправлять SMS-сообщения:

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/SecurityController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\TexterInterface;
use Symfony\Component\Routing\Attribute\Route;

class SecurityController
{
    #[Route('/login/success')]
    public function loginSuccess(TexterInterface $texter): Response
    {
        $options = (new ProviderOptions())
            ->setPriority('high')
        ;

        $sms = new SmsMessage(
            // номер телефона, по которому отправить SMS
            '+1411111111',
            // сообщение
            'A new login was detected!',
            // опционально, вы можете переопределить "from" по умолчанию, определённую в транспортах
            '+1422222222',
            // вы также можете добавить объект опций, реализующий MessageOptionsInterface
            $options
        );

        $sentMessage = $texter->send($sms);

        // ...
    }
}

Метод send() возвращает переменную типа SentMessage, которая предоставляет информацию ворде ID сообщения и изначального содержания сообщения.

Чат-канал

Caution

Если любое из значений DSN содержит любой символ, считающийся специальным в URI (такой как : / ? # [ ] @ ! $ & ' ( ) * + , ; =), вы должны зашифровать его. См. RFC 3986, чтобы увидеть полный список зарезервированных символов, или используйте функцию urlencode, чтобы зашифровать их.

Чат-канал используется для отправки сообщений пользователям в чаты используя классы Chatter. Symfony предоставляет интеграцию с этими сервисами чатов:

?????? ????? DSN
AmazonSns symfony/amazon-sns-notifier sns://ACCESS_KEY:SECRET_KEY@default?region=REGION
Bluesky symfony/bluesky-notifier bluesky://USERNAME:PASSWORD@default
Chatwork symfony/chatwork-notifier chatwork://API_TOKEN@default?room_id=ID
Discord symfony/discord-notifier discord://TOKEN@default?webhook_id=ID
FakeChat symfony/fake-chat-notifier fakechat+email://default?to=TO&from=FROM ??? fakechat+logger://default
Firebase symfony/firebase-notifier firebase://USERNAME:PASSWORD@default
Gitter symfony/gitter-notifier gitter://TOKEN@default?room_id=ROOM_ID
GoogleChat symfony/google-chat-notifier googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY
LINE Notify symfony/line-notify-notifier linenotify://TOKEN@default
LinkedIn symfony/linked-in-notifier linkedin://TOKEN:USER_ID@default
Mastodon symfony/mastodon-notifier mastodon://ACCESS_TOKEN@HOST
Mattermost symfony/mattermost-notifier mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL
Mercure symfony/mercure-notifier mercure://HUB_ID?topic=TOPIC
MicrosoftTeams symfony/microsoft-teams-notifier microsoftteams://default/PATH
RocketChat symfony/rocket-chat-notifier rocketchat://TOKEN@ENDPOINT?channel=CHANNEL
Slack symfony/slack-notifier slack://TOKEN@default?channel=CHANNEL
Telegram symfony/telegram-notifier telegram://TOKEN@default?channel=CHAT_ID
Twitter symfony/twitter-notifier twitter://API_KEY:API_SECRET:ACCESS_TOKEN:ACCESS_SECRET@default
Zendesk symfony/zendesk-notifier zendesk://EMAIL:TOKEN@SUBDOMAIN
Zulip symfony/zulip-notifier zulip://EMAIL:TOKEN@HOST?channel=CHANNEL

7.1

Интеграции Bluesky, Unifonic и Smsbox были представлены в Symfony 7.1.

Caution

По умолчанию, если у вас установлен компонентMessenger, уведомления будут отправляться через MessageBus. Если у вас не запущен потребитель сообщений, сообщения никогда не будут отправляться.

Чтобы изменить это поведение, добавьте следующую конфигурацию для отправки сообщений напрямую через транспорт:

1
2
3
4
# config/packages/notifier.yaml
framework:
    notifier:
        message_bus: false

Chatters конфигурируются с помощью настройки chatter_transports:

1
2
3
4
5
# config/packages/notifier.yaml
framework:
    notifier:
        chatter_transports:
            slack: '%env(SLACK_DSN)%'

Класс ChatterInterface позволяет вам отправлять сообщения в чат-сервисах:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/Controller/CheckoutController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Notifier\ChatterInterface;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Routing\Attribute\Route;

class CheckoutController extends AbstractController
{
    #[Route('/checkout/thankyou')]
    public function thankyou(ChatterInterface $chatter): Response
    {
        $message = (new ChatMessage('You got a new invoice for 15 EUR.'))
            // если не установлено ясно, сообщение отправляется в транспорт
            // по умолчанию (первый сконфигурированный)
            ->transport('slack');

        $sentMessage = $chatter->send($message);

        // ...
    }
}

Метод send() возвращает переменную типа SentMessage, которая предоставляет информацию ворде ID сообщения и изначального содержания сообщения.

Email-канал

Email канал использует Symfony Mailer для отправки уведомлений используя специальный NotificationEmail. Необходимо установить Twig bridge вместе с Inky и Twig расширениями CSS Inliner:

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

После этого сконфигурируйте mailer . Вы также можете настроить адрес email с которого будут приходить письма-уведомления:

1
2
3
4
5
6
# config/packages/mailer.yaml
framework:
    mailer:
        dsn: '%env(MAILER_DSN)%'
        envelope:
            sender: 'notifications@example.com'

Пуш-канал

Caution

Если любое из значений DSN содержит любой символ, считающийся специальным в URI (такой как : / ? # [ ] @ ! $ & ' ( ) * + , ; =), вы должны зашифровать его. См. RFC 3986, чтобы увидеть полный список зарезервированных символов, или используйте функцию urlencode, чтобы зашифровать их.

Пуш-канал используется для отправки пользователям уведомлений с использованием классов Texter. Symfony предоставляет интеграцию с этими пуш-сервисами:

?????? ????? DSN
Engagespot symfony/engagespot-notifier engagespot://API_KEY@default?campaign_name=CAMPAIGN_NAME
Expo symfony/expo-notifier expo://Token@default
Novu symfony/novu-notifier novu://API_KEY@default
Ntfy symfony/ntfy-notifier ntfy://default/TOPIC
OneSignal symfony/one-signal-notifier onesignal://APP_ID:API_KEY@default?defaultRecipientId=DEFAULT_RECIPIENT_ID
PagerDuty symfony/pager-duty-notifier pagerduty://TOKEN@SUBDOMAIN
Pushover symfony/pushover-notifier pushover://USER_KEY:APP_TOKEN@default
Pushy symfony/pushy-notifier pushy://API_KEY@default

Чтобы включить texter, добавьте правильную DSN в ваш файл .env, и сконфигурируйте texter_transports:

7.1

Интеграция Pushy была представлена в Symfony 7.1.

1
2
# .env
EXPO_DSN=expo://TOKEN@default
1
2
3
4
5
# config/packages/notifier.yaml
framework:
    notifier:
        texter_transports:
            expo: '%env(EXPO_DSN)%'

Настройка использования резервного транспорта или Round-Robin

Кроме настройки одного или нескольких отдельных транспортов вы также можете использовать специальные символы || и && для реализации резервного или round-robin транспорта:

1
2
3
4
5
6
7
8
9
10
# config/packages/notifier.yaml
framework:
    notifier:
        chatter_transports:
            # Отправлять уведомления в Slack и использовать Telegram, если
            # Slack выдал ошибку
            main: '%env(SLACK_DSN)% || %env(TELEGRAM_DSN)%'

            # Отправлять уведомления используя следующий запланированный транспорт, рассчитанный методом round robin
            roundrobin: '%env(SLACK_DSN)% && %env(TELEGRAM_DSN)%'

Создание и отправка уведомлений

Для отправлки уведомления автоподключите NotifierInterface (ID сервиса - notifier). У этого класса есть метод send() который позволяет вам отправлять уведомление Notification получателю 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
// src/Controller/InvoiceController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\NotifierInterface;
use Symfony\Component\Notifier\Recipient\Recipient;

class InvoiceController extends AbstractController
{
    #[Route('/invoice/create')]
    public function create(NotifierInterface $notifier): Response
    {
        // ...

        // Создать уведомление, которое отправится
        // через "email" канал
        $notification = (new Notification('New Invoice', ['email']))
            ->content('You got a new invoice for 15 EUR.');

        // Получатель уведомления
        $recipient = new Recipient(
            $user->getEmail(),
            $user->getPhonenumber()
        );

        // Отправить уведомление получателю
        $notifier->send($notification, $recipient);

        // ...
    }
}

Уведомление Notification создаётся с 2 аргументами: тема и каналы. Каналы указывают, какой канал или транспорт должен использоваться для отправки уведомления. Например, ['email', 'sms'] отправят и email и sms-уведомление пользователю.

Уведомление по умолчанию также имеет методы content() и emoji(), чтобы устанавливать содержание и иконку содержания.

Symfony предоставляет таких получателей:

NoRecipient
Получатель по умолчанию, который полезен, когда не нужно иметь информацию о получателе. Например, канал browser использует flashbag сессии текущего request;
Recipient
Может содержать и email и телефон пользователя. Этот получатель может использоваться для всех каналов (зависит от того установлены ли они действительно).

Конфигурация политики каналов

Вместо указания целевых каналов при создании Symfony также позволяет вам использовать уровни важности уведомлений. Обновите конфигурацию для указания какие каналы должны использоваться для нужных уровней (используя channel_policy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config/packages/notifier.yaml
framework:
    notifier:
        # ...
        channel_policy:
            # Использовать SMS, Slack и email для срочных уведомлений
            urgent: ['sms', 'chat/slack', 'email']

            # Использовать Slack для важных уведомлений
            high: ['chat/slack']

            # Использовать браузер для уведомлений среднего и низкого уровня
            medium: ['browser']
            low: ['browser']

Теперь, когда важность уведомления установлена в "high", оно будет отправлено через транспорт Slack:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ...
class InvoiceController extends AbstractController
{
    #[Route('/invoice/create')]
    public function invoice(NotifierInterface $notifier): Response
    {
        // ...

        $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'));

        // ...
    }
}

Настройка уведомлений

Вы можете расширить базовые классы Notification или Recipient для настройки их поведения. Например, вы можете переопределить метод getChannels(), чтобы возвращать sms только есл сумма счёте очень большая и у получателя есть телефонный номер:

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
namespace App\Notifier;

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

class InvoiceNotification extends Notification
{
    public function __construct(
        private int $price,
    ) {
    }

    public function getChannels(RecipientInterface $recipient): array
    {
        if (
            $this->price > 10000
            && $recipient instanceof SmsRecipientInterface
        ) {
            return ['sms'];
        }

        return ['email'];
    }
}

Настройка сообщений уведомлений

У каждого канала есть собственный интерфейс уведомлений, который вы можете реализовать для настройки сообщений уведомлений. Например, если вы хотите изменить сообщение на основе сервиса chat, реализуйте ChatNotificationInterface и его метод asChatMessage():

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
// 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\RecipientInterface;

class InvoiceNotification extends Notification implements ChatNotificationInterface
{
    public function __construct(
        private int $price,
    ) {
    }

    public function asChatMessage(RecipientInterface $recipient, string $transport = null): ?ChatMessage
    {
        // Добавьте пользовательский заголовок и emoji, если сообщение отправляется в Slack
        if ('slack' === $transport) {
            $this->subject('You\'re invoiced '.strval($this->price).' EUR.');
            $this->emoji("money");
            return ChatMessage::fromNotification($this);
        }

        // Если вы вернёте null, Notifier создаст ChatMessage
        // так как если бы этого метода не было
        return null;
    }
}

Также есть интерфейсы SmsNotificationInterface, EmailNotificationInterface и PushNotificationInterface для изменения сообщений, отправляемых по этим каналам.

Настройка уведомлений браузера (флеш-сообщения)

Поведение по умолчанию для уведомлений канала браузера - добавлять флеш-сообщений с notification в качестве ключа.

Однако, вы можете предпочесть связать уровень важности уведомления с типом флеш- сообщения, чтобы вы могли настроить их стиль.

Вы можете сделать это, переопределив сервис по умолчанию notifier.flash_message_importance_mapper на вашу собственную реализацию FlashMessageImportanceMapperInterface, где вы можете предоставить собственную "важность" отображению "уровня предупреждения".

На данный момент, Symfony предоставаляет реализацию для типичных уровней предупреждния фреймворка начальной загузки CSS, которые вы можете реализовать немедленно, используя:

1
2
3
4
# config/services.yaml
services:
    notifier.flash_message_importance_mapper:
        class: Symfony\Component\Notifier\FlashMessage\BootstrapFlashMessageImportanceMapper

Тестирование Notifier

Symfony предоставляет NotificationAssertionsTrait, который предоставляет полезные методы для тестирования вашей реализации Notifier. Вы можете использовать преимущества этого класса, используя его напрямую или расширив KernelTestCase.

См. документацию тестирования , чтобы увидеть список доступных утверждений.

Отключение доставки

Во время разработки и тестирования вы можете захотеть полностью отключить отправку уведомлений. Вы можете сделать это, дав Notifier транспорт NullTransport для всех настроенных транспортов texter и chatter, но только для dev (и/или test) окружений:

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

Using Events

Класс Transport` компонента Notifier позволяет вам опционально подключаться к жизненному циклу через события.

Событие MessageEvent::class

Типичные цели: Сделать что-то перед отправкой сообщения (вроде записи лога, какое сообщение будет отправлено, или отображения чего-либо про событие, которое будет выполнено).

Прямо перед отправкой сообщения, развёртывается класс события MessageEvent. Слушатели получают событие MessageEvent:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Notifier\Event\MessageEvent;

$dispatcher->addListener(MessageEvent::class, function (MessageEvent $event) {
    // получает экземпляр сообщения
    $message = $event->getMessage();

    // записать лог чего-то
    $this->logger(sprintf('Message with subject: %s will be send to %s, $message->getSubject(), $message->getRecipientId()'));
});

Событие FailedMessageEvent

Типичные цели: Сделать что-то перед вызовом исключения (повторно попробовать отправить сообщение или записать лог дополнительной информации).

Когда вызывается исключения прир отправке сообщения, развёртывается класс события FailedMessageEvent. Слушатель может сделать что-то полезное перед вызовом исключения.

Слушатели получают событие FailedMessageEvent:

1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\Notifier\Event\FailedMessageEvent;

$dispatcher->addListener(FailedMessageEvent::class, function (FailedMessageEvent $event) {
    // получает экземпляр сообщения
    $message = $event->getMessage();

    // получает экземпояр ошибки
    $error = $event->getError();

    // записать лог чего-то
    $this->logger(sprintf('Сообщение с темой: %s не было отправлено успешно. Ошибка: %s, $message->getSubject(), $error->getMessage()'));
});

Событие SentMessageEvent

Типичные цели: Выполнить какое-то действие при успешной отправке сообщения (вроде получения id, возвращённого после отправки сообщения).

После успешной отправки сообщения, разворачивается класс события SentMessageEvent. Слушатели получают событие SentMessageEvent:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Notifier\Event\SentMessageEvent;

$dispatcher->addListener(SentMessageEvent::class, function (SentMessageEvent $event) {
    // получает экземпляр сообщения
    $message = $event->getOriginalMessage();

    // записать лог чего-то
    $this->logger(sprintf('The message has been successfully sent and has id: %s, $message->getMessageId()'));
});