Створення та відправлення сповіщень

Дата оновлення перекладу 2022-12-15

Створення та відправлення сповіщень

Установка

Сучасні веб-додатки використовують багато каналів для відправлення повідомлень користувачам (такі як 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;
  • Браузер-канал використовує флеш-повідомлення .
  • Push-канал відправляє сповіщення на телефони та браузери через пуш-сповіщення.

Tip

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

SMS-канал

Caution

Якщо будь-яке зі значень DSN містить будь-який символ, який вважається спеціальним в URI (на кшталт, as +, @, $, #, /, :, *, !), ви повинні зашифрувати їх. Див. RFC 3986, щоб побачити повний перелік зарезервованих символів, або використайте функцію urlencode, щоб зашифрувати їх.

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

6.1

Інтеграції 46elks, OrangeSms, KazInfoTeh та Sendberry були представлені в Symfony 6.1.
Опція no_stop_clause в OvhCloud DSN була представлена в Symfony 6.1. Опція test в Smsapi DSN була представлена в Symfony 6.1.

6.2

Інтеграції ContactEveryone та SMSFactor були представлені вно Symfony 6.2.

Для ввімкнення texter, додайте коректний DSN у ваш файл .env та налаштуйте texter_transports:

1
2
# .env
TWILIO_DSN=twilio://SID:TOKEN@default?from=FROM
  • YAML
  • XML
  • PHP
1
2
3
4
5
# config/packages/notifier.yaml
framework:
    notifier:
        texter_transports:
            twilio: '%env(TWILIO_DSN)%'

Чат-канал

Caution

Якщо будь-яке зі значень DSN містить будь-який символ, який вважається спеціальним в URI (на кшталт, as +, @, $, #, /, :, *, !), ви повинні зашифрувати їх. Див. RFC 3986, щоб побачити повний перелік зарезервованих символів, або використайте функцію urlencode, щоб зашифрувати їх.

Канал чатів використовується для відправлення повідомлень користувачам у чати, використовуючи класи Chatter. Symfony надає інтеграцію з цими сервісами чатів:

?????? ????? DSN
AmazonSns symfony/amazon-sns-notifier sns://ACCESS_KEY:SECRET_KEY@default?region=REGION
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 or 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
LinkedIn symfony/linked-in-notifier linkedin://TOKEN:USER_ID@default
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
Zendesk symfony/zendesk-notifier zendesk://EMAIL:TOKEN@SUBDOMAIN
Zulip symfony/zulip-notifier zulip://EMAIL:TOKEN@HOST?channel=CHANNEL

6.2

Інтеграції Zendesk та Chatwork були представлені в Symfony 6.2.

Chatters конфігуруються за допомогою налаштування chatter_transports:

1
2
# .env
SLACK_DSN=slack://TOKEN@default?channel=CHANNEL
  • YAML
  • XML
  • PHP
1
2
3
4
5
# config/packages/notifier.yaml
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
  • XML
  • PHP
1
2
3
4
5
6
# config/packages/mailer.yaml
framework:
    mailer:
        dsn: '%env(MAILER_DSN)%'
        envelope:
            sender: 'notifications@example.com'

Push-канал

Caution

Якщо будь-яке зі значень DSN містить будь-який символ, який вважається спеціальним в URI (на кшталт, as +, @, $, #, /, :, *, !), ви повинні зашифрувати їх. Див. RFC 3986, щоб побачити повний перелік зарезервованих символів, або використайте функцію urlencode, щоб зашифрувати їх.

Push-канал використовується для відправлення користувачам сповіщень з використанням класів Texter. Symfony надає інтеграцію з цими пуш-сервісами:

?????? ????? DSN
Engagespot symfony/engagespot-notifier engagespot://API_KEY@default?campaign_name=CAMPAIGN_NAME
Expo symfony/expo-notifier expo://Token@default
OneSignal symfony/one-signal-notifier onesignal://APP_ID:API_KEY@default?defaultRecipientId=DEFAULT_RECIPIENT_ID''

6.1

Інтеграція Engagespot була представлена в Symfony 6.1.

Щоб увімкнути texter, додайте правильну DSN у ваш файл .env, та сконфігуруйте texter_transports:

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

Конфігурація резервного транспорту або балансування Round-Robin

Окрім налаштування одного або декількох окремих транспортів, ви також можете викоритовувати спеціальні символи || і && для реалізації резервного або round-robin транспорту:

  • YAML
  • XML
  • PHP
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
// 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()
        );

        // Відправити сповіщення отримувачу
        $notifier->send($notification, $recipient);

        // ...
    }
}

Сповіщення Notification створюється з 2 аргументами: тема та канали. Канали вказують, який канал або транспорт має використовуватися для відправлення сповіщення. Наприклад, ['email', 'sms'] відправлять і email, і sms-сповіщення користувачу.

Сповіщення за замовчуванням також має методи content() і emoji(), щоб встановлювати зміст та іконку змісту.

Symfony надає таких отримувачів:

NoRecipient
Отримувач за замовчуванням, який корисний, коли не треба мати інформацію про отримувача. Наприклад, браузер-канал використовує flashbag сесії поточного запиту;
Recipient
Може містити і email, і телефон користувача. Цей отримувач може використовуватися для всіх каналів (залежить від того, чи дійсно вони встановлені).

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

Замість вказування цільових каналів при створенні, Symfony також дозволяє вам використовувати рівні важливості сповіщень. Оновіть конфігурацію для вказання, які канали мають використовуватися для потрібних рівнів (використовуючи channel_policy):

  • YAML
  • XML
  • PHP
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)
    {
        // ...

        $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
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'];
    }
}

Користувацьке налаштування повідомлень сповіщень

У кожного каналу є власний інтерфейс сповіщень, який ви можете реалізувати для налаштування повідомлень сповіщень. Наприклад, якщо ви хочете змінити повідомлення на основі чат-сервісу, реалізуйте 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 для зміни повідомлень, що надсилаються по цих каналах.

Користувацьке налаштування сповіщень браузера (флеш-повідомлення)

6.1

Підтримка користувацького налаштування рівнів важливості була представлена в Symfony 6.1.

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

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

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

На даний момент Symfony надає реалізацію для типових рівнів небезпеки для CSS фреймворку Bootstrap, які ви можете реалізувати негайно, використавши:

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

Відключення доставки

Під час розробки та тестування ви можете захотіти повністю відключити відправлення сповіщень. Ви можете зробити це, надавши 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'
.. TODO
  • Використання автобусу повідомлень для асинхронних сповіщень
  • Описати обробник сповіщень monolog
  • Описати інтеграцію notification_on_failed_messages