创建和发送通知
安装
当前 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-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=FROM 或 fakesms+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
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: '[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,安装该软件包也将创建必要的环境变量和配置。否则,您需要手动添加以下内容
- 在您的
.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('[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
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()));
});