跳到内容

创建和发送通知

编辑此页

安装

当前 Web 应用程序使用许多不同的通道向用户发送消息(例如 SMS、Slack 消息、电子邮件、推送通知等)。Symfony 中的 Notifier 组件是对所有这些通道的抽象。它提供了一种动态方式来管理消息的发送方式。使用以下命令安装 Notifier

1
$ composer require symfony/notifier

通道

通道是指可以传递通知的不同媒介。这些通道包括电子邮件、SMS、聊天服务、推送通知等。每个通道都可以通过使用传输与不同的提供商(例如 Slack 或 Twilio SMS)集成。

Notifier 组件支持以下通道

7.2

Desktop 通道在 Symfony 7.2 中引入。

SMS 通道

SMS 通道使用 Texter 类向手机发送 SMS 消息。此功能需要订阅发送 SMS 消息的第三方服务。Symfony 提供了与一些流行的 SMS 服务的集成

警告

如果任何 DSN 值包含 URI 中被认为是特殊字符的字符(例如 : / ? # [ ] @ ! $ & ' ( ) * + , ; =),则必须对其进行编码。有关保留字符的完整列表,请参阅 RFC 3986,或使用 urlencode 函数对其进行编码。

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

提示

使用 Symfony 配置 secrets 安全地存储您的 API 令牌。

提示

一些第三方传输,当使用 API 时,支持通过 Webhook 进行状态回调。有关更多详细信息,请参阅 Webhook 文档

7.1

SmsboxSmsSluzbaSMSenseLOX24Unifonic 集成在 Symfony 7.1 中引入。

7.2

PrimotextoSipgateSweego 集成在 Symfony 7.2 中引入。

7.1

Sms77 集成自 Symfony 7.1 起已弃用,请改用 Seven.io 集成。

要启用 texter,请在您的 .env 文件中添加正确的 DSN 并配置 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(
            // the phone number to send the SMS message to
            '+1411111111',
            // the message
            'A new login was detected!',
            // optionally, you can override default "from" defined in transports
            '+1422222222',
            // you can also add options object implementing MessageOptionsInterface
            $options
        );

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

        // ...
    }
}

send() 方法返回 SentMessage 类型的变量,该变量提供诸如消息 ID 和原始消息内容之类的信息。

聊天通道

警告

如果任何 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=FROMfakechat+logger://default
Firebase symfony/firebase-notifier firebase://USERNAME:PASSWORD@default
GoogleChat symfony/google-chat-notifier googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY
LINE Bot symfony/line-bot-notifier linebot://TOKEN@default?receiver=RECEIVER
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 集成在 Symfony 7.1 中引入。

7.2

LINE Bot 集成在 Symfony 7.2 中引入。

7.2

Gitter 集成在 Symfony 7.2 中被移除,因为该服务不再提供 API。

警告

默认情况下,如果您安装了 Messenger 组件,通知将通过 MessageBus 发送。如果您没有运行消息消费者,消息将永远不会被发送。

要更改此行为,请添加以下配置以直接通过传输方式发送消息

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

聊天器使用 chatter_transports 设置进行配置

1
2
# .env
SLACK_DSN=slack://TOKEN@default?channel=CHANNEL
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.'))
            // if not set explicitly, the message is sent to the
            // default transport (the first one configured)
            ->transport('slack');

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

        // ...
    }
}

send() 方法返回 SentMessage 类型的变量,该变量提供诸如消息 ID 和原始消息内容之类的信息。

电子邮件通道

电子邮件通道使用 Symfony Mailer 使用特殊的 NotificationEmail 发送通知。需要安装 Twig 桥接器以及 Inky 和 CSS Inliner Twig 扩展

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

在此之后,配置邮件发送器。您还可以设置默认的“发件人”电子邮件地址,该地址应用于发送通知电子邮件

1
2
3
4
5
6
# config/packages/mailer.yaml
framework:
    mailer:
        dsn: '%env(MAILER_DSN)%'
        envelope:
            sender: '[email protected]'

推送通道

警告

如果任何 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,请在您的 .env 文件中添加正确的 DSN 并配置 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)%'

桌面通道

桌面通道用于在使用 Texter 类的同一主机上显示本地桌面通知。目前,Symfony 与以下提供商集成

提供商 DSN
JoliNotif symfony/joli-notif-notifier jolinotif://default

7.2

JoliNotif 桥接器在 Symfony 7.2 中引入。

如果您正在使用 Symfony Flex,安装该软件包也将创建必要的环境变量和配置。否则,您需要手动添加以下内容

  1. 在您的 .env 文件中添加正确的 DSN
1
2
# .env
JOLINOTIF=jolinotif://default
  1. 更新 Notifier 配置以添加新的 texter 传输方式
1
2
3
4
5
# config/packages/notifier.yaml
framework:
    notifier:
        texter_transports:
            jolinotif: '%env(JOLINOTIF)%'

现在您可以按如下所示向您的桌面发送通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/Notifier/SomeService.php
use Symfony\Component\Notifier\Message\DesktopMessage;
use Symfony\Component\Notifier\TexterInterface;
// ...

class SomeService
{
    public function __construct(
        private TexterInterface $texter,
    ) {
    }

    public function notifyNewSubscriber(User $user): void
    {
        $message = new DesktopMessage(
            'New subscription! 🎉',
            sprintf('%s is a new subscriber', $user->getFullName())
        );

        $texter->send($message);
    }
}

这些通知可以进一步自定义,并且根据您的操作系统,它们可能支持自定义声音、图标等功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use Symfony\Component\Notifier\Bridge\JoliNotif\JoliNotifOptions;
// ...

$options = (new JoliNotifOptions())
    ->setIconPath('/path/to/icons/error.png')
    ->setExtraOption('sound', 'sosumi')
    ->setExtraOption('url', 'https://example.com');

$message = new DesktopMessage('Production is down', <<<CONTENT
    ❌ Server prod-1 down
    ❌ Server prod-2 down
    ✅ Network is up
    CONTENT, $options);

$texter->send($message);

配置使用故障转移或轮询传输

除了配置一个或多个单独的传输方式之外,您还可以使用特殊的 ||&& 字符来实现故障转移或循环调度传输

1
2
3
4
5
6
7
8
9
10
# config/packages/notifier.yaml
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
// 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
    {
        // ...

        // Create a Notification that has to be sent
        // using the "email" channel
        $notification = (new Notification('New Invoice', ['email']))
            ->content('You got a new invoice for 15 EUR.');

        // The receiver of the Notification
        $recipient = new Recipient(
            $user->getEmail(),
            $user->getPhonenumber()
        );

        // Send the notification to the recipient
        $notifier->send($notification, $recipient);

        // ...
    }
}

Notification 通过使用两个参数创建:主题和通道。通道指定应使用哪个通道(或传输方式)发送通知。例如,['email', 'sms'] 将向用户发送电子邮件和短信通知。

默认通知还具有 content()emoji() 方法来设置通知内容和图标。

Symfony 提供了以下接收者

NoRecipient
这是默认设置,当无需了解接收者信息时非常有用。例如,浏览器通道使用当前请求的 session flashbag
Recipient
这可以包含用户的电子邮件地址和电话号码。此接收者可用于所有通道(取决于它们是否实际设置)。

配置通道策略

除了在创建时指定目标通道外,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:
            # 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']

现在,每当通知的重要性设置为“高”时,它将使用 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('[email protected]'));

        // ...
    }
}

自定义通知

您可以扩展 NotificationRecipient 基类以自定义其行为。例如,您可以覆盖 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'];
    }
}

自定义通知消息

每个通道都有自己的通知接口,您可以实现该接口以自定义通知消息。例如,如果您想根据聊天服务修改消息,请实现 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
    {
        // Add a custom subject and emoji if the message is sent to Slack
        if ('slack' === $transport) {
            $this->subject('You\'re invoiced '.strval($this->price).' EUR.');
            $this->emoji("money");
            return ChatMessage::fromNotification($this);
        }

        // If you return null, the Notifier will create the ChatMessage
        // based on this notification as it would without this method.
        return null;
    }
}

SmsNotificationInterfaceEmailNotificationInterfacePushNotificationInterfaceDesktopNotificationInterface 也存在,用于修改发送到这些通道的消息。

自定义浏览器通知 (Flash 消息)

浏览器通道通知的默认行为是添加一个 flash message,其键为 notification

但是,您可能更喜欢将通知的重要性级别映射到 flash message 的类型,以便您可以调整其样式。

您可以通过使用您自己的 FlashMessageImportanceMapperInterface 实现来覆盖默认的 notifier.flash_message_importance_mapper 服务,您可以在其中提供您自己的“重要性”到“警报级别”的映射。

Symfony 当前为 Bootstrap 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 仅在 dev(和/或 test)环境中对所有配置的 texter 和 chatter 传输方式使用 NullTransport 来实现此目的

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

使用事件

Notifier 组件的 Transport 类允许您通过事件选择性地挂钩到生命周期中。

MessageEvent 事件

典型用途:在消息发送之前执行某些操作(例如记录将要发送的消息,或显示有关要执行的事件的信息)。

就在发送消息之前,会调度事件类 MessageEvent。侦听器接收 MessageEvent 事件

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

$dispatcher->addListener(MessageEvent::class, function (MessageEvent $event): void {
    // gets the message instance
    $message = $event->getMessage();

    // log something
    $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): void {
    // gets the message instance
    $message = $event->getMessage();

    // gets the error instance
    $error = $event->getError();

    // log something
    $this->logger(sprintf('The message with subject: %s has not been sent successfully. The error is: %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): void {
    // gets the message instance
    $message = $event->getMessage();

    // log something
    $this->logger(sprintf('The message has been successfully sent and has id: %s', $message->getMessageId()));
});
这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可获得许可。
目录
    版本