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

Bouncer Bundle Laravel Package

neogen/bouncer-bundle

Neogen Bouncer Bundle wraps Bouncer's role and permission system for Laravel into a ready-to-use package, so you can define roles, assign abilities, and gate access with concise authorization checks and minimal configuration, keeping user permissions readable and easy to audit.

View on GitHub
Deep Wiki
Context7

Getting Started

Bouncer is a Symfony bundle that reads AWS SES bounce/complaint notifications (SQS or SNS-driven) and maintains a local bounce list so you can suppress bad addresses before handing mail to SwiftMailer. Because the last release is from December 2017, treat it as a legacy Symfony 2/3/4 (pre-flex) bundle and pin your expectations accordingly — it was written for PHP 5.6/7.0 and Symfony 2.8–3.4 era APIs.

Minimal steps:

  1. composer require neogen/bouncer-bundle — expect to add "minimum-stability": "dev" or a manual dev-master constraint, since the tagged release is old and may not satisfy a modern Symfony constraint solver.
  2. Register the bundle in app/AppKernel.php (or config/bundles.php if you're on Symfony 4 Flex): new Neogen\BouncerBundle\BouncerBundle().
  3. Import the bundle routing so the SES/SNS webhook endpoint is exposed:
    # app/config/routing.yml
    bouncer:
        resource: "@BouncerBundle/Resources/config/routing.yml"
        prefix:   /bouncer
    
  4. Configure credentials and the storage adapter in config.yml under bouncer: — you'll need AWS key/secret, region, and the SQS queue (or SNS topic) ARN that SES is publishing bounce/complaint notifications to.
  5. First use case to validate the install: point SES's "Bounce" and "Complaint" notification topics at the bundle's endpoint, send a test email to [email protected], and confirm the address shows up in your local bounce table and that subsequent SwiftMailer sends to it are blocked.

If you're on Symfony 5/6/7 or use Symfony Mailer instead of SwiftMailer, do not install this — the SwiftMailer plugin wiring it relies on was removed in Symfony 4.3+/5.0, and the AWS SDK v2/v3 signatures it uses have changed. In that case, read this document as a design reference and implement the same pattern (SES notification → suppression list → mailer filter) yourself with aws/aws-sdk-php and a Symfony Mailer event subscriber; it's roughly a day of work and you get something maintained.

Implementation Patterns

The core pattern: notification ingestion → suppression table → send-time filter. Bouncer's value is that it closes the loop automatically. AWS SES sends a JSON notification (via SNS → SQS or SNS → HTTP) whenever a message bounces permanently or is marked as a complaint. The bundle consumes that, extracts the recipient, and records it. Then a SwiftMailer beforeSendPerformed-style filter consults the table and silently drops (or throws on) any message to a suppressed address.

Pattern 1 — Cron-driven SQS polling. Most production setups don't expose a public HTTP endpoint. Instead you run the bundle's consumer as a periodic command (5-minute cron or a worker). This is the recommended pattern because SQS retains messages and gives you retry semantics; SNS HTTP delivery requires you to handle subscription confirmation handshakes yourself.

Pattern 2 — SNS webhook endpoint. For lower-latency suppression and simpler ops (no queue), point SNS at the bundle's route. You must handle the SubscriptionConfirmation message type first — this is easy to miss and means bounces silently never arrive. The route handler should verify the SNS signature before trusting the payload.

Pattern 3 — Batch import from SES suppression list. If you've been running in AWS for a while, seed Bouncer from SES's account-level suppression list (or from ses:GetIdentityNotificationAttributes + CloudWatch metrics) rather than starting empty. Otherwise the first weeks of mail are unprotected against addresses that bounced before you installed the bundle.

Integration tip — wire the filter, don't just ingest. Installing the bundle and letting it store bounces does nothing on its own; the SwiftMailer filter is what protects you. Confirm in a test that $mailer->send() to a known-bounced address is actually blocked, not just that the address is in the DB. The filter typically needs explicit enabling in config.yml under something like bouncer.swiftmailer.filter: true depending on the version.

Complaints are not bounces — treat them differently. A hard bounce means the address is dead; a complaint means the human hit "spam" and never wants to hear from you again, but the address is technically valid. Both should suppress, but complaints usually warrant an immediate unsubscribe action and possibly an alert to your support/CRM team, whereas bounces are routine. Bouncer stores them, but the downstream reaction is yours to build — hook the bundle's storage layer (or listen to its events, if your version exposes them) to feed complaints into your CRM.

Pair with SwiftMailer's own retry/backoff. Bouncer only suppresses; it doesn't retry. For soft bounces you likely want retry logic in a worker, and Bouncer only intervenes on the permanent cases. Don't let the bundle name mislead you into thinking it handles soft-bounce retry — it doesn't.

Gotchas and Tips

The package is abandoned. No commits since 2017, zero stars, zero dependents. Assume no security patches, no PHP 8 compatibility, no support. The AWS SDK it depends on (v2-era) is long deprecated. Do a hard audit of composer.lock before putting this near production, and seriously consider a fork-and-maintain or a rewrite.

SwiftMailer is EOL (Nov 2021). The whole integration surface — Swift_Plugins_*, the swiftmailer service — is gone in modern Symfony. If your app still runs SwiftMailer you're already on borrowed time; Bouncer is a symptom, not the cure.

SNS subscription confirmation is the #1 silent failure. If you set the webhook and bounces never appear, check whether the endpoint ever returned the SubscribeURL confirmation. SNS retries for a while, then gives up silently. Test with the SES simulator addresses ([email protected], [email protected], [email protected]) and confirm all three behave as expected.

Notification JSON shape changed over the years. SES moved to a unified eventType: Bounce | Complaint | Delivery | Open | Click envelope. Bouncer's 2017 parser expects the older notificationType shape. If your SNS topic emits modern events, the bundle may throw on Delivery and Open events it doesn't recognize — either filter the SQS subscription policy to only deliver Bounce and Complaint, or patch the parser. Filtering at the subscription is cleaner and cheaper.

Region and credentials are the usual AWS footguns. The bundle was written when us-east-1 was the default everywhere; if you're in a newer region, double-check the bouncer.aws.region key is actually read from config and not hard-coded in the service definition. Also confirm the IAM role/key has sqs:ReceiveMessage, sqs:DeleteMessage, sqs:GetQueueAttributes on the queue — missing delete permission means messages redeliver forever and you'll get duplicate suppression entries.

Suppression table growth and uniqueness. Bounce notifications can arrive multiple times for the same address (redelivery). Make sure the underlying storage enforces a unique constraint on the email/address column, or you'll accumulate duplicates and slow the send-time lookup. If Bouncer's schema doesn't include one (check the migration in Resources/), add an index yourself.

Extension points are thin. There's no event dispatcher integration in most versions of this bundle — the cleanest extension path is to decorate the storage service (bouncer.storage or similar — grep the service definitions in Resources/config/services.yml) so you can mirror suppressions into your own DB, CRM, or a Redis set for fast send-time checks. Decoration is your escape hatch for everything this bundle doesn't do: complaint alerting, soft-bounce retry, per-tenant suppression lists.

Debugging tips. When a bounce doesn't register: (1) check the SQS queue depth — non-zero means the consumer isn't running; (2) tail the consumer command's output for JSON parse errors; (3) verify the SES notification topic is enabled for both bounces and complaints in the SES identity console (it's off by default and easy to miss); (4) confirm the message reached SNS at all via the SNS console's delivery logs, which you must explicitly enable.

If you're starting greenfield, skip this bundle entirely. The pattern it implements is worth copying — SQS consumer → suppression table → mailer listener — but the code isn't. A modern equivalent is ~200 lines using aws/aws-sdk-php v3 and a Symfony Mailer MessageEvent listener, and you'll actually be able to get support on it in 2024+.

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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package