jcabanillas / yii2-notifications
Yii2 通知模块
Requires
- php: >=7.1
- minishlink/web-push: *
- yiisoft/yii2: ~2.0.13
This package is auto-updated.
Last update: 2024-09-09 09:22:50 UTC
README
本模块提供了一种在多种交付渠道(包括邮件、屏幕、SMS(通过Nexmo)等)发送通知的方法。通知也可以存储在数据库中,以便在您的Web界面中显示。
通知是简短的消息,用于通知用户应用程序中发生的事情。例如,如果您正在编写一个计费应用程序,您可能会通过电子邮件和短信渠道向用户发送“发票已支付”的通知。
要求
-
PHP 7.1+
- gmp
- mbstring
- curl
- openssl
-
推荐使用 PHP 7.2+ 以获得更好的性能。
安装
安装此扩展的首选方法是通过 composer。
运行以下命令
php composer.phar require --prefer-dist jcabanillas/yii2-notifications "*"
或
"jcabanillas/yii2-notifications": "*"
将以下内容添加到您的 composer.json
文件的 require 部分。
使用
通知通常用作应用程序模块,并像以下示例那样在应用程序配置中进行配置
[ 'modules' => [ 'notifications' => [ 'class' => 'jcabanillas\notifications\Module', 'channels' => [ 'screen' => [ 'class' => 'jcabanillas\notifications\channels\ScreenChannel', ], 'email' => [ 'class' => 'jcabanillas\notifications\channels\EmailChannel', 'message' => [ 'from' => 'example@email.com' ], ], 'web' => [ 'class' => 'jcabanillas\notifications\channels\WebChannel', 'enable' => true, // OPTIONAL (default: true) enable/disable web channel 'config' => [ 'serviceWorkerFilepath' => '/service-worker.js', // OPTIONAL (default: /service-worker.js) is the service worker filename 'serviceWorkerScope' => '/app', // OPTIONAL (default: './' the service worker path) the scope of the service worker: https://developers.google.com/web/ilt/pwa/introduction-to-service-worker#registration_and_scope 'serviceWorkerUrl' => 'url-to-serviceworker', // OPTIONAL (default: Url::to(['/notifications/web-push-notification/service-worker'])) 'subscribeUrl' => 'url-to-subscribe-handler', // OPTIONAL (default: Url::to(['/notifications/web-push-notification/subscribe'])) 'unsubscribeUrl' => 'url-to-unsubscribe-handler', // OPTIONAL (default: Url::to(['/notifications/web-push-notification/unsubscribe'])) 'subscribeLabel' => 'subscribe button label', // OPTIONAL (default: 'Subscribe') 'unsubscribeLabel' => 'subscribe button label', // OPTIONAL (default: 'Unsubscribe') ], 'auth' => [ 'VAPID' => [ 'subject' => 'mailto:me@website.com', // can be a mailto: or your website address 'publicKey' => '~88 chars', // (recommended) uncompressed public key P-256 encoded in Base64-URL 'privateKey' => '~44 chars', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL 'pemFile' => 'path/to/pem', // if you have a PEM file and can link to it on your filesystem 'pem' => 'pemFileContent', // if you have a PEM file and want to hardcode its content 'reuseVAPIDHeaders' => true // OPTIONAL (default: true) you can reuse the same JWT token them for the same flush session to boost performance using ], ], ], ], ], ], ];
要启用Web推送通知,浏览器需要验证您的身份。VAPID标准可以用于所有浏览器验证应用程序。您需要为您的服务器创建并提供公钥和私钥。这些密钥必须安全存储,且不应更改。
如果您想禁用Web推送通知,只需将标志 'notifications.web.enable' 设置为 false。
要在Linux bash中生成未压缩的公钥和私钥,编码为Base64,请输入以下内容
$ openssl ecparam -genkey -name prime256v1 -out private_key.pem
$ openssl ec -in private_key.pem -pubout -outform DER|tail -c 65|base64|tr -d '=' |tr '/+' '_-' >> public_key.txt
$ openssl ec -in private_key.pem -outform DER|tail -c +8|head -c 32|base64|tr -d '=' |tr '/+' '_-' >> private_key.txt
或者您可以使用模块中提供的方法
\Minishlink\WebPush\VAPID::createVapidKeys();
创建通知
每个通知由一个单独的类表示(通常存储在app/notifications目录中)。
namespace app\notifications; use Yii; use jcabanillas\notifications\Notification; class AccountNotification extends Notification { const KEY_NEW_ACCOUNT = 'new_account'; const KEY_RESET_PASSWORD = 'reset_password'; /** * @var \yii\web\User the user object */ public $user; /** * @inheritdoc */ public function getTitle(){ switch($this->key){ case self::KEY_NEW_ACCOUNT: return Yii::t('app', 'New account {user} created', ['user' => '#'.$this->user->id]); case self::KEY_RESET_PASSWORD: return Yii::t('app', 'Instructions to reset the password'); } } /** * @inheritdoc */ public function getRoute(){ return ['/users/edit', 'id' => $this->user->id]; } }
发送通知
创建通知后,您可以按以下方式发送它
$user = User::findOne(123); AccountNotification::create(AccountNotification::KEY_RESET_PASSWORD, ['user' => $user])->send();
指定交付渠道
每个通知类都有一个 shouldSend($channel) 方法,用于确定通知将在哪些类型和渠道上交付。在此示例中,通知将在除了“屏幕”或带有“new_account”键之外的任何渠道上交付。
/** * Get the notification's delivery channels. * @return boolean */ public function shouldSend($channel) { if($channel->id == 'screen'){ if(!in_array($this->key, [self::KEY_NEW_ACCOUNT])){ return false; } } return parent::shouldSend($channel); }
可以通过通知的 renotification_time
属性限制发送给用户的相同键/用户通知的数量。只有在指定的时间段内没有发送过具有相同用户/键的其他通知时,才会发送新通知。renotification_time
必须是 DateInterval::__constructor() 接受的字符串。
// For example to limit to 1 notification per hour $notification = AccountNotification::create(AccountNotification::KEY_RESET_PASSWORD, ['user' => $user]); $notification->renotification_time = 'PT1H'; $notification->send();
指定特定渠道的发送
每个渠道都有一个接收通知实例并定义该渠道发送通知方式的发送方法。但是,您可以通过在通知类中定义 toMail ("to" + [Channel ID]) 来覆盖发送方法。以下示例演示了如何这样做
/** * Override send to email channel * * @param $channel the email channel * @return void */ public function toEmail($channel){ switch($this->key){ case self::KEY_NEW_ACCOUNT: $subject = 'Welcome to MySite'; $template = 'newAccount'; break; case self::KEY_RESET_PASSWORD: $subject = 'Password reset for MySite'; $template = 'resetPassword'; break; } $message = $channel->mailer->compose($template, [ 'user' => $this->user, 'notification' => $this, ]); Yii::configure($message, $channel->message); $message->setTo($this->user->email); $message->setSubject($subject); $message->send($channel->mailer); }
自定义渠道
本模块提供了一些预构建的渠道,但您可能需要编写自己的渠道来发送通知。为此,您需要定义一个包含发送方法的类
namespace app\channels; use jcabanillas\notifications\Channel; use jcabanillas\notifications\Notification; class VoiceChannel extends Channel { /** * Send the given notification. * * @param Notification $notification * @return void */ public function send(Notification $notification) { // use $notification->getTitle() ou $notification->getDescription(); // Send your notification in this channel... } }
您还应在您的应用程序配置中配置渠道
[ 'modules' => [ 'notifications' => [ 'class' => 'jcabanillas\notifications\Module', 'channels' => [ 'voice' => [ 'class' => 'app\channels\VoiceChannel', ], //... ], ], ], ]
屏幕渠道
此通道用于显示如图像预览所示的小通知。通知将存储在数据库中,因此在使用此通道之前,您必须运行其迁移脚本
./yii migrate/up --migrationPath=vendor/jcabanillas/yii2-notifications/migrations/
因此您可以在应用程序布局中调用通知小部件来显示生成的通知
<div class="header"> ... <?php echo \jcabanillas\notifications\widgets\Notifications::widget() ?> </div>
Web 推送通知通道
此通道用于向订阅者发送 Web 推送通知。每个通知订阅都将存储在数据库中,因此在使用此通道之前,您必须运行其迁移脚本
./yii migrate/up --migrationPath=vendor/jcabanillas/yii2-notifications/migrations/
因此您可以在应用程序布局中调用通知小部件来显示生成的通知
<div> <?php echo \jcabanillas\notifications\widgets\WebNotifications::widget() ?> </div>
您可以按照以下方式自定义小部件的 HTML 模板。将模板设置为 false 将隐藏所有小部件 HTML,并且浏览器将提示用户允许通知。如果您自定义了 HTML 模板,请记住包括一个具有 id 'js-web-push-subscribe-button' 的按钮
<div> <?= \jcabanillas\notifications\widgets\WebNotifications::widget([ 'template' => '... <button id="js-web-push-subscribe-button" disabled="disabled"></button> ...' ]) ?> </div>
请记住,将 service-worker.js 文件放置在 Web 根目录中,以便在 WebNotifications 小部件初始化时提供服务工作者。