juhasev / laravel-ses
允许您在通过 Laravel 和 Amazon SES 发送电子邮件时跟踪打开、投递、退回、投诉和点击链接
Requires
- php: ^8.2
- aws/aws-php-sns-message-validator: ^1.7
- aws/aws-sdk-php: ^3.288.0
- guzzlehttp/guzzle: ^7.8.1
- illuminate/contracts: ^11.0
- nyholm/psr7: ^1.0
- paquettg/php-html-parser: ^3.1
- ramsey/uuid: ^4.3
- symfony/psr-http-message-bridge: ^7.0
Requires (Dev)
- ext-json: *
- mockery/mockery: ^1.0
- nunomaduro/collision: ^8.1
- orchestra/testbench: ^9.0
- phpunit/phpunit: ^10.5.0
- vimeo/psalm: ^5.25
- dev-master
- v5.0.0
- 4.2.1
- v4.2.0
- v4.1.0
- 4.0.0
- v3.3.0
- 3.2.0
- 3.1.0
- v3.0.4
- v3.0.3
- 3.0.2
- v3.0.1
- v3.0.0
- 2.6.0
- 2.5.1
- 2.5.0
- v2.4.0
- 2.3.0
- 2.2.0
- 2.1.0
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- v2.0.0
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.0
- v0.8.4
- v0.8.3
- v0.8.2
- v0.8.1
- v0.8.0
- v0.7.1
- v0.7.0
- v0.1.0
- dev-chore/laravel-11
- dev-fix/avoid-multiple-open-tracking
This package is auto-updated.
Last update: 2024-09-18 14:28:18 UTC
README
Laravel SES (AWS 简单电子邮件服务)
Laravel SES 是一个允许您获取通过 AWS SES(简单电子邮件服务)发送的电子邮件发送统计信息的包,包括投递、打开、退回、投诉和链接跟踪。此包最初由 Oliveready7 编写。不幸的是,原始作者已经停止维护此包,所以我决定创建这个分支,以便此包可以与当前的 Laravel 版本一起使用。最低要求是 PHP 7.3,Laravel 9 需要 PHP 8.x。
所有包都已更新到现代版本。我已经优化了原始的数据库存储以节省空间和适当的索引。此包与 Laravel 9.x 兼容。
Laravel SES 还支持 SMTP 错误代码,会抛出异常,例如当您超过速率限制时,您可以处理适当的退避。
Laravel 版本支持
- 如果您正在使用 Laravel 11,请使用
v5.*
- 如果您正在使用 Laravel 10,请使用
v4.*
- 如果您正在使用 Laravel 9,请使用
v3.*
- 如果您正在使用 Laravel 7 或 8,请使用
v1.1.5
- 如果您正在使用 Laravel 6,请使用
v0.8.4
安装
通过 composer 安装
composer require juhasev/laravel-ses composer require aws/aws-php-sns-message-validator (optional)
在 config/app.php 中确保加载服务提供者。这应该会自动完成。
Juhasev\LaravelSes\LaravelSesServiceProvider::class
Laravel 配置
确保您的 app/config/services.php 中有 SES 值已设置
'ses' => [ 'key' => your_ses_key, 'secret' => your_ses_secret, 'domain' => your_ses_domain, 'region' => your_ses_region ],
确保您的邮件驱动程序位于 app/config/mail.php 中,设置为 'ses'
'default' => env('MAIL_MAILER', 'ses')
发布公共资产
php artisan vendor:publish --tag=ses-assets --force
发布迁移
php artisan vendor:publish --tag=ses-migrations --force
发布包的配置(laravelses.php)
php artisan vendor:publish --tag=ses-config
路由
此包添加了 3 个公开路由到您的应用程序,AWS SNS 回调目标
/ses/notification/bounce
/ses/notification/complaint
/ses/notification/delivery
我们还添加了两个额外的公开路由来跟踪打开和链接点击
/ses/beacon
/ses/link
配置选项
- aws_sns_validator - 包是否使用 AWS 的 SNS 验证器来验证传入的 SNS 请求。默认 = false
- debug - 调试模式,记录所有 SNS 回调请求
https://github.com/aws/aws-php-sns-message-validator
AWS 配置
预阅读
如果您是首次使用 SES 通知,本文是一个很好的起点
https://docs.aws.amazon.com/sns/latest/dg/sns-http-https-endpoint-as-subscriber.html
IAM 用户和策略
您的应用程序 IAM 用户需要通过 SES 发送电子邮件并订阅 SNS 通知。这可以通过 AWS 控制面板完成,如上文章所述,或者使用以下 AWS CloudFormation 模板
AWS CloudFormation 策略示例
ApplicationSNSPolicy:
Type: "AWS::IAM::ManagedPolicy"
Properties:
Description: "Policy for sending subscribing to SNS bounce notifications"
Path: "/"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- sns:CreateTopic
- sns:DeleteTopic
- sns:Subscribe
- sns:Unsubscribe
Resource:
- 'arn:aws:sns:*'
ApplicationSESPolicy:
Type: "AWS::IAM::ManagedPolicy"
Properties:
Description: "Policy for creating SES bounce notification"
Path: "/"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ses:*
Resource:
- '*'
策略定义后,需要将其添加到配置的 IAM 用户。
# AWS PHP API User
APIUser:
Type: "AWS::IAM::User"
Properties:
ManagedPolicyArns:
- !Ref ApplicationSNSPolicy
- !Ref ApplicationSESPolicy
UserName: staging-user
运行设置
确保在您的 APP_URL(在 .env 中)设置正确,与您的发送域名匹配。如果您为多个域名发送电子邮件(即多租户应用程序),则可以使用此命令设置多个域名。
在继续之前,您需要准备好 SES 域
设置命令自动配置您的 SES 域以发送触发对您的 Laravel 应用程序进行回调的 SNS 通知。
php artisan sns:setup mydomain.com
注意:您不应尝试使用子域名 client.mydomain.com,目前 AWS 不支持此功能。
用法
要发送启用所有跟踪的电子邮件
SesMail::enableAllTracking() ->to('hello@example.com') ->send(new Mailable);
调用 enableAllTracking() 启用打开、拒绝、退回、投递、投诉和链接跟踪。
请注意,如果您在开启Open -tracking时尝试发送包含多个收件人的Mailable,将会抛出LaravelSesTooManyRecipients异常。
其他抛出的异常还包括
LaravelSesDailyQuotaExceededException::class LaravelSesInvalidSenderAddressException::class LaravelSesMaximumSendingRateExceeded::class LaravelSesSendFailedException::class LaravelSesTemporaryServiceFailureException::class LaravelSesTooManyRecipientsException::class
您可以使用基类来捕获所有这些异常
try { SesMail::enableAllTracking() ->to('hello@example.com') ->send(new Mailable); } catch (LaravelSesMaximumSendingRateExceeded $e) { // Implement back off logic } catch (LaravelSesException $e) { $smtpCode = $e->getCode(); $smtpErrorMessage = $e->getMessage(); // Do something like back of if rate limit is reached. ) You can, of course, disable and enable all the tracking options ```php SesMail::disableAllTracking(); SesMail::disableOpenTracking(); SesMail::disableLinkTracking(); SesMail::disableBounceTracking(); SesMail::disableComplaintTracking(); SesMail::disableDeliveryTracking(); SesMail::enableAllTracking(); SesMail::enableOpenTracking(); SesMail::enableLinkTracking(); SesMail::enableBounceTracking(); SesMail::enableComplaintTracking(); SesMail::enableDeliveryTracking();
批量选项让您有机会将邮件分组,这样您就可以获取特定组的统计结果
SesMail::enableAllTracking() ->setBatch('welcome_emails') ->to('hello@example.com') ->send(new Mailable);
您还可以获取汇总统计数据
Stats::statsForEmail($email); $stats = Stats::statsForBatch('welcome_emails'); print_r($stats)
[
"sent" => 8,
"deliveries" => 7,
"opens" => 4,
"bounces" => 1,
"complaints" => 2,
"clicks" => 3,
"link_popularity" => [
"https://welcome.page" => [
"clicks" => 3
],
"https://facebook.com/brand" => [
"clicks" => 1
]
]
]
要通过仓库获取单个统计信息
EmailStatRepository::getBouncedCount($email); EmailRepository::getBounces($email); BatchStatRepository::getBouncedCount($batch); BatchStatRepository::getDeliveredCount($batch); BatchStatRepository::getComplaintsCount($batch);
您还可以直接使用模型,就像使用任何其他Eloquent模型一样
$sentEmails = SentEmail::whereEmail($email)->get(); $emailBounces = EmailBounce::whereEmail($email)->get(); $emailComplaints = EmailComplaint::whereEmail($email)->get(); $emailLink = EmailLink::whereEmail($email)->get(); $emailOpen = EmailOpen::whereEmail($email)->get();
如果您正在使用自定义模型,则可以使用ModelResolver()助手,如下所示
$sentEmail = ModelResolver::get('SentEmail')::take(100)->get();
监听事件
可以创建事件订阅者
<?php namespace App\Listeners; use App\Actions\ProcessSesEvent; use Juhasev\LaravelSes\Factories\Events\SesBounceEvent; use Juhasev\LaravelSes\Factories\Events\SesComplaintEvent; use Juhasev\LaravelSes\Factories\Events\SesDeliveryEvent; use Juhasev\LaravelSes\Factories\Events\SesOpenEvent; use Juhasev\LaravelSes\Factories\Events\SesSentEvent; class SesSentEventSubscriber { /** * Subscribe to events * * @param $events */ public function subscribe($events) { $events->listen(SesBounceEvent::class, SesSentEventSubscriber::class . '@bounce'); $events->listen(SesComplaintEvent::class, SesSentEventSubscriber::class . '@complaint'); $events->listen(SesDeliveryEvent::class,SesSentEventSubscriber::class . '@delivery'); $events->listen(SesOpenEvent::class, SesSentEventSubscriber::class . '@open'); $events->listen(SesLinkEvent::class, SesSentEventSubscriber::class . '@link'); } /** * SES bounce event took place * * @param SesBounceEvent $event */ public function bounce(SesBounceEvent $event) { // Do something } /** * SES complaint event took place * * @param SesComplaintEvent $event */ public function complaint(SesComplaintEvent $event) { // Do something } /** * SES delivery event took place * * @param SesDeliveryEvent $event */ public function delivery(SesDeliveryEvent $event) { // Do something } /** * SES Open open event took place * * @param SesOpenEvent $event */ public function open(SesOpenEvent $event) { // Do something } /** * SES Open link event took place * * @param SesLinkEvent $event */ public function link(SesLinkEvent $event) { // Do something } }
为了使其工作,您需要在Laravel App/Providers/EventServiveProvider.php中注册EventSubscriber。
protected $subscribe = [ SesSentEventSubscriber::class ];
示例事件数据
print_r($event->data);
(
[id] => 22
[sent_email_id] => 49
[type] => Permanent
[bounced_at] => 2020-04-03 19:42:31
[sent_email] => Array
(
[id] => 49
[message_id] => 31b530dce8e2a282d12e5627e7109580@localhost
[email] => bounce@simulator.amazonses.com
[batch_id] => 7
[sent_at] => 2020-04-03 19:42:31
[delivered_at] =>
[batch] => Array
(
[id] => 7
[name] => fa04cbf2c2:Project:268
[created_at] => 2020-04-03 17:03:23
[updated_at] => 2020-04-03 17:03:23
)
)
)
)
术语
发送 = 尝试发送的邮件数量
投递 = 已成功投递的邮件数量
打开 = 已打开的邮件数量
投诉 = 将邮件放入垃圾箱的人数
点击 = 至少点击了您邮件中一个链接的人数
链接流行度 = 邮件中每个链接的唯一点击次数,按点击次数从多到少排序
开发
将Laravel SES仓库克隆到您的项目中的/packages目录下
git clone https://github.com/juhasev/laravel-ses.git
设置Composer.json以解决您的开发文件夹中的类
"autoload": { "psr-4": { "App\\": "app/", "Juhasev\\LaravelSes\\": "packages/juhasev/laravel-ses/src" } },
Composer require
require: { "juhasev/laravel-ses": "dev-master" }
或者运行require
composer require juhasev/laravel-ses:dev-master
要运行单元测试,请执行
phpunit