Дата обновления перевода: 2020-12-25
Создание и отправка уведомлений¶
New in version 5.0: Компонент Notifier появился в Symfony 5.0 как экспериментальная возможность.
Установка¶
Современные веб-приложения используют много каналов для отправки сообщений пользователям (такие как SMS, сообщения в Slack, email, push-уведомления и другие). Symfony-компонент Notifier - это абстракция над всеми этими каналами. Он предоставляет динамический способ управления как отправляются сообщения. Установите Notifier с помощью:
1 | $ composer require symfony/notifier
|
Каналы: Chatters, Texters, Email and Browser¶
Компонент Notifier может отправлять уведомления разными каналами. Каждый канал может с помощью транспортов интегрироваться с разными провайдерами (например, Slack или Twilio SMS).
Комонент Notifier поддерживает такие каналы:
- SMS канал отправляет уведомления на телефоны SMS-сообщениями;
- Chat канал отправляет уведомления в чат-сервисы как Slack и Telegram;
- Email канал интегрируется с Symfony Mailer;
- Browser канал использует flash-сообщения.
Tip
Используйте secrets для безопасного хранения ваших API-токенов.
SMS канал¶
SMS канал использует классы Texter
для отправки SMS-сообщений на мобильные телефоны. Эта функция требует подписки
на внешние сервисы, которые отправляют SMS-сообщения. Symfony предоставляет интеграцию
с несколькими популярными SMS-сервисами:
Сервис | Пакет | DSN |
---|---|---|
Esendex | symfony/esendex-notifier |
esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROM |
FreeMobile | symfony/free-mobile-notifier |
freemobile://LOGIN:PASSWORD@default?phone=PHONE |
Infobip | symfony/infobip-notifier |
infobip://TOKEN@default?from=FROM |
Mobyt | symfony/mobyt-notifier |
mobyt://USER_KEY:ACCESS_TOKEN@default?from=FROM |
Nexmo | symfony/nexmo-notifier |
nexmo://KEY:SECRET@default?from=FROM |
OvhCloud | symfony/ovhcloud-notifier |
ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME |
Sendinblue | symfony/sendinblue-notifier |
sendinblue://API_KEY@default?sender=PHONE |
Sinch | symfony/sinch-notifier |
sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM |
Smsapi | symfony/smsapi-notifier |
smsapi://TOKEN@default?from=FROM |
Twilio | symfony/twilio-notifier |
twilio://SID:TOKEN@default?from=FROM |
New in version 5.1: Интеграции OvhCloud, Sinch и FreeMobile появились в Symfony 5.1.
New in version 5.2: Интеграции Smsapi, Infobip, Mobyt, Esendex и Sendinblue появились в Symfony 5.2.
Для включения texter, добавьте корректный DSN в ваш .env
файл и
настройте texter_transports
:
1 2 | # .env
TWILIO_DSN=twilio://SID:[email protected]?from=FROM
|
- YAML
1 2 3 4 5
# config/packages/notifier.yaml framework: notifier: texter_transports: twilio: '%env(TWILIO_DSN)%'
- XML
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>
- PHP
1 2 3 4 5 6 7 8
# config/packages/notifier.php $container->loadFromExtension('framework', [ 'notifier' => [ 'texter_transports' => [ 'twilio' => '%env(TWILIO_DSN)%', ], ], ]);
Chat канал¶
Канал чатов используется для отправки сообщений пользователям в чаты используя
классы Chatter
. Symfony предоставляет
интеграцию с этими сервисами чатов:
Service | Package | DSN |
---|---|---|
GoogleChat | symfony/google-chat-notifier |
googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?threadKey=THREAD_KEY |
symfony/linked-in-notifier |
linkedin://TOKEN:USER_ID@default |
|
Mattermost | symfony/mattermost-notifier |
mattermost://TOKEN@ENDPOINT?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 |
Zulip | symfony/zulip-notifier |
zulip://EMAIL:APIKEY@ENDPOINT?channel=CHANNEL |
New in version 5.1: Интеграции с Mattermost и RocketChat появились в Symfony 5.1. Slack DSN изменилась в Symfony 5.1 для использования Slack Incoming Webhooks вместо устаревших токенов.
New in version 5.2: Интеграции с GoogleChat, LinkedIn и Zulip появились в Symfony 5.2.
Chatters конфигурируются с помощью настройки chatter_transports
:
1 2 | # .env
SLACK_DSN=slack://default/ID
|
- YAML
1 2 3 4 5
# config/packages/notifier.yaml framework: notifier: chatter_transports: slack: '%env(SLACK_DSN)%'
- XML
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>
- PHP
1 2 3 4 5 6 7 8
# config/packages/notifier.php $container->loadFromExtension('framework', [ 'notifier' => [ 'chatter_transports' => [ 'slack' => '%env(SLACK_DSN)%', ], ], ]);
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 с которого будут приходить письма-уведомления:
- YAML
1 2 3 4 5 6
# config/packages/mailer.yaml framework: mailer: dsn: '%env(MAILER_DSN)%' envelope: sender: '[email protected]'
- XML
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="[email protected]" /> </framework:mailer> </framework:config> </container>
- PHP
1 2 3 4 5 6 7 8 9
# config/packages/mailer.php $container->loadFromExtension('framework', [ 'mailer' => [ 'dsn' => '%env(MAILER_DSN)%', 'envelope' => [ 'sender' => '[email protected]', ], ], ]);
Настройка резервного транспорта или балансировка Round-Robin¶
Кроме настройки одного или нескольких отдельных транспортов вы также можете использовать
специальные символы ||
и &&
для реализации резервного или round-robin
транспорта:
- YAML
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)%'
- XML
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>
- PHP
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)%', ], ], ]);
Создание и отправка уведомлений¶
Для отправлки уведомления автоподключите
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 33 | // src/Controller/InvoiceController.php
namespace App\Controller;
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)
{
// ...
// Создать уведомление, которое отправится
// через "email" канал
$notification = (new Notification('New Invoice', ['email']))
->content('You got a new invoice for 15 EUR.');
// Получатель уведомления
$recipient = new Recipient(
$user->getEmail(),
$user->getPhonenumber()
);
// Отправить уведомление получателю
$sentMessage = $notifier->send($notification, $recipient);
// ...
}
}
|
Уведомление Notification
создаётся с 2 аргументами: тема и
каналы. Каналы указывают, какой канал или транспорт должен использоваться
для отправки уведомления. Например, ['email', 'sms']
отправят
и email и sms-уведомление пользователю.
Метод send()
отправляет уведомление и возвращает переменную типа
SentMessage
, которая предоставляет
такую информацию как message ID и содержимое отправленного сообщения.
New in version 5.2: Класс SentMessage
появился в Symfony 5.2.
Уведомление по умолчаниют также имеет методы content()
и emoji()
для
установки текста и иконки уведомления.
Symfony предоставляет таких получателей:
NoRecipient
- Получатель по умолчанию, который полезен, когда не нужно иметь информацию о получателе. Например, канал browser использует flashbag сессии текущего request;
Recipient
- Может содержать и email и телефон пользователя. Этот получатель может использоваться для всех каналов (зависит от того установлены ли они действительно).
New in version 5.2: Класс AdminRecipient
удалён в Symfony 5.2, используйте
вместо него Recipient
.
Настройка политик каналов¶
Вместо указания целевых каналов при создании Symfony также позволяет
вам использовать уровни важности уведомлений. Обновите конфигурацию для
указания какие каналы должны использоваться для нужных уровней (используя
channel_policy
):
- YAML
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'] # Использовать browser для уведомлений уровня средний и низкий medium: ['browser'] low: ['browser']
- XML
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>
- PHP
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'], ], ], ]);
Теперь, когда важность уведомления установлена в "high", оно будет отправлено через транспорт Slack:
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('[email protected]'));
// ...
}
}
|
Настройка уведомлений¶
Вы можете расширить базовые классы 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 26 27 | 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
{
private $price;
public function __construct(int $price)
{
$this->price = $price;
}
public function getChannels(RecipientInterface $recipient)
{
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 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\SmsRecipientInterface;
class InvoiceNotification extends Notification implements ChatNotificationInterface
{
private $price;
public function __construct(int $price)
{
$this->price = $price;
}
public function asChatMessage(RecipientInterface $recipient, string $transport = null): ?ChatMessage
{
// Добавьте свой emoji, если сообщение отправляется в Slack
if ('slack' === $transport) {
return (new ChatMessage('You\'re invoiced '.$this->price.' EUR.'))
->emoji('money');
}
// Если вы вернёте null, Notifier создаст ChatMessage
// так как если бы этого метода не было
return null;
}
}
|
Также есть интерфейсы
SmsNotificationInterface
и
EmailNotificationInterface
для изменения сообщений, отправляемых по этим каналам.
Отключение доставки¶
Во время разработки и тестирования вы можете захотеть полностью отключить отправку уведомлений.
Вы можете сделать это, дав 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'
|
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.