MailTracker

repository·master·Indexed 20 days ago

https://github.com/jdavidbakr/mail-tracker

A Laravel package for tracking outgoing emails. It provides functionality to track email opens via tracking pixels and link clicks via link rewriting, storing metadata and content in the database or filesystem. It includes an admin panel, support for Amazon SES events, and a system of events and listeners for auditing and analytics.

Tokens
6.4K
Snippets
22
Records
31
Agent score
70%

What's inside mail-tracker

  1. Handle MailTracker events with listeners

    master

    MailTracker dispatches events when emails are sent, viewed, or links are clicked. These events are processed via dispatched jobs to prevent database overload. You can customize the queue used for these jobs via the mail-tracker.tracker-queue configuration setting (set to null to use the default queue).

    Core Events

    • jdavidbakr\MailTracker\Events\EmailSentEvent: Contains the sent_email attribute (a SentEmail model).
    • jdavidbakr\MailTracker\Events\ViewEmailEvent: Contains sent_email and the ip_address that triggered the view.
    • jdavidbakr\MailTracker\Events\LinkClickedEvent: Contains sent_email, ip_address, and the link_url that was clicked.

    Amazon SES Events

    If using Amazon SNS, the following events are also available:

    • jdavidbakr\MailTracker\Events\EmailDeliveredEvent: Contains sent_email and email_address.
    • jdavidbakr\MailTracker\Events\ComplaintMessageEvent: Contains sent_email and email_address.
    • jdavidbakr\MailTracker\Events\PermanentBouncedMessageEvent: Contains sent_email and email_address.
    • jdavidbakr\MailTracker\Events\TransientBouncedMessageEvent: Contains sent_email, email_address, bounce_sub_type, and diagnostic_code.
  2. Configure Amazon SES callbacks

    master

    To use Amazon SES tracking features:

    1. Set up SES notifications in the Amazon SES control panel for your domain.
    2. Subscribe to the notification topic using the URL provided by the MailTracker admin page.
    3. For security, it is recommended to set the topic ARN in the mail-tracker configuration file.
  3. Upgrade from 4.x to 5.x

    master

    In version 5.x, recipient and sender columns in the sent_emails table have been replaced by separate name and email fields. To migrate your data:

    1. Run the artisan command to convert existing data:
      php artisan mail-tracker:migrate-recipients
    2. After running this, you may safely drop the recipient and sender columns from your database.

    Note: Accessors have been added to the model so existing code using $model->recipient or $model->sender will still work via the new fields.

    php artisan mail-tracker:migrate-recipients
  4. Link sent emails to custom models using headers

    master

    To associate a SentEmail with a specific model in your application (e.g., a User or Order), add a custom header to the outgoing email. You can then retrieve this header within your event listener to perform additional processing.

    Warning: Headers are sent with the email; do not include sensitive data you wouldn't want the recipient to see.

    /**
     * Send an email and 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);
    });
    
    // In your event listener:
    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
    }
  5. Implement an event listener for MailTracker

    master

    To react to tracking events, create a listener class and register it in your App\Providers\EventServiceProvider $listen array.

    Example of a listener for ViewEmailEvent:

    namespace App\Listeners;
    
    use jdavidbakr\MailTracker\Events\ViewEmailEvent;
    
    class EmailViewed
    {
        public function handle(ViewEmailEvent $event)
        {
            // Access the model using $event->sent_email
            // Access the IP address using $event->ip_address
        }
    }

    Registration in EventServiceProvider:

    protected $listen = [
        'jdavidbakr\MailTracker\Events\ViewEmailEvent' => [
            'App\Listeners\EmailViewed',
        ],
    ];
    <?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
        }
    }
  6. Customize MailTracker views and admin panel

    master

    Customizing Views

    After running php artisan vendor:publish, you can customize the email templates and admin panel views located in resources/views/vendor/emailTrakingViews.

    Admin Panel Configuration

    The built-in administration area is accessible via the route name mailTracker_Index (default path: /email-manager).

    Key configuration options:

    • Access Control: By default, the admin area is protected by the can:see-sent-emails middleware. You can change this to a custom gate in the config.
    • Route Customization: You can change the default prefix or disable the admin routes entirely in the config file.
    • Menu Integration: Use the mailTracker_Index route name to include the admin panel in your existing application menu.
  7. Skip migrations for MailTracker

    master

    If you prefer to manage your own migrations instead of using the ones provided by the package, call MailTracker::ignoreMigrations() in your AppServiceProvider's register method.

    // In AppServiceProvider
    
    public function register()
    {
        MailTracker::ignoreMigrations();
    }
  8. Install MailTracker via Composer

    master

    To install MailTracker in your Laravel project, follow these steps:

    1. Install the package via Composer:
      composer require jdavidbakr/mail-tracker
    2. Publish the configuration file and migrations:
      php artisan vendor:publish --provider="jdavidbakr\MailTracker\MailTrackerServiceProvider"
    3. Run the migrations:
      php artisan migrate

    Note: If you want to use a different database connection for MailTracker, update the connection key in config/mail-tracker.php before running the migrations.

    composer require jdavidbakr/mail-tracker
    php artisan vendor:publish --provider="jdavidbakr\MailTracker\MailTrackerServiceProvider"
    php artisan migrate
  9. Configure MailTracker options

    master

    MailTracker behavior is controlled via config/mail-tracker.php. Key options include:

    • name: The application name.
    • inject-pixel: Boolean. If true, injects a tracking pixel into HTML emails.
    • track-links: Boolean. If true, rewrites anchor href links to include tracking.
    • expire-days: Number of days to retain emails. Set to 0 to never purge.
    • route: Route prefix and middleware for tracking URLs.
    • admin-route: Route prefix and middleware for the admin panel.
    • admin-template: Parameters for the Admin Panel and Views.
    • date-format: Date format for the Admin Panel.
    • content-max-size: Maximum length for the content field. If increased, ensure the database column type is updated (e.g., from text to longtext).
  10. Store email content in the filesystem

    master

    To prevent the database from growing too large, you can store email content in the filesystem instead of the content database column. Update config/mail-tracker.php with the following settings:

    • log-content-strategy: Set to 'filesystem'.
    • tracker-filesystem: The disk to use (e.g., 'public').
    • tracker-filesystem-folder: The folder within the disk to store files (e.g., 'mail-tracker').
    'log-content-strategy' => 'filesystem',
    'tracker-filesystem' => 'public',
    'tracker-filesystem-folder' => 'mail-tracker',
  11. Publish MailTracker configuration and views

    master

    To customize the package behavior or the appearance of email tracking elements, you can publish the configuration file and the views to your application's directories using the Artisan command.

    Use the config tag to publish the configuration file to config/mail-tracker.php and the emailTrakingViews tag to publish views to resources/views/vendor/emailTrakingViews.

    # Example commands to publish assets
    php artisan vendor:publish --tag=config
    php artisan vendor:publish --tag=emailTrakingViews
  12. Skip tracking for Anti-virus/Spam Filters

    master

    To prevent automated mail scanners from triggering open or click events, you can listen to the ValidActionEvent and set $event->skip = true based on the User-Agent.

    class ValidUserListener {
        public function handle(ValidActionEvent $event)
        {
            if (in_array(request()->userAgent(), ['Mozilla/5.0', ...])) {
                $event->skip = true;
            }
        }
    }

    Ensure this listener is registered in your EventServiceProvider.

    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;
            }
        }
    }