jdavidbakr / mail-tracker
记录并跟踪Laravel发送的所有邮件
Requires
- php: ^8.1
- aws/aws-php-sns-message-validator: ^1.8
- aws/aws-sdk-php: ^3.258
- guzzlehttp/guzzle: ^7.2
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- mockery/mockery: ^1.4.4
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^9.5.10|^10.5
Suggests
- fedeisas/laravel-mail-css-inliner: Automatically inlines CSS into all outgoing mail.
- dev-master
- 7.16
- 7.15
- 7.14
- 7.13
- 7.12
- 7.11
- 7.10
- 7.9
- 7.8
- 7.7
- 7.6
- 7.5
- 7.4
- 7.3
- 7.2
- 7.1
- 7.0
- 6.0.11
- 6.0.10
- 6.0.9
- 6.0.8
- 6.0.7
- 6.0.6
- 6.0.5
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0
- 5.x-dev
- 5.0.9
- 5.0.8
- 5.0.7
- 5.0.6
- 5.0.5
- 5.0.4
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.0.11
- 4.0.10
- 4.0.9
- 4.0.8
- 4.0.7
- 4.0.6
- 4.0.5
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- v3.x-dev
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.2.2
- 2.2.1
- 2.2
- 2.1.26
- 2.1.25
- 2.1.24
- 2.1.23
- 2.1.22
- 2.1.21
- 2.1.20
- 2.1.19
- 2.1.18
- 2.1.17
- 2.1.16
- 2.1.15
- 2.1.14
- 2.1.13
- 2.1.12
- 2.1.11
- 2.1.10
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0
- dev-github-desktop-laravel-shift/l10-compatibility
- dev-fixing-travis
- dev-release/2.0
This package is auto-updated.
Last update: 2024-09-11 13:15:07 UTC
README
MailTracker会将钩子插入Laravel发送的所有邮件中,并向其中注入跟踪代码。它还会将渲染的邮件存储到数据库中。还有一个界面可以查看已发送的邮件。
注意:如果您正在使用Laravel 9.x,则必须使用版本9.6.0或更高版本。
从4.x升级到5.x
在4.x及之前版本中,发送电子邮件表中有一个存储RFC标准电子邮件格式的recipient
列<Name> email@example.com
。5.x已更新为分别存储名称和电子邮件。已从sent_emails
表迁移中删除了recipient
和sender
列,但没有添加迁移来删除这些列。已添加访问器以保留模型的recipient
和sender
属性,因此除非您专门查询sender
或recipient
列,否则不需要更新任何当前使用这些属性的代码。
要保留升级后的现有数据,请运行artisan命令mail-tracker:migrate-recipients
。这将把现有的recipient
和sender
数据转换为新的格式。在此之后,您可以删除recipient
和sender
列。
在sent_emails
表中还有一对新的属性:opened_at
和clicked_at
。分别存储用户首次打开和点击的时间。这已被添加到默认的跟踪索引页。您可以将它添加到您的页面上,或者根据您的需要使用这些值。
从3.x升级到4.x
从3.x到4.x没有破坏性更改,除了4.x仅适用于Laravel 7+。
从2.x升级到3.x
与版本3.0的更新相比,有一个破坏性更改,特别是关于触发的事件。如果您正在监听PermanentBouncedMessageEvent
以捕获所有不可投递的邮件,现在有两个单独的事件:PermanentBouncedMessageEvent
将仅在永久退回时触发,而新的ComplaintMessageEvent
将在投诉时触发。还有一个新的EmailDeliveredEvent
事件将在每次成功投递事件时触发。有关设置SES/SNS环境以接收有关这些事件的通知的详细信息,请参阅以下文档。
从2.0或更早版本升级
首先,通过运行
composer require jdavidbakr/mail-tracker ~2.2
如果您正在更新较早版本,则需要更新配置文件并运行新的迁移。为了获得最佳结果,请备份config/mail-tracker.php的副本和resources/views/vendor/emailTrackingViews中的视图(如果存在),以恢复您已定制的任何值,然后删除该文件并运行
php artisan vendor:publish
php artisan migrate
还请注意,sent_emails_url_clicked
表的迁移在版本2.1.13中发生了变化。更改是URL列现在是一个TEXT
字段,以便允许更长的URL。如果您有一个旧系统,您可能需要手动更改该列;没有包含执行此更新的迁移。
安装
通过Composer
composer require jdavidbakr/mail-tracker
发布配置文件和迁移
php artisan vendor:publish --provider="jdavidbakr\MailTracker\MailTrackerServiceProvider"
运行迁移
php artisan migrate
注意:如果您想使用不同的连接来存储模型,请在运行迁移之前更新mail-tracker.php配置条目的connection
。
如果您想使用自己的迁移,可以通过调用MailTracker::ignoreMigrations()
来跳过此库的迁移。例如
// In AppServiceProvider public function boot() { MailTracker::ignoreMigrations(); }
用法
安装后,所有发出的邮件都将记录到数据库中。以下配置选项可在config/mail-tracker.php中找到
- name:设置您的应用程序名称。
- inject-pixel:设置为true将在所有发出的HTML电子邮件中注入跟踪像素。
- track-links:设置为true将重写所有锚点href链接,以包含跟踪链接。链接将带用户回到您的网站,然后记录点击后重定向到最终目的地。
- expire-days:电子邮件应保留在数据库中的天数。如果您发送大量邮件,可能希望它们最终过期。将其设置为0以从不从数据库中清除旧电子邮件。
- route:跟踪URL的路由信息。根据需要设置前缀和中间件。
- admin-route:管理者的路由信息。设置前缀和中间件。
- admin-template:管理面板和视图的参数。您可以将现有的管理面板与MailTracker管理面板集成。
- date-format:您可以在管理面板中定义显示日期的格式。
- content-max-size:您可以通过覆盖数据库字段
content
的默认最大长度限制。如果您需要使其更长,不要忘记将其类型从text
更新。
如果您不希望跟踪电子邮件,则可以向您的消息中添加X-No-Track
标题。将任何随机字符串放入此标题中以防止跟踪。在发送之前将删除标题。
\Mail::send('email.test', [], function ($message) { // ... other settings here $message->getHeaders()->addTextHeader('X-No-Track',Str::random(10)); });
在文件系统中存储邮件内容
默认情况下,电子邮件的内容存储在数据库中的content
列,以便在发送后可以查看电子邮件。如果发送了大量邮件,这可能会消耗大量内存并减慢数据库的整体速度。可以在配置中指定将内容保存到文件系统中的文件。
'log-content-strategy' => 'filesystem', 'tracker-filesystem' => null 'tracker-filesystem-folder' => 'mail-tracker',
要使用文件系统,需要将log-content-strategy
从database
更改为filesystem
。您可以使用tracker-filesystem
指定磁盘,并使用tracker-filesystem-folder
指定它应存储文件的文件夹。
覆盖模型
在某些情况下,您可能想要覆盖内置模型。例如,您可以在AppServiceProvider
中使用以下方法轻松完成此操作:
MailTracker::useSentEmailModel(YourOwnSentEmailModel::class); MailTracker::useSentEmailUrlClickedModel(YourOwnSentEmailUrlClickedModel::class);
您的模型应该实现SentEmailModel
或SentEmailUrlClickedModel
接口。此包提供特质以轻松实现自己的模型,而无需重新实现或复制现有代码。
use Illuminate\Database\Eloquent\Model; use jdavidbakr\MailTracker\Concerns\IsSentEmailModel; use jdavidbakr\MailTracker\Contracts\SentEmailModel; class OwnEmailSentModel extends Model implements SentEmailModel { use IsSentEmailModel; protected static $unguarded = true; protected $casts = [ 'meta' => 'collection', 'opened_at' => 'datetime', 'clicked_at' => 'datetime', ]; }
跳过特定电子邮件的跟踪
如果您有不想跟踪的特定电子邮件,可以向电子邮件中添加X-No-Track
标题。这将防止跟踪电子邮件。在发送之前将删除标题。
从Laravel 9开始,您可以为Mailable类引入一个headers方法。这将阻止跟踪像素/点击跟踪应用于Mailable。
public function headers() { return [ 'X-No-Track' => Str::random(10), ]; }
跳过防病毒/垃圾邮件过滤器的打开/点击跟踪
某些邮件服务器可能会在交付之前扫描电子邮件,这可能会触发跟踪像素或点击链接。您可以添加事件监听器来处理此事件。
class ValidUserListener { public function handle(ValidActionEvent $event) { if (in_array(request()->userAgent(), ['Mozilla/5.0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246 Mozilla/5.0']) { $event->skip = true; } } }
确保您将监听器添加到您的EventServiceProvider
中的ValidActionEvent
,如果您不使用自动事件发现。
## Note on dev testing Several people have reported the tracking pixel not working while they were testing. What is happening with the tracking pixel is that the email client is connecting to your website to log the view. In order for this to happen, images have to be visible in the client, and the client has to be able to connect to your server. When you are in a dev environment (i.e. using the `.test` domain with Valet, or another domain known only to your computer) you must have an email client on your computer. Further complicating this is the fact that Gmail and some other web-based email clients don't connect to the images directly, but instead connect via proxy. That proxy won't have a connection to your `.test` domain and therefore will not properly track emails. I always recommend using [mailtrap.io](https://mailtrap.io) for any development environment when you are sending emails. Not only does this solve the issue (mailtrap.io does not use a proxy service to forward images in the emails) but it also protects you from accidentally sending real emails from your test environment. ## Events When an email is sent, viewed, or a link is clicked, its tracking information is counted in the database using the jdavidbakr\MailTracker\Model\SentEmail model. This processing is done via dispatched jobs to the queue in order to prevent the database from being overwhelmed in an email blast situation. You may choose the queue that these events are dispatched via the `mail-tracker.tracker-queue` config setting, or leave it `null` to use the default queue. By using a non-default queue, you can prioritize application-critical tasks above these tracking tasks. You may want to do additional processing on these events, so an event is fired in these cases: - jdavidbakr\MailTracker\Events\EmailSentEvent - Public attribute `sent_email` contains the `SentEmail` model - jdavidbakr\MailTracker\Events\ViewEmailEvent - Public attribute `sent_email` contains the `SentEmail` model - Public attribute `ip_address` contains the IP address that was used to trigger the event - jdavidbakr\MailTracker\Events\LinkClickedEvent - Public attribute `sent_email` contains the `SentEmail` model - Public attribute `ip_address` contains the IP address that was used to trigger the event - Public attribute `link_url` contains the clicked URL If you are using the Amazon SNS notification system, these events are fired so you can do additional processing. - jdavidbakr\MailTracker\Events\EmailDeliveredEvent (when you received a "message delivered" event, you may want to mark the email as "good" or "delivered" in your database) - Public attribute `sent_email` contains the `SentEmail` model - Public attribute `email_address` contains the specific address that was used to trigger the event - jdavidbakr\MailTracker\Events\ComplaintMessageEvent (when you received a complaint, ex: marked as "spam", you may want to remove the email from your database) - Public attribute `sent_email` contains the `SentEmail` model - Public attribute `email_address` contains the specific address that was used to trigger the event - jdavidbakr\MailTracker\Events\PermanentBouncedMessageEvent (when you receive a permanent bounce, you may want to mark the email as bad or remove it from your database) jdavidbakr\MailTracker\Events\TransientBouncedMessageEvent (when you receive a transient bounce. Check the event's public attributes for `bounce_sub_type` and `diagnostic_code` to determine if you want to do additional processing when this event is received.) - Public attribute `sent_email` contains the `SentEmail` model - Public attribute `email_address` contains the specific address that was used to trigger the event To install an event listener, you will want to create a file like the following: ```php <?php namespace App\Listeners; use jdavidbakr\MailTracker\Events\ViewEmailEvent; class EmailViewed { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param ViewEmailEvent $event * @return void */ public function handle(ViewEmailEvent $event) { // Access the model using $event->sent_email // Access the IP address that triggered the event using $event->ip_address } }
<?php namespace App\Listeners; use jdavidbakr\MailTracker\Events\PermanentBouncedMessageEvent; class BouncedEmail { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param PermanentBouncedMessageEvent $event * @return void */ public function handle(PermanentBouncedMessageEvent $event) { // Access the email address using $event->email_address } }
然后,您必须在您的\App\Providers\EventServiceProvider $listen数组中注册您想要处理的事件
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ 'jdavidbakr\MailTracker\Events\EmailSentEvent' => [ 'App\Listeners\EmailSent', ], 'jdavidbakr\MailTracker\Events\ViewEmailEvent' => [ 'App\Listeners\EmailViewed', ], 'jdavidbakr\MailTracker\Events\LinkClickedEvent' => [ 'App\Listeners\EmailLinkClicked', ], 'jdavidbakr\MailTracker\Events\EmailDeliveredEvent' => [ 'App\Listeners\EmailDelivered', ], 'jdavidbakr\MailTracker\Events\ComplaintMessageEvent' => [ 'App\Listeners\EmailComplaint', ], 'jdavidbakr\MailTracker\Events\PermanentBouncedMessageEvent' => [ 'App\Listeners\BouncedEmail', ], ];
向事件监听器传递数据
很多时候,您可能需要将一封已发送的电子邮件链接到另一个模型。处理此问题的最佳方法是向您的发送电子邮件添加一个标题,您可以在事件监听器中检索它。以下是一个示例
/** * Send an email and do processing on a model with the email */ \Mail::send('email.test', [], function ($message) use($email, $subject, $name, $model) { $message->from('from@johndoe.com', 'From Name'); $message->sender('sender@johndoe.com', 'Sender Name'); $message->to($email, $name); $message->subject($subject); // Create a custom header that we can later retrieve $message->getHeaders()->addTextHeader('X-Model-ID',$model->id); });
然后在您的事件监听器中
public function handle(EmailSentEvent $event)
{
$tracker = $event->sent_email;
$model_id = $event->sent_email->getHeader('X-Model-ID');
$model = Model::find($model_id);
// Perform your tracking/linking tasks on $model knowing the SentEmail object
}
请注意,您附加到电子邮件的标题实际上会随消息一起发送,因此请不要存储任何您不希望向您的电子邮件收件人公开的数据。
异常
以下异常可能会抛出。您可以在异常处理程序中将它们添加到忽略列表中,或者按您的意愿处理它们。
- jdavidbakr\MailTracker\Exceptions\BadUrlLink - URL链接出现问题。基本上,系统无法正确解析URL链接以发送重定向。
Amazon SES功能
如果您使用Amazon SES,您可以在跟踪中添加一些附加信息。要设置SES回调,首先在SES控制面板中设置您的域下的SES通知。然后通过转到通知主题的管理面板并创建一个订阅来订阅主题,该订阅包含您从管理页面复制的URL。系统应立即响应订阅请求。如果您喜欢,您可以使用多个订阅(例如,一个用于投递,一个用于退订)。有关在失败消息上触发的事件,请参阅上面。为了增加安全性,建议将主题ARN设置为mail-tracker配置。
视图
当您运行php artisan vendor:publish
命令时,简单视图将添加到您的resources/views/vendor/emailTrakingViews资源中,您可以根据需要进行自定义。您当然可以使用这些视图作为指南从头开始构建您自己的整个管理页面。
管理面板
MailTracker附带内置的管理区域。该包附带发布的默认配置将其放在can:see-sent-emails
中间件后面;您可以为此规则创建一个门或将其更改为使用您自己的中间件。您还可以更改默认前缀以及完全禁用管理路由。
路由名称是'mailTracker_Index'。标准管理面板路由位于/email-manager。您可以使用路由名称将其包含到您现有的管理菜单中。您可以在配置文件中自定义您的路由。您可以查看所有已发送的电子邮件、总打开次数、总URL点击次数、显示单个电子邮件以及显示点击的URL详细信息。
所有视图(电子邮件模板、面板)都可以在resources/views/vendor/emailTrakingViews中自定义。
贡献
有关详细信息,请参阅CONTRIBUTING和CONDUCT。
安全性
如果您发现任何安全相关的问题,请通过电子邮件me@jdavidbaker.com与我联系,而不是使用问题跟踪器。
鸣谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。