创建和发送通知
安装
当前 Web 应用程序使用许多不同的通道向用户发送消息(例如 SMS、Slack 消息、电子邮件、推送通知等)。Symfony 中的 Notifier 组件是对所有这些通道的抽象。它提供了一种动态方式来管理消息的发送方式。使用以下命令安装 Notifier
1
$ composer require symfony/notifier
通道
通道是指可以传递通知的不同媒介。这些通道包括电子邮件、SMS、聊天服务、推送通知等。每个通道都可以通过使用传输与不同的提供商(例如 Slack 或 Twilio SMS)集成。
Notifier 组件支持以下通道
- SMS 通道 通过 SMS 消息向手机发送通知;
- 聊天通道 向 Slack 和 Telegram 等聊天服务发送通知;
- 电子邮件通道 集成了 Symfony Mailer;
- 浏览器通道使用 flash 消息。
- 推送通道 通过推送通知向手机和浏览器发送通知。
- 桌面通道 在同一主机上显示桌面通知。
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-notifierDSN: forty-six-elks://API_USERNAME:API_PASSWORD@default?from=FROMWebhook 支持: 否 |
| AllMySms | 安装: composer require symfony/all-my-sms-notifierDSN: allmysms://LOGIN:APIKEY@default?from=FROMWebhook 支持: 否 |
| AmazonSns | 安装: composer require symfony/amazon-sns-notifierDSN: sns://ACCESS_KEY:SECRET_KEY@default?region=REGIONWebhook 支持: 否 |
| Bandwidth | 安装: composer require symfony/bandwidth-notifierDSN: bandwidth://USERNAME:PASSWORD@default?from=FROM&account_id=ACCOUNT_ID&application_id=APPLICATION_ID&priority=PRIORITYWebhook 支持: 否 |
| Brevo | 安装: composer require symfony/brevo-notifierDSN: brevo://API_KEY@default?sender=SENDERWebhook 支持: 否 |
| Clickatell | 安装: composer require symfony/clickatell-notifierDSN: clickatell://ACCESS_TOKEN@default?from=FROMWebhook 支持: 否 |
| ContactEveryone | 安装: composer require symfony/contact-everyone-notifierDSN: contact-everyone://TOKEN@default?&diffusionname=DIFFUSION_NAME&category=CATEGORYWebhook 支持: 否 |
| Esendex | 安装: composer require symfony/esendex-notifierDSN: esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROMWebhook 支持: 否 |
| FakeSms | 安装: composer require symfony/fake-sms-notifierDSN: fakesms+email://MAILER_SERVICE_ID?to=TO&from=FROM 或 fakesms+logger://defaultWebhook 支持: 否 |
| FreeMobile | 安装: composer require symfony/free-mobile-notifierDSN: freemobile://LOGIN:API_KEY@default?phone=PHONEWebhook 支持: 否 |
| GatewayApi | 安装: composer require symfony/gateway-api-notifierDSN: gatewayapi://TOKEN@default?from=FROMWebhook 支持: 否 |
| GoIP | 安装: composer require symfony/go-ip-notifierDSN: goip://USERNAME:PASSWORD@HOST:80?sim_slot=SIM_SLOTWebhook 支持: 否 |
| Infobip | 安装: composer require symfony/infobip-notifierDSN: infobip://AUTH_TOKEN@HOST?from=FROMWebhook 支持: 否 |
| Iqsms | 安装: composer require symfony/iqsms-notifierDSN: iqsms://LOGIN:PASSWORD@default?from=FROMWebhook 支持: 否 |
| iSendPro | 安装: composer require symfony/isendpro-notifierDSN: isendpro://ACCOUNT_KEY_ID@default?from=FROM&no_stop=NO_STOP&sandbox=SANDBOXWebhook 支持: 否 |
| KazInfoTeh | 安装: composer require symfony/kaz-info-teh-notifierDSN: kaz-info-teh://USERNAME:PASSWORD@default?sender=FROMWebhook 支持: 否 |
| LightSms | 安装: composer require symfony/light-sms-notifierDSN: lightsms://LOGIN:TOKEN@default?from=PHONEWebhook 支持: 否 |
| LOX24 | 安装: composer require symfony/lox24-notifierDSN: lox24://USER:TOKEN@default?from=FROMWebhook 支持: 否 |
| Mailjet | 安装: composer require symfony/mailjet-notifierDSN: mailjet://TOKEN@default?from=FROMWebhook 支持: 否 |
| MessageBird | 安装: composer require symfony/message-bird-notifierDSN: messagebird://TOKEN@default?from=FROMWebhook 支持: 否 |
| MessageMedia | 安装: composer require symfony/message-media-notifierDSN: messagemedia://API_KEY:API_SECRET@default?from=FROMWebhook 支持: 否 |
| Mobyt | 安装: composer require symfony/mobyt-notifierDSN: mobyt://USER_KEY:ACCESS_TOKEN@default?from=FROMWebhook 支持: 否 |
| Nexmo | 安装: composer require symfony/nexmo-notifier已废弃,推荐使用 Vonage(见下文) |
| Octopush | 安装: composer require symfony/octopush-notifierDSN: octopush://USERLOGIN:APIKEY@default?from=FROM&type=TYPEWebhook 支持: 否 |
| OrangeSms | 安装: composer require symfony/orange-sms-notifierDSN: orange-sms://CLIENT_ID:CLIENT_SECRET@default?from=FROM&sender_name=SENDER_NAMEWebhook 支持: 否 |
| OvhCloud | 安装: composer require symfony/ovh-cloud-notifierDSN: ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAMEWebhook 支持: 否 |
| Plivo | 安装: composer require symfony/plivo-notifierDSN: plivo://AUTH_ID:AUTH_TOKEN@default?from=FROMWebhook 支持: 否 |
| Primotexto | 安装: composer require symfony/primotexto-notifierDSN: primotexto://API_KEY@default?from=FROMWebhook 支持: 否 |
| Redlink | 安装: composer require symfony/redlink-notifierDSN: redlink://API_KEY:APP_KEY@default?from=SENDER_NAME&version=API_VERSIONWebhook 支持: 否 |
| RingCentral | 安装: composer require symfony/ring-central-notifierDSN: ringcentral://API_TOKEN@default?from=FROMWebhook 支持: 否 |
| Sendberry | 安装: composer require symfony/sendberry-notifierDSN: sendberry://USERNAME:PASSWORD@default?auth_key=AUTH_KEY&from=FROMWebhook 支持: 否 |
| Sendinblue | 安装: composer require symfony/sendinblue-notifierDSN: sendinblue://API_KEY@default?sender=PHONEWebhook 支持: 否 |
| Sms77 | 安装: composer require symfony/sms77-notifierDSN: sms77://API_KEY@default?from=FROMWebhook 支持: 否 |
| SimpleTextin | 安装: composer require symfony/simple-textin-notifierDSN: simpletextin://API_KEY@default?from=FROMWebhook 支持: 否 |
| Sinch | 安装: composer require symfony/sinch-notifierDSN: sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROMWebhook 支持: 否 |
| Sipgate | 安装: composer require symfony/sipgate-notifierDSN: sipgate://TOKEN_ID:TOKEN@default?senderId=SENDER_IDWebhook 支持: 否 |
| SmsSluzba | 安装: composer require symfony/sms-sluzba-notifierDSN: sms-sluzba://USERNAME:PASSWORD@defaultWebhook 支持: 否 |
| Smsapi | 安装: composer require symfony/smsapi-notifierDSN: smsapi://TOKEN@default?from=FROMWebhook 支持: 否 |
| Smsbox | 安装: composer require symfony/smsbox-notifierDSN: smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDERWebhook 支持: 否 |
| SmsBiuras | 安装: composer require symfony/sms-biuras-notifierDSN: smsbiuras://UID:API_KEY@default?from=FROM&test_mode=0Webhook 支持: 否 |
| Smsc | 安装: composer require symfony/smsc-notifierDSN: smsc://LOGIN:PASSWORD@default?from=FROMWebhook 支持: 否 |
| SMSense | 安装: composer require smsense-notifierDSN: smsense://API_TOKEN@default?from=FROMWebhook 支持: 否 |
| SMSFactor | 安装: composer require symfony/sms-factor-notifierDSN: sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPEWebhook 支持: 否 |
| SpotHit | 安装: composer require symfony/spot-hit-notifierDSN: spothit://TOKEN@default?from=FROMWebhook 支持: 否 |
| Sweego | 安装: composer require symfony/sweego-notifierDSN: sweego://API_KEY@default?region=REGION&campaign_type=CAMPAIGN_TYPEWebhook 支持: 是 |
| Telnyx | 安装: composer require symfony/telnyx-notifierDSN: telnyx://API_KEY@default?from=FROM&messaging_profile_id=MESSAGING_PROFILE_IDWebhook 支持: 否 |
| TurboSms | 安装: composer require symfony/turbo-sms-notifierDSN: turbosms://AUTH_TOKEN@default?from=FROMWebhook 支持: 否 |
| Twilio | 安装: composer require symfony/twilio-notifierDSN: twilio://SID:TOKEN@default?from=FROMWebhook 支持: 是 |
| Unifonic | 安装: composer require symfony/unifonic-notifierDSN: unifonic://APP_SID@default?from=FROMWebhook 支持: 否 |
| Vonage | 安装: composer require symfony/vonage-notifierDSN: vonage://KEY:SECRET@default?from=FROMWebhook 支持: 是 |
| Yunpian | 安装: composer require symfony/yunpian-notifierDSN: yunpian://APIKEY@defaultWebhook 支持: 否 |
提示
使用 Symfony 配置 secrets 安全地存储您的 API 令牌。
提示
一些第三方传输,当使用 API 时,支持通过 Webhook 进行状态回调。有关更多详细信息,请参阅 Webhook 文档。
7.1
Smsbox、SmsSluzba、SMSense、LOX24 和 Unifonic 集成在 Symfony 7.1 中引入。
7.2
Primotexto、Sipgate 和 Sweego 集成在 Symfony 7.2 中引入。
要启用 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=FROM 或 fakechat+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 |
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 |
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: 'notifications@example.com'
推送通道
警告
如果任何 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,安装该软件包也将创建必要的环境变量和配置。否则,您需要手动添加以下内容
- 在您的
.env文件中添加正确的 DSN
1 2
# .env
JOLINOTIF=jolinotif://default
- 更新 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('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'];
}
}
自定义通知消息
每个通道都有自己的通知接口,您可以实现该接口以自定义通知消息。例如,如果您想根据聊天服务修改消息,请实现 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;
}
}
SmsNotificationInterface、EmailNotificationInterface、PushNotificationInterface 和 DesktopNotificationInterface 也存在,用于修改发送到这些通道的消息。
自定义浏览器通知 (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()));
});