gustavoh3nryk/mail-tracker

记录并跟踪Laravel发送的所有邮件

1.0.2 2024-05-23 21:32 UTC

This package is auto-updated.

Last update: 2024-09-23 22:14:16 UTC


README

Latest Version on Packagist Software License Total Downloads

MailTracker 将会钩入 Laravel 发送的所有邮件,并向其注入跟踪代码。它还会将渲染后的邮件存储到数据库中。还提供了一个界面来查看已发送的邮件。

注意:如果您使用 Laravel 9.x,您必须使用 9.6.0 或更高版本。

安装

通过 Composer

composer require gustavoh3nryk/mail-tracker

发布配置文件和迁移文件

php artisan vendor:publish --provider="gustavoh3nryk\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));
});

关于开发测试的说明

有几个人报告说在测试时跟踪像素不起作用。跟踪像素的问题在于电子邮件客户端正在连接到您的网站以记录查看。为了实现这一点,图像必须在客户端可见,并且客户端必须能够连接到您的服务器。

当您处于开发环境(例如,使用 Valet 的 .test 域或只有您的电脑知道的另一个域)时,您必须在您的电脑上有一个电子邮件客户端。使问题更加复杂的是,Gmail 和一些其他基于网络的电子邮件客户端不会直接连接到图像,而是通过代理连接。该代理不会连接到您的 .test 域,因此无法正确跟踪电子邮件。我总是推荐在发送电子邮件时使用 mailtrap.io 进行任何开发环境。这不仅解决了问题(mailtrap.io 不使用代理服务转发邮件中的图像),还可以防止您从测试环境中意外发送真实邮件。

事件

当发送、查看电子邮件或点击链接时,其跟踪信息会通过gustavoh3nryk\MailTracker\Model\SentEmail模型在数据库中进行计数。此处理通过将任务派遣到队列中完成,以防止在电子邮件发送高峰时数据库过载。您可以通过mail-tracker.tracker-queue配置设置选择这些事件通过哪个队列派遣,或者将其留为null以使用默认队列。使用非默认队列,您可以优先处理应用程序关键任务,而将这些跟踪任务放在后面。

您可能想要对这些事件进行额外处理,因此在这些情况下会触发一个事件

  • gustavoh3nryk\MailTracker\Events\EmailSentEvent
    • 公共属性sent_email包含SentEmail模型
  • gustavoh3nryk\MailTracker\Events\ViewEmailEvent
    • 公共属性sent_email包含SentEmail模型
    • 公共属性ip_address包含触发事件的IP地址
  • gustavoh3nryk\MailTracker\Events\LinkClickedEvent
    • 公共属性sent_email包含SentEmail模型
    • 公共属性ip_address包含触发事件的IP地址
    • 公共属性link_url包含被点击的URL

如果您使用Amazon SNS通知系统,这些事件会被触发,以便您进行额外处理。

  • gustavoh3nryk\MailTracker\Events\EmailDeliveredEvent(当收到“消息已送达”事件时,您可能想在数据库中将电子邮件标记为“良好”或“已送达”)
    • 公共属性sent_email包含SentEmail模型
    • 公共属性email_address包含触发事件的特定地址
  • gustavoh3nryk\MailTracker\Events\ComplaintMessageEvent(当收到投诉时,例如被标记为“垃圾邮件”,您可能想从数据库中删除该电子邮件)
    • 公共属性sent_email包含SentEmail模型
    • 公共属性email_address包含触发事件的特定地址
  • gustavoh3nryk\MailTracker\Events\PermanentBouncedMessageEvent(当收到永久性退信时,您可能想将电子邮件标记为不良或从数据库中删除)gustavoh3nryk\MailTracker\Events\TransientBouncedMessageEvent(当收到暂时性退信时。检查事件的公共属性中的bounce_sub_typediagnostic_code以确定是否在接收到此事件时进行额外处理。)
    • 公共属性sent_email包含SentEmail模型
    • 公共属性email_address包含触发事件的特定地址

要安装事件监听器,您需要创建一个类似以下的文件

<?php

namespace App\Listeners;

use gustavoh3nryk\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 gustavoh3nryk\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 = [
    'gustavoh3nryk\MailTracker\Events\EmailSentEvent' => [
        'App\Listeners\EmailSent',
    ],
    'gustavoh3nryk\MailTracker\Events\ViewEmailEvent' => [
        'App\Listeners\EmailViewed',
    ],
    'gustavoh3nryk\MailTracker\Events\LinkClickedEvent' => [
        'App\Listeners\EmailLinkClicked',
    ],
    'gustavoh3nryk\MailTracker\Events\EmailDeliveredEvent' => [
        'App\Listeners\EmailDelivered',
    ],
    'gustavoh3nryk\MailTracker\Events\ComplaintMessageEvent' => [
        'App\Listeners\EmailComplaint',
    ],
    'gustavoh3nryk\MailTracker\Events\PermanentBouncedMessageEvent' => [
        'App\Listeners\BouncedEmail',
    ],
];

传递数据到事件监听器

通常您可能需要将发送的电子邮件链接到另一个模型。处理此问题的最佳方法是向您的 outgoing 电子邮件添加一个标题,您可以在事件监听器中检索它。以下是一个示例

/**
 * 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
}

请注意,您附加到电子邮件的标题实际上是随消息一起发送的,因此不要存储任何您不希望向电子邮件收件人暴露的数据。

异常

以下异常可能会抛出。您可以将它们添加到您的异常处理程序的忽略列表中,或按您希望的方式处理它们。

  • gustavoh3nryk\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。您可以使用路由名称将它们包含到现有的管理菜单中。您可以在配置文件中自定义您的路由。您可以查看所有已发送的电子邮件、总打开次数、总点击次数、查看个别电子邮件和查看点击详情的网址。

所有视图(电子邮件模板、面板)都可以在 resources/views/vendor/emailTrakingViews 中进行自定义。

贡献

请参阅 CONTRIBUTINGCONDUCT 以获取详细信息。

安全

如果您发现任何与安全相关的问题,请通过电子邮件 gustavo.h3nryk@gmail.com 联系我们,而不是使用问题跟踪器。

鸣谢

许可协议

MIT 许可协议(MIT)。请参阅 许可文件 以获取更多信息。