Create→Send via Microsoft Graph with Sent/NDR tracking, throttling/backoff, webhook subscriptions, REST APIs, RabbitMQ listener, templates, and a web UI.
This version now supports dual tracking modes:
- Webhook Mode (Microsoft Graph Subscriptions)
- Polling Mode (for closed networks without external HTTPS)
Both modes can be enabled independently.
composer require progressivestudios/laravel-graph-mail
php artisan vendor:publish --tag=graph-mail-config
php artisan vendor:publish --tag=graph-mail-migrations
php artisan vendor:publish --tag=graph-mail-views
php artisan vendor:publish --tag=graph-mail-assets
php artisan migrateConfigure .env with all required GRAPH_* and RabbitMQ settings.
GRAPH_TENANT_ID=
GRAPH_CLIENT_ID=
GRAPH_CLIENT_SECRET=
GRAPH_SENDER=
GRAPH_BASE="https://graph.microsoft.com/v1.0"
GRAPH_WEBHOOK_URL=
GRAPH_WEBHOOK_SECRET=
# Tracking modes
GRAPH_TRACKING_WEBHOOK=true
GRAPH_TRACKING_POLLING=true
GRAPH_SAVE_TO_SENT=true
GRAPH_MAIL_LOG_CHANNEL=graph-mail
GRAPH_API_PREFIX=graph-mail
-
POST
/api/{GRAPH_API_PREFIX}/messages
Accepts:html, ortemplate_key+data
-
GET
/api/{GRAPH_API_PREFIX}/messages/{id}
Returns message status. -
GET
/api/{GRAPH_API_PREFIX}/health
Connectivity check.
Enable:
GRAPH_RABBIT_ENABLED=true
Start consumer:
php artisan graph-mail:rabbit:consumeMessages published to RabbitMQ are handled by the same processing pipeline as REST and UI requests.
Templates may come from:
- DB (
mail_templates) - Blade views under
resources/views/emails/* - Custom mailable classes
Message creation supports:
template_keydata- Optional
subjectoverride
Seeder example provided at database/seeders/MailTemplateSeeder.php.
php artisan graph-mail:subscriptions:createSchedule renewals hourly:
$schedule->command('graph-mail:subscriptions:renew')->hourly();Webhook mode requires a public HTTPS endpoint set in:
GRAPH_WEBHOOK_URL=
Use this mode when:
- No public webhook URL is possible
- System runs in a closed or isolated network
Enable in .env:
GRAPH_TRACKING_WEBHOOK=false
GRAPH_TRACKING_POLLING=true
Add scheduler:
$schedule->command('graph-mail:status:poll')->everyMinute();Polling checks:
- Sent Items (marks mail as sent)
- Inbox (detects NDR / bounce emails)
Required:
Mail.SendMail.ReadWriteMailboxSettings.ReadSubscriptions.Read.All
Admin consent is required.
- OpenAPI spec:
openapi.yaml - Postman collection:
postman.collection.json - Docker compose (RabbitMQ):
docker-compose.yml - Template seeder:
MailTemplateSeeder.php
A separate commercial package adds:
- Multi-tenant support
- Bulk sending
- Advanced routing
- Analytics & dashboards
- High-volume worker optimizations
Available at:
progressivestudios/laravel-graph-mail-pro