copromatic/mailgun-admin-bundle
Installation
composer require copromatic/mailgun-admin-bundle
Configure config/packages/mailgun_admin.yaml
mailgun_admin:
api_key: '%env(MAILGUN_API_KEY)%'
entity_manager: 'mailgun_admin'
Update Doctrine Configuration
Add the mailgun_admin entity manager to your config/packages/doctrine.yaml:
doctrine:
orm:
entity_managers:
mailgun_admin:
connection: default
mappings:
MailgunAdminBundle: ~
Run Migrations
php bin/console doctrine:migration:diff
php bin/console doctrine:migration:migrate
Verify Mailgun Transport
Ensure your config/packages/swiftmailer.yaml uses tehplague.mailgun transport:
swiftmailer:
transport: '%env(MAILER_DSN)%' # e.g., mailgun://api:key@domain
First Use Case
Send an email via Swiftmailer. The bundle will automatically log the Message-Id to the mailgun_message table.
Email Logging
The bundle hooks into Swiftmailer’s SentEvent listener. Every email sent with a Message-Id (auto-generated by Mailgun) is recorded in mailgun_message.
Tracking Events Use Mailgun’s webhooks to push events (clicks, bounces, etc.) to your app. The bundle provides tables for:
mailgun_clickmailgun_bouncemailgun_deliverymailgun_openmailgun_spammailgun_unsubscribemailgun_complaintExample Webhook Endpoint (in src/Controller/MailgunWebhookController.php):
use Copromatic\MailgunAdminBundle\Event\MailgunEvent;
public function handleWebhook(Request $request, MailgunEvent $event)
{
$event->processWebhook($request->getContent());
return new Response('OK');
}
Querying Data Use Doctrine repositories to fetch tracked events:
$messages = $this->getDoctrine()
->getRepository('MailgunAdminBundle:MailgunMessage')
->findBy(['sentAt' => new \DateTime('-7 days')]);
Integration with Swiftmailer
Ensure your mailer uses the tehplague/swiftmailer-mailgun-bundle transport:
swiftmailer:
transport: mailgun://api:key@domain
Batch Processing
Use mailgun_message to audit sent emails and correlate them with tracking events.
$em = $this->getDoctrine()->getManager('mailgun_admin');
$messages = $em->getRepository('MailgunAdminBundle:MailgunMessage')
->findBy(['status' => 'queued'], 100);
Webhook Validation Validate Mailgun webhook signatures in your controller:
use Copromatic\MailgunAdminBundle\Validator\MailgunWebhookValidator;
$validator = new MailgunWebhookValidator($request->headers->get('X-Mailgun-Signature'));
if (!$validator->isValid($request->getContent())) {
throw new \RuntimeException('Invalid webhook signature');
}
Custom Tracking Logic Extend the bundle’s event processor to add business logic:
use Copromatic\MailgunAdminBundle\Event\MailgunEvent;
$event->on('click', function ($tracker) {
// Log analytics or trigger actions
});
Entity Manager Isolation
mailgun_admin). Forgetting to specify --em=mailgun_admin in Doctrine commands will fail silently.php bin/console doctrine:schema:update --em=mailgun_admin
Webhook Signature Mismatches
X-Mailgun-Signature header is missing or invalid, events will be rejected.# config/packages/mailgun_admin.yaml
mailgun_admin:
webhook_secret: '%env(MAILGUN_WEBHOOK_SECRET)%'
Duplicate Message-Ids
Message-Id for emails sent simultaneously. The bundle handles this, but queries may return duplicates.DISTINCT in queries or filter by sentAt:
$messages = $em->createQuery('
SELECT DISTINCT m
FROM MailgunAdminBundle:MailgunMessage m
WHERE m.sentAt > :date
')->setParameter('date', new \DateTime('-1 day'))->getResult();
Swiftmailer Transport Misconfiguration
tehplague.mailgun transport, the Message-Id won’t be logged.MAILER_DSN in .env:
MAILER_DSN=mailgun://api:key@domain
Missing Webhook Events
200 OK and includes the X-Mailgun-Signature header.mailgun_admin EM is properly connected.Log Webhook Payloads Temporarily log raw webhook data to verify payload structure:
file_put_contents(
'var/log/mailgun_webhook.log',
$request->getContent(),
FILE_APPEND
);
Check Doctrine Events Enable SQL logging to debug queries:
# config/packages/dev/doctrine.yaml
doctrine:
dbal:
logging: true
profiling: true
Validate API Key Test the Mailgun API connection manually:
curl -s -X GET https://api.mailgun.net/v3/domains \
-H "Authorization: Basic $(echo -n 'api:key' | base64)"
Custom Trackers Extend the bundle’s entity structure by creating a custom migration:
// src/Migrations/VersionYYYYMMDDHHMMSS.php
public function up(SchemaManager $manager)
{
$table = $manager->getConnection()->getSchemaManager()
->createTable('custom_mailgun_tracker');
$table->addColumn('mailgun_message_id', 'integer');
$table->addColumn('custom_data', 'json');
$table->addIndex(['mailgun_message_id']);
}
Override Event Processing
Replace the default MailgunEvent processor:
# config/services.yaml
services:
Copromatic\MailgunAdminBundle\Event\MailgunEvent:
class: App\Event\CustomMailgunEvent
arguments: ['@doctrine.orm.mailgun_admin_entity_manager']
Add Custom Fields to Messages
Extend the MailgunMessage entity:
// src/Entity/MailgunMessageExtension.php
use Doctrine\ORM\Mapping as ORM;
class MailgunMessageExtension
{
/**
* @ORM\Column(type="string", nullable=true)
*/
private $customField;
}
Batch Processing with Queues Offload heavy tracking logic to a queue (e.g., Symfony Messenger):
use Copromatic\MailgunAdminBundle\Message\ProcessMailgunEvents;
$message = new ProcessMailgunEvents($tracker);
$this->messageBus->dispatch($message);
How can I help you explore Laravel packages today?