mailgun/mailgun-php
Official Mailgun PHP SDK (PSR-18/PSR-7 compatible) for sending email and managing Mailgun API features like domains, IPs/pools, analytics, and subaccounts. Works with your chosen HTTP client; supports US/EU endpoints.
Guzzle/Symfony HTTP Client) aligns perfectly with the SDK’s requirements.messages, ips, metrics) map cleanly to Laravel’s service-layer organization. Each module can be injected as a service or facade, reducing boilerplate.Mailgun::create() factory method simplifies initialization, while Laravel’s service container can manage API key injection (e.g., via .env or config).MailgunMessageSent) for logging/auditing without modifying core logic.symfony/http-client or guzzlehttp/guzzle (not auto-resolved). Laravel’s illuminate/http may need shimming for full compatibility.Auth system?Illuminate\Support\Facades\Log or throw custom exceptions?429 Too Many Requests) be implemented?Mockery or a dedicated HTTP mock (e.g., vcr/vcr)?Bus or raw SDK calls?ArrayHydrator) impact memory usage for large datasets?mailgun driver with a custom wrapper using this SDK for full feature parity (e.g., tracking, analytics).config/mailgun.php).MailgunMessageSent, MailgunIpAssigned) for observability.symfony/http-client) to avoid duplication.Log facade for SDK debug logs.Validator to sanitize input (e.g., email addresses, IP ranges).mailgun driver with a custom MailgunService using the SDK’s messages() module.IpService) for dynamic pool assignments.MetricsService with cached results (e.g., Redis).MailgunFacade for fluent syntax (e.g., Mailgun::messages()->send()).php artisan mailgun:ips:list) for admin tasks.symfony/http-client version).composer.json overrides if needed to align with Laravel’s vendor versions.subaccounts) via Laravel’s deprecated() helper.| Step | Priority | Dependencies | Output |
|---|---|---|---|
| SDK Initialization | P0 | Laravel config, PSR-18 client | MailgunService class |
| Email Integration | P0 | Laravel Mail system | Custom MailgunTransport |
| IP Management | P1 | SDK ips() module |
IpService + Artisan commands |
| Analytics | P2 | SDK metrics() module |
Cached AnalyticsRepository |
| Testing | P0 | All above | Unit/feature tests |
composer.json conflict rules to block incompatible versions.MailgunKeyManager to rotate keys without downtime (e.g., via Laravel’s config/cache).deprecated() helper can mark old SDK methods (e.g., send() → messages()->send()).Sentry/Log with context (e.g., request payload, user ID).try {
$mg->messages()->send(...);
} catch (\Mailgun\Exception\MailgunException $e) {
Log::error("Mailgun failed", [
'error' => $e->getMessage(),
'code' => $e->getCode(),
'payload' => $e->getPayload(),
'user_id' => auth()->id(),
]);
}
NoopHydrator + Laravel’s dd() for raw response inspection.'debug' => env('MAILGUN_DEBUG', false),
README.md (e.g., "Using with Laravel Queues").Illuminate\Support\Facades\Retry.use Illuminate\Support\Facades\Retry;
Retry::retry(3, function () use ($mg) {
return $mg->messages()->send(...);
}, 100); // 100ms delay between retries
Bus to queue bulk operations (e.g., IP assignments) with MailgunJob.Bus::dispatch(new AssignIpToDomainsJob($ip, $domains));
Redis) with TTLs (e.g., 1 hour).Cache::remember():
$metrics = Cache::remember("mailgun:metrics:{$start}:{$end}", now()->addHours(1), function () use ($mg) {
return $mg->metrics()->loadMetrics([...]);
});
| Failure Scenario | Impact | Mitigation Strategy |
|---|---|---|
| Mailgun API downtime | Emails fail to send | Queue emails locally; retry with backoff. |
| Rate limit exceeded | API calls rejected | Implement retry logic + queue throttling. |
| Invalid API key | All requests fail | Validate key on SDK initialization. |
| IP assignment delays | Async operations hang | Track async ref IDs; poll for completion. |
| Large response payloads | Memory exhaustion | Stream responses; use ArrayHydrator. |
| Laravel cache invalidation | Stale metrics data | Short TTLs + cache tags (e.g., mailgun:metrics). |
How can I help you explore Laravel packages today?