PHPackages                             juhasev/laravel-ses - 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. [Mail &amp; Notifications](/categories/mail)
4. /
5. juhasev/laravel-ses

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

juhasev/laravel-ses
===================

Allows you to track opens, deliveries, bounces, complaints and clicked links when sending emails through Laravel and Amazon SES

6.0.1(1mo ago)1710.3k↑300%6MITPHPPHP ^8.2CI passing

Since Mar 25Pushed 1mo ago3 watchersCompare

[ Source](https://github.com/juhasev/laravel-ses)[ Packagist](https://packagist.org/packages/juhasev/laravel-ses)[ RSS](/packages/juhasev-laravel-ses/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (26)Versions (47)Used By (0)

[![alt text](laravel-ses.png "Laravel SES")](laravel-ses.png)

Laravel SES (Simple Email Service AWS)
======================================

[](#laravel-ses-simple-email-service-aws)

Laravel SES is package that allows you to get sending statistics for emails you send through AWS SES (Simple Email Service), including deliveries, opens, bounces, complaints and link tracking. This package was originally written by Oliveready7. Unfortunately, the original author had stopped maintaining this package, so I decided to create this fork so that this package can be used with current versions of Laravel.

All packages have been updated to modern versions. I have optimized the original database storage for space and proper indexing. This package is compatible with Laravel 11.x.

Laravel SES also supports SMTP errors codes will throw meaning exceptions like when you exceed your rate limits so you can handle proper back off.

Laravel version support:

- If you are using Laravel 11 use `v5.*`
- If you are using Laravel 10 use `v4.*`
- If you are using Laravel 9 use `v3.*`
- If you are using Laravel 7 or 8 use `v1.1.5`
- If you are using Laravel 6 use `v0.8.4`

Installation
------------

[](#installation)

Install via composer

```
composer require juhasev/laravel-ses
composer require aws/aws-php-sns-message-validator (optional)
```

In config/app.php make sure you load up the service provider. This should happen automatically.

```
Juhasev\LaravelSes\LaravelSesServiceProvider::class
```

Laravel configuration
---------------------

[](#laravel-configuration)

Make sure your app/config/services.php has SES values set

```
'ses' => [
    'key' => your_ses_key,
    'secret' => your_ses_secret,
    'domain' => your_ses_domain,
    'region' => your_ses_region
],
```

Make sure your mail driver located in app/config/mail.php is set to 'ses'

```
    'default' => env('MAIL_MAILER', 'ses')
```

Publish public assets

```
php artisan vendor:publish --tag=ses-assets --force
```

Publish migrations

```
php artisan vendor:publish --tag=ses-migrations --force
```

Publish the package's config (laravelses.php)

```
php artisan vendor:publish --tag=ses-config
```

### Routes

[](#routes)

This package add 3 public routes to your application that AWS SNS callbacks target

```
/ses/notification/bounce
/ses/notification/complaint
/ses/notification/delivery

```

We also add two more public routes for tracking opens and link clicks

```
/ses/beacon
/ses/link

```

Config Options

- aws\_sns\_validator - whether the package uses AWS's SNS validator for inbound SNS requests. Default = false
- debug - Debug mode that logs all SNS call back requests

AWS Configuration
-----------------

[](#aws-configuration)

### Pre-reading

[](#pre-reading)

If you are new to using SES Notification this article is a good starting point

### IAM User and policies

[](#iam-user-and-policies)

Your application IAM user needs to be send email via SES and subscribe to SNS notifications. This can be done in the AWS Control Panel as the article above suggests or AWS CloudFormation template like one below:

AWS CloudFormation policy example:

```
  ApplicationSNSPolicy:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      Description: "Policy for sending subscribing to SNS bounce notifications"
      Path: "/"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - sns:CreateTopic
              - sns:DeleteTopic
              - sns:Subscribe
              - sns:Unsubscribe
            Resource:
              - 'arn:aws:sns:*'

  ApplicationSESPolicy:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      Description: "Policy for creating SES bounce notification"
      Path: "/"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - ses:*
            Resource:
              - '*'

```

Once policies are defined they need to added to the configured IAM user.

```
  # AWS PHP API User
  APIUser:
    Type: "AWS::IAM::User"
    Properties:
      ManagedPolicyArns:
        - !Ref ApplicationSNSPolicy
        - !Ref ApplicationSESPolicy
      UserName: staging-user

```

### Running setup

[](#running-setup)

Make sure in your APP\_URL (in .env) is set correctly, matching your sending domain. If you do send email for multiple domains (i.e. multi tenant application) you can set multiple domains using this command.

> You need to have SES domain ready before continuing

The setup command automatically configures your SES domain to send SNS notifications that trigger call backs to your Laravel application.

```
php artisan sns:setup mydomain.com
```

> NOTE: You should not attempt to use sub domains client.mydomain.com, this is not currently supported by AWS.

Usage
-----

[](#usage)

To send an email with all tracking enabled

```
SesMail::enableAllTracking()
    ->to('hello@example.com')
    ->send(new Mailable);
```

Calling enableAllTracking() enables open, reject, bounce, delivery, complaint and link tracking.

### Overriding the tracking domain per message

[](#overriding-the-tracking-domain-per-message)

By default all tracking URLs (the open-tracking beacon and the rewritten link-tracking hrefs) are built from your global `APP_URL`. If you send mail for multiple domains (e.g. a multi-tenant application) you can override the domain for a single message with the chainable `customDomain()` method:

```
SesMail::enableAllTracking()
    ->customDomain('https://newdomain.com')
    ->to('hello@example.com')
    ->send(new Mailable);
```

The open beacon and every tracked link in that message will point at `https://newdomain.com/ses/...` instead of `APP_URL`. Pass `null` (or simply omit the call) to fall back to the global `APP_URL`. Make sure the package routes are reachable on the custom domain.

> Please note that an LaravelSesTooManyRecipients Exception is thrown if you attempt send a Mailable that contains multiple recipients when Open -tracking is enabled.

Other exception thrown are:

```
LaravelSesDailyQuotaExceededException::class
LaravelSesInvalidSenderAddressException::class
LaravelSesMaximumSendingRateExceeded::class
LaravelSesSendFailedException::class
LaravelSesTemporaryServiceFailureException::class
LaravelSesTooManyRecipientsException::class
```

You can catch them all using the base class:

```
try {
    SesMail::enableAllTracking()
        ->to('hello@example.com')
        ->send(new Mailable);

} catch (LaravelSesMaximumSendingRateExceeded $e) {

    // Implement back off logic

} catch (LaravelSesException $e) {

    $smtpCode = $e->getCode();
    $smtpErrorMessage = $e->getMessage();

    // Do something like back of if rate limit is reached.
)

You can, of course, disable and enable all the tracking options

```php
SesMail::disableAllTracking();
SesMail::disableOpenTracking();
SesMail::disableLinkTracking();
SesMail::disableBounceTracking();
SesMail::disableComplaintTracking();
SesMail::disableDeliveryTracking();

SesMail::enableAllTracking();
SesMail::enableOpenTracking();
SesMail::enableLinkTracking();
SesMail::enableBounceTracking();
SesMail::enableComplaintTracking();
SesMail::enableDeliveryTracking();
```

The batching option gives you the chance to group emails, so you can get the results for a specific group

```
SesMail::enableAllTracking()
    ->setBatch('welcome_emails')
    ->to('hello@example.com')
    ->send(new Mailable);
```

You can also get aggregate stats:

```
Stats::statsForEmail($email);

$stats = Stats::statsForBatch('welcome_emails');

print_r($stats)
```

```
[
    "sent" => 8,
    "deliveries" => 7,
    "opens" => 4,
    "bounces" => 1,
    "complaints" => 2,
    "clicks" => 3,
    "link_popularity" => [
        "https://welcome.page" => [
            "clicks" => 3
        ],
        "https://facebook.com/brand" => [
            "clicks" => 1
        ]
    ]
]

```

To get individual stats via Repositories

```
EmailStatRepository::getBouncedCount($email);
EmailRepository::getBounces($email);

BatchStatRepository::getBouncedCount($batch);
BatchStatRepository::getDeliveredCount($batch);
BatchStatRepository::getComplaintsCount($batch);
```

You can also use the models directly as you would any other Eloquent model:

```
$sentEmails = SentEmail::whereEmail($email)->get();

$emailBounces = EmailBounce::whereEmail($email)->get();
$emailComplaints = EmailComplaint::whereEmail($email)->get();
$emailLink = EmailLink::whereEmail($email)->get();
$emailOpen = EmailOpen::whereEmail($email)->get();
```

If you are using custom models then you can use ModelResolver() helper like so

```
$sentEmail = ModelResolver::get('SentEmail')::take(100)->get();
```

### Listening to event

[](#listening-to-event)

Event subscriber can be created:

```
