PHPackages                             akhan619/laravel-ses-event-manager - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. akhan619/laravel-ses-event-manager

ActiveLibrary[HTTP &amp; Networking](/categories/http)

akhan619/laravel-ses-event-manager
==================================

A Laravel package to manage incoming SES email events with http/s webhooks.

v1.0.4(2y ago)148.8k6[1 issues](https://github.com/akhan619/laravel-ses-event-manager/issues)MITPHPPHP ^8.0

Since Apr 26Pushed 2y ago2 watchersCompare

[ Source](https://github.com/akhan619/laravel-ses-event-manager)[ Packagist](https://packagist.org/packages/akhan619/laravel-ses-event-manager)[ Docs](https://github.com/akhan619/laravel-ses-event-manager)[ RSS](/packages/akhan619-laravel-ses-event-manager/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (9)Versions (6)Used By (0)

Laravel Ses Event Manager
=========================

[](#laravel-ses-event-manager)

[![Latest Stable Version](https://camo.githubusercontent.com/ab8645a9455ebf6a3cfe41e9ea8ac3a72e9b8633e57d20370a1e8abc08da18c0/687474703a2f2f706f7365722e707567782e6f72672f616b68616e3631392f6c61726176656c2d7365732d6576656e742d6d616e616765722f763f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akhan619/laravel-ses-event-manager)[![Tests](https://github.com/akhan619/laravel-ses-event-manager/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/akhan619/laravel-ses-event-manager/actions/workflows/test.yml/badge.svg?branch=main)[![PHP Version Require](https://camo.githubusercontent.com/40b4435ef9edb2a996bced99c4ea6112340013fa9f19b7fdeb5210d2a6fe7dd3/687474703a2f2f706f7365722e707567782e6f72672f616b68616e3631392f6c61726176656c2d7365732d6576656e742d6d616e616765722f726571756972652f7068703f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akhan619/laravel-ses-event-manager)[![Total Downloads](https://camo.githubusercontent.com/9c03506a85ffd0c2cf134950b9c3113b8ab40b52fd130cc7517300e5ffd0c9a9/687474703a2f2f706f7365722e707567782e6f72672f616b68616e3631392f6c61726176656c2d7365732d6576656e742d6d616e616765722f646f776e6c6f6164733f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akhan619/laravel-ses-event-manager)[![StyleCI](https://camo.githubusercontent.com/afdb9ce1da3f9b4387d0c74c3b493797500d36736cdffe699e4fe5ec88d17cd3/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3438343631393937382f736869656c643f6272616e63683d6d61696e)](https://github.styleci.io/repos/484619978?branch=main)[![License](https://camo.githubusercontent.com/679a9563a4d74c1b6207825d247952b4d1e05905d068e041702488d341dc0411/687474703a2f2f706f7365722e707567782e6f72672f616b68616e3631392f6c61726176656c2d7365732d6576656e742d6d616e616765722f6c6963656e73653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akhan619/laravel-ses-event-manager)

Manage incoming `SES` email event notifications over the http/s protocols. This package provides all the set up needed to send normal and queued emails using `SES` and then handle the email event notifications sent by `SES` to http/s webhook. This includes all 10 events as listed by `SES` like `send`, `bounce`, `open`, `click`, etc. Database and eloquent models are provided which store the event data. Don't want to use the models provided by the package or want to handle the event differently. Don't worry! you are covered. Every part of the pacakge is implemented to be modifable by the end user.

What this package does
----------------------

[](#what-this-package-does)

As mentioned this package handles the process of:

- Setting up the webhook routes to receive notifications.
- Setting up the controllers to confirm incoming subscription confirmations.
- Setting up the controllers to handle storing the event data to the database.
- Setting up the database tables.
- Define the eloquent models to represent the data to be stored.
- Send/Queue emails to be tracked.

What this package doesn't do
----------------------------

[](#what-this-package-doesnt-do)

The package will not do anything beyond what is mentioned above. So, the package won't:

- Create the AWS resources to actually set up the event notifications like
    - Configuration Sets
    - Event Destinations
    - SNS Topics
    - SNS Subscribers
- Perform post data-acquisition tasks like stats for emails sent, etc.

If you need to set up the `AWS SES/SNS` resources you may look at the package [Laravel Ses Tracking](https://github.com/akhan619/laravel-ses-tracking). The package provides a simple artisan command for setting up your `AWS` resources. Of course, this is completely optional and you may use any other method to set up the required resources.

> **FULL DISCLOSURE**: I am the package author for the `Laravel Ses Tracking` package.

Laravel and PHP Versions
========================

[](#laravel-and-php-versions)

The package is written for Laravel 9 and Php 8 and above.

Installation
============

[](#installation)

Via Composer

```
composer require akhan619/laravel-ses-event-manager
```

Configuration File

You can publish the configuration file using the following artisan command:

```
php artisan vendor:publish --provider="Akhan619\LaravelSesEventManager\LaravelSesEventManagerServiceProvider" --tag="lsem-config"
```

This is will publish a new configuration file called `laravel-ses-event-manager.php` in the `config` folder.

Migrations
==========

[](#migrations)

To use the eloquent models provided by the package, you must publish the database migrations of the package using the following artisan command:

```
php artisan vendor:publish --provider="Akhan619\LaravelSesEventManager\LaravelSesEventManagerServiceProvider" --tag="lsem-migrations"
```

Don't forget to run the migrations using

```
php artisan migrate
```

Local Development
=================

[](#local-development)

To test the package during local development you will need a way to actually serve the `Laravel` project so that `AWS` can send the event notifications. You may do so in many ways. One way to do so is by using a tunneling service. I personally used [Expose](https://expose.dev) by `Beyond Code` during development.

> **FULL DISCLOSURE**: I am NOT sponsored by `Beyond Code`.

Requirements
============

[](#requirements)

To start using the package, it is assumed that the necessary set up on `AWS` is complete. This means:

- Configuration Set exists
- SNS Topics exist.
- Event Destinations for the events to listen to exist.
- The webhooks (http/s) that will be used, have been subscribed to the SNS Topics.

> **NOTE**: You don't have to confirm the SNS subscription. The package can handle them for you. If you have already completed the above, you can go to the `AWS` console and resend the confirmation notifications and the package will confirm them for you.

Restrictions
============

[](#restrictions)

Since the package needs to track email events, there is a limit of **one** recipient per email. So fields like `cc` or `bcc` will not work and throw an exception. This is because `SES` will only send back one id even with multiple recipients. And with one `id` its' not possible to track email events correctly. If you need to send the same email to multiple recipients simply loop over the recipients like below:

```
foreach (['john@doe.com', 'jane@doe.com'] as $recipient) {
    SesMailer::to($recipient)->send($mailable);
}
```

Usage
=====

[](#usage)

The package provides the `SesMailer` facade. The facade mimics the Laravel `Mail` facade so can use it just the same. For receiving and storing the notifications successfully, you must use the facade provided by the package. This is so we can track emails by the id provided by `SES`.

Sending Emails
--------------

[](#sending-emails)

```
use Akhan619\LaravelSesEventManager\Facades\SesMailer;

SesMailer::to('john@doe.com')->send($someMailable);

// Or if the recipient in specified in the mailable then,

SesMailer::send($someMailable);
```

Queueing Emails
---------------

[](#queueing-emails)

To queue emails for now or later, you must add the `QueueForCustomMailer` trait to your mailable. Then you may queue mails as in the framework.

```
use Akhan619\LaravelSesEventManager\Traits\QueueForCustomMailer;

class TestMailableWithTrait extends Mailable
{
    use Queueable, SerializesModels, QueueForCustomMailer;

    ...
}

// Then, as before
$testMailableWithTrait = new TestMailableWithTrait();

SesMailer::to('john@doe.com')->later(now()->addHours(12), $testMailableWithTrait);
```

Models
------

[](#models)

The package uses eloquent models to store the outgoing/incoming email status. All models are specified in the `Akhan619\LaravelSesEventManager\App\Models` namespace under the `src/App/Models` directory. The main model is the `Email` model which provides the following fields:

```
protected $fillable = [
    'message_id', // The Ses id returned by the call to sendRawEmail
    'email', // The email recipient.
    'name', // Recipient name if any.

    // Boolean fields to show the events that have been received for the email.
    'has_send',
    'has_rendering_failure',
    'has_reject',
    'has_delivery',
    'has_bounce',
    'has_complaint',
    'has_delivery_delay',
    'has_subscription',
    'has_open',
    'has_click'
];
```

For every field above there is a Eloquent relationship which is also defined. The relationships are:

```
// Has Many
clicks()
opens()

// Has One
bounce()
complaint()
delivery()
send()
reject()
renderingFailure()
deliveryDelay()
subscription()
```

So you may use the above as:

```
use Akhan619\LaravelSesEventManager\App\Models\Email;

$email = Email::first();

if($mail->has_bounce) {
    echo 'Email has bounced';
}

// Get the bounce data
$bounce = $email->bounce;
```

All the relevant fields present in a given `SES` event are available via the Eloquent model for the event. Please refer to the model for more details. An example of the kind of data for the `EmailBounce` model is given below:

```
protected $fillable = [
    'message_id',
    'bounce_type',
    'bounce_sub_type',
    'feedback_id',
    'action',
    'status',
    'diagnostic_code',
    'reporting_mta',
    'bounced_at',
];
```

Custom Handler
--------------

[](#custom-handler)

If you don't want to use the models provided by the package you may register your own logic for handling the event by registering a `callback` for the given event. You will need to call the `extend` method of a `ModelResolver` instance with your callback in the `boot` method of a `ServiceProvider`. The `callback` will receive two parameters `eventType` and `data`. The possible values and the data they receive are:

EventTypeDataMessageSentIlluminate\\Mail\\SentMessageBounceObject \[The message field of a SNS notification\]ComplaintObject \[The message field of a SNS notification\]DeliveryObject \[The message field of a SNS notification\]SendObject \[The message field of a SNS notification\]RejectObject \[The message field of a SNS notification\]OpenObject \[The message field of a SNS notification\]ClickObject \[The message field of a SNS notification\]RenderingFailureObject \[The message field of a SNS notification\]DeliveryDelayObject \[The message field of a SNS notification\]SubscriptionObject \[The message field of a SNS notification\]For example, add the following to the boot method of the `AppServiceProvider` which comes with the default `Laravel` project.

```
use Akhan619\LaravelSesEventManager\Contracts\ModelResolverContract;

public function boot(ModelResolverContract $resolver)
{
    $resolver->extend('MessageSent', function($event, $data) {
        // Will echo the recipient email address.
        echo current($data->getOriginalMessage()->getTo())->getAddress();
    });
}

// OR

public function boot()
{
    $resolver = app()->make(ModelResolverContract::class);
    $resolver->extend('Bounce', function($event, $data) {
        // The bounce type
        echo $data->bounce->bounceType;
    });
}
```

Refer to the [Laravel](https://laravel.com/api/9.x/Illuminate/Mail/SentMessage.html) docs or the [AWS](https://docs.aws.amazon.com/ses/latest/dg/event-publishing-retrieving-sns-contents.html) docs for more info.

Configuration
=============

[](#configuration)

Debug Mode
----------

[](#debug-mode)

You may log debug data to the default logger by setting debug to `true` in the config file.

```
'debug' => false,
```

Subscription Confirmation
-------------------------

[](#subscription-confirmation)

By default, incoming subscription confirmations are automatically confirmed by the package. If you do not want this behavior, you may disable this by setting the `confirm_subscription` to `false` in the config file.

```
'confirm_subscription' => true,
```

Credentials
-----------

[](#credentials)

The credentials to use for `SES` will be picked up from the `.env` file. If you wish to use a different set of credentials, you may specify them in the `ses_options` key in the config file.

```
'ses_options' => [
    'key'       => env('AWS_ACCESS_KEY_ID'),
    'secret'    => env('AWS_SECRET_ACCESS_KEY'),
    'region'    => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ...
],
```

Configuration Set/Options
-------------------------

[](#configuration-setoptions)

The configuration set to use when sending emails to track must be specified in the `.env`.

```
CONFIGURATION_SET_NAME=

```

If you want, you can also specify it in the config file alongwith any other options under the `ses_options` key in the config file.

```
'ses_options' => [
    ...
    'options' => [
        'ConfigurationSetName' => env('CONFIGURATION_SET_NAME'),

    ],
],
```

Events
------

[](#events)

You may specify the notifications to listen for using the `active_email_events` key in the config file. Set the event to `true` to enable the event.

```
'active_email_events' => [
    'sends'                 => true,
    'rendering_failures'    => false,
    'rejects'               => false,
    'deliveries'            => true,
    'bounces'               => true,
    'complaints'            => false,
    'delivery_delays'       => true,
    'subscriptions'         => true,
    'opens'                 => false,
    'clicks'                => false,
],
```

Webhook Routes
--------------

[](#webhook-routes)

You must specify the routes to listen on, so that the controllers and named routes may be generated. These may be specified using the following in the config file:

```
'named_route_prefix' => 'lsem',

'route_prefix' => 'email/notification',

'routes' => [
    'sends'                     => 'sends',
    'rendering_failures'        => 'rendering-failures',
    'rejects'                   => 'rejects',
    'deliveries'                => 'deliveries',
    'bounces'                   => 'bounces',
    'complaints'                => 'complaints',
    'delivery_delays'           => 'delivery-delays',
    'subscriptions'             => 'subscriptions',
    'opens'                     => 'opens',
    'clicks'                    => 'clicks',
],
```

So for example on a fresh `Laravel` project the route for `delivery_delays` will be generated as:

```
Route_Key                      Route_Value
'delivery_delays'           => 'delivery-delays',

URL:
APP_URL/route_prefix/Route_Value

NAME:
named_route_prefix.Route_Key

Example:

URL:
http://localhost/email/notification/delivery-delays

NAME:
lsem.delivery_delays
```

> **NOTE**: Routes are registered only when the corresponding event is enabled.

You may specify any middleware that should be used in the `route_middleware` array.

```
'route_middleware' => [],
```

Database
--------

[](#database)

Make sure you have published the migration files and run `php artisan migrate`. By default the tables names are generated as:

```
lsem_****

Example:

lsem_emails
lsem_email_sends
...

```

If for some reason the table names are in conflict with existing tables, you may change the table prefix using the `database_name_prefix` key in the config file.

```
'database_name_prefix' => 'lsem',
```

Disable Webhook
---------------

[](#disable-webhook)

If for some reason you don't want the package to listen to incoming notifications, you may disable all the routes by setting `handle_email_events` to `false` in the config file.

```
'handle_email_events' => true,
```

This is will disable all the routes that were registered and partially disable the package.

> **NOTE**: This will not disable the sending of emails. So if you have used the `SesMailer` facade to send emails in your code, that will continue to work.

Change log
==========

[](#change-log)

Please see the [changelog](changelog.md) for more information on what has changed recently.

Testing
=======

[](#testing)

Run the tests using

```
composer test
```

Contributing
============

[](#contributing)

Please see [contributing.md](contributing.md) for details and a todolist.

Security
========

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
=======

[](#credits)

- Aman Khan

License
-------

[](#license)

MIT. Please see the [license file](license.md) for more information.

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity30

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 60% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~133 days

Total

5

Last Release

943d ago

PHP version history (2 changes)v1.0.0PHP ^8.0.2

v1.0.2PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/77b713dd3390ee3218fdfa200e37e46ccea3b9746722eac15e7eaab21b7a5ffc?d=identicon)[akhan619](/maintainers/akhan619)

---

Top Contributors

[![akhan619](https://avatars.githubusercontent.com/u/73259168?v=4)](https://github.com/akhan619 "akhan619 (6 commits)")[![TheDoctor0](https://avatars.githubusercontent.com/u/16612504?v=4)](https://github.com/TheDoctor0 "TheDoctor0 (3 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (1 commits)")

---

Tags

httphttpslaravelemaileventssendopenwebhooksbouncedeliverysesclick

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/akhan619-laravel-ses-event-manager/health.svg)

```
[![Health](https://phpackages.com/badges/akhan619-laravel-ses-event-manager/health.svg)](https://phpackages.com/packages/akhan619-laravel-ses-event-manager)
```

###  Alternatives

[pusher/pusher-http-laravel

\[DEPRECATED\] A Pusher bridge for Laravel

400509.0k3](/packages/pusher-pusher-http-laravel)[akhan619/laravel-ses-tracking

A Laravel artisan based package to create the AWS (SES + SNS) infrastructure to receive email event notifications with Http/Https endpoint.

149.9k](/packages/akhan619-laravel-ses-tracking)[renoki-co/laravel-aws-webhooks

Easy webhook handler for Laravel to catch AWS SNS notifications for various services.

73248.5k](/packages/renoki-co-laravel-aws-webhooks)[dragon-code/laravel-http-logger

Logging incoming HTTP requests

319.8k3](/packages/dragon-code-laravel-http-logger)[ankurk91/laravel-ses-webhooks

Handle AWS SES webhooks in Laravel php framework

2534.2k](/packages/ankurk91-laravel-ses-webhooks)[laravel-shift/curl-converter

A command line tool to convert curl requests to Laravel HTTP requests.

935.3k](/packages/laravel-shift-curl-converter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
