akhan619 / laravel-ses-event-manager
一个用于通过 http/s 网络钩子管理接收到的 SES 邮件事件的 Laravel 扩展包。
Requires
- php: ^8.0
- aws/aws-php-sns-message-validator: ^1.6
- aws/aws-sdk-php: ^3.218
- illuminate/support: ^9.0|^10.0
- nyholm/psr7: ^1.0
- symfony/psr-http-message-bridge: ^2.0
Requires (Dev)
- mockery/mockery: ^1.5
- orchestra/testbench: ^7.0
- phpunit/phpunit: ^9.0
- sempro/phpunit-pretty-print: ^1.4
README
通过 http/s 协议管理接收到的 SES
邮件事件通知。本扩展包提供了使用 SES
发送正常和队列邮件所需的全部设置,然后处理 SES
发送到 http/s 网络钩子的邮件事件通知。这包括 SES
列出的所有 10 个事件,如 send
、bounce
、open
、click
等。提供了数据库和 eloquent 模型以存储事件数据。如果您不想使用扩展包提供的模型或想以不同的方式处理事件,请不要担心!本扩展包的每个部分都是为最终用户可修改而实现的。
本扩展包的功能
如前所述,本扩展包处理以下过程:
- 设置 webhook 路由以接收通知。
- 设置控制器以确认接收到的订阅确认。
- 设置控制器以将事件数据存储到数据库。
- 设置数据库表。
- 定义 eloquent 模型以表示要存储的数据。
- 发送/排队要跟踪的电子邮件。
本扩展包不做什么
扩展包不会执行上述内容之外的操作。因此,扩展包不会
- 创建 AWS 资源来实际设置事件通知,例如
- 配置集
- 事件目标
- SNS 主题
- SNS 订阅者
- 执行数据采集后的任务,如发送电子邮件的统计等。
如果您需要设置 AWS SES/SNS
资源,您可以查看扩展包 Laravel Ses Tracking。该扩展包提供了一个简单的 artisan 命令来设置您的 AWS
资源。当然,这完全是可选的,您也可以使用其他任何方法来设置所需资源。
完全披露:我是扩展包
Laravel Ses Tracking
的作者。
Laravel 和 PHP 版本
本扩展包是为 Laravel 9 和 Php 8 及以上版本编写的。
安装
通过 Composer
composer require akhan619/laravel-ses-event-manager
配置文件
您可以使用以下 artisan 命令发布配置文件
php artisan vendor:publish --provider="Akhan619\LaravelSesEventManager\LaravelSesEventManagerServiceProvider" --tag="lsem-config"
这将会在 config
文件夹中发布一个名为 laravel-ses-event-manager.php
的新配置文件。
迁移
要使用扩展包提供的 eloquent 模型,您必须使用以下 artisan 命令发布扩展包的数据库迁移
php artisan vendor:publish --provider="Akhan619\LaravelSesEventManager\LaravelSesEventManagerServiceProvider" --tag="lsem-migrations"
不要忘记运行迁移
php artisan migrate
本地开发
在本地开发期间测试本扩展包,您需要一种方法来实际提供 Laravel
项目,以便 AWS
可以发送事件通知。您可以通过多种方式实现这一点。一种方法是通过隧道服务。我在开发期间个人使用了 Expose by Beyond Code
。
完全披露:我并非由
Beyond Code
赞助。
要求
要开始使用本扩展包,假设您已经在 AWS
上完成了必要的设置。这意味着
- 配置集存在
- SNS 主题存在。
- 存在用于监听事件的的事件目标。
- 将用于的 webhooks(http/s)已订阅到 SNS 主题。
注意:您不需要确认SNS订阅。该软件包可以为您处理它们。如果您已经完成上述操作,可以前往
AWS
控制台重新发送确认通知,软件包将为您确认。
限制
由于软件包需要跟踪电子邮件事件,每个电子邮件的限制为一个收件人。因此,像cc
或bcc
这样的字段将不起作用并引发异常。这是因为即使有多个收件人,SES
也只会发送一个id。只有一个id
,就无法正确跟踪电子邮件事件。如果您需要将相同的电子邮件发送给多个收件人,请像下面这样循环遍历收件人:
foreach (['john@doe.com', 'jane@doe.com'] as $recipient) { SesMailer::to($recipient)->send($mailable); }
用法
该软件包提供了SesMailer
外观。该外观模仿Laravel的Mail
外观,因此可以使用它。为了成功接收和存储通知,您必须使用软件包提供的外观。这样我们就可以通过SES
提供的id跟踪电子邮件。
发送电子邮件
use Akhan619\LaravelSesEventManager\Facades\SesMailer; SesMailer::to('john@doe.com')->send($someMailable); // Or if the recipient in specified in the mailable then, SesMailer::send($someMailable);
排队电子邮件
要现在或稍后排队电子邮件,您必须将QueueForCustomMailer
特质添加到您的可邮寄类中。然后您可以在框架中排队邮件。
use Akhan619\LaravelSesEventManager\Traits\QueueForCustomMailer; class TestMailableWithTrait extends Mailable { use Queueable, SerializesModels, QueueForCustomMailer; ... } // Then, as before $testMailableWithTrait = new TestMailableWithTrait(); SesMailer::to('john@doe.com')->later(now()->addHours(12), $testMailableWithTrait);
模型
该软件包使用eloquent模型来存储发出的/传入的电子邮件状态。所有模型都在src/App/Models
目录下的Akhan619\LaravelSesEventManager\App\Models
命名空间中指定。主要模型是Email
模型,它提供了以下字段:
protected $fillable = [ 'message_id', // The Ses id returned by the call to sendRawEmail 'email', // The email recipient. 'name', // Recipient name if any. // Boolean fields to show the events that have been received for the email. 'has_send', 'has_rendering_failure', 'has_reject', 'has_delivery', 'has_bounce', 'has_complaint', 'has_delivery_delay', 'has_subscription', 'has_open', 'has_click' ];
对于上述每个字段,都有一个Eloquent关系,也已定义。这些关系是:
// Has Many clicks() opens() // Has One bounce() complaint() delivery() send() reject() renderingFailure() deliveryDelay() subscription()
因此,您可以像下面这样使用它们:
use Akhan619\LaravelSesEventManager\App\Models\Email; $email = Email::first(); if($mail->has_bounce) { echo 'Email has bounced'; } // Get the bounce data $bounce = $email->bounce;
给定SES
事件中出现的所有相关字段都可通过该事件的Eloquent模型访问。请参阅模型以获取更多详细信息。以下是一个EmailBounce
模型的示例数据:
protected $fillable = [ 'message_id', 'bounce_type', 'bounce_sub_type', 'feedback_id', 'action', 'status', 'diagnostic_code', 'reporting_mta', 'bounced_at', ];
自定义处理程序
如果您不想使用软件包提供的模型,可以通过为给定事件注册一个callback
来自定义处理事件。您需要在ServiceProvider
的boot
方法中调用ModelResolver
实例的extend
方法,并提供您的回调。该callback
将接收两个参数eventType
和data
。可能的值和它们接收的数据是:
例如,将以下内容添加到默认Laravel
项目中的AppServiceProvider
的boot
方法中。
use Akhan619\LaravelSesEventManager\Contracts\ModelResolverContract; public function boot(ModelResolverContract $resolver) { $resolver->extend('MessageSent', function($event, $data) { // Will echo the recipient email address. echo current($data->getOriginalMessage()->getTo())->getAddress(); }); } // OR public function boot() { $resolver = app()->make(ModelResolverContract::class); $resolver->extend('Bounce', function($event, $data) { // The bounce type echo $data->bounce->bounceType; }); }
配置
调试模式
您可以通过在配置文件中将调试设置为true
来将调试数据记录到默认记录器。
'debug' => false,
订阅确认
默认情况下,该软件包会自动确认传入的订阅确认。如果您不希望这种行为,您可以在配置文件中将confirm_subscription
设置为false
来禁用它。
'confirm_subscription' => true,
凭证
用于SES
的凭证将来自.env
文件。如果您希望使用不同的凭证集,您可以在配置文件中的ses_options
键中指定它们。
'ses_options' => [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ... ],
配置集/选项
发送电子邮件以跟踪时必须使用的配置集必须在.env
中指定。
CONFIGURATION_SET_NAME=<Enter the name here>
如果您愿意,您还可以在配置文件中指定它,并在配置文件中的ses_options
键下指定任何其他选项。
'ses_options' => [ ... 'options' => [ 'ConfigurationSetName' => env('CONFIGURATION_SET_NAME'), <Other options here as key-value pairs> ], ],
事件
您可以使用配置文件中的active_email_events
键指定要监听的通知。将事件设置为true
以启用事件。
'active_email_events' => [ 'sends' => true, 'rendering_failures' => false, 'rejects' => false, 'deliveries' => true, 'bounces' => true, 'complaints' => false, 'delivery_delays' => true, 'subscriptions' => true, 'opens' => false, 'clicks' => false, ],
Webhook路由
您必须指定要监听的路径,以便生成控制器和命名路由。您可以使用以下方式在配置文件中指定它们:
'named_route_prefix' => 'lsem', 'route_prefix' => 'email/notification', 'routes' => [ 'sends' => 'sends', 'rendering_failures' => 'rendering-failures', 'rejects' => 'rejects', 'deliveries' => 'deliveries', 'bounces' => 'bounces', 'complaints' => 'complaints', 'delivery_delays' => 'delivery-delays', 'subscriptions' => 'subscriptions', 'opens' => 'opens', 'clicks' => 'clicks', ],
例如,在一个新的 Laravel
项目中,delivery_delays
的路由会被生成如下
Route_Key Route_Value 'delivery_delays' => 'delivery-delays', URL: APP_URL/route_prefix/Route_Value NAME: named_route_prefix.Route_Key Example: URL: https:///email/notification/delivery-delays NAME: lsem.delivery_delays
注意:只有在启用相应事件时才会注册路由。
您可以在 route_middleware
数组中指定任何应使用的中间件。
'route_middleware' => [],
数据库
请确保您已发布迁移文件并运行 php artisan migrate
。默认情况下,表名生成如下
lsem_****
Example:
lsem_emails
lsem_email_sends
...
如果由于某种原因,表名与现有表冲突,您可以通过在配置文件中使用 database_name_prefix
键来更改表前缀。
'database_name_prefix' => 'lsem',
禁用 Webhook
如果出于某种原因,您不想让包监听传入的通知,您可以通过在配置文件中将 handle_email_events
设置为 false
来禁用所有路由。
'handle_email_events' => true,
这将禁用所有已注册的路由并部分禁用该包。
注意:这将不会禁用发送电子邮件。因此,如果您已在代码中使用了
SesMailer
门面发送电子邮件,它将继续工作。
变更日志
有关最近更改的更多信息,请参阅变更日志。
测试
使用以下命令运行测试:
composer test
贡献
有关详细信息及待办事项列表,请参阅contributing.md。
安全性
如果您发现任何与安全相关的问题,请通过电子邮件amankhan.mailbox@gmail.com联系,而不是使用问题跟踪器。
致谢
- Aman Khan
许可证
MIT。有关更多信息,请参阅许可证文件。