devlab-studio / laravel-mailer
This is my package laravel-mailer
Fund package maintenance!
Requires
- php: ^8.3
- illuminate/contracts: ^13.0|^12.0
- laravel/framework: ^13.0|^12.0
- livewire/livewire: ^4.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
README
Laravel Mailer
Laravel package for advanced email sending with support for multiple SMTP senders, email logging and attachment management.
Summary
- Registers a custom channel to send notifications via SMTP configured per sender.
- Persists sent emails (body, metadata, status) and attachments to the database and storage (
storage/app/attachments/...). - Allows configuring SMTP senders via an interactive command or using
.envand a seeder.
Installation
Install via Composer:
composer require devlab-studio/laravel-mailer
Publish configuration (if applicable) and run migrations:
php artisan vendor:publish --tag=laravel-mailer-config php artisan migrate
SMTP Configuration (.env)
Before using the package, fill in your SMTP credentials in .env or use the interactive command:
MAIL_MAILER=smtpMAIL_HOST=your.smtp.hostMAIL_PORT=587MAIL_USERNAME=your@smtp.userMAIL_PASSWORD=secretMAIL_ENCRYPTION=tls# tls, ssl or nullMAIL_FROM_ADDRESS=from@example.comMAIL_FROM_NAME="Your Name"
Or run the interactive setup (it will save runtime config and run the seeder):
php artisan laravel-mailer
The command will ask for host, port, protocol, user, password, sender address and name and will run EmailSendersTableSeeder.
Senders Seeder
The EmailSendersTableSeeder inserts a sender into the email_senders table using current mail configuration (normally from .env). Run it manually:
php artisan db:seed --class=\\Devlab\\LaravelMailer\\Database\\Seeders\\EmailSendersTableSeeder
File: database/seeders/EmailSendersTableSeeder.php
Custom channel and send flow
The main channel is CustomMailChannel (src/CustomMail/CustomMailChannel.php) and does the following:
- Retrieves the recipient from the
notifiable. SupportsAnonymousNotifiable. - Resolves the sender (
from) from the message or from config (devlab.MAIL_FROM_ADDRESS). - Logs the email in the
emailstable storing HTML body, subject, to/cc/bcc and metadata. - Stores attachments in
storage/app/attachments/YYYY/M/D/and creates records inemails_attachments. - Selects which mailer to use by querying
email_senderstable:- If the sender exists, it dynamically creates a mailer
custom{ID}with the sender credentials (password decrypted) and uses it. - Otherwise it falls back to the default
smtpmailer.
- If the sender exists, it dynamically creates a mailer
- Sends the message using the selected mailer and updates the email record with status, sent date and errors if any.
Key files:
src/CustomMail/CustomMailChannel.phpsrc/Models/Email.php(logging and filters)src/Models/EmailsAttachment.php(attachment metadata)src/Models/EmailSender.php(SMTP senders)
Database structure
The package includes migrations in database/migrations to create:
email_senders— SMTP senders and credentials (password encrypted)emails— records of sent emails (body, status, to/cc/bcc, sent_at, etc.)emails_attachments— attachment metadata and storage paths
Check database/migrations for exact columns.
Attachments storage
Physical attachments are copied to storage/app/attachments/{year}/{month}/{day}/ and the path is recorded in the DB. The channel supports:
Illuminate\\Mail\\AttachmentIlluminate\\Http\\UploadedFile- Disk paths (strings)
Usage (quick example)
Inside a notification, implement toCustomMail() and return a Mailable or MailMessage with attachments and rawAttachments when needed. When notifying, the package:
// Notification public function toCustomMail($notifiable) { $mailable = new \\Illuminate\\Mail\\Mailable(); // configure view, subject, attachments, etc. return $mailable; } // Send $user->notify(new \\App\\Notifications\\MyNotification());
Errors and logging
On exception during sending, the channel captures the error, stores it on the email record and writes to the application log:
- Look for logs with
Log::error('CustomMailChannel error: ...')
Best practices & security
- Ensure SMTP credentials stored in the database are encrypted (the seeder uses
encrypt()during insert). - Protect access to
email_sendersif users can modify senders.
Useful commands
# Interactive setup and run seeder php artisan laravel-mailer # Run only the seeder php artisan db:seed --class=\\Devlab\\LaravelMailer\\Database\\Seeders\\EmailSendersTableSeeder # Run migrations (if not yet executed) php artisan migrate
Package entry file
The service provider registers config, migrations and the command:
src/LaravelMailerServiceProvider.php
Support
© 2026 Devlab Studio