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.
Installation:
composer require mailgun/mailgun-php symfony/http-client nyholm/psr7
Laravel users can skip symfony/http-client if using Laravel's built-in HTTP client.
Initialize the SDK:
use Mailgun\Mailgun;
$mg = Mailgun::create(config('mail.mailgun.api_key'), config('mail.mailgun.endpoint'));
Store your API key and endpoint in Laravel's .env:
MAIL_MAILGUN_API_KEY=your-api-key
MAIL_MAILGUN_ENDPOINT=https://api.mailgun.net
First Use Case: Send a test email via Laravel's Mail facade (if using Laravel):
Mail::to('recipient@example.com')->send(new TestEmail());
Or directly via the SDK:
$mg->messages()->send('example.com', [
'from' => 'sender@example.com',
'to' => 'recipient@example.com',
'subject' => 'Test Email',
'text' => 'Hello from Mailgun!'
]);
Sending Emails:
Mail::to('user@example.com')->send(new OrderConfirmation($order));
batch() method for large campaigns.
$mg->messages()->batch('example.com', [
'from' => 'newsletter@example.com',
'to' => ['user1@example.com', 'user2@example.com'],
'subject' => 'Weekly Newsletter',
'text' => 'Your weekly updates...'
]);
Tracking and Analytics:
$metrics = $mg->metrics()->loadMetrics([
'start' => '2023-01-01',
'end' => '2023-01-31',
'metrics' => ['delivered_count', 'opened_rate']
]);
// app/Console/Commands/EmailReport.php
public function handle() {
$metrics = $mg->metrics()->loadMetrics([...]);
// Process and log metrics
}
IP Management:
$mg->ips()->assign('example.com', '1.2.3.4');
booted method:
public function booted() {
$mg->ips()->rotate('example.com');
}
Dynamic IP Pools (DIPP):
$mg->ips()->createIpPool('Primary Pool', 'Main sending pool');
$mg->ips()->updateIpPool('pool-id', ['link_domain' => 'example.com']);
Subaccounts:
$mg->subaccounts()->create('marketing-team');
$subMg = Mailgun::create(config('mail.mailgun.api_key'), null, 'marketing-team');
Laravel Service Provider:
Bind the Mailgun client in AppServiceProvider:
public function register() {
$this->app->singleton('mailgun', function ($app) {
return Mailgun::create(
$app['config']['mail.mailgun.api_key'],
$app['config']['mail.mailgun.endpoint']
);
});
}
Inject it into controllers:
public function __construct(private Mailgun $mailgun) {}
Event Listeners:
Trigger Mailgun actions on Laravel events (e.g., registered):
public function handle($event) {
$this->mailgun->messages()->send('example.com', [
'from' => 'welcome@example.com',
'to' => $event->user->email,
'subject' => 'Welcome!',
'text' => 'Thank you for registering!'
]);
}
Queue Jobs: Offload email sending to Laravel queues:
// app/Jobs/SendWelcomeEmail.php
public function handle() {
$this->mailgun->messages()->send('example.com', [...]);
}
Domain Verification:
$mg->domains()->verify('example.com') in a Laravel command or observer.Rate Limits:
Async Operations:
assignIpToAllDomains) are async. Check the status with:
$ref = $mg->ips()->assignIpToAllDomains('1.2.3.4');
$status = $mg->ips()->getAsyncOperationStatus($ref->getReferenceId());
Time Zones in Scheduling:
o:deliverytime is in UTC format:
'o:deliverytime' => '2023-12-25 12:00:00 UTC'
Subaccount Scoping:
Mailgun::create() will default to the root account.$mg = Mailgun::create('api-key', null, 'subaccount-id');
Enable Debugging:
$configurator = new HttpClientConfigurator();
$configurator->setEndpoint('http://bin.mailgun.net/your-bin-id');
$configurator->setDebug(true);
$mg = new Mailgun($configurator, new NoopHydrator());
Handle Exceptions:
try {
$mg->messages()->send('example.com', [...]);
} catch (Mailgun\Exception\MailgunException $e) {
Log::error('Mailgun error: ' . $e->getMessage());
// Retry or notify admin
}
Logging Responses:
$response = $mg->messages()->send('example.com', [...]);
Log::debug('Mailgun response:', $response->getBody()->getContents());
Use Hydrators for Flexibility:
ArrayHydrator and default model hydrators based on needs:
$mg = new Mailgun($configurator, new ArrayHydrator());
Leverage Laravel's Mailable Classes:
Mailable classes with Mailgun's features:
// app/Mail/TestEmail.php
public function build() {
return $this->withSwiftMessage(function ($message) {
$message->getHeaders()
->addTextHeader('X-Tag', 'newsletter');
});
}
Batch Processing:
batch() for sending to large lists efficiently:
$users = User::where('is_active', true)->get();
$batches = array_chunk($users->pluck('email')->toArray(), 100);
foreach ($batches as $batch) {
$mg->messages()->batch('example.com', [
'from' => 'newsletter@example.com',
'to' => $batch,
'subject' => 'Monthly Newsletter',
'text' => 'Your updates...'
]);
}
Webhook Integration:
// routes/web.php
Route::post('/mailgun/webhook', [MailgunWebhookController::class, 'handle']);
mailgun/mailgun-php SDK to verify webhook signatures:
use Mailgun\Webhook\Webhook;
$webhook = new Webhook($request->getContent(), config('mail.mailgun.webhook_signing_key'));
if ($webhook->isValid()) {
//
How can I help you explore Laravel packages today?