Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mailgun Mail Status Bundle Laravel Package

moukail/mailgun-mail-status-bundle

Symfony bundle for tracking Mailgun email delivery statuses. Integrates Mailgun events/webhooks to monitor delivered, opened, clicked, bounced, and failed messages, helping applications manage transactional email feedback and status updates.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. That is the single most important thing to establish before anything else — a Laravel developer cannot composer require this and expect it to boot in app/Providers. There is no auto-discovery, no service provider, no publishable config. Everything is wired through Symfony's config/bundles.php, config/services.yaml, and the DependencyInjection compiler pass. Before committing to it, open composer.json and confirm the symfony/* constraints (likely ^4.0|^5.0 given the December 2021 release), then check whether your project is Symfony at all. If you are in a Laravel codebase, read the source as a reference implementation for Mailgun webhook handling rather than as a dependency.

For the Symfony context it was built for, the minimal path is:

  1. composer require moukail/mailgun-mail-status-bundle
  2. Register it in config/bundles.php:
    Moukail\MailgunMailStatusBundle\MailgunMailStatusBundle::class => ['all' => true],
    
  3. Add the config block (config/packages/mailgun_mail_status.yaml) — expect to supply at minimum your Mailgun API key and/or the HTTP webhook signing key. Both live in the Mailgun dashboard under Account → API Keys / Webhooks.
  4. Import the bundle's routes if it ships a webhook controller, or point your own route at its handler service.
  5. Configure the Mailgun webhook URL in the Mailgun dashboard to match.

The first useful use case is the obvious one: stop polling Mailgun and start receiving delivery events. You get delivered, opened, clicked, bounced, dropped, spam_complaint, unsubscribed pushed to you, and the bundle gives you an event layer on top so you can react (mark a DB row, dispatch a Laravel/Symfony job, suppress a contact).

Implementation Patterns

The bundle's value is the webhook → event → listener pipeline. The pattern you will actually write day-to-day is a listener or subscriber on the events it dispatches (namespaced around Mailgun status changes, typically one event per event-type or a single event carrying the event-data payload). Confirm the exact event class names by reading Event/ and EventDispatcher/Controller/ in the repo — with zero stars and no docs beyond the README, the source is the documentation.

Realistic integration patterns:

  • Persist raw + normalized. Store the raw Mailgun event-data JSON alongside normalized columns (message_id, recipient, event, timestamp). Webhook replays happen; dedupe on Mailgun's id / signature timestamp so retries don't produce duplicate state transitions.
  • State machine per message. Map Mailgun events onto your own statuses. Mailgun does not guarantee ordering, so never write status = bounced blindly — use "last event by timestamp wins" or a monotonic ranking (queued < accepted < delivered < opened < clicked).
  • Fan out to jobs. In the listener, do the minimum (validate, persist, enqueue). Bounce/complaint handling belongs in a queued job, especially if it touches your suppression list or CRM.
  • Suppression list sync. bounced (permanent) and spam_complaint should feed a suppression table immediately; temporary_fail should not. This is the highest-value pattern and the one the bundle's event model is designed to enable.
  • Testing. Construct the event objects directly in unit tests rather than faking HTTP. For integration, replay a captured Mailgun payload through the handler service. Note that signature verification will reject hand-crafted payloads — stub the verifier in test config.

If you are adapting this into Laravel (the likely intent for a Laravel developer evaluating it), do not attempt to boot the bundle. Instead:

  • Use mailgun/mailgun-php for sending, and write a POST /webhooks/mailgun route.
  • Verify the signature yourself: HMAC-SHA256(timestamp + token, signing_key) and compare to the signature field, plus a timestamp skew check (~15 min). This is the part the bundle saves you, and it is ~20 lines.
  • Dispatch a Laravel event per type (MailgunWebhookReceived, or typed events) and queue listeners. Mirror the bundle's event granularity so any future migration is mechanical.

The bundle is also worth borrowing wholesale for its route + controller wiring if you are on Symfony: copy the controller shape rather than re-inventing content negotiation, signature rejection (401), and the 200-always-or-Mailgun-will-retry semantics.

Gotchas and Tips

  • It is unmaintained. Last release 2021-12-14, zero stars, zero dependents. Treat it as frozen. Pin the version, and assume no fixes for Mailgun API changes or Symfony 6/7 compatibility. Read every file before trusting it in production; there is no community to catch a bug.
  • Symfony-only. The biggest trap for a Laravel dev is assuming "bundle" means "installable Laravel package." It does not. The only viable Laravel use is as reference code.
  • Signature verification is not optional. Mailgun sends timestamp, token, and signature at the top level of every webhook. If the bundle's config lets you disable verification for local dev, make absolutely sure it is re-enabled in production — an unverified webhook endpoint is an open door for anyone to mark arbitrary addresses as delivered or bounce them.
  • Mailgun retries. Mailgun retries failed webhooks with backoff. Your handler must be idempotent. Return 2xx fast, process async.
  • Config key naming quirks. With an undocumented bundle, the exact config path (e.g. mailgun_mail_status.api_key vs mailgun_mail_status.mailgun.key) has to be read off the Configuration.php (TreeBuilder) or the DependencyInjection/Configuration node. Don't guess from the README alone; it may be stale relative to source.
  • Service visibility. If your listener isn't being called, it's almost always a service autowiring/tag issue. Confirm the service is public or tagged (kernel.event_subscriber), and check bin/console debug:event-dispatcher for the Mailgun event name to see registered listeners.
  • Extension points are thin. The realistic customization surface is: your own event listeners/subscribers, and overriding the bundle's services in services.yaml. There is unlikely to be a clean strategy interface for swapping the storage layer — expect to write your own persistence in a listener rather than relying on whatever (if anything) the bundle ships.
  • Debugging. Mailgun's dashboard has a webhooks log with request/response bodies and delivery attempts — start there to separate "Mailgun never sent it" from "we failed to handle it." Combined with Symfony's debug:event-dispatcher and the profiler, you can triangulate quickly.
  • Verdict for a Laravel team: do not adopt. Use it as a 30-minute read to extract the webhook verification + event mapping pattern, then implement natively in Laravel with mailgun/mailgun-php and a queued listener. You get the same capability, supported, and without a 2021 Symfony dependency you cannot upgrade.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect